소스 검색

enhance(ui): new version installation tips instead of native alert message

charlie 4 년 전
부모
커밋
1370fb4d18

+ 4 - 0
resources/js/preload.js

@@ -25,6 +25,10 @@ contextBridge.exposeInMainWorld('apis', {
     return await ipcRenderer.invoke('main', arg)
   },
 
+  invoke: async (channel, args) => {
+    return await ipcRenderer.invoke(channel, ...args)
+  },
+
   addListener: ipcRenderer.on.bind(ipcRenderer),
   removeListener: ipcRenderer.removeListener.bind(ipcRenderer),
   removeAllListeners: ipcRenderer.removeAllListeners.bind(ipcRenderer),

+ 19 - 11
src/electron/electron/core.cljs

@@ -31,6 +31,7 @@
 
 (defonce *setup-fn (volatile! nil))
 (defonce *teardown-fn (volatile! nil))
+(defonce *quit-dirty? (volatile! true))
 
 ;; Handle creating/removing shortcuts on Windows when installing/uninstalling.
 (when (js/require "electron-squirrel-startup") (.quit app))
@@ -171,8 +172,13 @@
   (let [toggle-win-channel "toggle-max-or-min-active-win"
         call-app-channel "call-application"
         export-publish-assets "export-publish-assets"
+        quit-dirty-state "set-quit-dirty-state"
         web-contents (. win -webContents)]
     (doto ipcMain
+      (.handle quit-dirty-state
+               (fn [_ dirty?]
+                 (vreset! *quit-dirty? (boolean dirty?))))
+
       (.handle toggle-win-channel
                (fn [_ toggle-min?]
                  (when-let [active-win (.getFocusedWindow BrowserWindow)]
@@ -236,6 +242,7 @@
 
     #(do (.removeHandler ipcMain toggle-win-channel)
          (.removeHandler ipcMain export-publish-assets)
+         (.removeHandler ipcMain quit-dirty-state)
          (.removeHandler ipcMain call-app-channel))))
 
 (defn- destroy-window!
@@ -301,17 +308,18 @@
 
                ;; main window events
                (.on win "close" (fn [e]
-                                  (.preventDefault e)
-                                  (let [web-contents (. win -webContents)]
-                                    (.send web-contents "persistent-dbs"))
-                                  (async/go
-                                    (let [_ (async/<! state/persistent-dbs-chan)]
-                                      (if (or @*quitting? (not mac?))
-                                        (when-let [win @*win]
-                                          (destroy-window! win)
-                                          (reset! *win nil))
-                                        (do (.preventDefault ^js/Event e)
-                                            (.hide win)))))))
+                                  (when @*quit-dirty?
+                                    (.preventDefault e)
+                                    (let [web-contents (. win -webContents)]
+                                      (.send web-contents "persistent-dbs"))
+                                    (async/go
+                                      (let [_ (async/<! state/persistent-dbs-chan)]
+                                        (if (or @*quitting? (not mac?))
+                                          (when-let [win @*win]
+                                            (destroy-window! win)
+                                            (reset! *win nil))
+                                          (do (.preventDefault ^js/Event e)
+                                              (.hide win))))))))
                (.on app "before-quit" (fn [_e] (reset! *quitting? true)))
                (.on app "activate" #(if @*win (.show win)))))))))
 

+ 4 - 1
src/electron/electron/handler.cljs

@@ -1,5 +1,5 @@
 (ns electron.handler
-  (:require ["electron" :refer [ipcMain dialog app]]
+  (:require ["electron" :refer [ipcMain dialog app autoUpdater]]
             [cljs-bean.core :as bean]
             ["fs" :as fs]
             ["buffer" :as buffer]
@@ -220,6 +220,9 @@
 (defmethod handle :uninstallMarketPlugin [_ [_ id]]
   (plugin/uninstall! id))
 
+(defmethod handle :quitAndInstall []
+  (.quitAndInstall autoUpdater))
+
 (defmethod handle :default [args]
   (println "Error: no ipc handler for: " (bean/->js args)))
 

+ 11 - 3
src/electron/electron/updater.cljs

@@ -1,5 +1,5 @@
 (ns electron.updater
-  (:require [electron.utils :refer [mac? win32? prod? open fetch logger]]
+  (:require [electron.utils :refer [mac? win32? prod? open fetch logger *win]]
             [frontend.version :refer [version]]
             [clojure.string :as string]
             [promesa.core :as p]
@@ -9,7 +9,7 @@
             ["os" :as os]
             ["fs" :as fs]
             ["path" :as path]
-            ["electron" :refer [ipcMain app]]))
+            ["electron" :refer [ipcMain app autoUpdater]]))
 
 (def *update-ready-to-install (atom nil))
 (def *update-pending (atom nil))
@@ -110,6 +110,12 @@
              (fn []
                (emit "completed" nil))))))))
 
+(defn- new-version-downloaded-cb
+  [_ & args]
+  (.info logger "[update-downloaded]" args)
+  (when-let [web-contents (and @*win (. @*win -webContents))]
+    (.send web-contents "auto-updater-downloaded" (bean/->js args))))
+
 (defn init-auto-updater
   [repo]
   (when (.valid semver electron-version)
@@ -123,7 +129,9 @@
             (debug "Found remote version" remote-version)
             (when mac?
               (when-let [f (js/require "update-electron-app")]
-                (f #js{}))))
+                (f #js{:notifyUser false})
+                (.once autoUpdater "update-downloaded"
+                       new-version-downloaded-cb))))
 
           (debug "Skip remote version [ahead of pre-release]" remote-version))))))
 

+ 6 - 0
src/main/electron/ipc.cljs

@@ -9,3 +9,9 @@
   (when (util/electron?)
     (p/let [result (js/window.apis.doAction (bean/->js args))]
       result)))
+
+(defn invoke
+  [channel & args]
+  (when (util/electron?)
+    (p/let [result (js/window.apis.invoke channel (bean/->js args))]
+      result)))

+ 28 - 1
src/main/frontend/components/header.cljs

@@ -7,6 +7,7 @@
             [frontend.components.svg :as svg]
             [frontend.config :as config]
             [frontend.context.i18n :as i18n]
+            [frontend.handler :as handler]
             [frontend.handler.page :as page-handler]
             [frontend.handler.plugin :as plugin-handler]
             [frontend.handler.user :as user-handler]
@@ -15,6 +16,7 @@
             [frontend.state :as state]
             [frontend.ui :as ui]
             [frontend.util :as util]
+            [cljs-bean.core :as bean]
             [reitit.frontend.easy :as rfe]
             [rum.core :as rum]))
 
@@ -154,6 +156,29 @@
     {:title "Go Forward" :on-click #(js/window.history.forward)}
     svg/arrow-narrow-right]])
 
+(rum/defc updater-tips-new-version
+  [t]
+  (let [[downloaded, set-downloaded] (rum/use-state nil)
+        _ (rum/use-effect!
+            (fn []
+              (when-let [channel (and (util/electron?) "auto-updater-downloaded")]
+                (let [callback (fn [_ & args]
+                                 (js/console.debug "[new-version downloaded] args:" args)
+                                 (let [args (bean/->clj args)]
+                                   (set-downloaded args)
+                                   (state/set-state! :electron/auto-updater-downloaded args))
+                                 nil)]
+                  (js/apis.addListener channel callback)
+                  #(js/apis.removeListener channel callback))))
+            [])]
+
+    (when downloaded
+      [:div.cp__header-tips
+       [:p (t :updater/new-version-install)
+        [:a.ui__button.restart
+         {:on-click #(handler/quit-and-install-new-version!)}
+         (svg/reload 16) [:strong (t :updater/quit-and-install)]]]])))
+
 (rum/defc header < rum/reactive
   [{:keys [open-fn current-repo white? logged? page? route-match me default-home new-block-mode]}]
   (let [local-repo? (= current-repo config/local-repo)
@@ -238,4 +263,6 @@
                        :current-repo current-repo
                        :default-home default-home})
 
-       (when (not (state/sub :ui/sidebar-open?)) (sidebar/toggle))])))
+       (when (not (state/sub :ui/sidebar-open?)) (sidebar/toggle))
+
+       (updater-tips-new-version t)])))

+ 56 - 16
src/main/frontend/components/header.css

@@ -36,26 +36,66 @@
     transform: scale(0.6);
     color: red;
   }
+
+  &-tips {
+    position: absolute;
+    width: 100%;
+    padding: 0 0;
+    transform: translateY(100%);
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    background-color: var(--ls-secondary-background-color);
+    box-sizing: border-box;
+    margin: 0;
+    left: 0;
+    top: -2px;
+    color: var(--ls-secondary-text-color);
+
+    > p {
+      margin: 0;
+      padding: 0 0 6px 0;
+    }
+
+    a {
+      color: var(--ls-link-text-color) !important;
+    }
+
+    a.restart {
+      position: relative;
+      top: 3px;
+      cursor: pointer !important;
+
+      svg {
+        color: currentColor !important;
+      }
+
+      > strong {
+        display: inline-block;
+        padding-left: 2px;
+      }
+    }
+  }
 }
 
 .is-electron.is-mac .cp__header {
-    padding-left: 78px;
-    -moz-transition: padding-left .3s ease-in;
-    -o-transition: padding-left  .3s ease-in;
-    -webkit-transition: padding-left  .3s ease-in;
-    transition: padding-left  .3s ease-in;
+  padding-left: 78px;
+  -moz-transition: padding-left .3s ease-in;
+  -o-transition: padding-left .3s ease-in;
+  -webkit-transition: padding-left .3s ease-in;
+  transition: padding-left .3s ease-in;
 }
 
 .cp__header .navigation svg {
-    transform: scale(0.7);
+  transform: scale(0.7);
 }
 
 .is-electron.is-mac.is-fullscreen .cp__header {
-    padding-left: 0;
+  padding-left: 0;
 }
 
 .cp__header a, .cp__header svg {
-    -webkit-app-region: no-drag;
+  -webkit-app-region: no-drag;
 }
 
 .cp__header-left-menu {
@@ -103,7 +143,7 @@
 }
 
 .cp__header-logo svg {
-    transform: scale(0.9);
+  transform: scale(0.9);
 }
 
 #repo-name {
@@ -118,17 +158,17 @@
 }
 
 a.button {
-    padding: 0.25rem;
-    opacity: 0.6;
-    display: block;
-    border-radius: 4px;
+  padding: 0.25rem;
+  opacity: 0.6;
+  display: block;
+  border-radius: 4px;
 }
 
 a.button:hover {
-    opacity: 1;
-    background: var(--ls-tertiary-background-color);
+  opacity: 1;
+  background: var(--ls-tertiary-background-color);
 }
 
 .is-mac.is-electron :is(.cp__header, .cp__right-sidebar-topbar) :is(button, .button, a) {
-    cursor: default !important;
+  cursor: default !important;
 }

+ 8 - 0
src/main/frontend/dicts.cljs

@@ -335,6 +335,10 @@
         :pdf/copy-text "Copy text"
         :pdf/linked-ref "Linked references"
         :pdf/toggle-dashed "Dashed style for area highlight"
+
+        :updater/new-version-install "A new version has been downloaded. Restart the application to apply the updates."
+        :updater/quit-and-install "Restart to install"
+
         :command-palette/prompt "Type a command"}
 
    :de {:help/about "Über Logseq"
@@ -1031,6 +1035,10 @@
            :pdf/copy-text "复制文本"
            :pdf/linked-ref "转到注解"
            :pdf/toggle-dashed "区域选取为虚线"
+
+           :updater/new-version-install "新版本已经准备就绪,重启应用即可更新。"
+           :updater/quit-and-install "现在安装"
+
            :command-palette/prompt "输入指令"}
 
    :zh-Hant {:on-boarding/title "你好,歡迎使用 Logseq!"

+ 7 - 0
src/main/frontend/handler.cljs

@@ -229,3 +229,10 @@
                                                             (js/window.location.reload))))]])
                          (reset! triggered? false)
                          (set! (.-returnValue e) "")))))
+
+(defn quit-and-install-new-version!
+  []
+  (p/let [_ (el/persist-dbs!)
+          _ (reset! triggered? true)
+          _ (ipc/invoke "set-quit-dirty-state" false)]
+    (ipc/ipc :quitAndInstall)))

+ 1 - 0
src/main/frontend/state.cljs

@@ -126,6 +126,7 @@
       :preferred-language (storage/get :preferred-language)
 
       ;; electron
+      :electron/auto-updater-downloaded false
       :electron/updater-pending? false
       :electron/updater {}
       :electron/user-cfgs nil