feat(marketplace): download updates with one click

pull/3871/head
charlie 2022-01-11 17:06:27 +08:00 committed by Andelf
parent 9a7698c966
commit de1ea231e3
7 changed files with 307 additions and 173 deletions

View File

@ -39,7 +39,8 @@
zipball
(api "zipball"))
asset)
version])
version
(:body res)])
(fn [^js e]
(emit :lsp-installed {:status :error :payload e})
@ -130,7 +131,7 @@
(fn [resolve _reject]
;;(reset! *installing-or-updating item)
;; get releases
(-> (p/let [[asset latest-version] (fetch-latest-release-asset item)
(-> (p/let [[asset latest-version notes] (fetch-latest-release-asset item)
_ (debug "[Release Asset] #" latest-version " =>" (:url asset))
@ -160,7 +161,7 @@
{:status :completed
:only-check only-check
:payload (if only-check
(assoc item :latest-version latest-version)
(assoc item :latest-version latest-version :latest-notes notes)
(assoc item :zip dl-url :dst dest))})
(resolve nil))

View File

@ -576,6 +576,69 @@
(and updating (= (keyword (:id updating)) pid))
true nil (get coming-updates pid))) (:id item)))]])))
(rum/defcs waiting-coming-updates
< rum/reactive
{:will-mount (fn [s] (state/reset-unchecked-update) s)}
[_s]
(let [_ (state/sub :plugin/updates-coming)
downloading? (state/sub :plugin/updates-downloading?)
unchecked (state/sub :plugin/updates-unchecked)
updates (state/all-available-coming-updates)]
[:div.cp__plugins-waiting-updates
[:h1.mb-4.text-2xl.p-1 (util/format "Found %s updates" (util/safe-parse-int (count updates)))]
(if (seq updates)
;; lists
[:ul
{:class (when downloading? "downloading")}
(for [it updates
:let [k (str "lsp-it-" (:id it))
c? (not (contains? unchecked (:id it)))
notes (util/trim-safe (:latest-notes it))]]
[:li.flex.items-center
{:key k
:class (when c? "checked")}
[:label.flex-1
{:for k}
(ui/checkbox {:id k
:checked c?
:on-change (fn [^js e]
(when-not downloading?
(state/set-unchecked-update (:id it) (not (util/echecked? e)))))})
[:strong.px-3 (:title it)
[:sup (str (:version it) " 👉 " (:latest-version it))]]]
[:div.px-4
(when-not (string/blank? notes)
(ui/tippy
{:html [:p notes]}
[:span.opacity-30.hover:opacity-80 (ui/icon "info-circle")]))]])]
;; all done
[:div.py-4 [:strong.text-4xl "\uD83C\uDF89 All updated!"]])
;; actions
(when (seq updates)
[:div.pt-5
(ui/button
(if downloading?
[:span (ui/loading " Downloading...")]
[:span "Update all of selected"])
:on-click
#(when-not downloading?
(state/set-state! :plugin/updates-downloading? true)
(plugin-handler/check-or-update-marketplace-plugin
(assoc (state/get-next-selected-coming-update) :only-check false)
(fn [^js e] (notification/show! e :error))))
:disabled
(or downloading?
(and (not (empty? unchecked))
(= (count unchecked) (count updates)))))])]))
(defn open-select-theme!
[]
(state/set-sub-modal! installed-themes))
@ -677,5 +740,12 @@
(defn open-plugins-modal!
[]
(state/set-modal!
(fn [close!]
(plugins-page))))
(fn [_close!]
(plugins-page))))
(defn open-waiting-updates-modal!
[]
(state/set-sub-modal!
(fn [_close!]
(waiting-coming-updates))
{:center? true}))

View File

@ -425,6 +425,27 @@
&-details {
}
&-waiting-updates {
margin: -15px;
> ul {
li {
user-select: none;
justify-content: space-between;
opacity: .9;
sup {
padding-left: 8px;
font-weight: 400;
}
&:hover, &.checked {
opacity: 1;
}
}
}
}
}
.cp__themes {

View File

@ -211,6 +211,10 @@
(defmethod handle :go/plugins [_]
(plugin/open-plugins-modal!))
(defmethod handle :go/plugins-waiting-lists [_]
(plugin/open-waiting-updates-modal!))
(defmethod handle :redirect-to-home [_]
(page-handler/create-today-journal!))
@ -241,11 +245,22 @@
(str "Checked: " (:title coming))
:success))
;; try to start consume pending item
(when-let [n (second (first (:plugin/updates-pending @state/state)))]
(plugin-handler/check-or-update-marketplace-plugin
(assoc n :only-check true)
(fn [^js e] (js/console.error "[Check Err]" n e)))))
(if (and updated? (:plugin/updates-downloading? @state/state))
;; try to start consume downloading item
(if-let [n (state/get-next-selected-coming-update)]
(plugin-handler/check-or-update-marketplace-plugin
(assoc n :only-check false)
(fn [^js e] (js/console.error "[Download Err]" n e)))
(state/set-state! :plugin/updates-downloading? false))
;; try to start consume pending item
(if-let [n (second (first (:plugin/updates-pending @state/state)))]
(plugin-handler/check-or-update-marketplace-plugin
(assoc n :only-check true)
(fn [^js e] (js/console.error "[Check Err]" n e)))
;; try to open waiting updates list
(when (and pending? (seq (state/all-available-coming-updates)))
(plugin/open-waiting-updates-modal!)))))
(defn run!
[]

View File

@ -159,6 +159,8 @@
(if (and only-check updates-pending?)
(state/consume-updates-coming-plugin payload false)
;; TODO: consume failed download updates?
(notifications/show!
(str
(if (= :error type) "[Install Error]" "")

View File

@ -21,193 +21,195 @@
[cljs.cache :as cache]))
(defonce state
(let [document-mode? (or (storage/get :document/mode?) false)
current-graph (let [graph (storage/get :git/current-repo)]
(when graph (ipc/ipc "setCurrentGraph" graph))
graph)]
(atom
{:route-match nil
:today nil
:system/events (async/chan 100)
:db/batch-txs (async/chan 100)
:file/writes (async/chan 100)
:notification/show? false
:notification/content nil
:repo/cloning? false
:repo/loading-files? {}
:repo/importing-to-db? nil
:repo/sync-status {}
:repo/changed-files nil
:nfs/user-granted? {}
:nfs/refreshing? nil
:instrument/disabled? (storage/get "instrument-disabled")
;; TODO: how to detect the network reliably?
:network/online? true
:indexeddb/support? true
:me nil
:git/current-repo current-graph
:git/status {}
:format/loading {}
:draw? false
:db/restoring? nil
(let [document-mode? (or (storage/get :document/mode?) false)
current-graph (let [graph (storage/get :git/current-repo)]
(when graph (ipc/ipc "setCurrentGraph" graph))
graph)]
(atom
{:route-match nil
:today nil
:system/events (async/chan 100)
:db/batch-txs (async/chan 100)
:file/writes (async/chan 100)
:notification/show? false
:notification/content nil
:repo/cloning? false
:repo/loading-files? {}
:repo/importing-to-db? nil
:repo/sync-status {}
:repo/changed-files nil
:nfs/user-granted? {}
:nfs/refreshing? nil
:instrument/disabled? (storage/get "instrument-disabled")
;; TODO: how to detect the network reliably?
:network/online? true
:indexeddb/support? true
:me nil
:git/current-repo current-graph
:git/status {}
:format/loading {}
:draw? false
:db/restoring? nil
:journals-length 2
:journals-length 2
:search/q ""
:search/mode :global
:search/result nil
:search/graph-filters []
:search/q ""
:search/mode :global
:search/result nil
:search/graph-filters []
;; modals
:modal/label ""
:modal/show? false
:modal/panel-content nil
:modal/fullscreen? false
:modal/close-btn? nil
:modal/subsets []
;; modals
:modal/label ""
:modal/show? false
:modal/panel-content nil
:modal/fullscreen? false
:modal/close-btn? nil
:modal/subsets []
;; right sidebar
:ui/fullscreen? false
:ui/settings-open? false
:ui/sidebar-open? false
:ui/left-sidebar-open? (boolean (storage/get "ls-left-sidebar-open?"))
:ui/theme (or (storage/get :ui/theme) (if (mobile/is-native-platform?) "light" "dark"))
:ui/system-theme? ((fnil identity (or util/mac? util/win32? false)) (storage/get :ui/system-theme?))
:ui/wide-mode? false
;; :show-all, :hide-block-body, :hide-block-children
:ui/cycle-collapse :show-all
;; right sidebar
:ui/fullscreen? false
:ui/settings-open? false
:ui/sidebar-open? false
:ui/left-sidebar-open? (boolean (storage/get "ls-left-sidebar-open?"))
:ui/theme (or (storage/get :ui/theme) (if (mobile/is-native-platform?) "light" "dark"))
:ui/system-theme? ((fnil identity (or util/mac? util/win32? false)) (storage/get :ui/system-theme?))
:ui/wide-mode? false
;; :show-all, :hide-block-body, :hide-block-children
:ui/cycle-collapse :show-all
;; ui/collapsed-blocks is to separate the collapse/expand state from db for:
;; 1. right sidebar
;; 2. zoom-in view
;; 3. queries
;; 4. references
;; graph => {:block-id bool}
:ui/collapsed-blocks {}
:ui/sidebar-collapsed-blocks {}
:ui/root-component nil
:ui/file-component nil
:ui/custom-query-components {}
:ui/show-recent? false
:ui/command-palette-open? false
:ui/developer-mode? (or (= (storage/get "developer-mode") "true")
false)
;; remember scroll positions of visited paths
:ui/paths-scroll-positions {}
:ui/shortcut-tooltip? (if (false? (storage/get :ui/shortcut-tooltip?))
false
true)
:ui/visual-viewport-pending? false
:ui/visual-viewport-state nil
;; ui/collapsed-blocks is to separate the collapse/expand state from db for:
;; 1. right sidebar
;; 2. zoom-in view
;; 3. queries
;; 4. references
;; graph => {:block-id bool}
:ui/collapsed-blocks {}
:ui/sidebar-collapsed-blocks {}
:ui/root-component nil
:ui/file-component nil
:ui/custom-query-components {}
:ui/show-recent? false
:ui/command-palette-open? false
:ui/developer-mode? (or (= (storage/get "developer-mode") "true")
false)
;; remember scroll positions of visited paths
:ui/paths-scroll-positions {}
:ui/shortcut-tooltip? (if (false? (storage/get :ui/shortcut-tooltip?))
false
true)
:ui/visual-viewport-pending? false
:ui/visual-viewport-state nil
:document/mode? document-mode?
:document/mode? document-mode?
:github/contents {}
:config {}
:block/component-editing-mode? false
:editor/draw-mode? false
:editor/show-page-search? false
:editor/show-page-search-hashtag? false
:editor/show-date-picker? false
;; With label or other data
:editor/show-input nil
:editor/show-zotero false
:editor/last-saved-cursor nil
:editor/editing? nil
:editor/last-edit-block-input-id nil
:editor/last-edit-block-id nil
:editor/in-composition? false
:editor/content {}
:editor/block nil
:editor/block-dom-id nil
:editor/set-timestamp-block nil
:editor/last-input-time nil
:editor/pos nil
:editor/document-mode? document-mode?
:editor/args nil
:editor/on-paste? false
:editor/last-key-code nil
:github/contents {}
:config {}
:block/component-editing-mode? false
:editor/draw-mode? false
:editor/show-page-search? false
:editor/show-page-search-hashtag? false
:editor/show-date-picker? false
;; With label or other data
:editor/show-input nil
:editor/show-zotero false
:editor/last-saved-cursor nil
:editor/editing? nil
:editor/last-edit-block-input-id nil
:editor/last-edit-block-id nil
:editor/in-composition? false
:editor/content {}
:editor/block nil
:editor/block-dom-id nil
:editor/set-timestamp-block nil
:editor/last-input-time nil
:editor/pos nil
:editor/document-mode? document-mode?
:editor/args nil
:editor/on-paste? false
:editor/last-key-code nil
:db/last-transact-time {}
:db/last-persist-transact-ids {}
;; whether database is persisted
:db/persisted? {}
:db/latest-txs (or (storage/get-transit :db/latest-txs) {})
:cursor-range nil
:db/last-transact-time {}
:db/last-persist-transact-ids {}
;; whether database is persisted
:db/persisted? {}
:db/latest-txs (or (storage/get-transit :db/latest-txs) {})
:cursor-range nil
:selection/mode false
:selection/blocks []
:selection/start-block nil
;; either :up or :down, defaults to down
;; used to determine selection direction when two or more blocks are selected
:selection/direction :down
:custom-context-menu/show? false
:custom-context-menu/links nil
:selection/mode false
:selection/blocks []
:selection/start-block nil
;; either :up or :down, defaults to down
;; used to determine selection direction when two or more blocks are selected
:selection/direction :down
:custom-context-menu/show? false
:custom-context-menu/links nil
;; pages or blocks in the right sidebar
;; It is a list of `[repo db-id block-type block-data]` 4-tuple
:sidebar/blocks '()
;; pages or blocks in the right sidebar
;; It is a list of `[repo db-id block-type block-data]` 4-tuple
:sidebar/blocks '()
:preferred-language (storage/get :preferred-language)
:preferred-language (storage/get :preferred-language)
;; electron
:electron/auto-updater-downloaded false
:electron/updater-pending? false
:electron/updater {}
:electron/user-cfgs nil
;; electron
:electron/auto-updater-downloaded false
:electron/updater-pending? false
:electron/updater {}
:electron/user-cfgs nil
;; plugin
:plugin/enabled (and (util/electron?)
;; true false :theme-only
((fnil identity true) (storage/get :lsp-core-enabled)))
:plugin/indicator-text nil
:plugin/installed-plugins {}
:plugin/installed-themes []
:plugin/installed-commands {}
:plugin/installed-ui-items {}
:plugin/simple-commands {}
:plugin/selected-theme nil
:plugin/selected-unpacked-pkg nil
:plugin/marketplace-pkgs nil
:plugin/marketplace-stats nil
:plugin/installing nil
:plugin/active-readme nil
:plugin/updates-pending {}
:plugin/updates-coming {}
;; plugin
:plugin/enabled (and (util/electron?)
;; true false :theme-only
((fnil identity true) (storage/get :lsp-core-enabled)))
:plugin/indicator-text nil
:plugin/installed-plugins {}
:plugin/installed-themes []
:plugin/installed-commands {}
:plugin/installed-ui-items {}
:plugin/simple-commands {}
:plugin/selected-theme nil
:plugin/selected-unpacked-pkg nil
:plugin/marketplace-pkgs nil
:plugin/marketplace-stats nil
:plugin/installing nil
:plugin/active-readme nil
:plugin/updates-pending {}
:plugin/updates-coming {}
:plugin/updates-downloading? false
:plugin/updates-unchecked #{}
;; pdf
:pdf/current nil
:pdf/ref-highlight nil
;; pdf
:pdf/current nil
:pdf/ref-highlight nil
;; all notification contents as k-v pairs
:notification/contents {}
:graph/syncing? false
;; all notification contents as k-v pairs
:notification/contents {}
:graph/syncing? false
;; copied blocks
:copy/blocks {:copy/content nil :copy/block-tree nil}
;; copied blocks
:copy/blocks {:copy/content nil :copy/block-tree nil}
:copy/export-block-text-indent-style (or (storage/get :copy/export-block-text-indent-style)
"dashes")
:copy/export-block-text-remove-options (or (storage/get :copy/export-block-text-remove-options)
#{})
:date-picker/date nil
:copy/export-block-text-indent-style (or (storage/get :copy/export-block-text-indent-style)
"dashes")
:copy/export-block-text-remove-options (or (storage/get :copy/export-block-text-remove-options)
#{})
:date-picker/date nil
:youtube/players {}
:youtube/players {}
;; command palette
:command-palette/commands []
;; command palette
:command-palette/commands []
:view/components {}
:view/components {}
:debug/write-acks {}
:debug/write-acks {}
:encryption/graph-parsing? false
:encryption/graph-parsing? false
:favorites/dragging nil
:favorites/dragging nil
:srs/mode? false
:srs/mode? false
:srs/cards-due-count nil})))
:srs/cards-due-count nil})))
;; block uuid -> {content(String) -> ast}
(def blocks-ast-cache (atom (cache/lru-cache-factory {} :threshold 5000)))
@ -1704,7 +1706,7 @@
(defn consume-updates-coming-plugin
[payload updated?]
(when-let [id (keyword (:id payload))]
(let [pending? (seq (:plugin/updates-pending @state))]
(let [pending? (boolean (seq (:plugin/updates-pending @state)))]
(swap! state update :plugin/updates-pending dissoc id)
(if updated?
(swap! state update :plugin/updates-coming dissoc id)
@ -1720,6 +1722,28 @@
(when-let [pkg (and id (get (:plugin/updates-coming @state) (keyword id)))]
(coming-update-new-version? pkg)))
(defn all-available-coming-updates
[]
(when-let [updates (vals (:plugin/updates-coming @state))]
(filterv #(coming-update-new-version? %) updates)))
(defn get-next-selected-coming-update
[]
(when-let [updates (all-available-coming-updates)]
(let [unchecked (:plugin/updates-unchecked @state)]
(first
(if (seq unchecked)
(filter #(not (contains? unchecked (:id %))) updates)
updates)))))
(defn set-unchecked-update
[id unchecked?]
(swap! state update :plugin/updates-unchecked (if unchecked? conj disj) id))
(defn reset-unchecked-update
[]
(swap! state assoc :plugin/updates-unchecked #{}))
(defn sub-right-sidebar-blocks
[]
(when-let [current-repo (get-current-repo)]

View File

@ -181,6 +181,7 @@ html.is-mobile {
&:disabled {
opacity: 0.5;
cursor: not-allowed;
}
&:hover {