From 1e7e9a3c133b5fed0d846e59835616013753fffa Mon Sep 17 00:00:00 2001 From: Dasemu Date: Wed, 26 Aug 2026 15:59:39 +0200 Subject: [PATCH] Fase 8 (2/N): delete the client-side RTC/E2EE/sync UI and finish the teardown MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removes the client-side half of the remote CRDT sync protocol left after the worker-side deletion in 565c211: RTC/remote-graph UI (components/rtc/*, db/rtc/debug_ui.cljs, cloud-graph upload/download/leave/delete flows in components/repo.cljs and mobile/components/app.cljs), E2EE UI and handlers (components/e2ee.cljs, handler/e2ee.cljs, handler/events/rtc*.cljs), the db-worker-node ui-request RPC (handler/worker.cljs's :db-worker/ui-request, which existed only to serve E2EE password prompts), settings panels for the legacy custom sync-server URL, and the now-orphaned :rtc/* client state (presence UI, upload/download progress, remote-graph lists) — presence.cljs was already deleted in the worker-side pass, contrary to the plan's "keep" list, so all of this had zero producers left and was fully inert. Also fixes several dead thread-api invokes discovered on LIVE paths that would throw at runtime rather than being merely dead UI: - db/restore.cljs's restore-graph! (called on every graph load) - persist_db.cljs's --- shadow-cljs.edn | 3 +- src/main/frontend/components/block.cljs | 132 +-- src/main/frontend/components/container.cljs | 24 +- src/main/frontend/components/e2ee.cljs | 126 --- src/main/frontend/components/header.cljs | 112 +-- src/main/frontend/components/repo.cljs | 434 ++-------- .../frontend/components/right_sidebar.cljs | 8 - .../components/rtc/download_progress.cljs | 31 - .../frontend/components/rtc/indicator.cljs | 360 --------- src/main/frontend/components/settings.cljs | 301 +------ src/main/frontend/config.cljs | 58 -- src/main/frontend/core.cljs | 1 - src/main/frontend/db/restore.cljs | 4 - src/main/frontend/db/rtc/debug_ui.cljs | 136 ---- src/main/frontend/handler.cljs | 2 - src/main/frontend/handler/assets.cljs | 29 - .../frontend/handler/common/developer.cljs | 122 --- .../db_based/rtc_background_tasks.cljs | 45 -- .../frontend/handler/db_based/rtc_flows.cljs | 135 ---- src/main/frontend/handler/db_based/sync.cljs | 463 ----------- src/main/frontend/handler/e2ee.cljs | 68 -- src/main/frontend/handler/events.cljs | 69 -- src/main/frontend/handler/events/rtc.cljs | 108 --- .../frontend/handler/events/rtc_error.cljs | 38 - src/main/frontend/handler/events/ui.cljs | 83 +- src/main/frontend/handler/repo.cljs | 39 +- src/main/frontend/handler/user.cljs | 31 - src/main/frontend/handler/worker.cljs | 119 +-- .../frontend/modules/shortcut/config.cljs | 20 +- src/main/frontend/persist_db.cljs | 10 +- src/main/frontend/persist_db/browser.cljs | 8 - src/main/frontend/state.cljs | 70 +- src/main/logseq/sdk/debug.cljs | 23 - src/main/mobile/bottom_tabs.cljs | 75 -- src/main/mobile/components/app.cljs | 105 +-- src/main/mobile/components/header.cljs | 82 +- src/main/mobile/components/popup.cljs | 27 +- src/main/mobile/components/settings.cljs | 9 - src/main/mobile/core.cljs | 1 - src/test/frontend/components/repo_test.cljs | 420 +--------- .../components/rtc/indicator_test.cljs | 50 -- src/test/frontend/config_test.cljs | 54 -- src/test/frontend/db/restore_test.cljs | 13 +- .../handler/common/developer_test.cljs | 29 - .../handler/db_based/rtc_flows_test.cljs | 24 - .../frontend/handler/db_based/sync_test.cljs | 764 ------------------ .../handler/events/rtc_error_test.cljs | 21 - src/test/frontend/handler/events_test.cljs | 27 - src/test/frontend/handler/user_test.cljs | 38 - src/test/frontend/handler/worker_test.cljs | 52 +- src/test/frontend/persist_db_test.cljs | 42 - src/test/mobile/header_test.cljs | 21 - 52 files changed, 162 insertions(+), 4904 deletions(-) delete mode 100644 src/main/frontend/components/e2ee.cljs delete mode 100644 src/main/frontend/components/rtc/download_progress.cljs delete mode 100644 src/main/frontend/components/rtc/indicator.cljs delete mode 100644 src/main/frontend/db/rtc/debug_ui.cljs delete mode 100644 src/main/frontend/handler/db_based/rtc_background_tasks.cljs delete mode 100644 src/main/frontend/handler/db_based/rtc_flows.cljs delete mode 100644 src/main/frontend/handler/db_based/sync.cljs delete mode 100644 src/main/frontend/handler/e2ee.cljs delete mode 100644 src/main/frontend/handler/events/rtc.cljs delete mode 100644 src/main/frontend/handler/events/rtc_error.cljs delete mode 100644 src/test/frontend/components/rtc/indicator_test.cljs delete mode 100644 src/test/frontend/handler/db_based/rtc_flows_test.cljs delete mode 100644 src/test/frontend/handler/db_based/sync_test.cljs delete mode 100644 src/test/frontend/handler/events/rtc_error_test.cljs delete mode 100644 src/test/frontend/handler/events_test.cljs delete mode 100644 src/test/mobile/header_test.cljs diff --git a/shadow-cljs.edn b/shadow-cljs.edn index 5ae4d84..9a1ba41 100644 --- a/shadow-cljs.edn +++ b/shadow-cljs.edn @@ -38,8 +38,7 @@ goog.debug.LOGGING_ENABLED true frontend.modules.instrumentation.sentry/SENTRY-DSN #shadow/env "LOGSEQ_SENTRY_DSN" frontend.modules.instrumentation.posthog/POSTHOG-TOKEN #shadow/env "LOGSEQ_POSTHOG_TOKEN" - frontend.config/ENABLE-PLUGINS #shadow/env ["ENABLE_PLUGINS" :as :bool :default true] - frontend.config/ENABLE-DB-SYNC-LOCAL #shadow/env ["ENABLE_DB_SYNC_LOCAL" :as :bool :default false]} + frontend.config/ENABLE-PLUGINS #shadow/env ["ENABLE_PLUGINS" :as :bool :default true]} :devtools {:before-load frontend.core/stop ;; before live-reloading any code call this function :after-load frontend.core/start ;; after live-reloading finishes call this function diff --git a/src/main/frontend/components/block.cljs b/src/main/frontend/components/block.cljs index a57b4c0..0f2cb49 100644 --- a/src/main/frontend/components/block.cljs +++ b/src/main/frontend/components/block.cljs @@ -9,7 +9,6 @@ [clojure.string :as string] [dommy.core :as dom] [electron.ipc :as ipc] - [frontend.components.avatar :as avatar] [frontend.components.block.breadcrumb-model :as breadcrumb-model] [frontend.components.block.asset :as block-asset] [frontend.components.block.comments :as block-comments] @@ -1094,25 +1093,11 @@ [:a.asset-ref {:target "_blank" :href real-path-url} title-or-path])])) -(defn- maybe-request-asset-download! - [file-exists? requested? block] - (let [repo (state/get-current-repo) - asset-file-write-finish (state/get-state :assets/asset-file-write-finish) - asset-file-write-finished? (get-in asset-file-write-finish [repo (str (:block/uuid block))]) - file-ready? (or file-exists? asset-file-write-finished?)] - (when (and (true? @requested?) file-ready?) - (reset! requested? false)) - (when (and (not @requested?) - (assets-handler/maybe-request-remote-asset-download! repo block file-ready?)) - (reset! requested? true)))) - (defn- retry-missing-asset-upload! [repo block file-exists?*] (let [asset-rpath (block-asset/asset-relative-path block)] (p/let [exists? (fs/file-exists? (config/get-repo-dir repo) asset-rpath)] - (reset! file-exists?* exists?) - (when exists? - (state/ (assoc config :asset-block block) @@ -1202,12 +1170,7 @@ #(retry-missing-asset-upload! repo block file-exists?*)) (block-asset/show-image-placeholder? block file-ready? gallery-image?) img-placeholder)] - (if progress-view - [:div.asset-transfer-shell - (or content - [:div.asset-transfer-placeholder (t :asset/transfer-placeholder label)]) - progress-view] - content))) + content)) (defn- img-audio-video? [block] @@ -2227,24 +2190,11 @@ (open-comment-thread! block-uuid comment-thread))} (shui/tabler-icon "message-circle" {:size 15}))))))) -(defn- editing-user-avatar - [{:user/keys [name uuid]}] - (let [user-name (or name uuid)] - (when (avatar/initials user-name) - [:span.block-editing-avatar-wrap - (avatar/user-avatar - {:class "block-editing-avatar w-4 h-4 flex-none" - :title user-name - :name user-name - :uuid uuid - :fallback-props {:style {:font-size 9}}})]))) - (hsx/defc ^:large-vars/cleanup-todo block-control [config block {:keys [uuid block-id collapsed? has-children? *control-show? edit? selected? top? bottom?]}] (let [*bullet-dragging? (hooks/use-memo #(atom false) []) doc-mode? (rfx/use-sub [:document/mode?]) [control-show?] (hooks/use-atom *control-show?) - editing-user (rfx/use-sub [:rtc/editing-users-by-block (str uuid)]) ref? (:ref? config) container-id (:container-id config) empty-content? (block-content-empty? block) @@ -2276,8 +2226,6 @@ :is-with-icon with-icon? :bullet-closed collapsed? :bullet-hidden (:hide-bullet? config)}])} - (when (and (not page-title?) editing-user) - (editing-user-avatar editing-user)) (when (and (or (not fold-button-right?) collapsable? collapsed?) (not (:table? config))) [:a.block-control @@ -3296,78 +3244,6 @@ {:align :end}))} (clock/seconds->days:hours:minutes:seconds seconds))]))) -(defn- sync-conflict-attr-label - [attr] - (case attr - :block/title (t :property.built-in/title) - (name attr))) - -(defn- visible-sync-conflicts - [block conflicts] - (->> conflicts - (remove (fn [{:keys [attr value]}] - (= value (get block attr)))) - vec)) - -(hsx/defc sync-conflict-item - [{:keys [id attr value created-at]}] - [:div.border.rounded.p-3 {:key id} - [:div.flex.flex-row.items-center.justify-between.gap-3.mb-2.text-xs.text-muted-foreground - [:span (sync-conflict-attr-label attr)] - [:span (date/int->local-time-2 created-at)]] - [:pre.whitespace-pre-wrap.text-sm.bg-muted.p-2.rounded.max-h-64.overflow-auto value] - [:div.flex.justify-end.mt-2 - (shui/button - {:variant :secondary - :size :sm - :on-click (fn [] - (util/copy-to-clipboard! value) - (notification/show! (t :notification/copied) :success))} - (t :ui/copy))]]) - -(hsx/defc sync-conflicts-popup - [conflicts on-mark-resolved] - [:div.p-3.w-96 - {:style {:max-width "90vw"}} - [:h2.text-lg.font-medium.mb-2 (t :sync/conflicts-title)] - [:p.text-sm.text-muted-foreground.mb-3 - (t :sync/conflicts-description)] - [:div.flex.flex-col.gap-3 - (for [conflict conflicts] - (sync-conflict-item conflict))] - [:div.flex.justify-end.mt-3 - (ui/button (t :sync/mark-conflicts-resolved) - :on-click on-mark-resolved)]]) - -(hsx/defc sync-conflicts-warning-button - [block] - (let [repo (state/get-current-repo) - block-id (:block/uuid block) - conflicts (rfx/use-sub [:sync/block-conflicts repo (str block-id)]) - visible-conflicts (visible-sync-conflicts block conflicts)] - (when (seq visible-conflicts) - (ui/tooltip - (shui/button - {:variant :secondary - :size :sm - :title (t :sync/show-conflicts) - :class "ls-sync-conflict-warning ls-small-icon px-1 !py-0 h-5" - :on-click (fn [e] - (util/stop e) - (shui/popup-show! (.-target e) - (fn [] - (sync-conflicts-popup - visible-conflicts - (fn [] - (p/let [_ (state/ e .-target .-value))) - :on-blur (fn [] - (when-not (string/blank? password-confirm) - (set-matched! (= password-confirm password))))}) - - [:div.flex.flex-col.gap-2 - (shui/toggle-password - {:placeholder (t :encryption/enter-password-again) - :value password-confirm - :on-change (fn [e] (set-password-confirm! (-> e .-target .-value))) - :on-blur (fn [] (set-matched! (= password-confirm password)))}) - - (when (false? matched?) - [:div.text-warning.text-sm - (t :encryption/password-not-matched)])] - - (shui/button - {:on-click on-submit - :disabled (or (string/blank? password) - (false? matched?))} - (t :ui/submit))]]])) - -(hsx/defc e2ee-request-password - [password-promise] - (let [*password-input (hooks/use-ref nil) - [password set-password!] (hooks/use-state "") - on-submit (fn [] - (p/resolve! password-promise - (-> (hooks/deref *password-input) - .-value)) - (shui/dialog-close!))] - [:div.e2ee-password-modal-overlay - [:div.e2ee-password-modal-content.flex.flex-col.gap-8.p-4 - [:div.text-2xl.font-medium (t :encryption/enter-password-title)] - [:div.flex.flex-col.gap-4 - (shui/toggle-password - {:ref *password-input - :value password - :on-key-press (fn [e] - (when (= "Enter" (util/ekey e)) - (on-submit))) - :on-change (fn [e] - (set-password! (-> e .-target .-value)))}) - (shui/button - {:on-click on-submit - :disabled (string/blank? password) - :on-key-press (fn [e] - (when (= "Enter" (util/ekey e)) - (on-submit)))} - (t :ui/submit))]]])) - -(hsx/defc e2ee-password-to-decrypt-private-key - [encrypted-private-key private-key-promise] - (let [*password-input (hooks/use-ref nil) - [password set-password!] (hooks/use-state "") - [decrypt-fail? set-decrypt-fail!] (hooks/use-state false) - on-submit (fn [] - (-> - (p/let [entered-password (-> (hooks/deref *password-input) - .-value) - private-key (crypt/ e .-target .-value)))}) - (when decrypt-fail? [:p.text-warning.text-sm (t :encryption/wrong-password)])] - (shui/button - {:on-click on-submit - :disabled (string/blank? password) - :on-key-press (fn [e] - (when (= "Enter" (util/ekey e)) - (on-submit)))} - (t :ui/submit))]]])) diff --git a/src/main/frontend/components/header.cljs b/src/main/frontend/components/header.cljs index 4b24baa..5b9f84d 100644 --- a/src/main/frontend/components/header.cljs +++ b/src/main/frontend/components/header.cljs @@ -6,17 +6,13 @@ [clojure.string :as string] [dommy.core :as d] [electron.ipc :as ipc] - [frontend.components.avatar :as avatar] [frontend.components.block :as component-block] [frontend.components.email :as email-component] [frontend.components.export :as export] [frontend.components.page-menu :as page-menu] [frontend.components.plugins :as plugins] - [frontend.components.repo :as repo] [frontend.components.right-sidebar :as sidebar] - [frontend.components.rtc.indicator :as rtc-indicator] [frontend.components.server :as server] - [frontend.components.settings :as settings] [frontend.components.svg :as svg] [frontend.config :as config] [frontend.context.i18n :as i18n :refer [t]] @@ -32,7 +28,6 @@ [frontend.state :as state] [frontend.ui :as ui] [frontend.util :as util] - [frontend.util.email :as email-util] [frontend.util.entity :as entity] [frontend.version :refer [version]] [logseq.common.config :as common-config] @@ -55,86 +50,6 @@ (t :nav/home) {:trigger-props {:as-child true}})) -(defn current-local-uploadable-graph - [db-rtc-uuid] - (let [current-repo (state/get-current-repo)] - (some (fn [{:keys [url] :as graph}] - (when (and (= current-repo url) - (repo/local-uploadable-graph? - (assoc graph :rtc-graph? - (boolean db-rtc-uuid)))) - graph)) - (state/get-repos)))) - -(defn- use-db-rtc-uuid - [repo] - (let [[db-rtc-uuid set-db-rtc-uuid!] (hooks/use-state nil)] - (hooks/use-effect! - (fn [] - (when repo - (p/let [graph-uuid (state/ (:GraphUUID remote-graph) str) - state-graph-uuid (some-> (:graph-uuid rtc-state) str)] - (and current-repo - logged-in? - rtc-group? - remote-graph - (or db-rtc-uuid - (and (seq state-graph-uuid) - (= state-graph-uuid remote-graph-uuid)))))) - -(defn local-graph-sync-button - [graph] - (ui/tooltip - (shui/button-ghost-icon :cloud - {:class "local-graph-sync-btn" - :on-click #(repo/upload-local-graph-with-confirm! graph)}) - (t :graph/use-sync-beta) - {:trigger-props {:as-child true}})) - -(hsx/defc rtc-collaborators - [] - (let [rtc-graph-id (use-db-rtc-uuid (state/get-current-repo)) - config (rfx/use-sub [:config]) - online-users (rfx/use-sub [:rtc/state :online-users])] - (when rtc-graph-id - [:div.rtc-collaborators.flex.gap-1.text-sm.bg-gray-01.items-center - (shui/button-ghost-icon :user-plus - {:on-click #(shui/dialog-open! - (fn [] - [:div.p-2.-mb-8 - [:h1.text-3xl.-mt-2.-ml-2 (t :collaboration/members)] - (settings/settings-collaboration)]) - {:id :rtc-collaborators})}) - - (when (seq online-users) - (for [{user-email :user/email - user-name :user/name - user-uuid :user/uuid} online-users - :when user-name - :let [key (str "rtc-user-" (or user-uuid user-email user-name))]] - ^{:key key} - [:<> - (avatar/user-avatar - {:class "w-5 h-5" - :style {:app-region "no-drag"} - :title (email-util/display-email user-email config) - :name user-name - :uuid user-uuid - :fallback-props {:style {:font-size 11}}})]))]))) - (hsx/defc left-menu-button [{:keys [on-click]}] (ui/with-shortcut :ui/toggle-left-sidebar "bottom" @@ -502,9 +417,6 @@ (hsx/defc ^:large-vars/cleanup-todo header-aux [{:keys [current-repo default-home new-block-mode]}] (let [electron-mac? (and util/mac? (util/electron?)) - rtc-graphs (rfx/use-sub [:rtc/graphs]) - rtc-state (rfx/use-sub [:rtc/state]) - db-rtc-uuid (use-db-rtc-uuid current-repo) default-home-page (get-in (state/config-for-repo (rfx/use-sub [:config]) (state/get-current-repo)) [:default-home :page] "") @@ -554,28 +466,9 @@ [:div.flex.flex-1 (block-breadcrumb (state/get-current-page))] [:div.flex.items-center - (when (rtc-indicator-visible? - {:current-repo current-repo - :rtc-graphs rtc-graphs - :db-rtc-uuid db-rtc-uuid - :rtc-state rtc-state - :logged-in? (user-handler/logged-in?) - :rtc-group? (user-handler/rtc-group?)}) - [:<> - (recent-slider) - ^{:key (str "collab-" current-repo)} - [rtc-collaborators] - (rtc-indicator/indicator)]) - - (when (user-handler/logged-in?) - (rtc-indicator/downloading-detail)) - (when (user-handler/logged-in?) - (rtc-indicator/uploading-detail)) + (recent-slider) (search-index-progress) - (when-let [graph (current-local-uploadable-graph db-rtc-uuid)] - (local-graph-sync-button graph)) - (when (and (not= (state/get-current-route) :home) (not custom-home-page?)) (home-button)) @@ -608,6 +501,5 @@ (hsx/defc header [opts] - (let [_user-groups (rfx/use-sub [:user/info :UserGroups]) - _rtc-running? (rfx/use-sub [:rtc/state :rtc-lock])] + (let [_user-groups (rfx/use-sub [:user/info :UserGroups])] (header-aux opts))) diff --git a/src/main/frontend/components/repo.cljs b/src/main/frontend/components/repo.cljs index 2742b0b..f5e7454 100644 --- a/src/main/frontend/components/repo.cljs +++ b/src/main/frontend/components/repo.cljs @@ -1,23 +1,17 @@ (ns frontend.components.repo (:require [clojure.string :as string] - [frontend.components.rtc.indicator :as rtc-indicator] [frontend.config :as config] [frontend.context.i18n :as i18n :refer [t]] - [frontend.handler.db-based.sync :as rtc-handler] - [frontend.handler.events.rtc-error :as rtc-error] [frontend.handler.graph :as graph] [frontend.handler.notification :as notification] [frontend.handler.repo :as repo-handler] [frontend.handler.route :as route-handler] - [frontend.handler.user :as user-handler] - [frontend.mobile.util :as mobile-util] [frontend.rfx :as rfx] [frontend.state :as state] [frontend.ui :as ui] [frontend.util :as util] [frontend.util.text :as text-util] [goog.object :as gobj] - [lambdaisland.glogi :as log] [logseq.common.util :as common-util] [logseq.shui.hooks :as hooks] [logseq.shui.ui :as shui] @@ -25,11 +19,6 @@ [promesa.core :as p] [io.factorhouse.hsx.core :as hsx])) -(defn graph-sync-icon-name - [{:keys [remote? graph-e2ee?]}] - (when remote? - (if graph-e2ee? "lock" "cloud"))) - (defn- repo-display-name [repo-url] (let [repo-name (text-util/get-graph-name-from-path repo-url)] @@ -37,85 +26,15 @@ (config/db-graph-name repo-name) repo-name))) -(defn local-uploadable-graph? - [{:keys [root remote? rtc-graph?]}] - (and (or root - (mobile-util/native-platform?)) - (not remote?) - (not rtc-graph?) - (user-handler/logged-in?) - (user-handler/rtc-group?))) - -(defn (shui/dialog-confirm! - [:p.font-medium.mb-6 (t :graph/upload-local-confirm-desc graph-name)] - dialog-config) - (p/then - (fn [] - (p/let [_ ( (rtc-handler/ - [:a.flex.items-center {:title local-dir - :on-click #(on-click graph)} - [:span graph-name] - (when remote? - [:strong.px-1.flex.items-center (ui/icon (graph-sync-icon-name graph))])]])])) + [:a.flex.items-center {:title local-dir + :on-click #(on-click graph)} + [:span graph-name]])])) (defn sort-repos-with-metadata-local [repos] @@ -183,28 +102,19 @@ (when target (state/pub-event! [:graph/open-new-window target]))))) -(hsx/defc ^:large-vars/cleanup-todo repos-inner +(hsx/defc repos-inner "Graph list in `All graphs` page" [repos] - (for [{:keys [root url remote? graph-e2ee? GraphUUID GraphSchemaVersion GraphName created-at last-seen-at] :as repo} - (sort-repos-with-metadata-local repos) - :let [graph-name (config/db-graph-name url)]] - [:div.flex.justify-between.mb-2.items-center.group {:key (or url GraphUUID) + (for [{:keys [root url created-at last-seen-at] :as repo} + (sort-repos-with-metadata-local repos)] + [:div.flex.justify-between.mb-2.items-center.group {:key url "data-testid" url} [:div [:span.flex.items-center.gap-1 (normalized-graph-label repo (fn [] - (when-not (state/get-state :rtc/downloading-graph-uuid) - (cond - root ; exists locally - (state/pub-event! [:graph/switch url]) - - remote? - (state/pub-event! [:rtc/download-remote-graph GraphName GraphUUID GraphSchemaVersion graph-e2ee?]) - - :else - nil))))] + (when root + (state/pub-event! [:graph/switch url]))))] (when-let [time (some-> (or last-seen-at created-at) (safe-locale-date))] [:small.text-muted-foreground (t :graph/last-opened-at-label time)])] @@ -215,120 +125,42 @@ {:on-click #(open-repo-folder! repo)} (shui/tabler-icon "folder-pin") [:span.pl-1 root]]) - (let [manager? (user-handler/manager? url) - dialog-config {:cancel-label (t :ui/cancel) - :ok-label (t :ui/confirm)}] - (shui/dropdown-menu - (shui/dropdown-menu-trigger - {:asChild true} - (shui/button - {:variant "ghost" - :class "graph-action-btn !px-1" - :size :sm} - (ui/icon "dots" {:size 15}))) - (shui/dropdown-menu-content - {:align "end"} - (when (open-in-another-tab-action? repo) - (shui/dropdown-menu-item - {:key "open-in-another-tab" - :class "open-in-another-tab-menu-item" - :on-click #(open-graph-in-another-tab! repo)} - (t :graph/open-in-another-tab-action))) + (shui/dropdown-menu + (shui/dropdown-menu-trigger + {:asChild true} + (shui/button + {:variant "ghost" + :class "graph-action-btn !px-1" + :size :sm} + (ui/icon "dots" {:size 15}))) + (shui/dropdown-menu-content + {:align "end"} + (when (open-in-another-tab-action? repo) + (shui/dropdown-menu-item + {:key "open-in-another-tab" + :class "open-in-another-tab-menu-item" + :on-click #(open-graph-in-another-tab! repo)} + (t :graph/open-in-another-tab-action))) - (when root - (let [disabled? (not (can-delete-local-graph? repo))] - (shui/dropdown-menu-item - {:key "delete-locally" - :class "delete-local-graph-menu-item" - :disabled disabled? - :on-click #(when-not disabled? - (delete-local-graph! repo))} - (t :graph/delete-local-action)))) - - (when (and root - (user-handler/logged-in?) - (user-handler/rtc-group?) - (not remote?) - (= url (state/get-current-repo))) + (when root + (let [disabled? (not (can-delete-local-graph? repo))] (shui/dropdown-menu-item - {:key "logseq-sync" - :class "use-logseq-sync-menu-item" - :on-click #(upload-local-graph-with-confirm! repo)} - (t :graph/use-sync-beta))) - - (when (and remote? - manager?) - (shui/dropdown-menu-item - {:key "delete-remotely" - :class "delete-remote-graph-menu-item" - :on-click (fn [] - (let [prompt-str (t :graph/delete-server-confirm-desc graph-name)] - (-> (shui/dialog-confirm! - (assoc dialog-config - :title prompt-str - :description (t :graph/delete-warning))) - (p/then - (fn [] - (state/set-state! :rtc/loading-graphs? true) - (when (= (state/get-current-repo) repo) - (rtc-handler/ (shui/dialog-confirm! - [:p.font-medium.-my-4 prompt-str] - dialog-config) - (p/then - (fn [] - (state/set-state! :rtc/loading-graphs? true) - (when (= (state/get-current-repo) repo) - (rtc-handler/ (rtc-handler/> (if (and login? (seq remotes)) - (repo-handler/combine-local-&-remote-graphs repos remotes) - repos) - (util/distinct-by :url)) - repos (cond->> - (remove #(= (:url %) config/demo-repo) repos) - true - (filter (fn [item] - ;; use `config/db-based-graph?` to avoid loading old file graphs - (config/db-based-graph? (:url item))))) - {remote-graphs true local-graphs false} (group-by (comp boolean :remote?) repos) - {own-graphs true shared-graphs false} - (group-by (fn [graph] (= "manager" (:graph<->user-user-type graph))) remote-graphs)] - (hooks/use-effect! - (fn [] - (when (and login? (user-handler/rtc-group?)) - (rtc-handler/ - (when (seq own-graphs) - [:div - [:hr.mt-8] - [:div.flex.align-items.justify-between - [:h2.text-lg.font-medium.mb-4 (t :graph/remote-graphs)] - [:div - (ui/button - [:span.flex.items-center (t :ui/refresh) - (when remotes-loading? [:small.pl-2 (ui/loading nil)])] - :background "gray" - :disabled remotes-loading? - :on-click (fn [] (rtc-handler/ #" GraphUUID)] + short-repo-name (text-util/get-graph-name-from-path repo-url)] (when short-repo-name - {:title [:span.flex.items-center.title-wrap short-repo-name - (when remote? [:span.pl-1.flex.items-center - {:title title} - (ui/icon (if graph-e2ee? "lock" "cloud") {:size 18}) - (when-not ready-for-use? - [:span.opacity.text-sm.pl-1 (t :graph/preparing)]) - (when downloading? - [:span.opacity.text-sm.pl-1 (t :graph/downloading)])])] + {:title [:span.flex.items-center.title-wrap short-repo-name] :hover-detail repo-url ;; show full path on hover :options {:on-click (fn [e] - (when (and ready-for-use? (not downloading?)) - (when-let [on-click (:on-click opts)] - (on-click e)) - (if (and (gobj/get e "shiftKey") (:root graph)) - (if (util/electron?) - (state/pub-event! [:graph/open-new-window url]) - (if-let [target (graph-open-new-window-target graph)] - (state/pub-event! [:graph/open-new-window target]) - (p/let [target (> repo-links (remove nil?)))) @@ -458,35 +244,13 @@ [& {:keys [contentid footer?] :as opts :or {footer? true}}] (let [current-repo (rfx/use-sub [:git/current-repo]) - login? (boolean (rfx/use-sub [:auth/id-token])) repos (rfx/use-sub [:me :repos]) - rtc-graphs (rfx/use-sub [:rtc/graphs]) - downloading-graph-id (rfx/use-sub [:rtc/downloading-graph-uuid]) - remotes-loading? (rfx/use-sub [:rtc/loading-graphs?]) repos (sort-repos-with-metadata-local repos) - repos (->> - (if (and (seq rtc-graphs) login?) - (repo-handler/combine-local-&-remote-graphs repos rtc-graphs) - repos) - - (util/distinct-by :url)) - items-fn #(repos-dropdown-links repos current-repo downloading-graph-id opts) + repos (util/distinct-by :url repos) + items-fn #(repos-dropdown-links repos current-repo opts) header-fn #(when (> (count repos) 1) ; show switch to if there are multiple repos [:div.font-medium.md:text-sm.md:opacity-50.p-2.flex.flex-row.justify-between.items-center - [:h4.pb-1 (t :graph.switch/prompt)] - - (when login? - (if remotes-loading? - (ui/loading "") - (shui/button - {:variant :ghost - :size :sm - :title (t :graph/refresh-remote-graphs) - :class "!h-6 !px-1 relative right-[-4px]" - :on-click (fn [] - (rtc-handler/> user-repos (medley/find-first #(= current-repo (:url %)))) - remote? (:remote? current-repo') short-repo-name (if current-repo (repo-display-name current-repo) (t :graph.switch/select-prompt)) @@ -577,7 +340,7 @@ [:a.item.flex.items-center.gap-1.select-none selector-opts [:span.thumb - (shui/tabler-icon (if remote? "cloud" "topology-star") {:size 16})] + (shui/tabler-icon "topology-star" {:size 16})] [:strong short-repo-name] (shui/tabler-icon "selector" {:size 18})]])) @@ -623,28 +386,9 @@ (string/includes? graph-name "+") (string/includes? graph-name "/"))) -(defn ensure-e2ee-rsa-key-for-cloud! - [{:keys [cloud? graph-e2ee? refresh-token token user-uuid e2ee-rsa-key-ensured?]} set-e2ee-rsa-key-ensured?] - (if (and cloud? graph-e2ee? refresh-token token user-uuid (not e2ee-rsa-key-ensured?)) - (-> (p/do! - (state/pub-event! [:rtc/sync-app-state]) - ( - (p/do - (rtc-handler/ [] - (and developer-mode? (not config/publishing?)) - (conj {:db-id "rtc" :block-type :rtc :label "(Dev) RTC"}) - developer-mode? (conj {:db-id "undo-redo" :block-type :undo-redo :label "(Dev) Undo/Redo"}) diff --git a/src/main/frontend/components/rtc/download_progress.cljs b/src/main/frontend/components/rtc/download_progress.cljs deleted file mode 100644 index 078b940..0000000 --- a/src/main/frontend/components/rtc/download_progress.cljs +++ /dev/null @@ -1,31 +0,0 @@ -(ns frontend.components.rtc.download-progress - (:require [frontend.components.rtc.indicator :as indicator] - [frontend.context.i18n :refer [t]] - [frontend.mobile.util :as mobile-util] - [logseq.shui.ui :as shui])) - -(defn- content - [graph-name] - [:div.flex.flex-col.items-center.justify-center.gap-4 - [:div (t :sync/downloading-graph graph-name)] - (indicator/downloading-logs)]) - -(defn show! - [graph-name] - (if (mobile-util/native-platform?) - (shui/popup-show! - nil - #(content graph-name) - {:id :download-rtc-graph}) - (shui/dialog-open! - #(content graph-name) - {:id :download-rtc-graph - :content-props - {:onPointerDownOutside #(.preventDefault %) - :onOpenAutoFocus #(.preventDefault %)}}))) - -(defn hide! - [] - (if (mobile-util/native-platform?) - (shui/popup-hide! :download-rtc-graph) - (shui/dialog-close! :download-rtc-graph))) diff --git a/src/main/frontend/components/rtc/indicator.cljs b/src/main/frontend/components/rtc/indicator.cljs deleted file mode 100644 index 2b4fae7..0000000 --- a/src/main/frontend/components/rtc/indicator.cljs +++ /dev/null @@ -1,360 +0,0 @@ -(ns frontend.components.rtc.indicator - "RTC state indicator" - (:require [clojure.pprint :as pprint] - [clojure.string :as string] - [frontend.config :as config] - [frontend.db.async :as db-async] - [frontend.handler.db-based.rtc-flows :as rtc-flows] - [frontend.context.i18n :refer [locale-format-date t]] - [frontend.handler.db-based.sync :as rtc-handler] - [frontend.rfx :as rfx] - [frontend.state :as state] - [frontend.ui :as ui] - [frontend.util :as util] - [logseq.shui.hooks :as hooks] - [logseq.shui.ui :as shui] - [promesa.core :as p] - [io.factorhouse.hsx.core :as hsx])) - -(comment - (def rtc-state-schema - [:enum :open :close])) - -(defonce ^:private *detail-logs - (atom {:download-logs nil - :upload-logs nil - :misc-logs nil})) - -(defn rtc-state->detail-info - [state] - {:pending-local-ops (:unpushed-block-update-count state) - :pending-asset-ops (:pending-asset-ops-count state) - :missing-asset-upload-files (:missing-asset-upload-files state) - :pending-server-ops (or (:pending-server-ops-count state) - (when (and (number? (:remote-tx state)) - (number? (:local-tx state))) - (max 0 (- (:remote-tx state) (:local-tx state))))) - :graph-uuid (:graph-uuid state) - :local-tx (:local-tx state) - :remote-tx (:remote-tx state) - :local-checksum (:local-checksum state) - :remote-checksum (:remote-checksum state) - :rtc-state (if (:rtc-lock state) :open :close)}) - -(defn- update-detail-log! - [k log] - (when log - (swap! *detail-logs update k (fn [logs] (take 5 (conj logs log)))))) - -(add-watch rtc-flows/rtc-download-log ::update-detail-download-log - (fn [_ _ _ log] (update-detail-log! :download-logs log))) -(add-watch rtc-flows/rtc-upload-log ::update-detail-upload-log - (fn [_ _ _ log] (update-detail-log! :upload-logs log))) -(add-watch rtc-flows/rtc-misc-log ::update-detail-misc-log - (fn [_ _ _ log] (update-detail-log! :misc-logs log))) - -(defn use-detail-info - [] - (merge (rtc-state->detail-info (rfx/use-sub [:rtc/state])) - (hooks/use-atom-value *detail-logs))) - -(defn asset-transfer-counts - [progress] - (reduce-kv - (fn [counts _id {:keys [direction loaded total]}] - (if (and (contains? #{:upload :download} direction) - (number? loaded) - (number? total) - (not= loaded total)) - (update counts direction inc) - counts)) - {:upload 0 - :download 0} - (or progress {}))) - -(defn asset-status-rows - [{:keys [pending-asset-ops missing-asset-upload-files] - transfer-counts :asset-transfer-counts}] - (let [{:keys [upload download]} transfer-counts - missing-count (count missing-asset-upload-files) - pending-upload-count (max 0 (- (or pending-asset-ops 0) missing-count))] - (cond-> [] - (pos? missing-count) - (conj {:count missing-count - :label-key :sync/missing-asset-files}) - - (pos? pending-upload-count) - (conj {:count pending-upload-count - :label-key :sync/pending-asset-uploads}) - - (pos? (or upload 0)) - (conj {:count upload - :label-key :sync/assets-uploading}) - - (pos? (or download 0)) - (conj {:count download - :label-key :sync/assets-downloading})))) - -(defn indicator-button-class - [{:keys [online? rtc-state pending-local-ops pending-asset-ops pending-server-ops]}] - (let [open? (and online? (= :open rtc-state)) - syncing? (and open? (pos? (or pending-server-ops 0))) - idle? (and open? - (zero? (or pending-local-ops 0)) - (zero? (or pending-asset-ops 0)) - (zero? (or pending-server-ops 0))) - queuing? (or (pos? (or pending-local-ops 0)) - (pos? (or pending-asset-ops 0)))] - (string/join " " (cond-> ["cloud"] - open? (conj "on") - syncing? (conj "syncing") - idle? (conj "idle") - queuing? (conj "queuing"))))) - -(defn- asset-status-label - [label-key] - (case label-key - :sync/missing-asset-files (t :sync/missing-asset-files) - :sync/pending-asset-uploads (t :sync/pending-asset-uploads) - :sync/assets-uploading (t :sync/assets-uploading) - :sync/assets-downloading (t :sync/assets-downloading))) - -(hsx/defc missing-asset-files - [files] - (when (seq files) - [:details.assets-missing-files - [:summary - (t :sync/missing-asset-files-count (count files))] - [:div.flex.flex-col.gap-1.text-sm - (for [{:keys [file]} files] - [:div.flex.flex-row.gap-1.items-center - {:key file} - (ui/icon "alert-triangle" {:size 14}) - [:span.truncate file]])]])) - -(hsx/defc assets-progressing - [progress] - (let [ids (->> progress - (keep (fn [[id {:keys [loaded total]}]] - (when (and (not= loaded total) - (number? loaded) (number? total)) - (uuid id)))) - distinct - vec) - [id->block set-id->block!] (hooks/use-state {}) - _ (hooks/use-effect! - (fn [] - (p/let [results (db-async/block! (into {} (keep (fn [{:keys [block]}] - (when-let [id (:block/uuid block)] - [id block])) - results)))) - nil) - [ids]) - downloading (->> - (keep (fn [[id {:keys [direction loaded total]}]] - (when (and (= direction :download) - (not= loaded total) - (number? loaded) (number? total)) - (when-let [block (get id->block (uuid id))] - {:block block - :percent (int (* 100 (/ loaded total)))}))) progress) - (sort-by (fn [{:keys [block]}] (:block/title block)))) - uploading (->> (keep (fn [[id {:keys [direction loaded total]}]] - (when (and (= direction :upload) - (not= loaded total) - (number? loaded) (number? total)) - (when-let [block (get id->block (uuid id))] - {:block block - :percent (int (* 100 (/ loaded total)))}))) progress) - (sort-by (fn [{:keys [block]}] (:block/title block))))] - [:div.assets-sync-progress.flex.flex-col.gap-2 - (when (seq downloading) - [:details - [:summary - (t :sync/assets-downloading-count (count downloading))] - [:div.flex.flex-col.gap-1.text-sm - (for [{:keys [block percent]} downloading] - [:div.flex.flex-row.gap-1.items-center - (ui/indicator-progress-pie percent) - (:block/title block)])]]) - (when (seq uploading) - [:details - [:summary - (t :sync/assets-uploading-count (count uploading))] - [:div.flex.flex-col.gap-1.text-sm - (for [{:keys [block percent]} uploading] - [:div.flex.flex-row.gap-1.items-center - (ui/indicator-progress-pie percent) - (:block/title block)])]])])) - -(hsx/defc details - [] - (let [online? (rfx/use-sub [:network/online?]) - repo (state/get-current-repo) - asset-progress (rfx/use-sub [:rtc/asset-upload-download-progress repo]) - [expand-debug? set-expand-debug!] (hooks/use-state false) - show-checksums? (or config/dev? util/node-test?) - detail-info (use-detail-info) - {:keys [graph-uuid local-tx remote-tx local-checksum remote-checksum rtc-state - download-logs upload-logs misc-logs pending-local-ops pending-asset-ops - missing-asset-upload-files pending-server-ops]} - detail-info - asset-rows (asset-status-rows {:pending-asset-ops pending-asset-ops - :missing-asset-upload-files missing-asset-upload-files - :asset-transfer-counts (asset-transfer-counts asset-progress)})] - [:div.rtc-info.flex.flex-col.gap-1.p-2.text-gray-11 - [:div.font-medium.mb-2 (t (if online? :sync/online :sync/offline))] - [:div [:span.font-medium.mr-1 (or pending-local-ops 0)] (t :sync/pending-local-changes)] - (for [{:keys [count label-key]} asset-rows] - [:div {:key (name label-key)} - [:span.font-medium.mr-1 count] - (asset-status-label label-key)]) - ;; FIXME: pending-server-ops - [:div [:span.font-medium.mr-1 (or pending-server-ops 0)] (t :sync/pending-server-changes)] - (missing-asset-files missing-asset-upload-files) - (assets-progressing asset-progress) - ;; FIXME: What's the type for downloaded log? - (when-let [latest-log (some (fn [l] (when (contains? #{:rtc.log/push-local-update} (:type l)) l)) misc-logs)] - (when-let [time (:created-at latest-log)] - [:div.text-sm (t :sync/last-synced-time-label (locale-format-date time))])) - [:a.fade-link.text-sm {:on-click #(set-expand-debug! (not expand-debug?))} - (t :sync/more-debug-info)] - (when expand-debug? - [:div.rtc-info-debug - [:pre.select-text - (-> (cond-> {:pending-local-ops pending-local-ops} - download-logs (assoc :download download-logs) - upload-logs (assoc :upload upload-logs) - misc-logs (assoc :misc misc-logs) - graph-uuid (assoc :graph-uuid graph-uuid) - local-tx (assoc :local-tx local-tx) - remote-tx (assoc :remote-tx remote-tx) - (and show-checksums? local-checksum) (assoc :local-checksum local-checksum) - (and show-checksums? remote-checksum) (assoc :remote-checksum remote-checksum) - rtc-state (assoc :rtc-state rtc-state)) - pprint/pprint - with-out-str)]]) - (when-not (= rtc-state :open) - [:div.mt-4 - (shui/button {:variant :default - :size :sm - :on-click (fn [] - (rtc-handler/ (push-sync-config-to-worker!) - (p/then #(notification/show! (t :settings.sync-server/clear-success) :success)) - (p/catch #(notification/show! (str "Failed to update worker: " %) :error))))] - [:div.cp__settings-sync-server-cnt - [:h1.mb-2.text-2xl.font-bold (t :settings.sync-server/url)] - [:div.p-2 - [:p.text-sm.opacity-70.mb-4 (t :settings.sync-server/url-desc)] - [:p - [:label - [:strong "URL"] - [:input.form-input.is-small - {:value url - :placeholder config/default-db-sync-http-base - :style {:width "100%"} - :on-change #(set-url! (util/evalue %))}]]] - [:p.pt-2.flex.gap-2 - (shui/button - {:size :sm - :on-click (fn [] - (let [trimmed (string/trim url)] - (if (string/blank? trimmed) - (reset-url!) - (if-not (config/valid-sync-server-url? trimmed) - (notification/show! (t :settings.sync-server/url-invalid-error) :error) - (do - (config/set-custom-sync-server-url! trimmed) - (-> (push-sync-config-to-worker!) - (p/then #(notification/show! (t :settings.sync-server/save-success) :success)) - (p/catch #(notification/show! (str "Failed to update worker: " %) :error))))))))} - (t :ui/save)) - (when (seq url) - (shui/button - {:size :sm - :variant :outline - :on-click (fn [] (reset-url!))} - (t :settings.sync-server/reset)))]]])) - (hsx/defc db-worker-server-settings-container "Connects a web/mobile client to a self-hosted db-worker-node server (see frontend.persist-db/remote-runtime?). Electron manages its own local @@ -788,23 +734,6 @@ {:left-label "Server" :action (db-worker-server-button)})) -(hsx/defc sync-server-url-button - [] - (let [current-url (config/get-custom-sync-server-url)] - (ui/button [:span.flex.items-center - [:span.pr-1 - (if (seq current-url) - current-url - "Logseq Sync")] - (ui/icon "edit")] - :class "text-sm" - :on-click #(state/pub-event! [:go/sync-server-settings])))) - -(defn sync-server-url-row [] - (row-with-button-action - {:left-label (t :settings.sync-server/url) - :action (sync-server-url-button)})) - (hsx/defc publish-server-url-settings-container [] (let [current-url (config/get-custom-publish-server-url) @@ -1024,7 +953,6 @@ (usage-diagnostics-row t instrument-disabled?) (when-not (mobile-util/native-platform?) (developer-mode-row t developer-mode?)) (when-not (util/electron?) (db-worker-server-row)) - (sync-server-url-row) (publish-server-url-row) (when (util/electron?) (https-user-agent-row https-agent-opts)) (when (util/electron?) (auto-chmod-row t)) @@ -1294,221 +1222,6 @@ [:<>]) -(hsx/defc settings-rtc-members - [] - (let [[invite-email set-invite-email!] (hooks/use-state "") - [loading? set-loading!] (hooks/use-state true) - [graph-uuid set-graph-uuid!] (hooks/use-state nil) - current-repo (state/get-current-repo) - manager? (user-handler/manager? current-repo) - users-info (rfx/use-sub [:rtc/users-info]) - users (get users-info current-repo) - invite-user! (fn [] - (when-not (string/blank? invite-email) - (when graph-uuid - (rtc-handler/user-user-type :graph<->user/user-type} users] - (let [member? (= :member graph<->user-user-type) - can-remove? (and manager? member?)] - [:div.flex.flex-row.items-center.gap-2 - {:key (str "user-" (or user-uuid user-name))} - [:div user-name] - (when user-email - (email-component/email-address {:email user-email - :class "opacity-50 text-sm"})) - (when graph<->user-user-type [:div.opacity-50.text-sm (name graph<->user-user-type)]) - (when can-remove? - (shui/dropdown-menu - (shui/dropdown-menu-trigger - {:asChild true} - (shui/button - {:variant "ghost" - :size :sm - :class "px-1 h-7"} - (ui/icon "dots" {:size 14}))) - (shui/dropdown-menu-content - {:align "end"} - (shui/dropdown-menu-item - {:class "remove-member-menu-item" - :on-click (fn [] - (let [member-id user-uuid] - (when (and graph-uuid member-id) - (-> (rtc-handler/ (p/do! - (set-force-reset-status! (t :encryption/force-resetting-password)) - (state/ (p/let [r (state/ (p/let [{:keys [password]} (state/ (p/do! - (state/ (p/do! - (set-reset-password-status! (t :encryption/updating-password)) - (state/ws-url - "Derive a WebSocket sync URL from a custom HTTP base URL. Pure function." - [custom-url] - (let [scheme (if (string/starts-with? custom-url "https") "wss" "ws") - base (-> custom-url - (string/replace #"^https?://" "") - (string/replace #"/+$" ""))] - (str scheme "://" base "/sync/%s"))) - -(defn custom-url->http-base - "Normalize a custom HTTP base URL by stripping trailing slashes. Pure function." - [custom-url] - (string/replace custom-url #"/+$" "")) - -(defn db-sync-ws-url - "Return the WebSocket sync URL. Uses custom server when configured, otherwise the default." - [] - (if-let [custom (get-custom-sync-server-url)] - (custom-url->ws-url custom) - default-db-sync-ws-url)) - -(defn db-sync-http-base - "Return the HTTP base URL for sync. Uses custom server when configured, otherwise the default." - [] - (if-let [custom (get-custom-sync-server-url)] - (custom-url->http-base custom) - default-db-sync-http-base)) - ;; Web/mobile clients connect to a self-hosted db-worker-node daemon by ;; base URL + bearer token, instead of Electron's IPC-managed local runtime ;; (see frontend.persist-db/remote-runtime?). Stored client-side only; the diff --git a/src/main/frontend/core.cljs b/src/main/frontend/core.cljs index c04d504..45df9f4 100644 --- a/src/main/frontend/core.cljs +++ b/src/main/frontend/core.cljs @@ -7,7 +7,6 @@ [frontend.components.plugins :as plugins] [frontend.config :as config] [frontend.handler :as handler] - [frontend.handler.db-based.rtc-background-tasks] [frontend.handler.plugin :as plugin-handler] [frontend.handler.route :as route-handler] [frontend.log] diff --git a/src/main/frontend/db/restore.cljs b/src/main/frontend/db/restore.cljs index f80ff6e..750518f 100644 --- a/src/main/frontend/db/restore.cljs +++ b/src/main/frontend/db/restore.cljs @@ -16,12 +16,8 @@ {:keys [schema]} (persist-db/ {:user-uuid (user/user-uuid) - :graph (:graph-uuid debug-state*) - :rtc-state rtc-state - :rtc-logs rtc-logs - :local-tx (:local-tx debug-state*) - :pending-block-update-count (:unpushed-block-update-count debug-state*) - :remote-graphs (:remote-graphs debug-state*) - :online-users (:online-users debug-state*) - :auto-push? (:auto-push? debug-state*) - :remote-profile? (:remote-profile? debug-state*) - :current-page (state/get-current-page) - :blocks-count current-page-blocks-count - :schema-version {:app (db-schema/schema-version->string db-schema/version) - :local-graph (:local-graph-schema-version debug-state*) - :remote-graph (str (:remote-graph-schema-version debug-state*))}} - (fipp/pprint {:width 20}) - with-out-str)]] - - [:div.my-2.flex.gap-2 - (shui/button - {:variant :outline - :size :sm - :class "text-green-rx-09 border-green-rx-10 hover:text-green-rx-10" - :on-click (fn [] (rtc-handler/ (state/ keys-state - (fipp/pprint {:width 20}) - with-out-str)]]]])) diff --git a/src/main/frontend/handler.cljs b/src/main/frontend/handler.cljs index 5183651..573c7e3 100644 --- a/src/main/frontend/handler.cljs +++ b/src/main/frontend/handler.cljs @@ -15,10 +15,8 @@ [frontend.db.restore :as db-restore] [frontend.error :as error] [frontend.handler.command-palette :as command-palette] - [frontend.handler.e2ee] [frontend.handler.events :as events] [frontend.handler.events.export] - [frontend.handler.events.rtc] [frontend.handler.events.ui] [frontend.handler.graph :as graph-handler] [frontend.handler.global-config :as global-config-handler] diff --git a/src/main/frontend/handler/assets.cljs b/src/main/frontend/handler/assets.cljs index 0b588af..8377b8c 100644 --- a/src/main/frontend/handler/assets.cljs +++ b/src/main/frontend/handler/assets.cljs @@ -336,32 +336,3 @@ (p/let [[repo-dir assets-dir] (ensure-assets-dir! (state/get-current-repo))] (path/path-join repo-dir assets-dir filename))) -(defn- asset-transfer-in-progress? - [progress-entry] - (let [{:keys [loaded total]} progress-entry] - (and (number? loaded) (number? total) (pos? total) (not= loaded total)))) - -(defn should-request-remote-asset-download? - [repo asset-block file-ready? progress] - (let [asset-uuid (:block/uuid asset-block) - asset-type (:logseq.property.asset/type asset-block) - external-url (:logseq.property.asset/external-url asset-block) - remote-metadata (:logseq.property.asset/remote-metadata asset-block) - progress-entry (get progress (str asset-uuid))] - (and (seq repo) - remote-metadata - asset-uuid - (seq asset-type) - (string/blank? external-url) - (not file-ready?) - (not (asset-transfer-in-progress? progress-entry))))) - -(defn maybe-request-remote-asset-download! - [repo asset-block file-ready?] - (let [progress (get (or (state/get-state :rtc/asset-upload-download-progress) {}) repo)] - (when (should-request-remote-asset-download? repo asset-block file-ready? progress) - (state/ (or repo "graph") - (string/replace #"^/+" "") - (string/replace #"[\\/]+" "_") - (str "_checksum_" (quot (util/time-ms) 1000)))) - (defn- client-ops-export-file-name [repo] (-> (or repo "graph") @@ -98,113 +89,6 @@ (string/replace #"[\\/]+" "_") (str "_client_ops_" (quot (util/time-ms) 1000)))) -(defn- graph-id' str)] - (if (and (seq base) (seq graph-id)) - (rtc-handler/fetch-json (str base "/sync/" graph-id "/checksum/diagnostics") - {:method "GET"} - {:error-schema :error}) - (p/rejected (ex-info "missing sync diagnostics context" - {:repo repo - :base base - :graph-id graph-id}))))) - -(defn- normalize-diff-block - [{:keys [block/uuid block/parent block/page] :as block}] - (cond-> block - uuid (assoc :block/uuid (str uuid)) - parent (assoc :block/parent (str parent)) - page (assoc :block/page (str page)))) - -(defn- blocks-by-uuid - [blocks] - (into {} - (keep (fn [block] - (let [block' (normalize-diff-block block) - uuid (:block/uuid block')] - (when (seq uuid) - [uuid block'])))) - blocks)) - -(defn- different-blocks - [local-blocks server-blocks] - (let [local-by-uuid (blocks-by-uuid local-blocks) - server-by-uuid (blocks-by-uuid server-blocks) - block-uuids (sort (set/union (set (keys local-by-uuid)) - (set (keys server-by-uuid))))] - (->> block-uuids - (keep (fn [uuid] - (let [local-block (get local-by-uuid uuid) - server-block (get server-by-uuid uuid)] - (when (not= local-block server-block) - {:block/uuid uuid - :local-block local-block - :server-block server-block})))) - vec))) - -(defn- (state/js {:type "text/edn;charset=utf-8"})) - filename (checksum-export-file-name repo)] - (p/let [_ (-> (") - (or remote-checksum "") - filename - (count blocks) - (pr-str checksum-attrs)) - :success - false))) - (notification/show! (t :graph.diagnostics/checksum-unavailable-warning) :warning)))) - (p/catch (fn [error] - (js/console.error "recompute-checksum-diagnostics failed:" error) - (notification/show! (t :graph.diagnostics/checksum-failed-error) :error)))) - (notification/show! (t :graph.diagnostics/no-graph-warning) :warning))) - (defn ^:export export-client-ops-sqlite [] (if (and util/web-platform? (not (util/electron?))) @@ -238,9 +122,3 @@ (defn ^:export replace-graph-with-db-file [] (state/pub-event! [:dialog-select/db-graph-replace])) - -(defn ^:export rtc-stop [] - (rtc-handler/ current-graph-uuid str)) - (> 5000 (- (common-util/time-ms) t))) - (log/info :trying-to-restart-rtc graph-uuid :t (t/now)) - (rtc-handler/= (- now @last-emitted-at) 5000)) - (reset! last-emitted-at now) - (reset! state* {:graph-uuid graph-uuid :t now}))))] - (doseq [[watch-key atom'] {::rtc-try-restart-state rtc-state - ::rtc-try-restart-online flows/network-online? - ::rtc-try-restart-user flows/current-login-user}] - (add-watch atom' watch-key (fn [_ _ _ _] (update!)))) - state*)) - -(def logout - (let [state* (atom nil)] - (add-watch flows/current-login-user ::logout - (fn [_ _ _ user] - (when (= :logout user) - (reset! state* :logout)))) - state*)) - -(def ^:private *rtc-start-trigger (atom nil)) - -(defn trigger-rtc-start - [repo] - (assert (some? repo)) - (reset! *rtc-start-trigger repo)) - -(defn- document-visible->restart-event - [visibility] - (when (= "visible" visibility) - :document-visible&rtc-not-running)) - -(defn- network-online->restart-event - [online?] - (when online? - :network-online&rtc-not-running)) - -(defn- mobile-app-active->restart-event - [app-active?] - (when app-active? - :mobile-app-active&rtc-not-running)) - -(def trigger-start-rtc - (let [state* (atom nil) - timeout-id (atom nil) - emit! (fn [event] - (when @flows/current-login-user - (when-let [id @timeout-id] - (js/clearTimeout id)) - (reset! timeout-id (js/setTimeout #(reset! state* event) 50))))] - (add-watch flows/current-login-user ::trigger-start-rtc-login - (fn [_ _ _ user] - (when (:email user) - (emit! [:login])))) - (add-watch flows/current-repo ::trigger-start-rtc-repo - (fn [_ _ _ repo] - (when repo - (emit! [:graph-switch repo])))) - (add-watch *rtc-start-trigger ::trigger-start-rtc-manual - (fn [_ _ _ repo] - (when repo - (emit! [:trigger-rtc repo])))) - (add-watch flows/document-visibility-state ::trigger-start-rtc-visible - (fn [_ _ _ visibility] - (when-let [event (document-visible->restart-event visibility)] - (emit! [event])))) - (add-watch flows/network-online? ::trigger-start-rtc-online - (fn [_ _ _ online?] - (when-let [event (network-online->restart-event online?)] - (emit! [event])))) - (add-watch mobile-flows/*mobile-app-state ::trigger-start-rtc-mobile-active - (fn [_ _ _ app-active?] - (when-let [event (mobile-app-active->restart-event app-active?)] - (emit! [event])))) - state*)) diff --git a/src/main/frontend/handler/db_based/sync.cljs b/src/main/frontend/handler/db_based/sync.cljs deleted file mode 100644 index 131daba..0000000 --- a/src/main/frontend/handler/db_based/sync.cljs +++ /dev/null @@ -1,463 +0,0 @@ -(ns frontend.handler.db-based.sync - "DB-sync handler based on Cloudflare Durable Objects." - (:require [clojure.string :as string] - [frontend.config :as config] - [frontend.context.i18n :refer [t]] - [frontend.handler.notification :as notification] - [frontend.handler.repo :as repo-handler] - [frontend.handler.user :as user-handler] - [frontend.persist-db :as persist-db] - [frontend.state :as state] - [frontend.util :as util] - [lambdaisland.glogi :as log] - [logseq.db-sync.malli-schema :as db-sync-schema] - [promesa.core :as p])) - -(defn- ws->http-base [ws-url] - (when (string? ws-url) - (let [base (cond - (string/starts-with? ws-url "wss://") - (str "https://" (subs ws-url (count "wss://"))) - - (string/starts-with? ws-url "ws://") - (str "http://" (subs ws-url (count "ws://"))) - - :else ws-url) - base (string/replace base #"/sync/%s$" "")] - base))) - -(defn http-base [] - (or (config/db-sync-http-base) - (ws->http-base (config/db-sync-ws-url)))) - -(defn- auth-headers [] - (when-let [token (state/get-auth-id-token)] - {"authorization" (str "Bearer " token)})) - -(defn- with-auth-headers [opts] - (if-let [auth (auth-headers)] - (assoc opts :headers (merge (or (:headers opts) {}) auth)) - opts)) - -(declare fetch-json) - -(declare coerce-http-response) -(declare js (with-auth-headers opts))) - text (.text resp) - data (when (seq text) (js/JSON.parse text))] - (if (.-ok resp) - (let [body (js->clj data :keywordize-keys true) - body (if response-schema - (coerce-http-response response-schema body) - body)] - (if (or (nil? response-schema) body) - body - (throw (ex-info "db-sync invalid response" - {:status (.-status resp) - :url url - :body body})))) - (let [body (when data (js->clj data :keywordize-keys true)) - body (if error-schema - (coerce-http-response error-schema body) - body)] - (throw (ex-info "db-sync request failed" - {:status (.-status resp) - :url url - :body body})))))) - -(def ^:private invalid-coerce ::invalid-coerce) - -(defn- coerce - [coercer value context] - (try - (coercer value) - (catch :default e - (log/error :db-sync/malli-coerce-failed (merge context {:error e :value value})) - invalid-coerce))) - -(defn- coerce-http-request [schema-key body] - (if-let [coercer (get db-sync-schema/http-request-coercers schema-key)] - (let [coerced (coerce coercer body {:schema schema-key :dir :request})] - (when-not (= coerced invalid-coerce) - coerced)) - body)) - -(defn- coerce-http-response [schema-key body] - (if-let [coercer (get db-sync-schema/http-response-coercers schema-key)] - (let [coerced (coerce coercer body {:schema schema-key :dir :response})] - (when-not (= coerced invalid-coerce) - coerced)) - body)) - -(defn- remote-graph - [repo] - (some #(when (= repo (:url %)) %) (state/get-rtc-graphs))) - -(defn- graph-uuid str))) - -(defn- (p/let [_ ( (if (nil? (:git/current-repo payload)) - (dissoc payload :git/current-repo) - payload) - (seq config/OAUTH-DOMAIN) - (assoc :auth/oauth-domain config/OAUTH-DOMAIN) - - (seq config/COGNITO-CLIENT-ID) - (assoc :auth/oauth-client-id config/COGNITO-CLIENT-ID)))) - -(defn- role keyword)] - (cond-> {:user/uuid user-id - :user/name name - :graph<->user/user-type user-type} - (string? email) (assoc :user/email email)))) - members)] - (state/set-state! :rtc/users-info users :nested-path repo) - users) - - :else - (p/resolved nil)))))))) - -(defn (if (and graph-uuid base) - (p/let [_ (user-handler/ (p/let [_ (state/set-state! :rtc/loading-graphs? true) - _ (user-handler/user-user-type (:role graph) - :graph<->user-grant-by-user (:invited-by graph)} - (dissoc graph :graph-id :graph-name :schema-version :role :invited-by :graph-ready-for-use?)))) - graphs)] - (state/set-state! :rtc/graphs result) - (repo-handler/refresh-repos!) - result) - (p/finally - (fn [] - (state/set-state! :rtc/loading-graphs? false))))))) - -(defn - (p/let [_ (js body))} - {:response-schema :graph-members/create}) - repo (state/get-current-repo) - _ ( graph-uuid str) - member-id (some-> member-id str)] - (if (and base (string? graph-uuid) (string? member-id)) - (p/let [_ (user-handler/ (p/let [_ ( - (p/do! - (when (util/mobile?) - (download-progress/show! graph-name)) - (rtc-handler/ UI (defevent! :db/sync-changes [[_ data]] (pipeline/invoke-hooks data) diff --git a/src/main/frontend/handler/events/rtc.cljs b/src/main/frontend/handler/events/rtc.cljs deleted file mode 100644 index be5abf9..0000000 --- a/src/main/frontend/handler/events/rtc.cljs +++ /dev/null @@ -1,108 +0,0 @@ -(ns frontend.handler.events.rtc - "RTC events" - (:require-macros [frontend.handler.events.macros :refer [defevent!]]) - (:require [frontend.common.crypt :as crypt] - [frontend.components.e2ee :as e2ee] - [frontend.config :as config] - [frontend.context.i18n :refer [t]] - [frontend.flows :as flows] - [frontend.handler.events :as events] - [frontend.handler.notification :as notification] - [frontend.state :as state] - [lambdaisland.glogi :as log] - [logseq.shui.ui :as shui] - [promesa.core :as p])) - -(defn- rtc-collaborators-dialog? - [] - (= :rtc-collaborators (state/get-dialog-id))) - -(defn- close-e2ee-blocking-ui! - [] - (when-not (rtc-collaborators-dialog?) - (shui/dialog-close-all!)) - (shui/popup-hide! :download-rtc-graph)) - -(defevent! :rtc/decrypt-user-e2ee-private-key [[_ encrypted-private-key]] - (let [private-key-promise (p/deferred) - refresh-token (str (state/get-auth-refresh-token))] - (close-e2ee-blocking-ui!) - (-> - (p/let [{:keys [password]} (state/ (update-vals state-atoms deref) - (seq config/OAUTH-DOMAIN) - (assoc :auth/oauth-domain config/OAUTH-DOMAIN) - - (seq config/COGNITO-CLIENT-ID) - (assoc :auth/oauth-client-id config/COGNITO-CLIENT-ID))) - sync! (fn [] - (let [m (app-state)] - (when-not (= @last-state m) - (reset! last-state m) - (p/let [_ (when (:git/current-repo m) - (state/ error str))) - -(defn- error-texts - [error] - (when error - (let [data (ex-data error)] - (concat - [(throwable-message error) - (:error-message data) - (:error-cause data)] - (error-texts (:error data)) - (error-texts (ex-cause error)))))) - -(defn- error-codes - [error] - (when error - (let [data (ex-data error)] - (concat - [(:code data)] - (error-codes (:error data)) - (error-codes (ex-cause error)))))) - -(defn e2ee-decrypt-failed? - [error] - (boolean - (or (some e2ee-decrypt-error-codes (error-codes error)) - (some #{"decrypt-aes-key"} (error-texts error))))) diff --git a/src/main/frontend/handler/events/ui.cljs b/src/main/frontend/handler/events/ui.cljs index a0891ba..9b3b8c7 100644 --- a/src/main/frontend/handler/events/ui.cljs +++ b/src/main/frontend/handler/events/ui.cljs @@ -2,7 +2,6 @@ "UI events" (:require-macros [frontend.handler.events.macros :refer [defevent!]]) (:require [clojure.core.async :as async] - [clojure.core.async.interop :refer [p->c]] [frontend.components.assets :as assets] [frontend.components.cmdk.core :as cmdk] [frontend.components.icon :as icon-component] @@ -25,8 +24,6 @@ [frontend.extensions.pdf.assets :as pdf-assets] [frontend.fs :as fs] [frontend.handler.assets :as assets-handler] - [frontend.handler.db-based.rtc-flows :as rtc-flows] - [frontend.handler.db-based.sync :as rtc-handler] [frontend.handler.editor :as editor-handler] [frontend.handler.events :as events] [frontend.handler.notification :as notification] @@ -50,15 +47,6 @@ [promesa.core :as p] [logseq.shui.dialog.core :as shui-dialog])) -(defn- (p/do! - (state/pub-event! [:rtc/sync-app-state]) - (state/c (rtc-handler/ (or (:kv/value metadata) - (second sync-meta)) str)] - (if (and graph-id (nil? (:GraphUUID repo))) - (assoc repo :GraphUUID graph-id) - repo))) - local-repos) - (some->> remote-repos - (map #(assoc % :remote? true)))))] - (let [app-major-schema-version (str (:major (db-schema/parse-schema-version db-schema/version))) - repos' (group-by :url repos') - repos'' (mapcat (fn [[k vs]] - (if (some? k) - (let [remote-repos (filter :remote? vs) - version-matched-remote-repo - (first - (filter - #(= app-major-schema-version (:GraphSchemaVersion %)) - remote-repos))] - [(merge (first vs) (second vs) version-matched-remote-repo)]) - vs)) - repos')] - (sort-by (fn [repo] - (let [graph-name (or (:GraphName repo) - (last (string/split (:root repo) #"/")))] - [(:remote? repo) (string/lower-case graph-name)])) repos'')))) - (defn refresh-repos! [] - (p/let [repos (get-repos) - repos' (combine-local-&-remote-graphs - repos - (state/get-rtc-graphs))] - (state/set-repos! repos') - repos')) + (p/let [repos (get-repos)] + (state/set-repos! repos) + repos)) (defn graph-ready! ;; FIXME: Call electron that the graph is loaded, an ugly implementation for redirect to page when graph is restored diff --git a/src/main/frontend/handler/user.cljs b/src/main/frontend/handler/user.cljs index af321e9..66c4b55 100644 --- a/src/main/frontend/handler/user.cljs +++ b/src/main/frontend/handler/user.cljs @@ -5,7 +5,6 @@ [cljs-time.coerce :as tc] [cljs-time.core :as t] [cljs.core.async :as async :refer [ (state/ (some #(when (= repo (:url %)) %) (:rtc/graphs (state/get-state))) - :graph<->user-user-type)) - -(defn manager? - [repo] - (= (get-user-type repo) "manager")) - -;; TODO: Remove if still unused -#_(defn member? - [repo] - (= (get-user-type repo) "member")) - (defn payload - [error] - (let [data (ex-data error)] - (merge {:code (or (:code data) :ui-request-failed) - :message (or (ex-message error) (str error))} - (when (seq data) - {:data data})))) - -(defn- (payload error))))) - (log/error :db-worker/ui-request-invalid - {:request-id request-id - :action action - :payload payload}))) - -(defmethod handle :db-worker/ui-request [_ wrapped-worker data] - (> (keys all-built-in-keyboard-shortcuts) @@ -746,11 +734,8 @@ :dev/show-page-data :dev/replace-graph-with-db-file :dev/validate-db - :dev/recompute-checksum :dev/export-client-ops-sqlite :dev/gc-graph - :dev/rtc-stop - :dev/rtc-start :ui/customize-appearance]) (with-meta {:before m/enable-when-not-editing-mode!})) @@ -912,11 +897,8 @@ :dev/show-page-data :dev/replace-graph-with-db-file :dev/validate-db - :dev/recompute-checksum :dev/export-client-ops-sqlite :dev/gc-graph - :dev/rtc-stop - :dev/rtc-start :ui/clear-all-notifications] :shortcut.category/plugins diff --git a/src/main/frontend/persist_db.cljs b/src/main/frontend/persist_db.cljs index 80820d3..2107c1b 100644 --- a/src/main/frontend/persist_db.cljs +++ b/src/main/frontend/persist_db.cljs @@ -220,12 +220,6 @@ (ipc/ipc "releaseDbWorkerRuntime" repo) (p/resolved nil))) -(defn- current-db-sync-config - [] - {:enabled? true - :ws-url (config/db-sync-ws-url) - :http-base (config/db-sync-http-base)}) - (defn- (state/ (p/let [_ (state/ ... - :rtc/state {} - :rtc/editing-users-by-block {} - :rtc/loading-graphs? nil - ;; only latest rtc-log stored here, derive a log stream from state when needed. - :rtc/log nil - :rtc/uploading? false - :rtc/downloading-graph-uuid nil - :rtc/graphs [] - :rtc/online-info {} - :rtc/asset-upload-download-progress {} - :rtc/users-info {} :sync/block-conflicts {} :user/info {:UserGroups (storage/get :user-groups)} @@ -360,7 +348,6 @@ :ui/loading? {} :ui/container-id 0 :ui/cached-key->container-id {} - :feature/enable-sync? (storage/get :logseq-sync-enabled) :ui/find-in-page nil :comments/inline-thread nil @@ -879,23 +866,6 @@ should be done through this fn in order to get global config and config defaults [] (:git/current-repo (rfx/snapshot))) -(defn get-rtc-graphs - [] - (:rtc/graphs (rfx/snapshot))) - -;; TODO: rtc version -(comment - (defn get-remote-graph-usage - [graphs] - (->> graphs - (map #(hash-map :uuid (:GraphUUID %) - :name (:GraphName %) - :used-gbs (/ (:GraphStorageUsage %) 1024 1024 1024) - :limit-gbs (/ (:GraphStorageLimit %) 1024 1024 1024) - :used-percent (/ (:GraphStorageUsage %) (:GraphStorageLimit %) 0.01))) - (map #(assoc % :free-gbs (- (:limit-gbs %) (:used-gbs %)))) - (vec)))) - (defn get-repos [] (get-in (rfx/snapshot) [:me :repos])) @@ -1312,27 +1282,22 @@ should be done through this fn in order to get global config and config defaults (defn clear-edit! [& {:keys [clear-editing-block?] :or {clear-editing-block? true}}] - (let [online-users (some-> (get-state :rtc/state) :online-users)] - (swap-state! - (fn [db] - (cond-> (assoc db - :editor/action nil - :editor/args nil - :editor/start-pos nil - :editor/last-saved-cursor {} - :editor/cursor-range nil - :ui/select-query-cache {} - :editor/block-refs #{} - :editor/action-data nil - :view/selected-blocks nil) - clear-editing-block? - (assoc :editor/editing? nil - :editor/block nil - :editor/content {})))) - (when (and clear-editing-block? - (coll? online-users) - (> (count online-users) 1)) - (pub-event! [:rtc/presence-update {:editing-block-uuid nil}]))) + (swap-state! + (fn [db] + (cond-> (assoc db + :editor/action nil + :editor/args nil + :editor/start-pos nil + :editor/last-saved-cursor {} + :editor/cursor-range nil + :ui/select-query-cache {} + :editor/block-refs #{} + :editor/action-data nil + :view/selected-blocks nil) + clear-editing-block? + (assoc :editor/editing? nil + :editor/block nil + :editor/content {})))) nil) (defn set-editor-last-pos! @@ -1876,9 +1841,6 @@ should be done through this fn in order to get global config and config defaults (assoc-in [:editor/content block-id] content)) native-platform? (assoc :mobile/show-action-bar? false)))) - (let [online-users (some-> (get-state :rtc/state) :online-users)] - (when (and (coll? online-users) (> (count online-users) 1)) - (pub-event! [:rtc/presence-update {:editing-block-uuid (str block-id)}]))) (when (= :code (:logseq.property.node/display-type block)) (pub-event! [:editor/focus-code-editor block block-element])) (when-let [input (gdom/getElement edit-input-id)] diff --git a/src/main/logseq/sdk/debug.cljs b/src/main/logseq/sdk/debug.cljs index f13854b..a0097c3 100644 --- a/src/main/logseq/sdk/debug.cljs +++ b/src/main/logseq/sdk/debug.cljs @@ -8,26 +8,3 @@ (get (state/get-state) (keyword path)) (state/get-state)) (bean/->js))) - -(defn- current-repo-or-throw - [] - (if-let [repo (state/get-current-repo)] - repo - (throw (ex-info "No current repo" {:type :debug/no-current-repo})))) - -(defn ^:export syncStopUpload - [] - (state/ (rtc-handler/ (p/do! - (when (= (state/get-current-repo) url) - (rtc-handler/ (p/do! - (when (= (state/get-current-repo) url) - (rtc-handler/> (if (and login? (seq remotes)) - (repo-handler/combine-local-&-remote-graphs repos remotes) - repos) + [repos] + (let [repos (->> repos + (remove #(= (:url %) config/demo-repo)) + (filter (fn [item] (config/db-based-graph? (:url item)))) (util/distinct-by :url)) - repos (cond->> - (remove #(= (:url %) config/demo-repo) repos) - true - (filter (fn [item] - (config/db-based-graph? (:url item))))) - {remote-graphs true local-graphs false} (group-by (comp boolean :remote?) repos) - {own-graphs true shared-graphs false} - (group-by (fn [graph] (= "manager" (:graph<->user-user-type graph))) remote-graphs) - section (fn [id title refreshable? show-empty? graphs] - (let [items (vec (keep #(native-graph-item repos downloading-graph-id %) graphs))] - (when (or show-empty? (seq items)) - {:id id - :title title - :refreshable refreshable? - :graphs items})))] - (vec - (keep identity - [(section "local" (t :graph/local-graphs) false true local-graphs) - (section "remote" (t :graph/remote-graphs) true false own-graphs) - (section "shared" (t :graph/shared-graphs) false false shared-graphs)])))) + items (vec (keep #(native-graph-item repos %) repos))] + (if (seq items) + [{:id "local" + :title (t :graph/local-graphs) + :refreshable false + :graphs items}] + []))) (defn- use-native-graphs-effects! [] - (let [id-token (rfx/use-sub [:auth/id-token]) - repos (rfx/use-sub [:me :repos]) - remotes (rfx/use-sub [:rtc/graphs]) - downloading-graph-id (rfx/use-sub [:rtc/downloading-graph-uuid]) - loading-graphs? (rfx/use-sub [:rtc/loading-graphs?]) + (let [repos (rfx/use-sub [:me :repos]) route-match (rfx/use-sub [:route-match]) _preferred-language (rfx/use-sub [:preferred-language]) [tab] (hooks/use-atom mobile-state/*tab) - login? (boolean id-token) route-name (get-in route-match [:data :name]) visible? (and (= tab "graphs") (not (contains? #{:import :export} route-name))) - sections (native-graph-sections repos remotes login? downloading-graph-id) + sections (native-graph-sections repos) labels {:refresh (t :ui/refresh) :preparing (t :graph/preparing) :downloading (t :graph/downloading)}] - (hooks/use-effect! - (fn [] - (when (and (mobile-util/native-ios?) - login? - (user-handler/rtc-group?)) - (rtc-handler/ [] (nil? route-view) - (conj {:id "home-setting" :systemIcon "ellipsis"}) - (and show-local-upload? (not page?)) - (conj {:id "sync" :systemIcon "icloud.and.arrow.up" - :size "medium"}) - (and (not show-local-upload?) show-sync? (not page?)) - (conj {:id "sync" :systemIcon "circle.fill" :color sync-color - :size "small"})) + (conj {:id "home-setting" :systemIcon "ellipsis"})) (= tab "graphs") [{:id "graph-setting" :systemIcon "ellipsis"} @@ -325,43 +294,8 @@ native-ios-graphs? (and (mobile-util/native-ios?) (= tab "graphs")) page-route? (and (= route-name :page) (not native-ios-graphs?)) [*configure-top-bar-f _] (hooks/use-state (atom nil)) - [rtc-graph-uuid set-rtc-graph-uuid!] (hooks/use-state nil) - db-worker-ready? (hooks/use-atom-value state/db-worker-ready?) - detail-info (rtc-indicator/use-detail-info) _ (rfx/use-sub [:auth/current-login-user]) - online? (rfx/use-sub [:network/online?]) - rtc-state (:rtc-state detail-info) - graph-uuid (or (:graph-uuid detail-info) - rtc-graph-uuid) - local-uploadable-graph (current-local-uploadable-graph graph-uuid) - show-sync? (and current-repo graph-uuid (user-handler/logged-in?)) - show-local-upload? (some? local-uploadable-graph) - unpushed-block-update-count (:pending-local-ops detail-info) - pending-asset-ops (:pending-asset-ops detail-info) - fallback-title (build-fallback-title current-repo tab flashcards-header) - sync-color (if (and online? - (= :open rtc-state) - (zero? unpushed-block-update-count) - (zero? pending-asset-ops)) - ;; green - "#16A34A" - ;; yellow - "#CA8A04")] - (hooks/use-effect! - (fn [] - (if-let [rtc-graph-uuid-request ( rtc-graph-uuid-request - (p/then (fn [uuid] - (when-not @cancelled? - (set-rtc-graph-uuid! uuid)))) - (p/catch (fn [_] nil))) - #(reset! cancelled? true)) - (do - (set-rtc-graph-uuid! nil) - nil))) - [current-repo db-worker-ready?]) - + fallback-title (build-fallback-title current-repo tab flashcards-header)] (hooks/use-effect! (fn [] (when (and (mobile-util/native-platform?) @@ -374,14 +308,11 @@ :title title :route-name route-name :route-view route-view - :sync-color sync-color - :show-sync? show-sync? - :show-local-upload? show-local-upload? :favorited? favorited?}))] (reset! *configure-top-bar-f f) (f nil))) nil) - [current-repo tab route-name route-view fallback-title sync-color show-sync? show-local-upload?]) + [current-repo tab route-name route-view fallback-title]) (hooks/use-effect! (fn [] @@ -403,16 +334,13 @@ :title title :route-name route-name :route-view route-view - :sync-color sync-color - :show-sync? show-sync? - :show-local-upload? show-local-upload? :favorited? favorited?}))] (reset! *configure-top-bar-f f) (f favorited?)))) (p/catch (fn [_] nil))) #(reset! cancelled? true)) nil)) - [current-repo tab route-name route-view route-id sync-color show-sync? show-local-upload? page-route?]) + [current-repo tab route-name route-view route-id page-route?]) [:<>])) diff --git a/src/main/mobile/components/popup.cljs b/src/main/mobile/components/popup.cljs index 92a5c84..1e2a967 100644 --- a/src/main/mobile/components/popup.cljs +++ b/src/main/mobile/components/popup.cljs @@ -149,23 +149,16 @@ (defn popup-hide! [& args] - (cond - (= :download-rtc-graph (first args)) - (do - (dismiss-native-sheet!) - (mobile-state/set-tab! "home")) - - :else - (if (and @*last-popup? (not (= (first args) :editor.commands/commands))) - (if (some? @*pending-native-sheet-data) - (do - (reset! *pending-native-sheet-data nil) - (reset! *last-popup? false) - (reset! *last-popup-data nil) - (mobile-state/set-popup-presenting! false) - (mobile-state/set-popup! nil)) - (dismiss-native-sheet!)) - (apply shui-popup/hide! args)))) + (if (and @*last-popup? (not (= (first args) :editor.commands/commands))) + (if (some? @*pending-native-sheet-data) + (do + (reset! *pending-native-sheet-data nil) + (reset! *last-popup? false) + (reset! *last-popup-data nil) + (mobile-state/set-popup-presenting! false) + (mobile-state/set-popup! nil)) + (dismiss-native-sheet!)) + (apply shui-popup/hide! args))) (set! shui/popup-show! popup-show!) (set! shui/popup-hide! popup-hide!) diff --git a/src/main/mobile/components/settings.cljs b/src/main/mobile/components/settings.cljs index ea81a13..4a55676 100644 --- a/src/main/mobile/components/settings.cljs +++ b/src/main/mobile/components/settings.cljs @@ -4,7 +4,6 @@ [frontend.components.dnd :as dnd] [frontend.components.email :as email-component] [frontend.components.user.login :as login] - [frontend.config :as config] [frontend.context.i18n :refer [t]] [frontend.dicts :as dicts] [frontend.handler.ui :as ui-handler] @@ -278,14 +277,6 @@ (shui/popup-show! nil (fn [] (log)) {}))} [:span.text-base (t :mobile.settings/check-log)]] - [:div.mobile-setting-item - {:on-click #(state/pub-event! [:go/sync-server-settings])} - [:span.text-base (t :settings.sync-server/url)] - [:span.text-sm.opacity-70 - (if-let [custom (config/get-custom-sync-server-url)] - custom - "Logseq Sync")]] - (when login? [:div.mobile-setting-item {:on-click (fn [] diff --git a/src/main/mobile/core.cljs b/src/main/mobile/core.cljs index 6a651e0..e3679fa 100644 --- a/src/main/mobile/core.cljs +++ b/src/main/mobile/core.cljs @@ -4,7 +4,6 @@ [clojure.string :as string] [frontend.background-tasks] [frontend.handler :as fhandler] - [frontend.handler.db-based.rtc-background-tasks] [frontend.handler.notification :as notification] [frontend.handler.route :as route-handler] [frontend.mobile.util :as mobile-util] diff --git a/src/test/frontend/components/repo_test.cljs b/src/test/frontend/components/repo_test.cljs index 962c24a..7f8e976 100644 --- a/src/test/frontend/components/repo_test.cljs +++ b/src/test/frontend/components/repo_test.cljs @@ -1,31 +1,15 @@ (ns frontend.components.repo-test (:require [cljs.test :refer [deftest is async]] [frontend.components.repo :as repo] - [frontend.components.rtc.indicator :as rtc-indicator] - [frontend.handler.db-based.sync :as rtc-handler] [frontend.handler.graph :as graph-handler] - [frontend.handler.repo :as repo-handler] - [frontend.handler.user :as user-handler] [frontend.state :as state] - [frontend.mobile.util :as mobile-util] [frontend.util :as util] - [logseq.shui.ui :as shui] [promesa.core :as p])) -(defn- ensure-rsa-key-fn - [] - #'repo/ensure-e2ee-rsa-key-for-cloud!) - (defn- finish-async-test! [done] (js/setTimeout done 0)) -(deftest local-uploadable-graph-allows-native-mobile-local-graph-without-root-test - (with-redefs [mobile-util/native-platform? (constantly true) - user-handler/logged-in? (constantly true) - user-handler/rtc-group? (constantly true)] - (is (true? (repo/local-uploadable-graph? {:url "logseq_db_mobile"}))))) - (deftest open-in-another-tab-action-is-web-only-for-existing-graphs-test (let [actionable-f (some-> (resolve 'frontend.components.repo/open-in-another-tab-action?) deref)] (is (fn? actionable-f) "All graphs should expose a web open-in-another-tab action predicate") @@ -80,381 +64,6 @@ (is false (str error)) (finish-async-test! done)))))))) -(deftest upload-local-graph-with-confirm-asks-before-upload-test - (async done - (let [upload-fn (some-> (resolve 'frontend.components.repo/upload-local-graph-with-confirm!) deref) - dialogs (atom []) - upload-calls (atom []) - finished-calls (atom 0)] - (if-not upload-fn - (do - (is false "missing upload-local-graph-with-confirm!") - (finish-async-test! done)) - (-> (p/with-redefs [shui/dialog-confirm! (fn [content opts] - (swap! dialogs conj {:content content - :opts opts}) - (p/resolved nil)) - rtc-handler/ (resolve 'frontend.components.repo/upload-local-graph-with-confirm!) deref) - current-repo (atom "logseq_db_current") - calls (atom [])] - (if-not upload-fn - (do - (is false "missing upload-local-graph-with-confirm!") - (finish-async-test! done)) - (-> (p/with-redefs [shui/dialog-confirm! (fn [_content _opts] - (p/resolved nil)) - state/get-current-repo (fn [] - @current-repo) - state/pub-event! (fn [event] - (swap! calls conj event) - (reset! current-repo (second event)) - (p/resolved nil)) - repo/ (resolve 'frontend.components.repo/upload-local-graph-with-confirm!) deref) - calls (atom [])] - (if-not upload-fn - (do - (is false "missing upload-local-graph-with-confirm!") - (finish-async-test! done)) - (-> (p/with-redefs [shui/dialog-confirm! (fn [_content _opts] - (p/resolved nil)) - state/get-current-repo (fn [] - "logseq_db_demo") - repo/ (resolve 'frontend.components.repo/upload-local-graph-with-confirm!) deref) - calls (atom [])] - (if-not upload-fn - (do - (is false "missing upload-local-graph-with-confirm!") - (finish-async-test! done)) - (-> (p/with-redefs [shui/dialog-confirm! (fn [_content _opts] - (p/resolved nil)) - state/get-current-repo (fn [] - "logseq_db_demo") - rtc-handler/ (resolve 'frontend.components.repo/upload-local-graph-with-confirm!) deref) - calls (atom [])] - (if-not upload-fn - (do - (is false "missing upload-local-graph-with-confirm!") - (finish-async-test! done)) - (-> (p/with-redefs [shui/dialog-confirm! (fn [_content _opts] - (p/resolved nil)) - state/get-current-repo (fn [] - "logseq_db_demo") - rtc-handler/ (p/with-redefs [state/pub-event! (fn [_event] - (p/resolved nil)) - repo/ (p/with-redefs [state/pub-event! (fn [_event] - (p/resolved nil)) - repo/ (p/with-redefs [repo/ (p/with-redefs [repo/ (resolve 'frontend.components.repo/close-sidebar-after-repo-popup-action!) @@ -498,35 +107,12 @@ (is (true? (target? (target true)))) (is (false? (target? (target false))))))) -(deftest shift-click-opens-downloaded-remote-graph-in-new-tab-with-graph-id-test - (let [events (atom []) - links (#'repo/repos-dropdown-links - [{:url "logseq_db_demo" - :root "/graphs/demo" - :remote? true - :rtc-graph? true - :GraphName "demo" - :GraphUUID "graph-uuid" - :GraphSchemaVersion "65" - :graph-ready-for-use? true}] - nil - nil) - on-click (get-in (first links) [:options :on-click])] - (with-redefs [state/pub-event! (fn [event] - (swap! events conj event))] - (on-click #js {:shiftKey true}) - (is (= [[:graph/open-new-window {:repo "logseq_db_demo" - :graph-id "graph-uuid"}]] - @events))))) - (deftest shift-click-opens-local-graph-in-new-tab-with-registry-graph-id-test (async done (let [events (atom []) links (#'repo/repos-dropdown-links [{:url "logseq_db_demo" - :root "/graphs/demo" - :graph-ready-for-use? true}] - nil + :root "/graphs/demo"}] nil) on-click (get-in (first links) [:options :on-click])] (-> (p/with-redefs [graph-handler/detail-info {}))))) - -(deftest indicator-button-class-is-space-separated - (let [class-name (indicator/indicator-button-class - {:online? true - :rtc-state :open - :pending-local-ops 0 - :pending-asset-ops 0 - :pending-server-ops 0})] - (is (string? class-name)) - (is (not (re-find #"," class-name))) - (is (= #{"cloud" "on" "idle"} - (set (.split class-name " ")))))) diff --git a/src/test/frontend/config_test.cljs b/src/test/frontend/config_test.cljs index a6e3eaa..d69fbe7 100644 --- a/src/test/frontend/config_test.cljs +++ b/src/test/frontend/config_test.cljs @@ -14,60 +14,6 @@ (is (= "/tmp/home/logseq/graphs/foo~2Fbar/backup" (config/get-electron-backup-dir (str common-config/db-version-prefix "foo/bar")))))) -(deftest custom-url->ws-url-test - (testing "https URL becomes wss" - (is (= "wss://my-server.example.com/sync/%s" - (config/custom-url->ws-url "https://my-server.example.com")))) - - (testing "http URL becomes ws" - (is (= "ws://localhost:8787/sync/%s" - (config/custom-url->ws-url "http://localhost:8787")))) - - (testing "trailing slashes are stripped" - (is (= "wss://my-server.example.com/sync/%s" - (config/custom-url->ws-url "https://my-server.example.com/"))) - (is (= "wss://my-server.example.com/sync/%s" - (config/custom-url->ws-url "https://my-server.example.com///")))) - - (testing "preserves port in URL" - (is (= "wss://example.com:3000/sync/%s" - (config/custom-url->ws-url "https://example.com:3000")))) - - (testing "preserves subpath in host" - ;; Users should only provide a base URL, but verify trailing path doesn't break things - (is (= "wss://example.com/api/sync/%s" - (config/custom-url->ws-url "https://example.com/api"))))) - -(deftest custom-url->http-base-test - (testing "returns URL as-is when no trailing slash" - (is (= "https://my-server.example.com" - (config/custom-url->http-base "https://my-server.example.com")))) - - (testing "strips trailing slashes" - (is (= "https://my-server.example.com" - (config/custom-url->http-base "https://my-server.example.com/"))) - (is (= "https://my-server.example.com" - (config/custom-url->http-base "https://my-server.example.com///")))) - - (testing "preserves http scheme" - (is (= "http://localhost:8787" - (config/custom-url->http-base "http://localhost:8787")))) - - (testing "preserves port" - (is (= "https://example.com:3000" - (config/custom-url->http-base "https://example.com:3000/"))))) - -(deftest default-urls-are-returned-when-no-custom-url - (testing "db-sync-ws-url returns default when no custom URL is set" - ;; In test environment, node-test? is true so get-custom-sync-server-url - ;; always returns nil, meaning we always get the default - (is (string? (config/db-sync-ws-url))) - (is (= config/default-db-sync-ws-url (config/db-sync-ws-url)))) - - (testing "db-sync-http-base returns default when no custom URL is set" - (is (string? (config/db-sync-http-base))) - (is (= config/default-db-sync-http-base (config/db-sync-http-base))))) - (deftest valid-sync-server-url?-test (testing "accepts http and https URLs" (is (config/valid-sync-server-url? "https://my-server.example.com")) diff --git a/src/test/frontend/db/restore_test.cljs b/src/test/frontend/db/restore_test.cljs index 1025600..9273da8 100644 --- a/src/test/frontend/db/restore_test.cljs +++ b/src/test/frontend/db/restore_test.cljs @@ -11,8 +11,6 @@ (deftest restore-graph-does-not-create-renderer-datascript-conn-test (async done (let [repo "logseq_db_restore_without_ui_conn" - block-id (str (random-uuid)) - conflicts-by-block {block-id [{:value "remote"}]} previous-state (state/get-state) previous-conns @db-conn/conns calls (atom []) @@ -36,13 +34,6 @@ (swap! calls conj [:current-repo repo']) (state/swap-state! assoc :git/current-repo repo') nil) - state/ (p/let [result (#'dev-common-handler/restart-event "visible"))) - (is (= :network-online&rtc-not-running - (#'rtc-flows/network-online->restart-event true))) - (is (= :mobile-app-active&rtc-not-running - (#'rtc-flows/mobile-app-active->restart-event true)))) - -(deftest rtc-background-watch-consumes-existing-event-test - (let [source (atom [:graph-switch "repo"]) - events (atom [])] - (with-redefs [config/publishing? false] - (#'rtc-background-tasks/add-watch-when-not-publishing! - source - ::consume-existing-event - #(swap! events conj %)) - (is (= [[:graph-switch "repo"]] @events)) - (remove-watch source ::consume-existing-event)))) diff --git a/src/test/frontend/handler/db_based/sync_test.cljs b/src/test/frontend/handler/db_based/sync_test.cljs deleted file mode 100644 index 401df9e..0000000 --- a/src/test/frontend/handler/db_based/sync_test.cljs +++ /dev/null @@ -1,764 +0,0 @@ -(ns frontend.handler.db-based.sync-test - (:require [cljs.test :refer [deftest is async]] - [clojure.string :as string] - [frontend.config :as config] - [frontend.handler.db-based.sync :as db-sync] - [frontend.persist-db :as persist-db] - [frontend.handler.repo :as repo-handler] - [frontend.handler.user :as user-handler] - [frontend.state :as state] - [frontend.util :as util] - [promesa.core :as p])) - -(defn- finish-async-test! - [done] - (js/setTimeout done 0)) - -(deftest coerce-http-request-does-not-add-client-revision-to-member-request-test - (is (= {:email "user@example.com"} - (#'db-sync/coerce-http-request :graph-members/create - {:email "user@example.com"})))) - -(deftest remove-member-request-test - (async done - (let [called (atom nil)] - (-> (p/with-redefs [db-sync/http-base (fn [] "http://base") - db-sync/fetch-json (fn [url opts _] - (reset! called {:url url :opts opts}) - (p/resolved {:ok true})) - user-handler/ (p/with-redefs [db-sync/http-base (fn [] "http://base") - db-sync/fetch-json (fn [url opts _] - (reset! called {:url url :opts opts}) - (p/resolved {:ok true})) - user-handler/ (p/with-redefs [user-handler/user-uuid (fn [] nil)] - (db-sync/ (p/with-redefs [db-sync/http-base (fn [] "http://base") - db-sync/ (p/with-redefs [db-sync/http-base (fn [] "http://base") - state/ (p/with-redefs [db-sync/http-base (fn [] "http://base") - user-handler/ promise - (p/then (fn [result] [:resolved result])) - (p/catch (fn [reason] [:rejected reason]))))] - (state/set-state! :rtc/uploading? false) - (reset! state/*db-worker - (fn [op & _args] - (if (contains? #{:thread-api/db-sync-create-remote-graph - :thread-api/db-sync-upload-graph} - op) - (p/resolved error) - (p/resolved :ok)))) - (-> (p/with-redefs [user-handler/ (p/with-redefs [db-sync/http-base (fn [] "http://base") - user-handler/ (p/with-redefs [user-handler/ (p/with-redefs [db-sync/http-base (fn [] "http://base") - user-handler/ (p/with-redefs [db-sync/http-base (fn [] "http://base") - user-handler/ (p/with-redefs [state/ (p/with-redefs [db-sync/ (p/with-redefs [state/get-rtc-graphs (fn [] [{:url "demo-graph"}]) - state/ (p/with-redefs [state/get-rtc-graphs (fn [] [{:url "demo-graph" - :graph-ready-for-use? false}]) - state/ (p/with-redefs [user-handler/ {:git/current-repo "demo-graph" - :config {:a 1} - :auth/id-token "id-token" - :auth/access-token "access-token" - :auth/refresh-token "refresh-token" - :auth/oauth-token-url nil - :user/info {:sub "user-1"}} - (seq config/OAUTH-DOMAIN) - (assoc :auth/oauth-domain config/OAUTH-DOMAIN) - - (seq config/COGNITO-CLIENT-ID) - (assoc :auth/oauth-client-id config/COGNITO-CLIENT-ID)) - (second (first @calls)))) - (is (= [:thread-api/db-sync-start "demo-graph"] - (second @calls))) - (finish-async-test! done))) - (p/catch (fn [error] - (is false (str error)) - (finish-async-test! done))) - (p/finally (fn [] - (reset! state/*db-worker worker-prev) - (state/replace-state! state-prev))))))) - -(deftest rtc-download-graph-emits-feedback-before-snapshot-fetch-test - (let [trace (atom []) - log-events (atom [])] - (with-redefs [db-sync/http-base (fn [] "http://base") - state/set-state! (fn [k v] - (swap! trace conj [:set k v])) - state/pub-event! (fn [[event payload :as e]] - (when (and (= :rtc/log event) - (= "graph-1" (:graph-uuid payload))) - (swap! trace conj :log) - (swap! log-events conj e))) - ;; Keep auth pending so we only validate immediate click-time feedback. - user-handler/ (p/with-redefs [db-sync/http-base (fn [] "http://base") - user-handler/ (p/with-redefs [db-sync/http-base (fn [] "http://base") - user-handler/ (p/with-redefs [db-sync/http-base (fn [] "http://base") - user-handler/ (p/with-redefs [db-sync/http-base (fn [] "http://base") - user-handler/ (p/with-redefs [db-sync/http-base (fn [] "http://base") - user-handler/ (p/with-redefs [db-sync/http-base (fn [] "http://base") - user-handler/ (p/with-redefs [db-sync/http-base (fn [] "http://base") - user-handler/ (p/with-redefs [db-sync/http-base (fn [] "http://base") - user-handler/ (p/with-redefs [db-sync/http-base (fn [] "http://base") - user-handler/ (worker-handler/handle :db-worker/ui-request - wrapped-worker - {:request-id "req-1" - :action :request-e2ee-password - :payload {:reason :decrypt-user-rsa-private-key}}) - (p/then (fn [_] - (is (= [[:thread-api/resolve-ui-request ["req-1" {:password "pw"}]]] - @calls)) - (done))) - (p/catch (fn [error] - (is nil (str "unexpected error: " error)) - (done)))))))) - -(deftest db-worker-ui-request-reject-passes-request-id-and-error-test - (async done - (let [calls (atom []) - wrapped-worker (fn [qkw & args] - (swap! calls conj [qkw args]) - (p/resolved {:ok true}))] - (with-redefs [worker-handler/ (worker-handler/handle :db-worker/ui-request - wrapped-worker - {:request-id "req-2" - :action :request-e2ee-password - :payload {:reason :decrypt-user-rsa-private-key}}) - (p/then (fn [_] - (is (= [[:thread-api/reject-ui-request - ["req-2" - {:code :boom - :message "boom" - :data {:code :boom - :x 1}}]]] - @calls)) - (done))) - (p/catch (fn [error] - (is nil (str "unexpected error: " error)) - (done)))))))) diff --git a/src/test/frontend/persist_db_test.cljs b/src/test/frontend/persist_db_test.cljs index 843e73f..70acb97 100644 --- a/src/test/frontend/persist_db_test.cljs +++ b/src/test/frontend/persist_db_test.cljs @@ -2,7 +2,6 @@ (:require [cljs.test :refer [async deftest is use-fixtures]] [electron.ipc :as ipc] [frontend.common.thread-api :as thread-api] - [frontend.config :as config] [frontend.handler.notification :as notification] [frontend.persist-db.browser :as browser] [frontend.persist-db :as persist-db] @@ -680,47 +679,6 @@ (set! storage/remove original-storage-remove) (done))))))) -(deftest electron-ensure-remote-pushes-db-sync-config-on-start-test - (async done - (let [worker-calls (atom []) - ensure-remote! #'persist-db/FakeRemote repo - (fn [qkw & args] - (swap! worker-calls conj [qkw args]) - (p/resolved nil))))) - (set! remote/stop! (fn [_] (p/resolved true))) - (-> (p/let [_ (ensure-remote! "logseq_db_graph_a")] - (let [set-config-call (first (filter #(= :thread-api/set-db-sync-config (first %)) - @worker-calls))] - (is (= [:thread-api/set-db-sync-config - [{:enabled? true - :ws-url "wss://sync.example.test/sync/%s" - :http-base "https://sync.example.test"}]] - set-config-call)))) - (p/catch (fn [e] - (is false (str "unexpected error: " e)))) - (p/finally (fn [] - (set! ipc/ipc original-ipc) - (set! remote/start! original-start!) - (set! remote/stop! original-stop!) - (set! config/db-sync-ws-url original-ws) - (set! config/db-sync-http-base original-http) - (done))))))) - (deftest electron-ensure-remote-pushes-markdown-mirror-setting-on-start-test (async done (let [worker-calls (atom []) diff --git a/src/test/mobile/header_test.cljs b/src/test/mobile/header_test.cljs deleted file mode 100644 index 7f1814a..0000000 --- a/src/test/mobile/header_test.cljs +++ /dev/null @@ -1,21 +0,0 @@ -(ns mobile.header-test - (:require [cljs.test :refer [deftest is testing]] - [frontend.state :as state] - [mobile.components.header :as header])) - -(deftest rtc-graph-uuid-is-not-loaded-before-db-worker-is-ready - (testing "mobile startup does not invoke the DB worker before initialization" - (let [calls (atom [])] - (with-redefs [state/