From f7997bee24f0adfb7cc9de7b8fa92c78671fb12b Mon Sep 17 00:00:00 2001 From: charlie Date: Fri, 18 Apr 2025 08:48:28 +0800 Subject: [PATCH] enhance(capacitor): dev scripts --- deps/shui/src/logseq/shui/util.cljs | 2 +- gulpfile.js | 5 +- shadow-cljs.edn | 8 +- src/main/capacitor/app.cljs | 2 + src/main/capacitor/core.cljs | 6 +- src/main/capacitor/events.cljs | 42 ++++++ src/main/capacitor/handler.cljs | 164 ++++++++++++++++++++++ src/main/frontend/db/transact.cljs | 1 + src/main/frontend/persist_db/browser.cljs | 2 +- 9 files changed, 224 insertions(+), 8 deletions(-) create mode 100644 src/main/capacitor/events.cljs create mode 100644 src/main/capacitor/handler.cljs diff --git a/deps/shui/src/logseq/shui/util.cljs b/deps/shui/src/logseq/shui/util.cljs index f9152e3dac..71bdf736ca 100644 --- a/deps/shui/src/logseq/shui/util.cljs +++ b/deps/shui/src/logseq/shui/util.cljs @@ -137,4 +137,4 @@ [name] (if NODETEST #js {} - (aget js/window.LSUI name))) + (some-> js/window.LSUI (aget name)))) diff --git a/gulpfile.js b/gulpfile.js index f98a7fe7c1..24d5bb5bda 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -117,7 +117,10 @@ const common = { 'node_modules/react-dom/umd/react-dom.production.min.js', 'node_modules/react-dom/umd/react-dom.development.js', 'node_modules/prop-types/prop-types.min.js' - ]).pipe(gulp.dest(path.join(outputPath, 'capacitor', 'js'))) + ]).pipe(gulp.dest(path.join(outputPath, 'capacitor', 'js'))), + () => gulp.src([ + 'node_modules/@logseq/sqlite-wasm/sqlite-wasm/jswasm/sqlite3.wasm', + ]).pipe(gulp.dest(path.join(outputPath, 'capacitor'))) )(...params) }, diff --git a/shadow-cljs.edn b/shadow-cljs.edn index 6e583795cd..cea3630b8b 100644 --- a/shadow-cljs.edn +++ b/shadow-cljs.edn @@ -2,7 +2,7 @@ {:deps true :nrepl {:port 8701} - ;:ssl {:password "logseq"} + :ssl {:password "logseq"} ;; "." for /static :dev-http {3001 ["static" "."] 3002 "static/capacitor" @@ -79,7 +79,11 @@ {:entries []} :main {:init-fn capacitor.core/init - :depends-on #{:shared}}} + :depends-on #{:shared}} + :db-worker + {:init-fn frontend.worker.db-worker/init + :depends-on #{:shared} + :web-worker true}} :output-dir "./static/capacitor" :asset-path "/static/capacitor" diff --git a/src/main/capacitor/app.cljs b/src/main/capacitor/app.cljs index 79642d2cf0..8519bad355 100644 --- a/src/main/capacitor/app.cljs +++ b/src/main/capacitor/app.cljs @@ -5,6 +5,7 @@ [promesa.core :as p] [capacitor.ionic :as ionic] [capacitor.state :as state] + [frontend.state :as fstate] [capacitor.pages.settings :as settings])) (rum/defc app-sidebar [] @@ -47,6 +48,7 @@ (ionic/ion-content [:div.pt-10.px-8 [:h1.text-3xl.font-mono.font-bold.py-2 "Suggested"] + [:h2 (fstate/get-current-repo)] [:p.flex.py-4.justify-center.bg-gray-03.flex-col.gap-6 (ionic/ion-button {:on-click #(js/alert "hello click me!") :size "large"} diff --git a/src/main/capacitor/core.cljs b/src/main/capacitor/core.cljs index f22e5808b8..66b654b7a4 100644 --- a/src/main/capacitor/core.cljs +++ b/src/main/capacitor/core.cljs @@ -1,6 +1,7 @@ (ns capacitor.core (:require ["react-dom/client" :as rdc] - [capacitor.app :as app])) + [capacitor.app :as app] + [capacitor.handler :as handler])) (defonce ^js root (rdc/createRoot (.getElementById js/document "root"))) @@ -13,8 +14,7 @@ ;; this is called in the index.html and must be exported ;; so it is available even in :advanced release builds (prn "[capacitor-new] init!") - (start!) - ) + (handler/start! start!)) (defn ^:export stop! [] ;; stop is called before any code is reloaded diff --git a/src/main/capacitor/events.cljs b/src/main/capacitor/events.cljs new file mode 100644 index 0000000000..d0516e0aaa --- /dev/null +++ b/src/main/capacitor/events.cljs @@ -0,0 +1,42 @@ +(ns capacitor.events + (:require [cljs.core.async :as async] + [frontend.modules.outliner.pipeline :as pipeline] + [frontend.state :as state] + [logseq.db :as ldb] + [frontend.db :as db] + [datascript.core :as d] + [promesa.core :as p])) + +(defmulti handle first) + +(defmethod handle :db/sync-changes [[_ data]] + (let [retract-datoms (filter (fn [d] (and (= :block/uuid (:a d)) (false? (:added d)))) (:tx-data data)) + retracted-tx-data (map (fn [d] [:db/retractEntity (:e d)]) retract-datoms) + tx-data (concat (:tx-data data) retracted-tx-data)] + (pipeline/invoke-hooks (assoc data :tx-data tx-data)) + + nil)) + +(defmethod handle :default [[k]] + (prn "[skip handle] " k)) + +(defn run! + [] + (let [chan (state/get-events-chan)] + (async/go-loop [] + (let [[payload d] (async/ + (try + (p/resolved (handle payload)) + (catch :default error + (p/rejected error))) + (p/then (fn [result] + (p/resolve! d result))) + (p/catch (fn [error] + (let [type :handle-system-events/failed] + (state/pub-event! [:capture-error {:error error + :payload {:type type + :payload payload}}]) + (p/reject! d error)))))) + (recur)) + chan)) diff --git a/src/main/capacitor/handler.cljs b/src/main/capacitor/handler.cljs new file mode 100644 index 0000000000..5b623de0e6 --- /dev/null +++ b/src/main/capacitor/handler.cljs @@ -0,0 +1,164 @@ +(ns capacitor.handler + (:require [cljs-bean.core :as bean] + ;[electron.ipc :as ipc] + [electron.listener :as el] + [frontend.config :as config] + [frontend.context.i18n :as i18n] + [frontend.db.react :as react] + [frontend.db.restore :as db-restore] + [frontend.error :as error] + [capacitor.events :as events] + ;[frontend.handler.events :as events] + ;[frontend.handler.file-based.events] + ;[frontend.handler.file-based.file :as file-handler] + [frontend.handler.global-config :as global-config-handler] + [frontend.handler.notification :as notification] + [frontend.handler.page :as page-handler] + [frontend.handler.plugin-config :as plugin-config-handler] + [frontend.handler.repo :as repo-handler] + [frontend.handler.repo-config :as repo-config-handler] + [frontend.handler.test :as test] + ;[frontend.handler.ui :as ui-handler] + ;[frontend.handler.user :as user-handler] + [frontend.idb :as idb] + ;[frontend.mobile.core :as mobile] + ;[frontend.mobile.util :as mobile-util] + ;[frontend.modules.shortcut.core :as shortcut] + [frontend.persist-db :as persist-db] + [frontend.persist-db.browser :as db-browser] + [frontend.state :as state] + [frontend.util :as util] + [frontend.util.persist-var :as persist-var] + [goog.object :as gobj] + [lambdaisland.glogi :as log] + [promesa.core :as p])) + +(defn- set-global-error-notification! + [] + (when-not config/dev? + (set! js/window.onerror + (fn [message, _source, _lineno, _colno, error] + (when-not (error/ignored? message) + (js/console.error message) + (log/error :exception error)))))) + +;(defn- watch-for-date! +; [] +; (let [f (fn [] +; (let [repo (state/get-current-repo)] +; (when (or +; (config/db-based-graph? repo) +; (and (not (state/nfs-refreshing?)) +; (not (contains? (:file/unlinked-dirs @state/state) +; (config/get-repo-dir repo))))) +; ;; Don't create the journal file until user writes something +; (page-handler/create-today-journal!))))] +; (f) +; (js/setInterval f 5000))) + +(defn restore-and-setup! + [repo] + (when repo + (-> (p/let [_ (db-restore/restore-graph! repo)] + (repo-config-handler/start {:repo repo})) + (p/then + (fn [] + ;; try to load custom css only for current repo + ;(ui-handler/add-style-if-exists!) + + (-> + (p/do! + (when (config/global-config-enabled?) + (global-config-handler/start {:repo repo})) + (when (config/plugin-config-enabled?) + (plugin-config-handler/start))) + (p/finally + (fn [] + ;; install after config is restored + ;(shortcut/refresh!) + + (state/set-db-restoring! false)))))) + (p/then + (fn [] + (js/console.log "db restored, setting up repo hooks") + + ;(state/pub-event! [:modal/nfs-ask-permission]) + + (page-handler/init-commands!) + + ;(watch-for-date!) + ;(when (and (not (config/db-based-graph? repo)) (util/electron?)) + ; (file-handler/watch-for-current-graph-dir!)) + )) + (p/catch (fn [error] + (log/error :exception error)))))) + +(defn- handle-connection-change + [e] + (let [online? (= (gobj/get e "type") "online")] + (state/set-online! online?))) + +(defn set-network-watcher! + [] + (js/window.addEventListener "online" handle-connection-change) + (js/window.addEventListener "offline" handle-connection-change)) + +;(defn- get-system-info +; [] +; (when (util/electron?) +; (p/let [info (ipc/ipc :system/info)] +; (state/set-state! :system/info (bean/->clj info))))) + +(defn start! + [render] + + (idb/start) + ;(get-system-info) + (set-global-error-notification!) + + ;(user-handler/restore-tokens-from-localstorage) + (state/set-db-restoring! true) + + (render) + + (i18n/start) + + (state/set-online! js/navigator.onLine) + (set-network-watcher!) + + (-> (util/indexeddb-check?) + (p/catch (fn [_e] + (notification/show! "Sorry, it seems that your browser doesn't support IndexedDB, we recommend to use latest Chrome(Chromium) or Firefox(Non-private mode)." :error false) + (state/set-indexedb-support! false)))) + + (react/run-custom-queries-when-idle!) + + (events/run!) + + (p/do! + ;(when (mobile-util/native-platform?) + ; (mobile/mobile-preinit)) + (-> (p/let [_ (db-browser/start-db-worker!) + repos (repo-handler/get-repos) + _ (state/set-repos! repos) + ;_ (mobile-util/hide-splash) ;; hide splash as early as ui is stable + repo (or (state/get-current-repo) (:url (first repos))) + _ (if (empty? repos) + (repo-handler/new-db! config/demo-repo) + (restore-and-setup! repo))] + (when (util/electron?) + (persist-db/run-export-periodically!)) + ;(when (mobile-util/native-platform?) + ; (state/restore-mobile-theme!)) + ) + (p/catch (fn [e] + (js/console.error "Error while restoring repos: " e))) + (p/finally (fn [] + (state/set-db-restoring! false)))) + + (util/