Просмотр исходного кода

Enhance(UX): marketplace (#9609)

* fix(ui): hidden proxy label for the default system proxy network mode

* improve(plugin): support option to enable/disable the auto-check the installed plugins

* fix(revert): codes

* improve(ux): add the auto-check updates switcher to the toolbar plugins manager

* improve(i18n): plugin-related i18n

* enhance(plugin): add Github proxy server for the plugin updates

* enhance(plugin): add Github proxy server for the plugin updates

* fix(ui): warning

* fix: typo

* fix(ui): hidden proxy label for the default system proxy network mode

* improve(plugin): support option to enable/disable the auto-check the installed plugins

* fix(revert): codes

* improve(ux): add the auto-check updates switcher to the toolbar plugins manager

* improve(i18n): plugin-related i18n

* enhance(plugin): add Github proxy server for the plugin updates

* enhance(plugin): add Github proxy server for the plugin updates

* fix(ui): warning

* fix: typo
Charlie 2 лет назад
Родитель
Сommit
741edecc57

+ 37 - 14
src/electron/electron/plugin.cljs

@@ -19,6 +19,23 @@
               (.. win -webContents
                   (send (name type) (bean/->js payload))))))
 
+(defonce github-api-0 "https://api.github.com")
+(defonce github-api-1 "https://plugins.logseq.io/github/api")
+(defonce *github-api (atom github-api-0))
+(defonce *last-valid-github-api (atom nil))
+
+(defn valid-github-api!
+  []
+  (when (or (nil? @*last-valid-github-api)
+            (> (- (js/Date.now) @*last-valid-github-api) (* 1000 60)))
+    (let [target github-api-1]
+      (-> (fetch (str target "/rate_limit") {:timeout 2000})
+          (p/then #(when (not= (.-status %) 200) (throw (js/Error. (.-statusText %)))))
+          (p/then #(do (reset! *github-api target) (debug "INFO: use github api - " target)))
+          (p/catch #(do (reset! *github-api github-api-0) (debug "ERR: valid github api - " %)))
+          (p/finally #(reset! *last-valid-github-api (js/Date.now)))))))
+
+
 (defn dotdir-file?
   [file]
   (and file (string/starts-with? (node-path/normalize file) cfgs/dot-root)))
@@ -34,13 +51,14 @@
 (defn- fetch-release-asset
   [{:keys [repo theme]} url-suffix {:keys [response-transform]
                                     :or   {response-transform identity}}]
-  (-> (p/let [repo         (some-> repo (string/trim) (string/replace #"^/+(.+?)/+$" "$1"))
-              api          #(str "https://api.github.com/repos/" repo "/" %)
+  (-> (p/let [_            (valid-github-api!)
+              repo         (some-> repo (string/trim) (string/replace #"^/+(.+?)/+$" "$1"))
+              api          #(str @*github-api "/repos/" repo "/" %)
               endpoint     (api url-suffix)
-              ^js res      (fetch endpoint)
+              ^js res      (fetch endpoint {:timeout (* 1000 5)})
               illegal-text (when-not (= 200 (.-status res)) (.text res))
               _            (when-not (string/blank? illegal-text) (throw (js/Error. (str "Github API Failed(" (.-status res) ") " illegal-text))))
-              _            (debug "[Release URL] " endpoint "[Status/Text]" (.-status res))
+              _            (debug "Release latest:" endpoint ":status" (.-status res))
               res          (response-transform res)
               res          (.json res)
               res          (bean/->clj res)
@@ -83,7 +101,7 @@
                             ;; cases. Previous logseq versions did not store the
                             ;; plugin's git tag required to correctly install it
                             (let [repo' (some-> repo (string/trim) (string/replace #"^/+(.+?)/+$" "$1"))
-                                  api   #(str "https://api.github.com/repos/" repo' "/" %)]
+                                  api   #(str @*github-api "/repos/" repo' "/" %)]
                               (fetch (api "releases/latest")))
                             res))}))
 
@@ -174,10 +192,10 @@
           updating?       (and version (. semver valid coerced-version)
                                (not= action :install))]
 
-      (debug (if updating? "Updating:" "Installing:") repo)
+      (debug "===" (if updating? "Updating:" "Installing:") repo "===")
 
       (-> (p/create
-            (fn [resolve _reject]
+            (fn [resolve reject]
               ;;(reset! *installing-or-updating item)
               ;; get releases
               (-> (p/let [[asset latest-version notes]
@@ -185,18 +203,19 @@
                             (fetch-specific-release-asset item)
                             (fetch-latest-release-asset item))
 
-                          _      (debug "[Release Asset] #" latest-version " =>" (:url asset))
+                          _      (debug "Release latest:" latest-version " from" (:url asset))
 
                           ;; compare latest version
                           _      (when-let [coerced-latest-version
                                             (and updating? latest-version
                                                  (. semver coerce latest-version))]
 
-                                   (debug "[Updating Latest?] " version " > " latest-version)
+                                   (debug "Release compare:" version "(current) > " latest-version "(latest)")
 
                                    (if (. semver lt coerced-version coerced-latest-version)
-                                     (debug "[Updating Latest] " latest-version)
-                                     (throw (js/Error. :no-new-version))))
+                                     (debug "Updating latest:" latest-version)
+                                     (do (debug "Update skip: no new version")
+                                         (throw (js/Error. :no-new-version)))))
 
                           dl-url (if-not (string? asset)
                                    (:browser_download_url asset) asset)
@@ -207,7 +226,7 @@
 
                           dest   (.join node-path cfgs/dot-root "plugins" (:id item))
                           _      (when-not only-check (download-asset-zip item dl-url latest-version dest))
-                          _      (debug (str "[" (if only-check "Checked" "Updated") "DONE]") latest-version)]
+                          _      (debug (str "[" (if only-check "Checked" "Updated") " DONE]") latest-version)]
 
                     (emit :lsp-updates
                           {:status     :completed
@@ -224,8 +243,12 @@
                             {:status     :error
                              :only-check only-check
                              :payload    (assoc item :error-code (.-message e))})
-                      (debug e))
-                    (resolve nil)))))
+                      (reject e))))))
+
+          (p/catch
+            (fn [^js e]
+              (when-not (contains? #{":no-new-version"} (.-message e))
+                (debug e))))
 
           (p/finally
             (fn []))))

+ 32 - 6
src/main/frontend/components/plugins.cljs

@@ -457,6 +457,22 @@
                                 (state/set-state! [:electron/user-cfgs :settings/agent] opts)
                                 (state/close-sub-modal! :https-proxy-panel))))]]]))
 
+(rum/defc auto-check-for-updates-control
+  []
+  (let [[enabled, set-enabled!] (rum/use-state (plugin-handler/get-enabled-auto-check-for-updates?))
+        text (t :plugin/auto-check-for-updates)]
+
+    [:div.flex.items-center.justify-between.px-4.py-2
+     {:on-click (fn []
+                  (let [t (not enabled)]
+                    (set-enabled! t)
+                    (plugin-handler/set-enabled-auto-check-for-updates t)
+                    (notification/show!
+                      [:span text [:strong.pl-1 (if t "ON" "OFF")] "!"]
+                      (if t :success :info))))}
+     [:span.pr-3.opacity-80 text]
+     (ui/toggle enabled #() true)]))
+
 (rum/defc ^:large-vars/cleanup-todo panel-control-tabs < rum/static
   [search-key *search-key category *category
    sort-by *sort-by filter-by *filter-by total-nums
@@ -590,7 +606,11 @@
                    {:title   [:span.flex.items-center.whitespace-nowrap.space-x-1 (ui/icon "bug") (t :plugin/open-logseq-dir) [:code "~/.logseq"]]
                     :options {:on-click
                               #(p/let [root (plugin-handler/get-ls-dotdir-root)]
-                                 (js/apis.openPath root))}}]))
+                                 (js/apis.openPath root))}}])
+
+                [{:hr true :key "dropdown-more"}
+                 {:title   (auto-check-for-updates-control)
+                  :options {:no-padding? true}}])
         {})
 
       ;; developer
@@ -1045,7 +1065,11 @@
                       [:span (t :plugin/found-updates)] (ui/point "bg-red-600" 5 {:style {:margin-top 2}})]
             :options {:on-click #(open-waiting-updates-modal!)
                       :class    "extra-item"}
-            :icon    (ui/icon "download")})])
+            :icon    (ui/icon "download")})]
+
+        [{:hr true :key "dropdown-more"}
+         {:title (auto-check-for-updates-control)
+          :options {:no-padding? true}}])
       {:trigger-class "toolbar-plugins-manager-trigger"})))
 
 (rum/defc header-ui-items-list-wrap
@@ -1251,9 +1275,11 @@
       (fn []
         (when online?
           (let [last-updates (storage/get :lsp-last-auto-updates)]
-            (when (or (not (number? last-updates))
-                      ;; interval 12 hours
-                      (> (- (js/Date.now) last-updates) (* 60 60 12 1000)))
+            (when (and (not (false? last-updates))
+                       (or (true? last-updates)
+                           (not (number? last-updates))
+                           ;; interval 12 hours
+                           (> (- (js/Date.now) last-updates) (* 60 60 12 1000))))
               (js/setTimeout
                 (fn []
                   (plugin-handler/auto-check-enabled-for-updates!)
@@ -1293,7 +1319,7 @@
            [:ul.settings-plugin-list
             (for [{:keys [id name title icon]} plugins]
               [:li
-               {:class (util/classnames [{:active (= id focused)}])}
+               {:key id :class (util/classnames [{:active (= id focused)}])}
                [:a.flex.items-center.settings-plugin-item
                 {:data-id  id
                  :on-click #(do (state/set-state! :plugin/focused-settings id))}

+ 9 - 2
src/main/frontend/handler/plugin.cljs

@@ -7,6 +7,7 @@
             [logseq.graph-parser.mldoc :as gp-mldoc]
             [frontend.handler.notification :as notification]
             [frontend.handler.common.plugin :as plugin-common-handler]
+            [frontend.storage :as storage]
             [camel-snake-kebab.core :as csk]
             [frontend.state :as state]
             [medley.core :as medley]
@@ -186,8 +187,6 @@
   []
   (let [channel  (name :lsp-updates)
         listener (fn [_ ^js e]
-                   (js/console.debug (str :lsp-updates) e)
-
                    (when-let [{:keys [status payload only-check]} (bean/->clj e)]
                      (case (keyword status)
 
@@ -631,6 +630,14 @@
       (state/pub-event! [:plugin/consume-updates])
       (set-auto-checking! true))))
 
+(defn get-enabled-auto-check-for-updates?
+  []
+  (not (false? (storage/get :lsp-last-auto-updates))))
+
+(defn set-enabled-auto-check-for-updates
+  [v?]
+  (storage/set :lsp-last-auto-updates (boolean v?)))
+
 (defn call-plugin
   [^js pl type payload]
   (when pl

+ 4 - 3
src/main/frontend/state.cljs

@@ -2027,9 +2027,10 @@ Similar to re-frame subscriptions"
                    (fn [old-value] (merge old-value m)))))
 
 (defn http-proxy-enabled-or-val? []
-  (when-let [agent-opts (sub [:electron/user-cfgs :settings/agent])]
-    (when (every? not-empty (vals agent-opts))
-      (str (:protocol agent-opts) "://" (:host agent-opts) ":" (:port agent-opts)))))
+  (when-let [{:keys [type protocol host port] :as agent-opts} (sub [:electron/user-cfgs :settings/agent])]
+    (when (and  (not (contains? #{"system"} type))
+                (every? not-empty (vals agent-opts)))
+      (str protocol "://" host ":" port))))
 
 (defn set-mobile-app-state-change
   [is-active?]

+ 10 - 4
src/main/frontend/ui.cljs

@@ -175,12 +175,18 @@
                   sequence)]))
 
 (rum/defc menu-link
-  [options child shortcut]
-  (if (:only-child? options)
+  [{:keys [only-child? no-padding? class] :as options} child shortcut]
+  (if only-child?
     [:div.menu-link
      (dissoc options :only-child?) child]
     [:a.flex.justify-between.px-4.py-2.text-sm.transition.ease-in-out.duration-150.cursor.menu-link
-     options
+     (cond-> options
+             (true? no-padding?)
+             (assoc :class (str class " no-padding"))
+
+             true
+             (dissoc :no-padding?))
+
      [:span.flex-1 child]
      (when shortcut
        [:span.ml-1 (render-keyboard-shortcut shortcut)])]))
@@ -214,7 +220,7 @@
                                   [:div.title-wrap {:style {:margin-right "8px"
                                                             :margin-left  "4px"}} title]]))]
                  (if hr
-                   [:hr.menu-separator {:key "dropdown-hr"}]
+                   [:hr.menu-separator {:key (or key "dropdown-hr")}]
                    (rum/with-key
                     (menu-link new-options child nil)
                     title)))))

+ 6 - 0
src/main/frontend/ui.css

@@ -41,6 +41,12 @@
   }
 }
 
+.menu-link {
+  &.no-padding {
+    padding: 0 !important;
+  }
+}
+
 .ui__ac-group-name {
   @apply p-2 text-xs;
   color: var(--ls-block-ref-link-text-color);

+ 1 - 0
src/resources/dicts/en.edn

@@ -459,6 +459,7 @@
  :plugin/remote-error "Remote error: "
  :plugin/checking-for-updates "Checking for plugin updates ..."
  :plugin/list-of-updates "Plugin Updates: "
+ :plugin/auto-check-for-updates "Auto check for updates"
  :plugin.install-from-file/menu-title "Install from plugins.edn"
  :plugin.install-from-file/title "Install plugins from plugins.edn"
  :plugin.install-from-file/notice "The following plugins will replace your plugins:"

+ 12 - 0
src/resources/dicts/zh-cn.edn

@@ -274,6 +274,18 @@
  :plugin/unpacked-tips "用于开发目的或者从本地磁盘载入可信的社区插件。"
  :plugin/custom-js-alert "发现 custom.js 自定义脚本,是否允许执行?(如果您对该文件的内容不了解 或 来源不可靠,建议不要允许执行)"
 
+ :plugin/search-plugin "搜索插件"
+ :plugin/open-preferences "打开插件偏好设置"
+ :plugin/open-logseq-dir "打开"
+ :plugin/remote-error "远端错误: "
+ :plugin/checking-for-updates "正在检查插件更新 ..."
+ :plugin/list-of-updates "可用的插件更新: "
+ :plugin/auto-check-for-updates "是否自动检查更新"
+ :plugin.install-from-file/menu-title "从 plugins.edn 安装"
+ :plugin.install-from-file/title "从 plugins.edn 配置中安装插件"
+ :plugin.install-from-file/notice "以下插件会替换已安装的插件:"
+ :plugin.install-from-file/success "插件全部安装完毕!"
+
  :pdf/copy-ref "复制引用"
  :pdf/copy-text "复制文本"
  :pdf/linked-ref "转到注解"