From 283d084de254f40dacea103f2e0b28c08ba76aaa Mon Sep 17 00:00:00 2001 From: Gabriel Horner Date: Thu, 18 Jan 2024 10:18:23 -0500 Subject: [PATCH 01/23] Simplify fn translations in light of #10868 - Reverted overly complex fn translations from #10810 - Updated guidelines so it's clear that fn translations need to remain simple. They shouldn't be so complex that they fail for edge cases - Updated catch so we are aware when translations fail --- docs/contributing-to-translations.md | 5 ++++- docs/dev-practices.md | 3 +-- src/main/frontend/context/i18n.cljs | 12 +++++++++--- src/resources/dicts/fr.edn | 15 ++------------- 4 files changed, 16 insertions(+), 19 deletions(-) diff --git a/docs/contributing-to-translations.md b/docs/contributing-to-translations.md index fabb52f76e..8d8c1a0969 100644 --- a/docs/contributing-to-translations.md +++ b/docs/contributing-to-translations.md @@ -84,7 +84,10 @@ Almost all translations are small. The only exceptions to this are the keys `:tu * Some translations may include punctuation like `:` or `!`. When translating them, please use the punctuation that makes the most sense for your language as you don't have to follow the English ones. * Some translations may include arguments/interpolations e.g. `{1}`. If you see them in a translation, be sure to include them. These arguments are substituted in the string and are usually used for something the app needs to calculate e.g. a number. See [these docs](https://github.com/tonsky/tongue#interpolation) for more examples. -* Rarely, a translation may need to translate formatted text by returning [hiccup-style HTML](https://github.com/weavejester/hiccup#syntax). In this case, a Clojure function is the recommended approach. For example, a function translation would look like `(fn [] [:div "FOO"])`. See `:on-boarding/main-title` for an example. +* Rarely, a translation is a function that calls code and look like `(fn ... )` + * The logic for these fns must be simple and can only use the following fns: `str`, `when`, `if` and `=`. + * These fn translations are usually used to handle pluralization or handle formatted text by returning [hiccup-style HTML](https://github.com/weavejester/hiccup#syntax). For example, a hiccup style translation would look like `(fn [] [:div "FOO"])`. See `:on-boarding/main-title` for more examples. + ## Fix Mistakes There is a lint command to catch common translation mistakes - `bb diff --git a/docs/dev-practices.md b/docs/dev-practices.md index dbf56b71e6..ea6a1f1ae4 100644 --- a/docs/dev-practices.md +++ b/docs/dev-practices.md @@ -90,8 +90,7 @@ translations here are some things to keep in mind: fn translation. Hiccup vectors are needed when word order matters for a translation and formatting is involved. See [this 3 word Turkish example](https://github.com/logseq/logseq/commit/1d932f07c4a0aad44606da6df03a432fe8421480#r118971415). -* Translations can have arguments for interpolating strings. When they do, be - sure translators are using them correctly. +* Translations can be anonymous fns with arguments for interpolating strings. Fns should be simple and only include the following fns: `str`, `when`, `if` and `=`. ### Spell Checker diff --git a/src/main/frontend/context/i18n.cljs b/src/main/frontend/context/i18n.cljs index 39a1b5dff9..9a21656622 100644 --- a/src/main/frontend/context/i18n.cljs +++ b/src/main/frontend/context/i18n.cljs @@ -4,7 +4,8 @@ throughout the application." (:require [frontend.dicts :as dicts] [tongue.core :as tongue] - [frontend.state :as state])) + [frontend.state :as state] + [lambdaisland.glogi :as log])) (def dicts (merge dicts/dicts {:tongue/fallback :en})) @@ -17,8 +18,13 @@ (try (apply translate preferred-language args) (catch :default e - (js/console.error "Translating dict" e) - (apply translate :en args))))) + (log/error :failed-translation {:arguments args + :lang preferred-language}) + (apply translate :en args) + (state/pub-event! [:capture-error {:error e + :payload {:type :failed-translation + :arguments args + :lang preferred-language}}]))))) (defn- fetch-local-language [] (.. js/window -navigator -language)) diff --git a/src/resources/dicts/fr.edn b/src/resources/dicts/fr.edn index a0bbce484d..bad57eb060 100644 --- a/src/resources/dicts/fr.edn +++ b/src/resources/dicts/fr.edn @@ -172,7 +172,7 @@ :linked-references/filter-excludes "Exclut : " :linked-references/filter-heading "Filtrer" :linked-references/filter-includes "Inclut : " - :linked-references/reference-count (fn [filtered-count total] (cond (= filtered-count nil) (cond (= total 0) "Aucune référence liée" (= total 1) "1 référence liée" :else (str total " références liées")) (= filtered-count 1) (str "1 référence liée / " total) :else (str filtered-count " références liées / " total) )) + :linked-references/reference-count (fn [filtered-count total] (str filtered-count (when filtered-count (if (= filtered-count 1) " référence liée" " références liées")) " parmi " total)) :linked-references/filter-search "Rechercher dans les pages liées" :linked-references/unexpected-error "Références liées : erreur inattendue. Veuillez d'abord ré-indexer votre graphe." :on-boarding/add-graph "Ajouter un graphe" @@ -806,15 +806,4 @@ :settings-page/auto-chmod "Automatiquement changer les permissions du fichier" :settings-page/auto-chmod-desc "Désactiver pour permettre l'édition par plusieurs utilisateurs avec les permissions données par l'appartenance au groupe." :settings-page/tab-keymap "Raccourcis" - :unlinked-references/reference-count (fn [total] - (cond - (or (nil? total) (= total "")) - "Références non liées" - (= total 0) - "Aucune référence non liée" - (= total 1) - "1 référence non liée" - (> total 1) - (str total " références non liées") - :else - "Références non liées"))} + :unlinked-references/reference-count (fn [total] (str total (if (= total 1) " référence non liée" " références non liées")))} From 46d7e80057fcd1f8a94c17c755ec738c512c8ed5 Mon Sep 17 00:00:00 2001 From: Gabriel Horner Date: Thu, 18 Jan 2024 10:34:50 -0500 Subject: [PATCH 02/23] fix default lang in catch --- src/main/frontend/context/i18n.cljs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/frontend/context/i18n.cljs b/src/main/frontend/context/i18n.cljs index 9a21656622..59e7ca787d 100644 --- a/src/main/frontend/context/i18n.cljs +++ b/src/main/frontend/context/i18n.cljs @@ -20,11 +20,11 @@ (catch :default e (log/error :failed-translation {:arguments args :lang preferred-language}) - (apply translate :en args) (state/pub-event! [:capture-error {:error e :payload {:type :failed-translation :arguments args - :lang preferred-language}}]))))) + :lang preferred-language}}]) + (apply translate :en args))))) (defn- fetch-local-language [] (.. js/window -navigator -language)) From 8b128cad74d36ca55c36d1e932b9e6bb98129d9f Mon Sep 17 00:00:00 2001 From: ChristianAvila Date: Wed, 22 Nov 2023 22:27:14 -0500 Subject: [PATCH 03/23] Add new switch to control commit on close - Extend the git commit up to 24 hours --- src/electron/electron/core.cljs | 4 +++- src/electron/electron/git.cljs | 7 +++++++ src/electron/electron/state.cljs | 4 ++++ src/main/frontend/components/settings.cljs | 20 ++++++++++++++++++-- src/main/frontend/state.cljs | 4 ++++ src/resources/dicts/en.edn | 1 + src/resources/dicts/es.edn | 1 + 7 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/electron/electron/core.cljs b/src/electron/electron/core.cljs index 37420f0355..e9975897b9 100644 --- a/src/electron/electron/core.cljs +++ b/src/electron/electron/core.cljs @@ -330,7 +330,9 @@ (.setFullScreen win false)) (.hide win))) :else - nil))))) + nil))) + (git/commit-current-graph!) + )) (.on app "before-quit" (fn [_e] (reset! win/*quitting? true))) diff --git a/src/electron/electron/git.cljs b/src/electron/electron/git.cljs index b5372c6f56..e21b9d767e 100644 --- a/src/electron/electron/git.cljs +++ b/src/electron/electron/git.cljs @@ -181,3 +181,10 @@ (js/setTimeout add-all-and-commit! 5000) (let [interval (js/setInterval add-all-and-commit! (* seconds 1000))] (state/set-git-commit-interval! interval)))))) + +(defn commit-current-graph! + [] + (when (not (state/git-auto-commit-disabled?)) + (when (not (state/git-commit-on-close-disabled?)) + (state/clear-git-commit-interval!) + (js/setTimeout add-all-and-commit! 3000)))) diff --git a/src/electron/electron/state.cljs b/src/electron/electron/state.cljs index acc44f9087..5911e7e458 100644 --- a/src/electron/electron/state.cljs +++ b/src/electron/electron/state.cljs @@ -45,6 +45,10 @@ [] (get-in @state [:config :git/disable-auto-commit?] true)) +(defn git-commit-on-close-disabled? + [] + (get-in @state [:config :git/disable-commit-on-close?] true)) + (defn get-graph-path [] (:graph/current @state)) diff --git a/src/main/frontend/components/settings.cljs b/src/main/frontend/components/settings.cljs index e8b0bc5754..995cd62025 100644 --- a/src/main/frontend/components/settings.cljs +++ b/src/main/frontend/components/settings.cljs @@ -253,6 +253,21 @@ (ipc/ipc :userAppCfgs :git/disable-auto-commit? enabled?)) true)]]])) +(rum/defcs switch-git-commit-on-close < rum/reactive + [state t] + (let [enabled? (state/get-git-commit-on-close-enabled?)] + [:div.it.sm:grid.sm:grid-cols-3.sm:gap-4.sm:items-center + [:label.block.text-sm.font-medium.leading-5.opacity-70 + (t :settings-page/git-commit-on-close-switcher-label)] + [:div + [:div.rounded-md.sm:max-w-xs + (ui/toggle + enabled? + (fn [] + (state/set-state! [:electron/user-cfgs :git/disable-commit-on-close?] enabled?) + (ipc/ipc :userAppCfgs :git/disable-commit-on-close? enabled?)) + true)]]])) + (rum/defcs git-auto-commit-seconds < rum/reactive [state t] (let [secs (or (state/sub [:electron/user-cfgs :git/auto-commit-seconds]) 60)] @@ -267,13 +282,13 @@ (let [value (-> (util/evalue event) util/safe-parse-int)] (if (and (number? value) - (< 0 value (inc 600))) + (< 0 value (inc 86400))) (do (state/set-state! [:electron/user-cfgs :git/auto-commit-seconds] value) (ipc/ipc :userAppCfgs :git/auto-commit-seconds value)) (when-let [elem (gobj/get event "target")] (notification/show! - [:div "Invalid value! Must be a number between 1 and 600."] + [:div "Invalid value! Must be a number between 1 and 86400"] :warning true) (gobj/set elem "value" secs)))))}]]]])) @@ -746,6 +761,7 @@ (t :settings-page/git-desc-3)]] [:br] (switch-git-auto-commit-row t) + (switch-git-commit-on-close t) (git-auto-commit-seconds t) (ui/admonition diff --git a/src/main/frontend/state.cljs b/src/main/frontend/state.cljs index c50d01403b..d4e80eb859 100644 --- a/src/main/frontend/state.cljs +++ b/src/main/frontend/state.cljs @@ -1930,6 +1930,10 @@ Similar to re-frame subscriptions" [] (false? (sub [:electron/user-cfgs :git/disable-auto-commit?]))) +(defn get-git-commit-on-close-enabled? + [] + (false? (sub [:electron/user-cfgs :git/disable-commit-on-close?]))) + (defn set-last-key-code! [key-code] (set-state! :editor/last-key-code key-code)) diff --git a/src/resources/dicts/en.edn b/src/resources/dicts/en.edn index 4b221430fd..4e37697694 100644 --- a/src/resources/dicts/en.edn +++ b/src/resources/dicts/en.edn @@ -287,6 +287,7 @@ :settings-page/git-desc-1 "To view page's edit history, click the three horizontal dots in the top-right corner and select \"View page history\"." :settings-page/git-desc-2 "For professional users, Logseq also supports using " :settings-page/git-desc-3 " for version control. Use Git at your own risk as general Git issues are not supported by the Logseq team." + :settings-page/git-commit-on-close-switcher-label "Git commit on window close" :settings-page/git-switcher-label "Enable Git auto commit" :settings-page/git-commit-delay "Git auto commit seconds" :settings-page/git-confirm "You need to restart the app after updating the Git settings." diff --git a/src/resources/dicts/es.edn b/src/resources/dicts/es.edn index db09152730..68984bd2fa 100644 --- a/src/resources/dicts/es.edn +++ b/src/resources/dicts/es.edn @@ -654,6 +654,7 @@ :settings-page/git-desc-1 "Para ver el historial de edición de la página, da clic en los tres puntos horizontales en la esquina superior derecha y selecciona \"Ver historial de página\"." :settings-page/git-desc-2 "Para usuarios profesionales, Logseq también es compatible con" :settings-page/git-desc-3 " para control de versiones. Usa Git bajo tu propio riesgo ya que problemas generales con Git no son respaldados por el equipo de Logseq." + :settings-page/git-commit-on-close-switcher-label "Git auto commit" :settings-page/git-switcher-label "Habilitar Git auto commit" :settings-page/git-tip "Si tienes Logseq Sync habilitado, puedes ver el historial de edición de la página directamente. Esta sección es solo para conocedores de tecnología." :settings-page/home-default-page "Establecer página de inicio" From 8efce54a3a0d754ac3436050505412551d9ba497 Mon Sep 17 00:00:00 2001 From: Andelf Date: Wed, 17 Jan 2024 14:42:43 +0800 Subject: [PATCH 04/23] refactor(electron): rewrite git auto-commit - Supports change auto-commit settings on the fly --- src/electron/electron/core.cljs | 7 ++-- src/electron/electron/git.cljs | 38 ++++++++++++++-------- src/electron/electron/handler.cljs | 4 +++ src/electron/electron/state.cljs | 22 ++++--------- src/main/frontend/components/settings.cljs | 27 ++++++++------- src/main/frontend/state.cljs | 2 +- src/resources/dicts/de.edn | 1 - src/resources/dicts/en.edn | 3 +- src/resources/dicts/es.edn | 3 +- src/resources/dicts/fr.edn | 1 - src/resources/dicts/id.edn | 1 - src/resources/dicts/it.edn | 1 - src/resources/dicts/ja.edn | 1 - src/resources/dicts/ko.edn | 1 - src/resources/dicts/nb-no.edn | 3 +- src/resources/dicts/nl.edn | 1 - src/resources/dicts/pl.edn | 1 - src/resources/dicts/pt-br.edn | 1 - src/resources/dicts/pt-pt.edn | 1 - src/resources/dicts/ru.edn | 1 - src/resources/dicts/sk.edn | 1 - src/resources/dicts/tr.edn | 1 - src/resources/dicts/uk.edn | 1 - src/resources/dicts/zh-cn.edn | 1 - src/resources/dicts/zh-hant.edn | 1 - 25 files changed, 54 insertions(+), 71 deletions(-) diff --git a/src/electron/electron/core.cljs b/src/electron/electron/core.cljs index e9975897b9..e93c8c5c1f 100644 --- a/src/electron/electron/core.cljs +++ b/src/electron/electron/core.cljs @@ -291,7 +291,7 @@ (search/open-dbs!) - (git/auto-commit-current-graph!) + (git/configure-auto-commit!) (vreset! *setup-fn (fn [] @@ -310,6 +310,7 @@ ;; main window events (.on win "close" (fn [e] + (git/before-graph-close-hook!) (when @*quit-dirty? ;; when not updating (.preventDefault e) @@ -330,9 +331,7 @@ (.setFullScreen win false)) (.hide win))) :else - nil))) - (git/commit-current-graph!) - )) + nil))))) (.on app "before-quit" (fn [_e] (reset! win/*quitting? true))) diff --git a/src/electron/electron/git.cljs b/src/electron/electron/git.cljs index e21b9d767e..f368eb8264 100644 --- a/src/electron/electron/git.cljs +++ b/src/electron/electron/git.cljs @@ -171,20 +171,30 @@ (p/resolved result)) (p/catch error-handler)))) -(defn auto-commit-current-graph! +(defonce auto-commit-interval (atom nil)) +(defn- auto-commit-tick-fn [] - (when (not (state/git-auto-commit-disabled?)) - (state/clear-git-commit-interval!) - (js/setTimeout add-all-and-commit! 3000) - (let [seconds (state/get-git-commit-seconds)] - (when (int? seconds) - (js/setTimeout add-all-and-commit! 5000) - (let [interval (js/setInterval add-all-and-commit! (* seconds 1000))] - (state/set-git-commit-interval! interval)))))) + (when (state/git-auto-commit-enabled?) + (logger/debug ::auto-commit) + (add-all-and-commit!))) -(defn commit-current-graph! +(defn configure-auto-commit! + "Configure auto commit interval, reentrantable" [] - (when (not (state/git-auto-commit-disabled?)) - (when (not (state/git-commit-on-close-disabled?)) - (state/clear-git-commit-interval!) - (js/setTimeout add-all-and-commit! 3000)))) + (when @auto-commit-interval + (swap! auto-commit-interval js/clearInterval)) + (when (state/git-auto-commit-enabled?) + (let [seconds (state/get-git-commit-seconds) + millis (if (int? seconds) + (* seconds 1000) + 6000)] + (logger/info ::auto-commit-interval seconds) + ;; each time we change the auto-commit settings, we will commit the current graph in 5 seconds + (js/setTimeout add-all-and-commit! 5000) + (reset! auto-commit-interval (js/setInterval auto-commit-tick-fn millis))))) + +(defn before-graph-close-hook! + [] + (when (and (state/git-auto-commit-enabled?) + (state/git-commit-on-close-enabled?)) + (add-all-and-commit!))) diff --git a/src/electron/electron/handler.cljs b/src/electron/electron/handler.cljs index e8ad447e38..f48371ef95 100644 --- a/src/electron/electron/handler.cljs +++ b/src/electron/electron/handler.cljs @@ -501,6 +501,10 @@ (defmethod handle :gitStatus [_ [_]] (git/short-status!)) +(defmethod handle :setGitAutoCommit [] + (git/configure-auto-commit!) + nil) + (defmethod handle :installMarketPlugin [_ [_ mft]] (plugin/install-or-update! mft)) diff --git a/src/electron/electron/state.cljs b/src/electron/electron/state.cljs index 5911e7e458..c85ecbdab5 100644 --- a/src/electron/electron/state.cljs +++ b/src/electron/electron/state.cljs @@ -6,9 +6,7 @@ (defonce persistent-dbs-chan (async/chan 1)) (defonce state - (atom {:git/auto-commit-interval nil - - :config (config/get-config) + (atom {:config (config/get-config) ;; FIXME: replace with :window/graph :graph/current nil @@ -28,26 +26,18 @@ (swap! state assoc-in path value) (swap! state assoc path value))) -(defn set-git-commit-interval! - [v] - (set-state! :git/auto-commit-interval v)) - -(defn clear-git-commit-interval! - [] - (when-let [interval (get @state :git/auto-commit-interval)] - (js/clearInterval interval))) - (defn get-git-commit-seconds [] (get-in @state [:config :git/auto-commit-seconds] 60)) -(defn git-auto-commit-disabled? +(defn git-auto-commit-enabled? [] - (get-in @state [:config :git/disable-auto-commit?] true)) + ;; For backward compatibility, use negative logic + (false? (get-in @state [:config :git/disable-auto-commit?] true))) -(defn git-commit-on-close-disabled? +(defn git-commit-on-close-enabled? [] - (get-in @state [:config :git/disable-commit-on-close?] true)) + (get-in @state [:config :git/commit-on-close?] false)) (defn get-graph-path [] diff --git a/src/main/frontend/components/settings.cljs b/src/main/frontend/components/settings.cljs index 995cd62025..9688262c72 100644 --- a/src/main/frontend/components/settings.cljs +++ b/src/main/frontend/components/settings.cljs @@ -250,22 +250,24 @@ enabled? (fn [] (state/set-state! [:electron/user-cfgs :git/disable-auto-commit?] enabled?) - (ipc/ipc :userAppCfgs :git/disable-auto-commit? enabled?)) + (p/do! + (ipc/ipc :userAppCfgs :git/disable-auto-commit? enabled?) + (ipc/ipc :setGitAutoCommit))) true)]]])) -(rum/defcs switch-git-commit-on-close < rum/reactive +(rum/defcs switch-git-commit-on-close-row < rum/reactive [state t] (let [enabled? (state/get-git-commit-on-close-enabled?)] [:div.it.sm:grid.sm:grid-cols-3.sm:gap-4.sm:items-center [:label.block.text-sm.font-medium.leading-5.opacity-70 - (t :settings-page/git-commit-on-close-switcher-label)] + (t :settings-page/git-commit-on-close)] [:div [:div.rounded-md.sm:max-w-xs (ui/toggle enabled? (fn [] - (state/set-state! [:electron/user-cfgs :git/disable-commit-on-close?] enabled?) - (ipc/ipc :userAppCfgs :git/disable-commit-on-close? enabled?)) + (state/set-state! [:electron/user-cfgs :git/commit-on-close?] (not enabled?)) + (ipc/ipc :userAppCfgs :git/commit-on-close? (not enabled?))) true)]]])) (rum/defcs git-auto-commit-seconds < rum/reactive @@ -283,9 +285,10 @@ util/safe-parse-int)] (if (and (number? value) (< 0 value (inc 86400))) - (do + (p/do! (state/set-state! [:electron/user-cfgs :git/auto-commit-seconds] value) - (ipc/ipc :userAppCfgs :git/auto-commit-seconds value)) + (ipc/ipc :userAppCfgs :git/auto-commit-seconds value) + (ipc/ipc :setGitAutoCommit)) (when-let [elem (gobj/get event "target")] (notification/show! [:div "Invalid value! Must be a number between 1 and 86400"] @@ -752,7 +755,7 @@ [:p (t :settings-page/git-tip)]) [:span.text-sm.opacity-50.my-4 (t :settings-page/git-desc-1)] - [:br][:br] + [:br] [:br] [:span.text-sm.opacity-50.my-4 (t :settings-page/git-desc-2)] [:a {:href "https://git-scm.com/" :target "_blank"} @@ -761,12 +764,8 @@ (t :settings-page/git-desc-3)]] [:br] (switch-git-auto-commit-row t) - (switch-git-commit-on-close t) - (git-auto-commit-seconds t) - - (ui/admonition - :warning - [:p (t :settings-page/git-confirm)])]) + (switch-git-commit-on-close-row t) + (git-auto-commit-seconds t)]) (rum/defc settings-advanced < rum/reactive [current-repo] diff --git a/src/main/frontend/state.cljs b/src/main/frontend/state.cljs index d4e80eb859..83fca36fb9 100644 --- a/src/main/frontend/state.cljs +++ b/src/main/frontend/state.cljs @@ -1932,7 +1932,7 @@ Similar to re-frame subscriptions" (defn get-git-commit-on-close-enabled? [] - (false? (sub [:electron/user-cfgs :git/disable-commit-on-close?]))) + (sub [:electron/user-cfgs :git/commit-on-close?])) (defn set-last-key-code! [key-code] diff --git a/src/resources/dicts/de.edn b/src/resources/dicts/de.edn index 4292efd51e..8924fcef1b 100644 --- a/src/resources/dicts/de.edn +++ b/src/resources/dicts/de.edn @@ -575,7 +575,6 @@ :settings-page/export-theme "Theme exportieren" :settings-page/filename-format "Dateinamen-Format" :settings-page/git-commit-delay "Anzahl Sekunden für Git Auto Commit" - :settings-page/git-confirm "Sie müssen die App neu starten, nachdem Sie die Git-Einstellungen angepasst haben." :settings-page/git-switcher-label "Git Auto Commit aktivieren" :settings-page/home-default-page "Standard-Homepage einrichten" :settings-page/login-prompt "Um vor allen anderen auf neue Funktionen zugreifen zu können, müssen Sie ein Open Collective Sponsor oder Backer von Logseq sein und sich daher zuerst anmelden." diff --git a/src/resources/dicts/en.edn b/src/resources/dicts/en.edn index 4e37697694..bf8341f758 100644 --- a/src/resources/dicts/en.edn +++ b/src/resources/dicts/en.edn @@ -287,10 +287,9 @@ :settings-page/git-desc-1 "To view page's edit history, click the three horizontal dots in the top-right corner and select \"View page history\"." :settings-page/git-desc-2 "For professional users, Logseq also supports using " :settings-page/git-desc-3 " for version control. Use Git at your own risk as general Git issues are not supported by the Logseq team." - :settings-page/git-commit-on-close-switcher-label "Git commit on window close" + :settings-page/git-commit-on-close "Git commit on window close" :settings-page/git-switcher-label "Enable Git auto commit" :settings-page/git-commit-delay "Git auto commit seconds" - :settings-page/git-confirm "You need to restart the app after updating the Git settings." :settings-page/edit-config-edn "Edit config.edn" :settings-page/edit-global-config-edn "Edit global config.edn" :settings-page/edit-custom-css "Edit custom.css" diff --git a/src/resources/dicts/es.edn b/src/resources/dicts/es.edn index 68984bd2fa..e2ace24d87 100644 --- a/src/resources/dicts/es.edn +++ b/src/resources/dicts/es.edn @@ -650,11 +650,10 @@ :settings-page/export-theme "Tema exportación" :settings-page/filename-format "Formato de nombre de archivo" :settings-page/git-commit-delay "Segundos para Git auto commit" - :settings-page/git-confirm "Debe reiniciar la aplicación después de actualizar las opciones de Git." :settings-page/git-desc-1 "Para ver el historial de edición de la página, da clic en los tres puntos horizontales en la esquina superior derecha y selecciona \"Ver historial de página\"." :settings-page/git-desc-2 "Para usuarios profesionales, Logseq también es compatible con" :settings-page/git-desc-3 " para control de versiones. Usa Git bajo tu propio riesgo ya que problemas generales con Git no son respaldados por el equipo de Logseq." - :settings-page/git-commit-on-close-switcher-label "Git auto commit" + :settings-page/git-commit-on-close "Git auto commit" :settings-page/git-switcher-label "Habilitar Git auto commit" :settings-page/git-tip "Si tienes Logseq Sync habilitado, puedes ver el historial de edición de la página directamente. Esta sección es solo para conocedores de tecnología." :settings-page/home-default-page "Establecer página de inicio" diff --git a/src/resources/dicts/fr.edn b/src/resources/dicts/fr.edn index bad57eb060..0ff5980515 100644 --- a/src/resources/dicts/fr.edn +++ b/src/resources/dicts/fr.edn @@ -269,7 +269,6 @@ :settings-page/export-theme "Exporter le thème" :settings-page/filename-format "Format de nom de fichier" :settings-page/git-commit-delay "Délai (secondes) des commits Git automatiques" - :settings-page/git-confirm "Vous devez redémarrer l'application après avoir mis à jour le dossier Git" :settings-page/git-switcher-label "Activer les commits Git automatiques" :settings-page/home-default-page "Régler la page d'accueil par défaut" :settings-page/login-prompt "Pour accéder aux nouvelles fonctionnalités avant tout le monde, vous devez être sponsor ou \"backer\" (contributeur) sur Open Collective, puis vous connecter." diff --git a/src/resources/dicts/id.edn b/src/resources/dicts/id.edn index 64f12c1ae4..d19fb76cda 100644 --- a/src/resources/dicts/id.edn +++ b/src/resources/dicts/id.edn @@ -261,7 +261,6 @@ :settings-page/git-desc-3 " untuk kontrol versi. Gunakan Git dengan risiko Anda sendiri karena masalah umum Git tidak didukung oleh tim Logseq." :settings-page/git-switcher-label "Aktifkan komit otomatis Git" :settings-page/git-commit-delay "Detik komit otomatis Git" - :settings-page/git-confirm "Anda perlu me-restart aplikasi setelah memperbarui pengaturan Git." :settings-page/edit-config-edn "Sunting config.edn" :settings-page/edit-global-config-edn "Sunting global config.edn" :settings-page/edit-custom-css "Sunting custom.css" diff --git a/src/resources/dicts/it.edn b/src/resources/dicts/it.edn index c4ab7156be..8261c5912a 100644 --- a/src/resources/dicts/it.edn +++ b/src/resources/dicts/it.edn @@ -77,7 +77,6 @@ :content/copy-block-emebed "Copia blocco incorporato" :content/open-in-sidebar "Apri nel pannello laterale" :content/click-to-edit "Clicca per modificare" - :settings-page/git-confirm "Devi riavviare l'app dopo aver aggiornato le impostazioni di Git." :settings-page/git-switcher-label "Commit automatico" :settings-page/git-commit-delay "Secondi per commit automatico" :settings-page/edit-config-edn "Modifica config.edn" diff --git a/src/resources/dicts/ja.edn b/src/resources/dicts/ja.edn index 06b633aeb6..448ec807f6 100644 --- a/src/resources/dicts/ja.edn +++ b/src/resources/dicts/ja.edn @@ -270,7 +270,6 @@ :settings-page/git-desc-3 " の利用も用意しています。Gitの利用はご自身の責任で行ってください。一般的なGitの問題について、Logseqチームはサポートしません。" :settings-page/git-switcher-label "Gitの自動コミットを有効化" :settings-page/git-commit-delay "Gitの自動コミット間隔(秒)" - :settings-page/git-confirm "Git設定を更新するにはアプリを再起動する必要があります。" :settings-page/edit-config-edn "config.ednを編集" :settings-page/edit-global-config-edn "グローバルなconfig.ednを編集" :settings-page/edit-custom-css "custom.cssを編集" diff --git a/src/resources/dicts/ko.edn b/src/resources/dicts/ko.edn index b76826a3c2..7ad7a7b58c 100644 --- a/src/resources/dicts/ko.edn +++ b/src/resources/dicts/ko.edn @@ -78,7 +78,6 @@ :content/copy-block-emebed "블록 임베드 복사" :content/open-in-sidebar "사이드바에서 열기" :content/click-to-edit "클릭하여 수정" - :settings-page/git-confirm "Git 설정을 변경한 뒤 앱을 재시작해야 합니다." :settings-page/git-switcher-label "Git 자동 커밋 설정" :settings-page/git-commit-delay "Git 자동 커밋 간격 (초)" :settings-page/edit-config-edn "config.edn 수정" diff --git a/src/resources/dicts/nb-no.edn b/src/resources/dicts/nb-no.edn index ada614a010..e8429aedce 100644 --- a/src/resources/dicts/nb-no.edn +++ b/src/resources/dicts/nb-no.edn @@ -79,7 +79,6 @@ :content/copy-block-emebed "Kopier innebygging av blokk" :content/open-in-sidebar "Åpne i sidefeltet" :content/click-to-edit "Klikk for å redigere" - :settings-page/git-confirm "Du må starte appen på nytt etter å ha oppdatert Git innstillingene." :settings-page/git-switcher-label "Skru på Git auto commit" :settings-page/git-commit-delay "Git auto commit sekunder" :settings-page/edit-config-edn "Rediger config.edn for nåværende repo" @@ -790,7 +789,7 @@ :settings-page/auto-chmod-desc "Deaktiver for å tillate redigering av flere brukere med tillatelser gitt av gruppemedlemskap." :settings-page/tab-keymap "Tastatur" :whiteboard/toggle-pen-mode "Veksle pen-modus" - + :command.command-palette/toggle "Søk kommandoer" :command.go/search-in-page "Søk blokker på side" :command.ui/cycle-color "Veksle farge" diff --git a/src/resources/dicts/nl.edn b/src/resources/dicts/nl.edn index 55479c25ee..b27d2b85a5 100644 --- a/src/resources/dicts/nl.edn +++ b/src/resources/dicts/nl.edn @@ -199,7 +199,6 @@ :settings-page/enable-tooltip "Tooltips inschakelen" :settings-page/export-theme "Exporteer thema" :settings-page/git-commit-delay "Git auto commit seconden" - :settings-page/git-confirm "Je moet de app opnieuw opstarten nadat je de Git instellingen hebt aangepast." :settings-page/git-switcher-label "Git auto commit inschakelen" :settings-page/home-default-page "De standaard startpagina instellen" :settings-page/network-proxy "Netwerk proxy" diff --git a/src/resources/dicts/pl.edn b/src/resources/dicts/pl.edn index 03bd27c2ed..bd14aa5e57 100644 --- a/src/resources/dicts/pl.edn +++ b/src/resources/dicts/pl.edn @@ -82,7 +82,6 @@ :content/copy-block-emebed "Kopiuj blok jako embed" :content/open-in-sidebar "Otwórz w panelu bocznym" :content/click-to-edit "Kliknij, aby edytować" - :settings-page/git-confirm "Musisz uruchomić ponownie aplikację żeby zastosować zmiany w ustawieniach Gita." :settings-page/git-switcher-label "Włącz opcję autocommit w Git" :settings-page/git-commit-delay "Wykonaj commit co każde [s.]" :settings-page/edit-config-edn "Edytuj config.edn" diff --git a/src/resources/dicts/pt-br.edn b/src/resources/dicts/pt-br.edn index 8bc511820d..a732192b18 100644 --- a/src/resources/dicts/pt-br.edn +++ b/src/resources/dicts/pt-br.edn @@ -265,7 +265,6 @@ :settings-page/git-desc-3 " para controle de versão. Use o Git por sua própria conta e risco, uma vez que questões gerais do Git não são suportadas pela equipe do Logseq." :settings-page/git-switcher-label "Ativar confirmação automática do Git" :settings-page/git-commit-delay "Segundos para confirmação automática do Git" - :settings-page/git-confirm "Você precisa reiniciar o aplicativo após atualizar as configurações do Git." :settings-page/edit-config-edn "Editar config.edn" :settings-page/edit-global-config-edn "Editar config.edn global" :settings-page/edit-custom-css "Editar custom.css" diff --git a/src/resources/dicts/pt-pt.edn b/src/resources/dicts/pt-pt.edn index f5bd56e54f..ed396ebeba 100644 --- a/src/resources/dicts/pt-pt.edn +++ b/src/resources/dicts/pt-pt.edn @@ -140,7 +140,6 @@ :content/delete-ref "Apagar esta referência" :content/open-in-sidebar "Abrir na barra lateral" :content/click-to-edit "Clicar para editar" - :settings-page/git-confirm "É necessário reiniciar a aplicação após atualizar as definições do Git." :settings-page/git-switcher-label "Ativar o auto commit do Git" :settings-page/git-commit-delay "Segundos entre cada auto commit" :settings-page/edit-config-edn "Editar config.edn" diff --git a/src/resources/dicts/ru.edn b/src/resources/dicts/ru.edn index 0dde68923c..2c37e6df4b 100644 --- a/src/resources/dicts/ru.edn +++ b/src/resources/dicts/ru.edn @@ -172,7 +172,6 @@ :context-menu/input-template-name "Как назовём шаблон?" :context-menu/template-include-parent-block "Включить родительский блок в шаблон?" :context-menu/template-exists-warning "Шаблон уже существует!" - :settings-page/git-confirm "Необходимо перезапустить приложение после изменения настроек Git." :settings-page/git-switcher-label "Включить автокоммит в Git" :settings-page/git-commit-delay "Задержка автокоммита Git в секундах" :settings-page/edit-config-edn "Редактировать config.edn" diff --git a/src/resources/dicts/sk.edn b/src/resources/dicts/sk.edn index 76f003cc1c..2f17e14e13 100644 --- a/src/resources/dicts/sk.edn +++ b/src/resources/dicts/sk.edn @@ -266,7 +266,6 @@ :settings-page/git-desc-3 " pre správu verzií. Používajte Git na vlastné riziko, pretože všeobecné problémy s Git nie sú podporované tímom Logseq." :settings-page/git-switcher-label "Povoliť automatický zápis do Git" :settings-page/git-commit-delay "Automatický zápis do Git po sekundách" - :settings-page/git-confirm "Po aktualizácii nastavení Git je potrebné reštartovať aplikáciu." :settings-page/edit-config-edn "Upraviť config.edn" :settings-page/edit-global-config-edn "Upraviť globálny config.edn" :settings-page/edit-custom-css "Upraviť custom.css" diff --git a/src/resources/dicts/tr.edn b/src/resources/dicts/tr.edn index 3ea8197da0..bc7fde1ef6 100644 --- a/src/resources/dicts/tr.edn +++ b/src/resources/dicts/tr.edn @@ -289,7 +289,6 @@ :settings-page/git-desc-3 " kullanımını da destekler. Genel Git sorunları Logseq ekibi tarafından desteklenmediğinden Git'i kullanmanın riski size aittir." :settings-page/git-switcher-label "Otomatik git commit'i etkinleştir" :settings-page/git-commit-delay "Otomatik git commit saniyesi" - :settings-page/git-confirm "Git ayarlarını güncelledikten sonra uygulamayı yeniden başlatmanız gerekiyor." :settings-page/edit-config-edn "config.edn dosyasını düzenle" :settings-page/edit-global-config-edn "Genel config.edn dosyasını düzenle" :settings-page/edit-custom-css "custom.css dosyasını düzenle" diff --git a/src/resources/dicts/uk.edn b/src/resources/dicts/uk.edn index d4113bd7d3..4980b36deb 100644 --- a/src/resources/dicts/uk.edn +++ b/src/resources/dicts/uk.edn @@ -162,7 +162,6 @@ :context-menu/input-template-name "Як назвемо шаблон?" :context-menu/template-include-parent-block "Включити батьківський блок у шаблон?" :context-menu/template-exists-warning "Шаблон вже існує!" - :settings-page/git-confirm "Вам потрібно перезапустити програму після оновлення налаштувань Git." :settings-page/git-switcher-label "Увімкнути Git авто commit" :settings-page/git-commit-delay "Секунди Git авто commit" :settings-page/edit-config-edn "Редагувати config.edn" diff --git a/src/resources/dicts/zh-cn.edn b/src/resources/dicts/zh-cn.edn index 6d11845129..049639f8ef 100644 --- a/src/resources/dicts/zh-cn.edn +++ b/src/resources/dicts/zh-cn.edn @@ -191,7 +191,6 @@ :settings-page/edit-custom-css "编辑 custom.css (当前库)" :settings-page/custom-configuration "自定义配置" :settings-page/custom-theme "自定义主题" - :settings-page/git-confirm "更新 Git 设置后,需要重启应用" :settings-page/git-switcher-label "开启 Git 自动 commit" :settings-page/git-commit-delay "Git 自动 commit 间隔秒数" :settings-page/preferred-outdenting "逻辑缩进" diff --git a/src/resources/dicts/zh-hant.edn b/src/resources/dicts/zh-hant.edn index 0bdcac457e..f7ffc0173c 100644 --- a/src/resources/dicts/zh-hant.edn +++ b/src/resources/dicts/zh-hant.edn @@ -138,7 +138,6 @@ :content/copy-block-emebed "複製嵌入區塊" :content/open-in-sidebar "在側邊欄中打開" :content/click-to-edit "點擊以編輯" - :settings-page/git-confirm "在更新 Git 設置後,您需要重新啟動應用程式。" :settings-page/git-switcher-label "啟用 Git 自動提交" :settings-page/git-commit-delay "Git 自動提交間隔" :settings-page/edit-config-edn "編輯 config.edn" From 095be37cc8b7fdceeb996f19a4b647978be93e7f Mon Sep 17 00:00:00 2001 From: Andelf Date: Wed, 17 Jan 2024 15:56:39 +0800 Subject: [PATCH 05/23] fix: use debounced git auto commit setting fn --- src/electron/electron/git.cljs | 6 ++---- src/electron/electron/handler.cljs | 5 ++++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/electron/electron/git.cljs b/src/electron/electron/git.cljs index f368eb8264..32922784ed 100644 --- a/src/electron/electron/git.cljs +++ b/src/electron/electron/git.cljs @@ -175,7 +175,6 @@ (defn- auto-commit-tick-fn [] (when (state/git-auto-commit-enabled?) - (logger/debug ::auto-commit) (add-all-and-commit!))) (defn configure-auto-commit! @@ -188,9 +187,8 @@ millis (if (int? seconds) (* seconds 1000) 6000)] - (logger/info ::auto-commit-interval seconds) - ;; each time we change the auto-commit settings, we will commit the current graph in 5 seconds - (js/setTimeout add-all-and-commit! 5000) + (logger/info ::set-auto-commit-interval seconds) + (js/setTimeout add-all-and-commit! 100) (reset! auto-commit-interval (js/setInterval auto-commit-tick-fn millis))))) (defn before-graph-close-hook! diff --git a/src/electron/electron/handler.cljs b/src/electron/electron/handler.cljs index f48371ef95..ddd348ad94 100644 --- a/src/electron/electron/handler.cljs +++ b/src/electron/electron/handler.cljs @@ -29,6 +29,7 @@ [electron.state :as state] [electron.utils :as utils] [electron.window :as win] + [goog.functions :refer [debounce]] [logseq.common.graph :as common-graph] [promesa.core :as p])) @@ -501,10 +502,12 @@ (defmethod handle :gitStatus [_ [_]] (git/short-status!)) +(def debounced-configure-auto-commit! (debounce git/configure-auto-commit! 5000)) (defmethod handle :setGitAutoCommit [] - (git/configure-auto-commit!) + (debounced-configure-auto-commit!) nil) + (defmethod handle :installMarketPlugin [_ [_ mft]] (plugin/install-or-update! mft)) From a6d13fb7b2a46807603b9cf72591b51d27c9789e Mon Sep 17 00:00:00 2001 From: Reilly Brogan Date: Thu, 18 Jan 2024 13:13:30 -0600 Subject: [PATCH 06/23] Update better-sqlite to v9.3.0 --- resources/package.json | 28 ++++++++++++++-------------- static/yarn.lock | 12 ++++++------ 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/resources/package.json b/resources/package.json index 862bba1146..8c986538ed 100644 --- a/resources/package.json +++ b/resources/package.json @@ -20,30 +20,30 @@ "forge": "./forge.config.js" }, "dependencies": { - "better-sqlite3": "8.0.1", + "@fastify/cors": "8.2.0", + "@logseq/rsapi": "0.0.81", + "@sentry/electron": "2.5.1", + "abort-controller": "3.0.0", + "better-sqlite3": "9.3.0", "chokidar": "^3.5.1", + "command-exists": "1.2.9", + "diff-match-patch": "1.0.5", "dugite": "2.5.0", + "electron-deeplink": "1.0.10", "electron-dl": "3.3.0", "electron-log": "4.3.1", "electron-squirrel-startup": "1.0.0", "electron-window-state": "5.0.3", + "extract-zip": "2.0.1", + "fastify": "latest", "fs-extra": "9.1.0", + "https-proxy-agent": "7.0.2", "node-fetch": "2.6.7", "open": "7.3.1", - "semver": "7.5.2", - "update-electron-app": "2.0.1", - "extract-zip": "2.0.1", - "diff-match-patch": "1.0.5", - "https-proxy-agent": "7.0.2", - "socks-proxy-agent": "8.0.2", - "@sentry/electron": "2.5.1", "posthog-js": "1.10.2", - "@logseq/rsapi": "0.0.81", - "electron-deeplink": "1.0.10", - "abort-controller": "3.0.0", - "fastify": "latest", - "@fastify/cors": "8.2.0", - "command-exists": "1.2.9" + "semver": "7.5.2", + "socks-proxy-agent": "8.0.2", + "update-electron-app": "2.0.1" }, "devDependencies": { "@electron-forge/cli": "^6.0.4", diff --git a/static/yarn.lock b/static/yarn.lock index 0af2bddaf0..1b63ac2cab 100644 --- a/static/yarn.lock +++ b/static/yarn.lock @@ -1068,13 +1068,13 @@ base64-js@^1.3.1, base64-js@^1.5.1: resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== -better-sqlite3@8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/better-sqlite3/-/better-sqlite3-8.0.1.tgz#3a596d21fbcefadf36f94e126c5cf24d5697d0b8" - integrity sha512-JhTZjpyapA1icCEjIZB4TSSgkGdFgpWZA2Wszg7Cf4JwJwKQmbvuNnJBeR+EYG/Z29OXvR4G//Rbg31BW/Z7Yg== +better-sqlite3@9.3.0: + version "9.3.0" + resolved "https://registry.yarnpkg.com/better-sqlite3/-/better-sqlite3-9.3.0.tgz#2a8aaad65fa0210a4df5e8a0bcbc9156f6138d56" + integrity sha512-ww73jVpQhRRdS9uMr761ixlkl4bWoXi8hMQlBGhoN6vPNlUHpIsNmw4pKN6kjknlt/wopdvXHvLk1W75BI+n0Q== dependencies: bindings "^1.5.0" - prebuild-install "^7.1.0" + prebuild-install "^7.1.1" binary-extensions@^2.0.0: version "2.2.0" @@ -4034,7 +4034,7 @@ posthog-js@1.10.2: dependencies: fflate "^0.4.1" -prebuild-install@^7.1.0: +prebuild-install@^7.1.1: version "7.1.1" resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.1.1.tgz#de97d5b34a70a0c81334fd24641f2a1702352e45" integrity sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw== From 74325f24e1fa32fd62f315603958b8d225c9aaa2 Mon Sep 17 00:00:00 2001 From: Tienson Qin Date: Sat, 20 Jan 2024 03:08:44 +0800 Subject: [PATCH 07/23] fix: don't use opfs for publishing graphs --- src/main/frontend/db_worker.cljs | 37 +++++++++++++++++------ src/main/frontend/persist_db/browser.cljs | 4 +-- src/main/frontend/publishing.cljs | 11 +++---- 3 files changed, 34 insertions(+), 18 deletions(-) diff --git a/src/main/frontend/db_worker.cljs b/src/main/frontend/db_worker.cljs index 09f252f5dc..1c297dd2aa 100644 --- a/src/main/frontend/db_worker.cljs +++ b/src/main/frontend/db_worker.cljs @@ -29,6 +29,7 @@ (defonce *sqlite-conns worker-state/*sqlite-conns) (defonce *datascript-conns worker-state/*datascript-conns) (defonce *opfs-pools worker-state/*opfs-pools) +(defonce *publishing? (atom false)) (defn- get-pool-name [graph-name] @@ -36,16 +37,21 @@ (defn- Date: Thu, 18 Jan 2024 13:32:35 -0500 Subject: [PATCH 10/23] fix: publishing doesn't build a db-worker --- shadow-cljs.edn | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/shadow-cljs.edn b/shadow-cljs.edn index d4ba9b8888..b3da0ebab0 100644 --- a/shadow-cljs.edn +++ b/shadow-cljs.edn @@ -93,8 +93,11 @@ :publishing {:target :browser :module-loader true :js-options {:ignore-asset-requires true} - :modules {:main - {:init-fn frontend.publishing/init} + :modules {:shared + {:entries []} + :main + {:init-fn frontend.publishing/init + :depends-on #{:shared}} :code-editor {:entries [frontend.extensions.code] :depends-on #{:main}} @@ -103,7 +106,11 @@ :depends-on #{:main}} :tldraw {:entries [frontend.extensions.tldraw] - :depends-on #{:main}}} + :depends-on #{:main}} + :db-worker + {:init-fn frontend.db-worker/init + :depends-on #{:shared} + :web-worker true}} :output-dir "./static/js/publishing" :asset-path "static/js" From a80a182a8f8f56815b675e04f197e9f6da81914a Mon Sep 17 00:00:00 2001 From: Gabriel Horner Date: Fri, 19 Jan 2024 10:52:38 -0500 Subject: [PATCH 11/23] fix: update publishing setup since there are 2 more assets Also add compilation flag for code splitting bug --- deps/publishing/src/logseq/publishing/export.cljs | 2 +- deps/publishing/src/logseq/publishing/html.cljs | 1 + shadow-cljs.edn | 5 ++++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/deps/publishing/src/logseq/publishing/export.cljs b/deps/publishing/src/logseq/publishing/export.cljs index 2e857e5818..13ea11f39e 100644 --- a/deps/publishing/src/logseq/publishing/export.cljs +++ b/deps/publishing/src/logseq/publishing/export.cljs @@ -8,7 +8,7 @@ (def ^:api js-files "js files from publishing release build" - ["main.js" "code-editor.js" "excalidraw.js" "tldraw.js"]) + ["shared.js" "main.js" "code-editor.js" "excalidraw.js" "tldraw.js" "db-worker.js"]) (def ^:api static-dirs "dirs under static dir to copy over" diff --git a/deps/publishing/src/logseq/publishing/html.cljs b/deps/publishing/src/logseq/publishing/html.cljs index 0e1b9697c6..657dbd60df 100644 --- a/deps/publishing/src/logseq/publishing/html.cljs +++ b/deps/publishing/src/logseq/publishing/html.cljs @@ -122,6 +122,7 @@ necessary db filtering" } }(window.location))"] ;; TODO: should make this configurable + [:script {:src "static/js/shared.js"}] [:script {:src "static/js/main.js"}] [:script {:src "static/js/interact.min.js"}] [:script {:src "static/js/highlight.min.js"}] diff --git a/shadow-cljs.edn b/shadow-cljs.edn index b3da0ebab0..50cdd3fe86 100644 --- a/shadow-cljs.edn +++ b/shadow-cljs.edn @@ -121,7 +121,10 @@ :externs ["datascript/externs.js" "externs.js"] :warnings {:fn-deprecated false - :redef false}} + :redef false} + ;; https://github.com/thheller/shadow-cljs/issues/611#issuecomment-620845276 + ;; fixes cljs.spec bug with code splitting + :cross-chunk-method-motion false} :devtools {:before-load frontend.core/stop :after-load frontend.core/start :preloads [devtools.preload]}}}} From b8ece3f268a690db0329828fed3577b52f433319 Mon Sep 17 00:00:00 2001 From: Gabriel Horner Date: Fri, 19 Jan 2024 13:54:02 -0500 Subject: [PATCH 12/23] fix: handle errors thrown by comlink instead of causing another error publishing's web worker threw an error and was causing a secondary error since data was a map while `[e payload]` expected a vec --- src/main/frontend/handler/worker.cljs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main/frontend/handler/worker.cljs b/src/main/frontend/handler/worker.cljs index 7746dd9549..1459cbcc63 100644 --- a/src/main/frontend/handler/worker.cljs +++ b/src/main/frontend/handler/worker.cljs @@ -46,5 +46,11 @@ (fn [event] (let [data (.-data event)] (when-not (= (.-type data) "RAW") - (let [[e payload] (bean/->clj data)] - (handle (keyword e) wrapped-worker payload))))))) + ;; Log thrown exceptions from comlink + ;; https://github.com/GoogleChromeLabs/comlink/blob/dffe9050f63b1b39f30213adeb1dd4b9ed7d2594/src/comlink.ts#L223-L236 + (if (and (= "HANDLER" (.-type data)) (= "throw" (.-name data))) + (if (.-isError (.-value data)) + (js/console.error "Unexpected webworker error:" (-> data bean/->clj (get-in [:value :value]))) + (js/console.error "Unexpected webworker error:" data)) + (let [[e payload] (bean/->clj data)] + (handle (keyword e) wrapped-worker payload)))))))) From 4ad1fd7dac4f089c30d572d780b6605c3ff1f092 Mon Sep 17 00:00:00 2001 From: Tienson Qin Date: Sat, 20 Jan 2024 05:09:07 +0800 Subject: [PATCH 13/23] fix: download rtc graphs --- src/main/frontend/db_worker.cljs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/frontend/db_worker.cljs b/src/main/frontend/db_worker.cljs index 1c297dd2aa..5ea290311d 100644 --- a/src/main/frontend/db_worker.cljs +++ b/src/main/frontend/db_worker.cljs @@ -109,9 +109,7 @@ #js {:$addr addr :$content (pr-str data)}) addr+data-seq)] - ;; async write so that UI can be refreshed earlier - (async/go - (upsert-addr-content! repo data delete-addrs)))) + (upsert-addr-content! repo data delete-addrs))) (-restore [_ addr] (restore-data-from-addr repo addr)))) @@ -339,7 +337,7 @@ [_this repo] ( Date: Sat, 20 Jan 2024 05:43:55 +0800 Subject: [PATCH 14/23] Remove unused check for publishing --- src/main/frontend/publishing.cljs | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/main/frontend/publishing.cljs b/src/main/frontend/publishing.cljs index 528b49ed1f..52c8bb8fe1 100644 --- a/src/main/frontend/publishing.cljs +++ b/src/main/frontend/publishing.cljs @@ -65,15 +65,11 @@ (state/set-db-restoring! true) - (when-not (db/entity :db/transacted?) - (let [data (unescape-html data) - db (db/string->db data) - datoms (d/datoms db :eavt)] - (db/transact! repo - (conj (vec datoms) - {:db/ident :db/transacted? :db/transacted? true}) - {:init-db? true - :new-graph? true}))) + (let [data (unescape-html data) + db (db/string->db data) + datoms (d/datoms db :eavt)] + (db/transact! repo datoms {:init-db? true + :new-graph? true})) (state/set-db-restoring! false) From 760a9f8c25fe27ae6e3a5c3674e5e7c945f13d4a Mon Sep 17 00:00:00 2001 From: Tienson Qin Date: Sun, 21 Jan 2024 14:50:29 +0800 Subject: [PATCH 15/23] fix: redirect to all pages for publishing graphs --- src/main/frontend/handler/repo.cljs | 3 ++- src/main/frontend/publishing.cljs | 24 +++++++++--------------- 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/src/main/frontend/handler/repo.cljs b/src/main/frontend/handler/repo.cljs index 5053546252..448db3bd57 100644 --- a/src/main/frontend/handler/repo.cljs +++ b/src/main/frontend/handler/repo.cljs @@ -418,7 +418,8 @@ (global-config-handler/restore-global-config!)) ;; Don't have to unlisten the old listener, as it will be destroyed with the conn (ui-handler/add-style-if-exists!) - (state/set-db-restoring! false))) + (when-not config/publishing? + (state/set-db-restoring! false)))) (defn rebuild-index! [url] diff --git a/src/main/frontend/publishing.cljs b/src/main/frontend/publishing.cljs index 52c8bb8fe1..a26f4fe387 100644 --- a/src/main/frontend/publishing.cljs +++ b/src/main/frontend/publishing.cljs @@ -59,21 +59,14 @@ (when-let [data js/window.logseq_db] (let [repo (-> @state/state :config keys first)] (state/set-current-repo! repo) - (p/do! - - (repo-handler/restore-and-setup-repo! repo) - - (state/set-db-restoring! true) - - (let [data (unescape-html data) - db (db/string->db data) - datoms (d/datoms db :eavt)] - (db/transact! repo datoms {:init-db? true - :new-graph? true})) - - (state/set-db-restoring! false) - - (ui-handler/re-render-root!))))) + (p/let [_ (repo-handler/restore-and-setup-repo! repo) + _ (let [data (unescape-html data) + db (db/string->db data) + datoms (d/datoms db :eavt)] + (db/transact! repo datoms {:init-db? true + :new-graph? true}))] + (state/set-db-restoring! false) + (ui-handler/re-render-root!))))) (defn restore-state! [] @@ -117,6 +110,7 @@ (events/run!) (p/do! (db-browser/start-db-worker!) + (state/set-db-restoring! true) (start) (restore-from-transit-str!))) From e571c571ec33e7a07da11fae8844606378c3969a Mon Sep 17 00:00:00 2001 From: Tienson Qin Date: Sun, 21 Jan 2024 18:15:44 +0800 Subject: [PATCH 16/23] wip: export refactor 1. Move fns to worker 2. Don't rely on :block/file, use db blocks to build page content --- src/main/frontend/components/export.cljs | 4 +- src/main/frontend/components/file.cljs | 8 +- src/main/frontend/db_worker.cljs | 19 + src/main/frontend/handler/export.cljs | 369 ++++--------------- src/main/frontend/handler/export/common.cljs | 50 ++- src/main/frontend/handler/export/opml.cljs | 23 +- src/main/frontend/handler/export/text.cljs | 21 +- src/main/frontend/handler/whiteboard.cljs | 28 +- src/main/frontend/worker/export.cljs | 68 ++++ src/test/frontend/handler/export_test.cljs | 95 +++-- 10 files changed, 254 insertions(+), 431 deletions(-) create mode 100644 src/main/frontend/worker/export.cljs diff --git a/src/main/frontend/components/export.cljs b/src/main/frontend/components/export.cljs index 3d676c58c8..35c8c81b44 100644 --- a/src/main/frontend/components/export.cljs +++ b/src/main/frontend/components/export.cljs @@ -22,10 +22,10 @@ [:h1.title (t :export)] [:ul.mr-1 [:li.mb-4 - [:a.font-medium {:on-click #(export/export-repo-as-edn-v2! current-repo)} + [:a.font-medium {:on-click #(export/export-repo-as-edn! current-repo)} (t :export-edn)]] [:li.mb-4 - [:a.font-medium {:on-click #(export/export-repo-as-json-v2! current-repo)} + [:a.font-medium {:on-click #(export/export-repo-as-json! current-repo)} (t :export-json)]] (when (config/db-based-graph? current-repo) [:li.mb-4 diff --git a/src/main/frontend/components/file.cljs b/src/main/frontend/components/file.cljs index 5603029934..cb94ba9599 100644 --- a/src/main/frontend/components/file.cljs +++ b/src/main/frontend/components/file.cljs @@ -57,13 +57,7 @@ (if (or (nil? modified-at) (zero? modified-at)) (t :file/no-data) (date/get-date-time-string - (t/to-default-time-zone (tc/to-date-time modified-at))))]]) - - (when-not mobile? - [:td [:a.text-sm - {:on-click (fn [_e] - (export-handler/download-file! file))} - [:span (t :download)]]])]))]]))) + (t/to-default-time-zone (tc/to-date-time modified-at))))]])]))]]))) (rum/defc files [] diff --git a/src/main/frontend/db_worker.cljs b/src/main/frontend/db_worker.cljs index 5ea290311d..7e5ab7c957 100644 --- a/src/main/frontend/db_worker.cljs +++ b/src/main/frontend/db_worker.cljs @@ -15,6 +15,7 @@ [logseq.db.sqlite.util :as sqlite-util] [frontend.worker.state :as worker-state] [frontend.worker.file :as file] + [frontend.worker.export :as worker-export] [logseq.db :as ldb] [frontend.worker.rtc.op-mem-layer :as op-mem-layer] [frontend.worker.rtc.db-listener :as rtc-db-listener] @@ -405,6 +406,24 @@ (worker-state/set-new-state! new-state) nil)) + ;; Export + (block->content + [this repo block-uuid-or-page-name tree->file-opts context] + (when-let [conn (worker-state/get-datascript-conn repo)] + (worker-export/block->content repo @conn block-uuid-or-page-name + (edn/read-string tree->file-opts) + (edn/read-string context)))) + + (get-all-pages + [this repo] + (when-let [conn (worker-state/get-datascript-conn repo)] + (bean/->js (worker-export/get-all-pages repo @conn)))) + + (get-all-page->content + [this repo] + (when-let [conn (worker-state/get-datascript-conn repo)] + (bean/->js (worker-export/get-all-page->content repo @conn)))) + ;; RTC (rtc-start [this repo token] diff --git a/src/main/frontend/handler/export.cljs b/src/main/frontend/handler/export.cljs index e528614953..df7ecbd283 100644 --- a/src/main/frontend/handler/export.cljs +++ b/src/main/frontend/handler/export.cljs @@ -5,74 +5,24 @@ [clojure.set :as s] [clojure.string :as string] [clojure.walk :as walk] - [datascript.core :as d] [frontend.config :as config] [frontend.db :as db] [frontend.extensions.zip :as zip] [frontend.external.roam-export :as roam-export] - [frontend.format.mldoc :as mldoc] [frontend.handler.notification :as notification] [frontend.mobile.util :as mobile-util] - [frontend.modules.file.core :as outliner-file] - [frontend.modules.outliner.tree :as outliner-tree] [logseq.publishing.html :as publish-html] [frontend.state :as state] [frontend.util :as util] - [frontend.handler.property.file :as property-file] [goog.dom :as gdom] [lambdaisland.glogi :as log] - [logseq.graph-parser.property :as gp-property] - [logseq.common.util.block-ref :as block-ref] - [logseq.common.util.page-ref :as page-ref] [promesa.core :as p] - [frontend.persist-db :as persist-db]) + [frontend.persist-db :as persist-db] + [frontend.persist-db.browser :as db-browser] + [cljs-bean.core :as bean]) (:import [goog.string StringBuffer])) -(defn- get-page-content - [repo page] - (outliner-file/tree->file-content - (outliner-tree/blocks->vec-tree - (db/get-page-blocks-no-cache repo page) page) {:init-level 1})) - -(defn- get-file-content - [repo file-path] - (if-let [page-name - (ffirst (d/q '[:find ?pn - :in $ ?path - :where - [?p :block/file ?f] - [?p :block/name ?pn] - [?f :file/path ?path]] - (db/get-db repo) file-path))] - (get-page-content repo page-name) - (ffirst - (d/q '[:find ?content - :in $ ?path - :where - [?f :file/path ?path] - [?f :file/content ?content]] - (db/get-db repo) file-path)))) - -(defn- get-blocks-contents - [repo root-block-uuid] - (-> - (db/get-block-and-children repo root-block-uuid) - (outliner-tree/blocks->vec-tree (str root-block-uuid)) - (outliner-file/tree->file-content {:init-level 1}))) - -(defn download-file! - [file-path] - (when-let [repo (state/get-current-repo)] - (when-let [content (get-file-content repo file-path)] - (let [data (js/Blob. ["\ufeff" (array content)] ; prepend BOM - (clj->js {:type "text/plain;charset=utf-8,"})) - anchor (gdom/getElement "download") - url (js/window.URL.createObjectURL data)] - (.setAttribute anchor "href" url) - (.setAttribute anchor "download" file-path) - (.click anchor))))) - (defn download-repo-as-html! "download public pages as html" [repo] @@ -98,28 +48,21 @@ (.setAttribute anchor "download" "index.html") (.click anchor)))))) -(defn- get-file-contents - ([repo] - (get-file-contents repo {:init-level 1})) - ([repo file-opts] - (let [db (db/get-db repo)] - (->> (d/q '[:find ?n ?fp - :where - [?e :block/file ?f] - [?f :file/path ?fp] - [?e :block/name ?n]] db) - (mapv (fn [[page-name file-path]] - [file-path - (outliner-file/tree->file-content - (outliner-tree/blocks->vec-tree - (db/get-page-blocks-no-cache page-name) page-name) - file-opts)])))))) +(defn- content + [repo] + (when-let [^object worker @db-browser/*worker] + (.get-all-page->content worker repo))) (defn export-repo-as-zip! [repo] - (let [files (get-file-contents repo) - [owner repo-name] (util/get-git-owner-and-repo repo) - repo-name (str owner "-" repo-name)] + (p/let [page->content (content repo) + [owner repo-name] (util/get-git-owner-and-repo repo) + repo-name (str owner "-" repo-name) + files (map (fn [[title content]] + [(str title "." (if (= :org (state/get-preferred-format)) + "org" + "md")) + content]) page->content)] (when (seq files) (p/let [zipfile (zip/make-zip repo-name files repo)] (when-let [anchor (gdom/getElement "download")] @@ -127,137 +70,6 @@ (.setAttribute anchor "download" (.-name zipfile)) (.click anchor)))))) -(defn- get-embed-pages-from-ast [ast] - (let [result (transient #{})] - (doseq [item ast] - (walk/prewalk (fn [i] - (cond - (and (vector? i) - (= "Macro" (first i)) - (= "embed" (some-> (:name (second i)) - (string/lower-case))) - (some-> (:arguments (second i)) - first - page-ref/page-ref?)) - (let [arguments (:arguments (second i)) - page-ref (first arguments) - page-name (-> page-ref - (subs 2) - (#(subs % 0 (- (count %) 2))) - (string/lower-case))] - (conj! result page-name) - i) - :else - i)) - item)) - (persistent! result))) - -(defn- get-embed-blocks-from-ast [ast] - (let [result (transient #{})] - (doseq [item ast] - (walk/prewalk (fn [i] - (cond - (and (vector? i) - (= "Macro" (first i)) - (= "embed" (some-> (:name (second i)) - (string/lower-case))) - (some-> (:arguments (second i)) - (first) - block-ref/string-block-ref?)) - (let [arguments (:arguments (second i)) - block-uuid (block-ref/get-string-block-ref-id (first arguments))] - (conj! result block-uuid) - i) - :else - i)) item)) - (persistent! result))) - -(defn- get-block-refs-from-ast [ast] - (let [result (transient #{})] - (doseq [item ast] - (walk/prewalk (fn [i] - (cond - (and (vector? i) - (= "Block_ref" (first i)) - (some? (second i))) - (let [block-uuid (second i)] - (conj! result block-uuid) - i) - :else - i)) item)) - (persistent! result))) - -(declare get-page-page&block-refs) -(defn get-block-page&block-refs [repo block-uuid embed-pages embed-blocks block-refs] - (let [block (db/entity [:block/uuid (uuid block-uuid)]) - block-content (get-blocks-contents repo (:block/uuid block)) - format (:block/format block) - ast (mldoc/->edn block-content format) - embed-pages-new (get-embed-pages-from-ast ast) - embed-blocks-new (get-embed-blocks-from-ast ast) - block-refs-new (get-block-refs-from-ast ast) - embed-pages-diff (s/difference embed-pages-new embed-pages) - embed-blocks-diff (s/difference embed-blocks-new embed-blocks) - block-refs-diff (s/difference block-refs-new block-refs) - embed-pages* (s/union embed-pages-new embed-pages) - embed-blocks* (s/union embed-blocks-new embed-blocks) - block-refs* (s/union block-refs-new block-refs) - [embed-pages-1 embed-blocks-1 block-refs-1] - (->> - (mapv (fn [page-name] - (let [{:keys [embed-pages embed-blocks block-refs]} - (get-page-page&block-refs repo page-name embed-pages* embed-blocks* block-refs*)] - [embed-pages embed-blocks block-refs])) embed-pages-diff) - (apply mapv vector) ; [[1 2 3] [4 5 6] [7 8 9]] -> [[1 4 7] [2 5 8] [3 6 9]] - (mapv #(apply s/union %))) - [embed-pages-2 embed-blocks-2 block-refs-2] - (->> - (mapv (fn [block-uuid] - (let [{:keys [embed-pages embed-blocks block-refs]} - (get-block-page&block-refs repo block-uuid embed-pages* embed-blocks* block-refs*)] - [embed-pages embed-blocks block-refs])) (s/union embed-blocks-diff block-refs-diff)) - (apply mapv vector) - (mapv #(apply s/union %)))] - {:embed-pages (s/union embed-pages-1 embed-pages-2 embed-pages*) - :embed-blocks (s/union embed-blocks-1 embed-blocks-2 embed-blocks*) - :block-refs (s/union block-refs-1 block-refs-2 block-refs*)})) - - -(defn get-page-page&block-refs [repo page-name embed-pages embed-blocks block-refs] - (let [page-name* (util/page-name-sanity-lc page-name) - page-content (get-page-content repo page-name*) - format (:block/format (db/entity [:block/name page-name*])) - ast (mldoc/->edn page-content format) - embed-pages-new (get-embed-pages-from-ast ast) - embed-blocks-new (get-embed-blocks-from-ast ast) - block-refs-new (get-block-refs-from-ast ast) - embed-pages-diff (s/difference embed-pages-new embed-pages) - embed-blocks-diff (s/difference embed-blocks-new embed-blocks) - block-refs-diff (s/difference block-refs-new block-refs) - embed-pages* (s/union embed-pages-new embed-pages) - embed-blocks* (s/union embed-blocks-new embed-blocks) - block-refs* (s/union block-refs-new block-refs) - [embed-pages-1 embed-blocks-1 block-refs-1] - (->> - (mapv (fn [page-name] - (let [{:keys [embed-pages embed-blocks block-refs]} - (get-page-page&block-refs repo page-name embed-pages* embed-blocks* block-refs*)] - [embed-pages embed-blocks block-refs])) embed-pages-diff) - (apply mapv vector) - (mapv #(apply s/union %))) - [embed-pages-2 embed-blocks-2 block-refs-2] - (->> - (mapv (fn [block-uuid] - (let [{:keys [embed-pages embed-blocks block-refs]} - (get-block-page&block-refs repo block-uuid embed-pages* embed-blocks* block-refs*)] - [embed-pages embed-blocks block-refs])) (s/union embed-blocks-diff block-refs-diff)) - (apply mapv vector) - (mapv #(apply s/union %)))] - {:embed-pages (s/union embed-pages-1 embed-pages-2 embed-pages*) - :embed-blocks (s/union embed-blocks-1 embed-blocks-2 embed-blocks*) - :block-refs (s/union block-refs-1 block-refs-2 block-refs*)})) - - (defn- export-file-on-mobile [data path] (p/catch (.writeFile Filesystem (clj->js {:path path @@ -294,56 +106,26 @@ x)) vec-tree)) -(defn- safe-keywordize - [block] - (update block :block/properties - (fn [properties] - (when (seq properties) - (->> (filter (fn [[k _v]] - (gp-property/valid-property-name? (str k))) properties) - (into {})))))) +(defn- > (d/q '[:find (pull ?b [*]) - :in $ - :where - [?b :block/original-name] - [?b :block/name]] db) - - (map (fn [[{:block/keys [name] :as page}]] - (let [whiteboard? (contains? (set (:block/type page)) "whiteboard") - blocks (db/get-page-blocks-no-cache - (state/get-current-repo) - name - {:transform? false}) - blocks' (if whiteboard? - blocks - (map (fn [b] - (let [b' (if (seq (:block/properties b)) - (update b :block/content - (fn [content] - (property-file/remove-properties-when-file-based - repo (:block/format b) content))) - b)] - (safe-keywordize b'))) blocks)) - children (if whiteboard? - blocks' - (outliner-tree/blocks->vec-tree blocks' name)) - page' (safe-keywordize page)] - (assoc page' :block/children children)))) - (nested-select-keys - [:block/id - :block/type - :block/page-name - :block/properties - :block/format - :block/children - :block/content - :block/created-at - :block/updated-at]))}) +(defn- (string/replace repo config/local-db-prefix "") @@ -351,15 +133,15 @@ (str "_" (quot (util/time-ms) 1000)) (str "." (string/lower-case (name extension))))) -(defn- export-repo-as-edn-str [repo] - (when-let [db (db/get-db repo)] +(defn- > edn-str js/encodeURIComponent (str "data:text/edn;charset=utf-8,")) @@ -380,23 +162,22 @@ x)) vec-tree)) -(defn export-repo-as-json-v2! +(defn export-repo-as-json! [repo] - (when-let [db (db/get-db repo)] - (let [json-str - (-> (blocks repo db) - nested-update-id - clj->js - js/JSON.stringify) + (p/let [result ( result + nested-update-id + clj->js + js/JSON.stringify) filename (file-name repo :json) data-str (str "data:text/json;charset=utf-8," (js/encodeURIComponent json-str))] - (if (mobile-util/native-platform?) - (export-file-on-mobile json-str filename) - (when-let [anchor (gdom/getElement "download-as-json-v2")] - (.setAttribute anchor "href" data-str) - (.setAttribute anchor "download" filename) - (.click anchor)))))) + (if (mobile-util/native-platform?) + (export-file-on-mobile json-str filename) + (when-let [anchor (gdom/getElement "download-as-json-v2")] + (.setAttribute anchor "href" data-str) + (.setAttribute anchor "download" filename) + (.click anchor))))) (defn export-repo-as-sqlite-db! [repo] @@ -415,39 +196,25 @@ ;; https://roamresearch.com/#/app/help/page/Nxz8u0vXU ;; export to roam json according to above spec -(defn- roam-json [db] - (->> (d/q '[:find (pull ?b [*]) - :in $ - :where - [?b :block/file] - [?b :block/original-name] - [?b :block/name]] db) - - (map (fn [[{:block/keys [name] :as page}]] - (assoc page - :block/children - (outliner-tree/blocks->vec-tree - (db/get-page-blocks-no-cache - (state/get-current-repo) - name - {:transform? false}) name)))) - - (roam-export/traverse - [:page/title - :block/string - :block/uid - :block/children]))) +(defn- (roam-json db) - clj->js - js/JSON.stringify) + (p/let [data ( data + bean/->js + js/JSON.stringify) data-str (str "data:text/json;charset=utf-8," (js/encodeURIComponent json-str))] - (when-let [anchor (gdom/getElement "download-as-roam-json")] - (.setAttribute anchor "href" data-str) - (.setAttribute anchor "download" (file-name (str repo "_roam") :json)) - (.click anchor))))) + (when-let [anchor (gdom/getElement "download-as-roam-json")] + (.setAttribute anchor "href" data-str) + (.setAttribute anchor "download" (file-name (str repo "_roam") :json)) + (.click anchor)))) diff --git a/src/main/frontend/handler/export/common.cljs b/src/main/frontend/handler/export/common.cljs index e4017ad4f4..6f8988e608 100644 --- a/src/main/frontend/handler/export/common.cljs +++ b/src/main/frontend/handler/export/common.cljs @@ -5,7 +5,6 @@ (:refer-clojure :exclude [map filter mapcat concat remove]) (:require [cljs.core.match :refer [match]] [clojure.string :as string] - [datascript.core :as d] [frontend.db :as db] [frontend.format.mldoc :as mldoc] [frontend.modules.file.core :as outliner-file] @@ -15,7 +14,9 @@ [logseq.common.util :as common-util] [frontend.handler.property.util :as pu] [malli.core :as m] - [malli.util :as mu])) + [malli.util :as mu] + [frontend.db.async :as db-async] + [promesa.core :as p])) ;;; TODO: split frontend.handler.export.text related states (def ^:dynamic *state* @@ -179,38 +180,33 @@ ast-content))) inline-coll))) -(defn- get-file-contents +(defn- > (d/q '[:find ?fp - :where - [?e :block/file ?f] - [?f :file/path ?fp]] db) - (mapv (fn [[file-path]] - [file-path - (db/get-file file-path)]))))) + (db-async/> md-files - (mapv (fn [[path content]] {:path path :content content - :names (d/q '[:find [?n ?n2] - :in $ ?p - :where [?e :file/path ?p] - [?e2 :block/file ?e] - [?e2 :block/name ?n] - [?e2 :block/original-name ?n2]] db path) - :format (common-util/get-format path)}))))) + (mapv (fn [[page-title path content]] + {:path path + :content content + :title page-title + :format (common-util/get-format path)}))))) ;;; utils (ends) diff --git a/src/main/frontend/handler/export/opml.cljs b/src/main/frontend/handler/export/opml.cljs index 1562649737..56629ddbf2 100644 --- a/src/main/frontend/handler/export/opml.cljs +++ b/src/main/frontend/handler/export/opml.cljs @@ -450,21 +450,22 @@ "options see also `export-blocks-as-opml`" [files options] (mapv - (fn [{:keys [path content names format]}] - (when (first names) + (fn [{:keys [path content title format]}] + (when title (util/profile (print-str :export-files-as-opml path) - [path (export-helper content format options :title (first names))]))) + [path (export-helper content format options :title title)]))) files)) (defn export-repo-as-opml! [repo] - (when-let [files (common/get-file-contents-with-suffix repo)] - (let [files (export-files-as-opml files nil) - zip-file-name (str repo "_opml_" (quot (util/time-ms) 1000))] - (p/let [zipfile (zip/make-zip zip-file-name files repo)] - (when-let [anchor (gdom/getElement "export-as-opml")] - (.setAttribute anchor "href" (js/window.URL.createObjectURL zipfile)) - (.setAttribute anchor "download" (.-name zipfile)) - (.click anchor)))))) + (p/let [files (common/clj-keywordize [obj] @@ -255,39 +254,18 @@ blocks (:block/_page react-page)] (whiteboard-clj->tldr react-page blocks))) -(defn- get-whiteboard-blocks - "Given a page, return all the logseq blocks (exclude all shapes)" - [page-name] - (let [blocks (model/get-page-blocks-no-cache page-name)] - (remove pu/shape-block? blocks))) - -(defn- get-last-root-block - "Get the last root Logseq block in the page. Main purpose is to calculate the new :block/left id" - [page-name] - (let [page-id (:db/id (model/get-page page-name)) - blocks (get-whiteboard-blocks page-name) - root-blocks (filter (fn [block] (= page-id (:db/id (:block/parent block)))) blocks) - root-block-left-ids (->> root-blocks - (map (fn [block] (get-in block [:block/left :db/id] nil))) - (remove nil?) - (set)) - blocks-with-no-next (remove #(root-block-left-ids (:db/id %)) root-blocks)] - (when (seq blocks-with-no-next) (first blocks-with-no-next)))) - (defn content + "Converts a block including its children (recursively) to plain-text." + [repo db root-block-uuid-or-page-name tree->file-opts context] + (let [root-block-uuid (or + (and (uuid? root-block-uuid-or-page-name) root-block-uuid-or-page-name) + (:block/uuid (d/entity db [:block/name (common-util/page-name-sanity-lc + root-block-uuid-or-page-name)]))) + init-level (or (:init-level tree->file-opts) + (if (uuid? root-block-uuid-or-page-name) 1 0)) + blocks (ldb/get-block-and-children repo db root-block-uuid) + tree (otree/blocks->vec-tree repo db blocks (str root-block-uuid))] + (worker-file/tree->file-content repo db tree + (assoc tree->file-opts :init-level init-level) + context))) + +(defn- safe-keywordize + [block] + (update block :block/properties + (fn [properties] + (when (seq properties) + (->> (filter (fn [[k _v]] + (gp-property/valid-property-name? (str k))) properties) + (into {})))))) + +(defn get-all-pages + "Get all pages and their children blocks." + [repo db] + (->> (d/q '[:find (pull ?b [*]) + :in $ + :where + [?b :block/original-name] + [?b :block/name]] db) + + (map (fn [[{:block/keys [name] :as page}]] + (let [whiteboard? (contains? (set (:block/type page)) "whiteboard") + blocks (ldb/get-page-blocks db name {}) + blocks' (if whiteboard? + blocks + (map (fn [b] + (let [b' (if (seq (:block/properties b)) + (update b :block/content + (fn [content] + (gp-property/remove-properties (:block/format b) content))) + b)] + (safe-keywordize b'))) blocks)) + children (if whiteboard? + blocks' + (otree/blocks->vec-tree repo db blocks' name)) + page' (safe-keywordize page)] + (assoc page' :block/children children)))))) + +(defn get-all-page->content + [repo db] + (->> (d/datoms db :avet :block/name) + (map (fn [d] + (let [e (d/entity db (:e d))] + [(:block/original-name e) + (block->content repo db (:v d) {} {})]))))) diff --git a/src/test/frontend/handler/export_test.cljs b/src/test/frontend/handler/export_test.cljs index c9e7cb6302..ea522a9d7f 100644 --- a/src/test/frontend/handler/export_test.cljs +++ b/src/test/frontend/handler/export_test.cljs @@ -15,11 +15,11 @@ (string/trim " - 1 id:: 61506710-484c-46d5-9983-3d1651ec02c8 - - 2 - id:: 61506711-5638-4899-ad78-187bdc2eaffc - - 3 - id:: 61506712-3007-407e-b6d3-d008a8dfa88b - - ((61506712-3007-407e-b6d3-d008a8dfa88b)) + - 2 + id:: 61506711-5638-4899-ad78-187bdc2eaffc + - 3 + id:: 61506712-3007-407e-b6d3-d008a8dfa88b + - ((61506712-3007-407e-b6d3-d008a8dfa88b)) - 4 id:: 61506712-b8a7-491d-ad84-b71651c3fdab")} {:file/path "pages/page2.md" @@ -27,7 +27,7 @@ (string/trim " - 3 id:: 97a00e55-48c3-48d8-b9ca-417b16e3a616 - - {{embed [[page1]]}}")}]) + - {{embed [[page1]]}}")}]) (use-fixtures :once {:before (fn [] @@ -44,18 +44,18 @@ {:remove-options #{:property}}))) (string/trim " - 1 - - 2 - - 3 - - 3") + - 2 + - 3 + - 3") "61506710-484c-46d5-9983-3d1651ec02c8" (string/trim " - 3 - - 1 - - 2 - - 3 - - 3 - - 4") + - 1 + - 2 + - 3 + - 3 + - 4") "97a00e55-48c3-48d8-b9ca-417b16e3a616")) @@ -65,25 +65,25 @@ (string/trim " - 1 id:: 61506710-484c-46d5-9983-3d1651ec02c8 - - 2 - id:: 61506711-5638-4899-ad78-187bdc2eaffc - - 3 - id:: 61506712-3007-407e-b6d3-d008a8dfa88b - - 3") + - 2 + id:: 61506711-5638-4899-ad78-187bdc2eaffc + - 3 + id:: 61506712-3007-407e-b6d3-d008a8dfa88b + - 3") "61506710-484c-46d5-9983-3d1651ec02c8" (string/trim " - 3 id:: 97a00e55-48c3-48d8-b9ca-417b16e3a616 - - 1 - id:: 61506710-484c-46d5-9983-3d1651ec02c8 - - 2 - id:: 61506711-5638-4899-ad78-187bdc2eaffc - - 3 - id:: 61506712-3007-407e-b6d3-d008a8dfa88b - - 3 - - 4 - id:: 61506712-b8a7-491d-ad84-b71651c3fdab") + - 1 + id:: 61506710-484c-46d5-9983-3d1651ec02c8 + - 2 + id:: 61506711-5638-4899-ad78-187bdc2eaffc + - 3 + id:: 61506712-3007-407e-b6d3-d008a8dfa88b + - 3 + - 4 + id:: 61506712-b8a7-491d-ad84-b71651c3fdab") "97a00e55-48c3-48d8-b9ca-417b16e3a616")) (deftest export-blocks-as-markdown-level Date: Sun, 21 Jan 2024 18:46:18 +0800 Subject: [PATCH 17/23] fix: export zip file --- src/main/frontend/handler/export.cljs | 26 ++----- src/main/frontend/handler/export/common.cljs | 72 +++++++++++--------- src/main/frontend/handler/export/opml.cljs | 4 +- src/main/frontend/handler/export/text.cljs | 2 +- 4 files changed, 47 insertions(+), 57 deletions(-) diff --git a/src/main/frontend/handler/export.cljs b/src/main/frontend/handler/export.cljs index df7ecbd283..7de3fa2114 100644 --- a/src/main/frontend/handler/export.cljs +++ b/src/main/frontend/handler/export.cljs @@ -18,8 +18,8 @@ [lambdaisland.glogi :as log] [promesa.core :as p] [frontend.persist-db :as persist-db] - [frontend.persist-db.browser :as db-browser] - [cljs-bean.core :as bean]) + [cljs-bean.core :as bean] + [frontend.handler.export.common :as export-common-handler]) (:import [goog.string StringBuffer])) @@ -48,21 +48,12 @@ (.setAttribute anchor "download" "index.html") (.click anchor)))))) -(defn- content - [repo] - (when-let [^object worker @db-browser/*worker] - (.get-all-page->content worker repo))) - (defn export-repo-as-zip! [repo] - (p/let [page->content (content repo) + (p/let [files (export-common-handler/content)] + files (map (fn [{:keys [path content]}] [path content]) files)] (when (seq files) (p/let [zipfile (zip/make-zip repo-name files repo)] (when-let [anchor (gdom/getElement "download")] @@ -106,14 +97,9 @@ x)) vec-tree)) -(defn- edn content format)))))) -(defn get-page-content +(defn content worker repo page-name nil + (pr-str {:export-bullet-indentation (state/get-export-bullet-indentation)}))))) + +(defn get-page-content + [page-name] + (let [repo (state/get-current-repo) + db (db/get-db repo)] + (worker-export/block->content repo db page-name + nil + {:export-bullet-indentation (state/get-export-bullet-indentation)}))) (defn- page-name->ast [page-name] (when-let [content (get-page-content page-name)] - (let [format :markdown] - (removev Properties-block-ast? - (mapv remove-block-ast-pos - (mldoc/->edn content format)))))) + (when content + (let [format :markdown] + (removev Properties-block-ast? + (mapv remove-block-ast-pos + (mldoc/->edn content format))))))) (defn- update-level-in-block-ast-coll [block-ast-coll origin-level] @@ -180,33 +190,27 @@ ast-content))) inline-coll))) -(defn- clj result)))) -(defn- content [repo] - (p/let [result (content worker repo)] + (bean/->clj result)))) -(defn > - md-files - (mapv (fn [[page-title path content]] - {:path path - :content content - :title page-title - :format (common-util/get-format path)}))))) + (p/let [page->content (content repo)] + (clojure.core/map (fn [[page-title content]] + {:path (str page-title ".md") + :content content + :title page-title + :format :markdown}) + page->content))) ;;; utils (ends) diff --git a/src/main/frontend/handler/export/opml.cljs b/src/main/frontend/handler/export/opml.cljs index 56629ddbf2..01743664a7 100644 --- a/src/main/frontend/handler/export/opml.cljs +++ b/src/main/frontend/handler/export/opml.cljs @@ -446,7 +446,7 @@ format (or (:block/format first-block) (state/get-preferred-format))] (export-helper content format options :title title)))) -(defn export-files-as-opml +(defn- export-files-as-opml "options see also `export-blocks-as-opml`" [files options] (mapv @@ -458,7 +458,7 @@ (defn export-repo-as-opml! [repo] - (p/let [files (common/ Date: Mon, 22 Jan 2024 09:47:48 +0800 Subject: [PATCH 18/23] fix: export issues --- src/main/frontend/db_worker.cljs | 4 +- src/main/frontend/extensions/zip.cljs | 15 +- src/main/frontend/handler/export.cljs | 32 +- src/main/frontend/handler/export/common.cljs | 11 +- src/main/frontend/handler/export/opml.cljs | 13 +- ...~3f773ed876c3d1b88bdcae855dbed02d3f2d4c62~ | 470 ++++++++++++++++++ src/main/frontend/handler/export/text.cljs | 8 +- 7 files changed, 516 insertions(+), 37 deletions(-) create mode 100644 src/main/frontend/handler/export/opml.cljs.~3f773ed876c3d1b88bdcae855dbed02d3f2d4c62~ diff --git a/src/main/frontend/db_worker.cljs b/src/main/frontend/db_worker.cljs index 7e5ab7c957..23d5fe2a02 100644 --- a/src/main/frontend/db_worker.cljs +++ b/src/main/frontend/db_worker.cljs @@ -417,12 +417,12 @@ (get-all-pages [this repo] (when-let [conn (worker-state/get-datascript-conn repo)] - (bean/->js (worker-export/get-all-pages repo @conn)))) + (pr-str (worker-export/get-all-pages repo @conn)))) (get-all-page->content [this repo] (when-let [conn (worker-state/get-datascript-conn repo)] - (bean/->js (worker-export/get-all-page->content repo @conn)))) + (pr-str (worker-export/get-all-page->content repo @conn)))) ;; RTC (rtc-start diff --git a/src/main/frontend/extensions/zip.cljs b/src/main/frontend/extensions/zip.cljs index 7264becb2f..4a24e3da1d 100644 --- a/src/main/frontend/extensions/zip.cljs +++ b/src/main/frontend/extensions/zip.cljs @@ -1,6 +1,5 @@ (ns frontend.extensions.zip (:require [clojure.string :as string] - [frontend.config :as config] ["jszip" :as JSZip] [promesa.core :as p])) @@ -11,15 +10,13 @@ (aset args "lastModified" last-modified) (js/File. blob-content file-name args))) -(defn make-zip [zip-filename file-name->content repo] +(defn make-zip [zip-filename file-name->content _repo] (let [zip (JSZip.) - zip-foldername (subs zip-filename (inc (string/last-index-of zip-filename "/"))) - src-filepath (string/replace repo config/local-db-prefix "") - folder (.folder zip zip-foldername)] + folder (.folder zip zip-filename)] (doseq [[file-name content] file-name->content] - (.file folder (-> file-name - (string/replace src-filepath "") - (string/replace #"^/+" "")) - content)) + (when-not (string/blank? content) + (.file folder (-> file-name + (string/replace #"^/+" "")) + content))) (p/let [zip-blob (.generateAsync zip #js {:type "blob"})] (make-file zip-blob (str zip-filename ".zip") {:type "application/zip"})))) diff --git a/src/main/frontend/handler/export.cljs b/src/main/frontend/handler/export.cljs index 7de3fa2114..713ad11dec 100644 --- a/src/main/frontend/handler/export.cljs +++ b/src/main/frontend/handler/export.cljs @@ -50,7 +50,7 @@ (defn export-repo-as-zip! [repo] - (p/let [files (export-common-handler/ (string/replace repo config/local-db-prefix "") @@ -121,23 +121,25 @@ (defn- > edn-str - js/encodeURIComponent - (str "data:text/edn;charset=utf-8,")) - filename (file-name repo :edn)] - (if (mobile-util/native-platform?) - (export-file-on-mobile edn-str filename) - (when-let [anchor (gdom/getElement "download-as-edn-v2")] - (.setAttribute anchor "href" data-str) - (.setAttribute anchor "download" filename) - (.click anchor)))))) + (p/let [edn-str (> edn-str + js/encodeURIComponent + (str "data:text/edn;charset=utf-8,")) + filename (file-name repo :edn)] + (if (mobile-util/native-platform?) + (export-file-on-mobile edn-str filename) + (when-let [anchor (gdom/getElement "download-as-edn-v2")] + (.setAttribute anchor "href" data-str) + (.setAttribute anchor "download" filename) + (.click anchor))))))) (defn- nested-update-id [vec-tree] diff --git a/src/main/frontend/handler/export/common.cljs b/src/main/frontend/handler/export/common.cljs index 13a534c3d0..3dc2a87b7a 100644 --- a/src/main/frontend/handler/export/common.cljs +++ b/src/main/frontend/handler/export/common.cljs @@ -16,7 +16,8 @@ [promesa.core :as p] [frontend.persist-db.browser :as db-browser] [cljs-bean.core :as bean] - [frontend.worker.export :as worker-export])) + [frontend.worker.export :as worker-export] + [clojure.edn :as edn])) ;;; TODO: split frontend.handler.export.text related states (def ^:dynamic *state* @@ -194,19 +195,19 @@ [repo] (when-let [^object worker @db-browser/*worker] (p/let [result (.get-all-pages worker repo)] - (bean/->clj result)))) + (edn/read-string result)))) (defn content [repo] (when-let [^object worker @db-browser/*worker] (p/let [result (.get-all-page->content worker repo)] - (bean/->clj result)))) + (edn/read-string result)))) (defn content (content repo)] (clojure.core/map (fn [[page-title content]] - {:path (str page-title ".md") + {:path (str page-title "."suffix) :content content :title page-title :format :markdown}) diff --git a/src/main/frontend/handler/export/opml.cljs b/src/main/frontend/handler/export/opml.cljs index 01743664a7..d462280810 100644 --- a/src/main/frontend/handler/export/opml.cljs +++ b/src/main/frontend/handler/export/opml.cljs @@ -15,7 +15,8 @@ [goog.dom :as gdom] [hiccups.runtime :as h] [frontend.format.mldoc :as mldoc] - [promesa.core :as p])) + [promesa.core :as p] + [frontend.config :as config])) ;;; *opml-state* (def ^:private ^:dynamic @@ -451,16 +452,20 @@ [files options] (mapv (fn [{:keys [path content title format]}] - (when title + (when (and title (not (string/blank? content))) (util/profile (print-str :export-files-as-opml path) [path (export-helper content format options :title title)]))) files)) (defn export-repo-as-opml! [repo] - (p/let [files (common/ repo + (string/replace config/db-version-prefix "") + (string/replace config/local-db-prefix "")) + files (->> (export-files-as-opml files nil) + (clojure.core/remove nil?)) zip-file-name (str repo "_opml_" (quot (util/time-ms) 1000))] (p/let [zipfile (zip/make-zip zip-file-name files repo)] (when-let [anchor (gdom/getElement "export-as-opml")] diff --git a/src/main/frontend/handler/export/opml.cljs.~3f773ed876c3d1b88bdcae855dbed02d3f2d4c62~ b/src/main/frontend/handler/export/opml.cljs.~3f773ed876c3d1b88bdcae855dbed02d3f2d4c62~ new file mode 100644 index 0000000000..1562649737 --- /dev/null +++ b/src/main/frontend/handler/export/opml.cljs.~3f773ed876c3d1b88bdcae855dbed02d3f2d4c62~ @@ -0,0 +1,470 @@ +(ns frontend.handler.export.opml + "export blocks/pages as opml" + (:refer-clojure :exclude [map filter mapcat concat remove newline]) + (:require ["/frontend/utils" :as utils] + [clojure.string :as string] + [clojure.zip :as z] + [frontend.db :as db] + [frontend.extensions.zip :as zip] + [frontend.handler.export.common :as common :refer + [*state* raw-text simple-asts->string space]] + [frontend.handler.export.zip-helper :refer [get-level goto-last + goto-level]] + [frontend.state :as state] + [frontend.util :as util :refer [concatv mapcatv removev]] + [goog.dom :as gdom] + [hiccups.runtime :as h] + [frontend.format.mldoc :as mldoc] + [promesa.core :as p])) + +;;; *opml-state* +(def ^:private ^:dynamic + *opml-state* + {:outside-em-symbol nil}) + +;;; utils for construct opml hiccup +;; - a +;; - b +;; - c +;; - d +;; [:outline +;; {:text "a"} +;; [:outline {:text "b"} [:outline {:text "c"}]] +;; [:outline {:text "d"}]] + +(defn- branch? [node] (= :outline (first node))) + +(defn- outline-hiccup-zip + [root] + (z/zipper branch? + rest + (fn [node children] (with-meta (apply vector :outline children) (meta node))) + root)) + +(def ^:private init-opml-body-hiccup + (z/down (outline-hiccup-zip [:outline [:placeholder]]))) + +(defn- goto-last-outline + "[:outline [:outline [:outline]]] + ^ + goto here" + + [loc] + (-> loc + goto-last + z/up)) + +(defn- add-same-level-outline-at-right + [loc attr-map] + {:pre [(map? attr-map)]} + (-> loc + (z/insert-right [:outline attr-map]) + z/right)) + +(defn- add-next-level-outline + [loc attr-map] + {:pre [(map? attr-map)]} + (-> loc + (z/append-child [:outline attr-map]) + goto-last-outline)) + +(defn- append-text-to-current-outline + [loc text] + (-> loc + z/down + (z/edit #(update % :text str text)) + z/up)) + +(defn- append-text-to-current-outline* + "if current-level = 0(it's just `init-opml-body-hiccup`), need to add a new outline item." + [loc text] + (if (pos? (get-level loc)) + (append-text-to-current-outline loc text) + ;; at root + (-> loc + z/down + (add-same-level-outline-at-right {:text nil}) + (append-text-to-current-outline text)))) + +(defn- zip-loc->opml + [hiccup title] + (let [[_ _ & body] hiccup] + (str + "\n" + (utils/prettifyXml + (h/render-html + [:opml {:version "2.0"} + [:head [:title title]] + (concatv [:body] body)]))))) + +;;; utils for construct opml hiccup (ends) + +;;; block/inline-ast -> hiccup & simple-ast + +(declare inline-ast->simple-ast + block-ast->hiccup) + +(defn- emphasis-wrap-with + [inline-coll em-symbol] + (binding [*opml-state* (assoc *opml-state* :outside-em-symbol (first em-symbol))] + (concatv [(raw-text em-symbol)] + (mapcatv inline-ast->simple-ast inline-coll) + [(raw-text em-symbol)]))) + +(defn- inline-emphasis + [[[type] inline-coll]] + (let [outside-em-symbol (:outside-em-symbol *opml-state*)] + (case type + "Bold" + (emphasis-wrap-with + inline-coll (if (= outside-em-symbol "*") "__" "**")) + "Italic" + (emphasis-wrap-with + inline-coll (if (= outside-em-symbol "*") "_" "*")) + "Underline" + (binding [*opml-state* (assoc *opml-state* :outside-em-symbol outside-em-symbol)] + (mapcatv (fn [inline] (cons space (inline-ast->simple-ast inline))) inline-coll)) + "Strike_through" + (emphasis-wrap-with inline-coll "~~") + "Highlight" + (emphasis-wrap-with inline-coll "^^") + ;; else + (assert false (print-str :inline-emphasis type "is invalid"))))) + +;; FIXME: how to add newlines to opml text attr? +(defn- inline-break-line + [] + [space]) + +(defn- inline-link + [{full-text :full_text}] + [(raw-text full-text)]) + +(defn- inline-nested-link + [{content :content}] + [(raw-text content)]) + +(defn- inline-subscript + [inline-coll] + (concatv [(raw-text "_{")] + (mapcatv (fn [inline] (cons space (inline-ast->simple-ast inline))) inline-coll) + [(raw-text "}")])) + + +(defn- inline-superscript + [inline-coll] + (concatv [(raw-text "^{")] + (mapcatv (fn [inline] (cons space (inline-ast->simple-ast inline))) inline-coll) + [(raw-text "}")])) + +(defn- inline-footnote-reference + [{name :name}] + [(raw-text "[" name "]")]) + +(defn- inline-cookie + [ast-content] + [(raw-text + (case (first ast-content) + "Absolute" + (let [[_ current total] ast-content] + (str "[" current "/" total "]")) + "Percent" + (str "[" (second ast-content) "%]")))]) + +(defn- inline-latex-fragment + [ast-content] + (let [[type content] ast-content + wrapper (case type + "Inline" "$" + "Displayed" "$$")] + [space (raw-text (str wrapper content wrapper)) space])) + +(defn- inline-macro + [{:keys [name arguments]}] + (-> + (if (= name "cloze") + (string/join "," arguments) + (let [l (cond-> ["{{" name] + (pos? (count arguments)) (conj "(" (string/join "," arguments) ")") + true (conj "}}"))] + (string/join l))) + raw-text + vector)) + +(defn- inline-entity + [{unicode :unicode}] + [(raw-text unicode)]) + +(defn- inline-timestamp + [ast-content] + (let [[type timestamp-content] ast-content] + (-> (case type + "Scheduled" ["SCHEDULED: " (common/timestamp-to-string timestamp-content)] + "Deadline" ["DEADLINE: " (common/timestamp-to-string timestamp-content)] + "Date" [(common/timestamp-to-string timestamp-content)] + "Closed" ["CLOSED: " (common/timestamp-to-string timestamp-content)] + "Clock" ["CLOCK: " (common/timestamp-to-string (second timestamp-content))] + "Range" (let [{:keys [start stop]} timestamp-content] + [(str (common/timestamp-to-string start) "--" (common/timestamp-to-string stop))])) + string/join + raw-text + vector))) + +(defn- inline-email + [{:keys [local_part domain]}] + [(raw-text (str "<" local_part "@" domain ">"))]) + + +(defn- inline-ast->simple-ast + [inline] + (let [[ast-type ast-content] inline] + (case ast-type + "Emphasis" + (inline-emphasis ast-content) + ("Break_Line" "Hard_Break_Line") + (inline-break-line) + "Verbatim" + [(raw-text ast-content)] + "Code" + [(raw-text "`" ast-content "`")] + "Tag" + [(raw-text "#" (common/hashtag-value->string ast-content))] + "Spaces" ; what's this ast-type for ? + nil + "Plain" + [(raw-text ast-content)] + "Link" + (inline-link ast-content) + "Nested_link" + (inline-nested-link ast-content) + "Target" + [(raw-text (str "<<" ast-content ">>"))] + "Subscript" + (inline-subscript ast-content) + "Superscript" + (inline-superscript ast-content) + "Footnote_Reference" + (inline-footnote-reference ast-content) + "Cookie" + (inline-cookie ast-content) + "Latex_Fragment" + (inline-latex-fragment ast-content) + "Macro" + (inline-macro ast-content) + "Entity" + (inline-entity ast-content) + "Timestamp" + (inline-timestamp ast-content) + "Radio_Target" + [(raw-text (str "<<<" ast-content ">>>"))] + "Email" + (inline-email ast-content) + "Inline_Hiccup" + [(raw-text ast-content)] + "Inline_Html" + [(raw-text ast-content)] + ("Export_Snippet" "Inline_Source_Block") + nil + (assert false (print-str :inline-ast->simple-ast ast-type "not implemented yet"))))) + +(defn- block-paragraph + [loc inline-coll] + (-> loc + goto-last-outline + (append-text-to-current-outline* + (simple-asts->string + (cons space (mapcatv inline-ast->simple-ast inline-coll)))))) + +(defn- block-heading + [loc {:keys [title _tags marker level _numbering priority _anchor _meta _unordered _size]}] + (let [loc (goto-last-outline loc) + current-level (get-level loc) + title* (mapcatv inline-ast->simple-ast title) + marker* (and marker (raw-text marker)) + priority* (and priority (raw-text (common/priority->string priority))) + simple-asts (removev nil? (concatv [marker* space priority* space] title*)) + ;; remove leading spaces + simple-asts (drop-while #(= % space) simple-asts) + s (simple-asts->string simple-asts)] + (if (> level current-level) + (add-next-level-outline loc {:text s}) + (-> loc + (goto-level level) + z/rightmost + (add-same-level-outline-at-right {:text s}))))) + +(declare block-list) +(defn- block-list-item + [loc {:keys [content items]}] + (let [current-level (get-level loc) + ;; if current loc node is empty(= {}), + ;; the outline node is already created. + loc (if (empty? (second (z/node loc))) + loc + (add-same-level-outline-at-right loc {:text nil})) + loc* (reduce block-ast->hiccup loc content) + loc** (if (seq items) (block-list loc* items) loc*)] + (-> loc** + (goto-level current-level) + z/rightmost))) + +(defn- block-list + [loc list-items] + (reduce block-list-item (add-next-level-outline loc {}) list-items)) + +(defn- block-example + [loc str-coll] + (append-text-to-current-outline* loc (string/join " " str-coll))) + +(defn- block-src + [loc {:keys [_language lines]}] + (append-text-to-current-outline* loc (string/join " " lines))) + +(defn- block-quote + [loc block-ast-coll] + (reduce block-ast->hiccup loc block-ast-coll)) + +(defn- block-latex-env + [loc [name options content]] + (append-text-to-current-outline* + loc + (str "\\begin{" name "}" options "\n" + content "\n" + "\\end{" name "}"))) + +(defn- block-displayed-math + [loc s] + (append-text-to-current-outline* loc s)) + +(defn- block-footnote-definition + [loc [name inline-coll]] + (let [inline-simple-asts (mapcatv inline-ast->simple-ast inline-coll)] + (append-text-to-current-outline* + loc + (str "[^" name "]: " (simple-asts->string inline-simple-asts))))) + +(defn- block-ast->hiccup + [loc block-ast] + (let [[ast-type ast-content] block-ast] + (case ast-type + "Paragraph" + (block-paragraph loc ast-content) + "Paragraph_line" + (assert false "Paragraph_line is mldoc internal ast") + "Paragraph_Sep" + loc + "Heading" + (block-heading loc ast-content) + "List" + (block-list loc ast-content) + ("Directive" "Results" "Property_Drawer" "Export" "CommentBlock" "Custom") + loc + "Example" + (block-example loc ast-content) + "Src" + (block-src loc ast-content) + "Quote" + (block-quote loc ast-content) + "Latex_Fragment" + (append-text-to-current-outline* loc (simple-asts->string (inline-latex-fragment ast-content))) + "Latex_Environment" + (block-latex-env loc (rest block-ast)) + "Displayed_Math" + (block-displayed-math loc ast-content) + "Drawer" + loc + "Footnote_Definition" + (block-footnote-definition loc (rest block-ast)) + "Horizontal_Rule" + loc + "Table" + loc + "Comment" + loc + "Raw_Html" + loc + "Hiccup" + loc + (assert false (print-str :block-ast->simple-ast ast-type "not implemented yet"))))) + +;;; block/inline-ast -> hiccup (ends) + +;;; export fns +(defn- export-helper + [content format options & {:keys [title] :or {title "untitled"}}] + (let [remove-options (set (:remove-options options)) + other-options (:other-options options)] + (binding [*state* (merge *state* + {:export-options + {:remove-emphasis? (contains? remove-options :emphasis) + :remove-page-ref-brackets? (contains? remove-options :page-ref) + :remove-tags? (contains? remove-options :tag) + :keep-only-level<=N (:keep-only-level<=N other-options)}}) + *opml-state* *opml-state*] + (let [ast (mldoc/->edn content format) + ast (mapv common/remove-block-ast-pos ast) + ast (removev common/Properties-block-ast? ast) + keep-level<=n (get-in *state* [:export-options :keep-only-level<=N]) + ast (if (pos? keep-level<=n) + (common/keep-only-level<=n ast keep-level<=n) + ast) + ast* (common/replace-block&page-reference&embed ast) + ast** (if (= "no-indent" (get-in *state* [:export-options :indent-style])) + (mapv common/replace-Heading-with-Paragraph ast*) + ast*) + config-for-walk-block-ast (cond-> {} + (get-in *state* [:export-options :remove-emphasis?]) + (update :mapcat-fns-on-inline-ast conj common/remove-emphasis) + + (get-in *state* [:export-options :remove-page-ref-brackets?]) + (update :map-fns-on-inline-ast conj common/remove-page-ref-brackets) + + (get-in *state* [:export-options :remove-tags?]) + (update :mapcat-fns-on-inline-ast conj common/remove-tags)) + ast*** (if-not (empty? config-for-walk-block-ast) + (mapv (partial common/walk-block-ast config-for-walk-block-ast) ast**) + ast**) + hiccup (z/root (reduce block-ast->hiccup init-opml-body-hiccup ast***))] + (zip-loc->opml hiccup title))))) + +(defn export-blocks-as-opml + "options: see also `export-blocks-as-markdown`" + [repo root-block-uuids-or-page-name options] + {:pre [(or (coll? root-block-uuids-or-page-name) + (string? root-block-uuids-or-page-name))]} + (util/profile + :export-blocks-as-opml + (let [content + (if (string? root-block-uuids-or-page-name) + ;; page + (common/get-page-content root-block-uuids-or-page-name) + (common/root-block-uuids->content repo root-block-uuids-or-page-name)) + title (if (string? root-block-uuids-or-page-name) + root-block-uuids-or-page-name + "untitled") + first-block (db/entity [:block/uuid (first root-block-uuids-or-page-name)]) + format (or (:block/format first-block) (state/get-preferred-format))] + (export-helper content format options :title title)))) + +(defn export-files-as-opml + "options see also `export-blocks-as-opml`" + [files options] + (mapv + (fn [{:keys [path content names format]}] + (when (first names) + (util/profile (print-str :export-files-as-opml path) + [path (export-helper content format options :title (first names))]))) + files)) + +(defn export-repo-as-opml! + [repo] + (when-let [files (common/get-file-contents-with-suffix repo)] + (let [files (export-files-as-opml files nil) + zip-file-name (str repo "_opml_" (quot (util/time-ms) 1000))] + (p/let [zipfile (zip/make-zip zip-file-name files repo)] + (when-let [anchor (gdom/getElement "export-as-opml")] + (.setAttribute anchor "href" (js/window.URL.createObjectURL zipfile)) + (.setAttribute anchor "download" (.-name zipfile)) + (.click anchor)))))) + +;;; export fns (ends) diff --git a/src/main/frontend/handler/export/text.cljs b/src/main/frontend/handler/export/text.cljs index 195571fb16..9ec56bcc12 100644 --- a/src/main/frontend/handler/export/text.cljs +++ b/src/main/frontend/handler/export/text.cljs @@ -13,7 +13,8 @@ [goog.dom :as gdom] [frontend.format.mldoc :as mldoc] [malli.core :as m] - [promesa.core :as p])) + [promesa.core :as p] + [frontend.config :as config])) ;;; block-ast, inline-ast -> simple-ast @@ -504,9 +505,12 @@ (defn export-repo-as-markdown! "TODO: indent-style and remove-options" [repo] - (p/let [files (util/profile :get-file-content (common/ repo + (string/replace config/db-version-prefix "") + (string/replace config/local-db-prefix "")) zip-file-name (str repo "_markdown_" (quot (util/time-ms) 1000))] (p/let [zipfile (zip/make-zip zip-file-name files repo)] (when-let [anchor (gdom/getElement "export-as-markdown")] From 4698d8cfea92a7f52d2c914968241ba8a636dcf5 Mon Sep 17 00:00:00 2001 From: Tienson Qin Date: Mon, 22 Jan 2024 09:57:09 +0800 Subject: [PATCH 19/23] fix: don't export id property for db graphs --- src/main/frontend/handler/export/common.cljs | 1 - src/main/frontend/worker/file/core.cljs | 9 +++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/frontend/handler/export/common.cljs b/src/main/frontend/handler/export/common.cljs index 3dc2a87b7a..1a1392955f 100644 --- a/src/main/frontend/handler/export/common.cljs +++ b/src/main/frontend/handler/export/common.cljs @@ -15,7 +15,6 @@ [malli.util :as mu] [promesa.core :as p] [frontend.persist-db.browser :as db-browser] - [cljs-bean.core :as bean] [frontend.worker.export :as worker-export] [clojure.edn :as edn])) diff --git a/src/main/frontend/worker/file/core.cljs b/src/main/frontend/worker/file/core.cljs index c7a9ff4655..05c171cd18 100644 --- a/src/main/frontend/worker/file/core.cljs +++ b/src/main/frontend/worker/file/core.cljs @@ -7,7 +7,8 @@ [datascript.core :as d] [logseq.db :as ldb] [frontend.worker.date :as worker-date] - [frontend.worker.util :as worker-util])) + [frontend.worker.util :as worker-util] + [logseq.db.sqlite.util :as sqlite-util])) (defonce *writes (atom {})) (defonce *request-id (atom 0)) @@ -44,7 +45,8 @@ (defn transform-content [repo db {:block/keys [collapsed? format pre-block? content left page parent properties] :as b} level {:keys [heading-to-list?]} context] (let [block-ref-not-saved? (and (seq (:block/_refs (d/entity db (:db/id b)))) - (not (string/includes? content (str (:block/uuid b))))) + (not (string/includes? content (str (:block/uuid b)))) + (not (sqlite-util/db-based-graph? repo))) heading (:heading properties) markdown? (= :markdown format) content (or content "") @@ -58,8 +60,7 @@ (str content "\n")) :else - (let [ - ;; first block is a heading, Markdown users prefer to remove the `-` before the content + (let [;; first block is a heading, Markdown users prefer to remove the `-` before the content markdown-top-heading? (and markdown? (= parent page left) heading) From fce15fb2d602ed7a3e79fcceb578a49f49f6a3a6 Mon Sep 17 00:00:00 2001 From: Tienson Qin Date: Mon, 22 Jan 2024 10:02:27 +0800 Subject: [PATCH 20/23] chore: remove bak file --- ...~3f773ed876c3d1b88bdcae855dbed02d3f2d4c62~ | 470 ------------------ 1 file changed, 470 deletions(-) delete mode 100644 src/main/frontend/handler/export/opml.cljs.~3f773ed876c3d1b88bdcae855dbed02d3f2d4c62~ diff --git a/src/main/frontend/handler/export/opml.cljs.~3f773ed876c3d1b88bdcae855dbed02d3f2d4c62~ b/src/main/frontend/handler/export/opml.cljs.~3f773ed876c3d1b88bdcae855dbed02d3f2d4c62~ deleted file mode 100644 index 1562649737..0000000000 --- a/src/main/frontend/handler/export/opml.cljs.~3f773ed876c3d1b88bdcae855dbed02d3f2d4c62~ +++ /dev/null @@ -1,470 +0,0 @@ -(ns frontend.handler.export.opml - "export blocks/pages as opml" - (:refer-clojure :exclude [map filter mapcat concat remove newline]) - (:require ["/frontend/utils" :as utils] - [clojure.string :as string] - [clojure.zip :as z] - [frontend.db :as db] - [frontend.extensions.zip :as zip] - [frontend.handler.export.common :as common :refer - [*state* raw-text simple-asts->string space]] - [frontend.handler.export.zip-helper :refer [get-level goto-last - goto-level]] - [frontend.state :as state] - [frontend.util :as util :refer [concatv mapcatv removev]] - [goog.dom :as gdom] - [hiccups.runtime :as h] - [frontend.format.mldoc :as mldoc] - [promesa.core :as p])) - -;;; *opml-state* -(def ^:private ^:dynamic - *opml-state* - {:outside-em-symbol nil}) - -;;; utils for construct opml hiccup -;; - a -;; - b -;; - c -;; - d -;; [:outline -;; {:text "a"} -;; [:outline {:text "b"} [:outline {:text "c"}]] -;; [:outline {:text "d"}]] - -(defn- branch? [node] (= :outline (first node))) - -(defn- outline-hiccup-zip - [root] - (z/zipper branch? - rest - (fn [node children] (with-meta (apply vector :outline children) (meta node))) - root)) - -(def ^:private init-opml-body-hiccup - (z/down (outline-hiccup-zip [:outline [:placeholder]]))) - -(defn- goto-last-outline - "[:outline [:outline [:outline]]] - ^ - goto here" - - [loc] - (-> loc - goto-last - z/up)) - -(defn- add-same-level-outline-at-right - [loc attr-map] - {:pre [(map? attr-map)]} - (-> loc - (z/insert-right [:outline attr-map]) - z/right)) - -(defn- add-next-level-outline - [loc attr-map] - {:pre [(map? attr-map)]} - (-> loc - (z/append-child [:outline attr-map]) - goto-last-outline)) - -(defn- append-text-to-current-outline - [loc text] - (-> loc - z/down - (z/edit #(update % :text str text)) - z/up)) - -(defn- append-text-to-current-outline* - "if current-level = 0(it's just `init-opml-body-hiccup`), need to add a new outline item." - [loc text] - (if (pos? (get-level loc)) - (append-text-to-current-outline loc text) - ;; at root - (-> loc - z/down - (add-same-level-outline-at-right {:text nil}) - (append-text-to-current-outline text)))) - -(defn- zip-loc->opml - [hiccup title] - (let [[_ _ & body] hiccup] - (str - "\n" - (utils/prettifyXml - (h/render-html - [:opml {:version "2.0"} - [:head [:title title]] - (concatv [:body] body)]))))) - -;;; utils for construct opml hiccup (ends) - -;;; block/inline-ast -> hiccup & simple-ast - -(declare inline-ast->simple-ast - block-ast->hiccup) - -(defn- emphasis-wrap-with - [inline-coll em-symbol] - (binding [*opml-state* (assoc *opml-state* :outside-em-symbol (first em-symbol))] - (concatv [(raw-text em-symbol)] - (mapcatv inline-ast->simple-ast inline-coll) - [(raw-text em-symbol)]))) - -(defn- inline-emphasis - [[[type] inline-coll]] - (let [outside-em-symbol (:outside-em-symbol *opml-state*)] - (case type - "Bold" - (emphasis-wrap-with - inline-coll (if (= outside-em-symbol "*") "__" "**")) - "Italic" - (emphasis-wrap-with - inline-coll (if (= outside-em-symbol "*") "_" "*")) - "Underline" - (binding [*opml-state* (assoc *opml-state* :outside-em-symbol outside-em-symbol)] - (mapcatv (fn [inline] (cons space (inline-ast->simple-ast inline))) inline-coll)) - "Strike_through" - (emphasis-wrap-with inline-coll "~~") - "Highlight" - (emphasis-wrap-with inline-coll "^^") - ;; else - (assert false (print-str :inline-emphasis type "is invalid"))))) - -;; FIXME: how to add newlines to opml text attr? -(defn- inline-break-line - [] - [space]) - -(defn- inline-link - [{full-text :full_text}] - [(raw-text full-text)]) - -(defn- inline-nested-link - [{content :content}] - [(raw-text content)]) - -(defn- inline-subscript - [inline-coll] - (concatv [(raw-text "_{")] - (mapcatv (fn [inline] (cons space (inline-ast->simple-ast inline))) inline-coll) - [(raw-text "}")])) - - -(defn- inline-superscript - [inline-coll] - (concatv [(raw-text "^{")] - (mapcatv (fn [inline] (cons space (inline-ast->simple-ast inline))) inline-coll) - [(raw-text "}")])) - -(defn- inline-footnote-reference - [{name :name}] - [(raw-text "[" name "]")]) - -(defn- inline-cookie - [ast-content] - [(raw-text - (case (first ast-content) - "Absolute" - (let [[_ current total] ast-content] - (str "[" current "/" total "]")) - "Percent" - (str "[" (second ast-content) "%]")))]) - -(defn- inline-latex-fragment - [ast-content] - (let [[type content] ast-content - wrapper (case type - "Inline" "$" - "Displayed" "$$")] - [space (raw-text (str wrapper content wrapper)) space])) - -(defn- inline-macro - [{:keys [name arguments]}] - (-> - (if (= name "cloze") - (string/join "," arguments) - (let [l (cond-> ["{{" name] - (pos? (count arguments)) (conj "(" (string/join "," arguments) ")") - true (conj "}}"))] - (string/join l))) - raw-text - vector)) - -(defn- inline-entity - [{unicode :unicode}] - [(raw-text unicode)]) - -(defn- inline-timestamp - [ast-content] - (let [[type timestamp-content] ast-content] - (-> (case type - "Scheduled" ["SCHEDULED: " (common/timestamp-to-string timestamp-content)] - "Deadline" ["DEADLINE: " (common/timestamp-to-string timestamp-content)] - "Date" [(common/timestamp-to-string timestamp-content)] - "Closed" ["CLOSED: " (common/timestamp-to-string timestamp-content)] - "Clock" ["CLOCK: " (common/timestamp-to-string (second timestamp-content))] - "Range" (let [{:keys [start stop]} timestamp-content] - [(str (common/timestamp-to-string start) "--" (common/timestamp-to-string stop))])) - string/join - raw-text - vector))) - -(defn- inline-email - [{:keys [local_part domain]}] - [(raw-text (str "<" local_part "@" domain ">"))]) - - -(defn- inline-ast->simple-ast - [inline] - (let [[ast-type ast-content] inline] - (case ast-type - "Emphasis" - (inline-emphasis ast-content) - ("Break_Line" "Hard_Break_Line") - (inline-break-line) - "Verbatim" - [(raw-text ast-content)] - "Code" - [(raw-text "`" ast-content "`")] - "Tag" - [(raw-text "#" (common/hashtag-value->string ast-content))] - "Spaces" ; what's this ast-type for ? - nil - "Plain" - [(raw-text ast-content)] - "Link" - (inline-link ast-content) - "Nested_link" - (inline-nested-link ast-content) - "Target" - [(raw-text (str "<<" ast-content ">>"))] - "Subscript" - (inline-subscript ast-content) - "Superscript" - (inline-superscript ast-content) - "Footnote_Reference" - (inline-footnote-reference ast-content) - "Cookie" - (inline-cookie ast-content) - "Latex_Fragment" - (inline-latex-fragment ast-content) - "Macro" - (inline-macro ast-content) - "Entity" - (inline-entity ast-content) - "Timestamp" - (inline-timestamp ast-content) - "Radio_Target" - [(raw-text (str "<<<" ast-content ">>>"))] - "Email" - (inline-email ast-content) - "Inline_Hiccup" - [(raw-text ast-content)] - "Inline_Html" - [(raw-text ast-content)] - ("Export_Snippet" "Inline_Source_Block") - nil - (assert false (print-str :inline-ast->simple-ast ast-type "not implemented yet"))))) - -(defn- block-paragraph - [loc inline-coll] - (-> loc - goto-last-outline - (append-text-to-current-outline* - (simple-asts->string - (cons space (mapcatv inline-ast->simple-ast inline-coll)))))) - -(defn- block-heading - [loc {:keys [title _tags marker level _numbering priority _anchor _meta _unordered _size]}] - (let [loc (goto-last-outline loc) - current-level (get-level loc) - title* (mapcatv inline-ast->simple-ast title) - marker* (and marker (raw-text marker)) - priority* (and priority (raw-text (common/priority->string priority))) - simple-asts (removev nil? (concatv [marker* space priority* space] title*)) - ;; remove leading spaces - simple-asts (drop-while #(= % space) simple-asts) - s (simple-asts->string simple-asts)] - (if (> level current-level) - (add-next-level-outline loc {:text s}) - (-> loc - (goto-level level) - z/rightmost - (add-same-level-outline-at-right {:text s}))))) - -(declare block-list) -(defn- block-list-item - [loc {:keys [content items]}] - (let [current-level (get-level loc) - ;; if current loc node is empty(= {}), - ;; the outline node is already created. - loc (if (empty? (second (z/node loc))) - loc - (add-same-level-outline-at-right loc {:text nil})) - loc* (reduce block-ast->hiccup loc content) - loc** (if (seq items) (block-list loc* items) loc*)] - (-> loc** - (goto-level current-level) - z/rightmost))) - -(defn- block-list - [loc list-items] - (reduce block-list-item (add-next-level-outline loc {}) list-items)) - -(defn- block-example - [loc str-coll] - (append-text-to-current-outline* loc (string/join " " str-coll))) - -(defn- block-src - [loc {:keys [_language lines]}] - (append-text-to-current-outline* loc (string/join " " lines))) - -(defn- block-quote - [loc block-ast-coll] - (reduce block-ast->hiccup loc block-ast-coll)) - -(defn- block-latex-env - [loc [name options content]] - (append-text-to-current-outline* - loc - (str "\\begin{" name "}" options "\n" - content "\n" - "\\end{" name "}"))) - -(defn- block-displayed-math - [loc s] - (append-text-to-current-outline* loc s)) - -(defn- block-footnote-definition - [loc [name inline-coll]] - (let [inline-simple-asts (mapcatv inline-ast->simple-ast inline-coll)] - (append-text-to-current-outline* - loc - (str "[^" name "]: " (simple-asts->string inline-simple-asts))))) - -(defn- block-ast->hiccup - [loc block-ast] - (let [[ast-type ast-content] block-ast] - (case ast-type - "Paragraph" - (block-paragraph loc ast-content) - "Paragraph_line" - (assert false "Paragraph_line is mldoc internal ast") - "Paragraph_Sep" - loc - "Heading" - (block-heading loc ast-content) - "List" - (block-list loc ast-content) - ("Directive" "Results" "Property_Drawer" "Export" "CommentBlock" "Custom") - loc - "Example" - (block-example loc ast-content) - "Src" - (block-src loc ast-content) - "Quote" - (block-quote loc ast-content) - "Latex_Fragment" - (append-text-to-current-outline* loc (simple-asts->string (inline-latex-fragment ast-content))) - "Latex_Environment" - (block-latex-env loc (rest block-ast)) - "Displayed_Math" - (block-displayed-math loc ast-content) - "Drawer" - loc - "Footnote_Definition" - (block-footnote-definition loc (rest block-ast)) - "Horizontal_Rule" - loc - "Table" - loc - "Comment" - loc - "Raw_Html" - loc - "Hiccup" - loc - (assert false (print-str :block-ast->simple-ast ast-type "not implemented yet"))))) - -;;; block/inline-ast -> hiccup (ends) - -;;; export fns -(defn- export-helper - [content format options & {:keys [title] :or {title "untitled"}}] - (let [remove-options (set (:remove-options options)) - other-options (:other-options options)] - (binding [*state* (merge *state* - {:export-options - {:remove-emphasis? (contains? remove-options :emphasis) - :remove-page-ref-brackets? (contains? remove-options :page-ref) - :remove-tags? (contains? remove-options :tag) - :keep-only-level<=N (:keep-only-level<=N other-options)}}) - *opml-state* *opml-state*] - (let [ast (mldoc/->edn content format) - ast (mapv common/remove-block-ast-pos ast) - ast (removev common/Properties-block-ast? ast) - keep-level<=n (get-in *state* [:export-options :keep-only-level<=N]) - ast (if (pos? keep-level<=n) - (common/keep-only-level<=n ast keep-level<=n) - ast) - ast* (common/replace-block&page-reference&embed ast) - ast** (if (= "no-indent" (get-in *state* [:export-options :indent-style])) - (mapv common/replace-Heading-with-Paragraph ast*) - ast*) - config-for-walk-block-ast (cond-> {} - (get-in *state* [:export-options :remove-emphasis?]) - (update :mapcat-fns-on-inline-ast conj common/remove-emphasis) - - (get-in *state* [:export-options :remove-page-ref-brackets?]) - (update :map-fns-on-inline-ast conj common/remove-page-ref-brackets) - - (get-in *state* [:export-options :remove-tags?]) - (update :mapcat-fns-on-inline-ast conj common/remove-tags)) - ast*** (if-not (empty? config-for-walk-block-ast) - (mapv (partial common/walk-block-ast config-for-walk-block-ast) ast**) - ast**) - hiccup (z/root (reduce block-ast->hiccup init-opml-body-hiccup ast***))] - (zip-loc->opml hiccup title))))) - -(defn export-blocks-as-opml - "options: see also `export-blocks-as-markdown`" - [repo root-block-uuids-or-page-name options] - {:pre [(or (coll? root-block-uuids-or-page-name) - (string? root-block-uuids-or-page-name))]} - (util/profile - :export-blocks-as-opml - (let [content - (if (string? root-block-uuids-or-page-name) - ;; page - (common/get-page-content root-block-uuids-or-page-name) - (common/root-block-uuids->content repo root-block-uuids-or-page-name)) - title (if (string? root-block-uuids-or-page-name) - root-block-uuids-or-page-name - "untitled") - first-block (db/entity [:block/uuid (first root-block-uuids-or-page-name)]) - format (or (:block/format first-block) (state/get-preferred-format))] - (export-helper content format options :title title)))) - -(defn export-files-as-opml - "options see also `export-blocks-as-opml`" - [files options] - (mapv - (fn [{:keys [path content names format]}] - (when (first names) - (util/profile (print-str :export-files-as-opml path) - [path (export-helper content format options :title (first names))]))) - files)) - -(defn export-repo-as-opml! - [repo] - (when-let [files (common/get-file-contents-with-suffix repo)] - (let [files (export-files-as-opml files nil) - zip-file-name (str repo "_opml_" (quot (util/time-ms) 1000))] - (p/let [zipfile (zip/make-zip zip-file-name files repo)] - (when-let [anchor (gdom/getElement "export-as-opml")] - (.setAttribute anchor "href" (js/window.URL.createObjectURL zipfile)) - (.setAttribute anchor "download" (.-name zipfile)) - (.click anchor)))))) - -;;; export fns (ends) From c4f7494fcce7478506104006d67f5985ea76d673 Mon Sep 17 00:00:00 2001 From: Andelf Date: Mon, 22 Jan 2024 10:37:41 +0800 Subject: [PATCH 21/23] fix: bring back #10434 --- src/main/frontend/components/block.cljs | 1 - src/main/frontend/db/model.cljs | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/frontend/components/block.cljs b/src/main/frontend/components/block.cljs index 1c5ae62be0..3878a65035 100644 --- a/src/main/frontend/components/block.cljs +++ b/src/main/frontend/components/block.cljs @@ -547,7 +547,6 @@ All page-names are sanitized except page-name-in-block" [state config page-name-in-block page-name redirect-page-name page-entity contents-page? children html-export? label whiteboard-page?] (let [*hover? (::hover? state) - ;; FIXME: Bring back fix from https://github.com/logseq/logseq/pull/10434/commits/42f68ce32e7a035e6926bc2798d46843bbd70297 *mouse-down? (::mouse-down? state) tag? (:tag? config) breadcrumb? (:breadcrumb? config) diff --git a/src/main/frontend/db/model.cljs b/src/main/frontend/db/model.cljs index 9aa8c1f8b6..84ecb40446 100644 --- a/src/main/frontend/db/model.cljs +++ b/src/main/frontend/db/model.cljs @@ -620,7 +620,9 @@ independent of format as format specific heading characters are stripped" page-name' (nil? page-entity) - page-name + (if-let [journal-name (date/journal-title->custom-format page-name)] + (util/page-name-sanity-lc journal-name) + page-name) (page-empty-or-dummy? (state/get-current-repo) (:db/id page-entity)) (let [source-page (get-alias-source-page (state/get-current-repo) page-name')] From 8204c939774a60436631296939db23e9f6585a67 Mon Sep 17 00:00:00 2001 From: Tienson Qin Date: Mon, 22 Jan 2024 12:21:42 +0800 Subject: [PATCH 22/23] fix: outliner dep test --- deps/db/deps.edn | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/deps/db/deps.edn b/deps/db/deps.edn index 4ede836a3e..93166ec059 100644 --- a/deps/db/deps.edn +++ b/deps/db/deps.edn @@ -3,7 +3,8 @@ {datascript/datascript {:git/url "https://github.com/logseq/datascript" ;; fork :sha "21fc7880c7042fb1d9086135d162ea7a91681f89"} com.cognitect/transit-cljs {:mvn/version "0.8.280"} - logseq/common {:local/root "../common"}} + logseq/common {:local/root "../common"} + funcool/promesa {:mvn/version "4.0.2"}} :aliases {:clj-kondo From a9e8340aa57a33876bbda29b01e714d7151e5209 Mon Sep 17 00:00:00 2001 From: Tienson Qin Date: Mon, 22 Jan 2024 12:46:04 +0800 Subject: [PATCH 23/23] chore: remove debug --- src/main/frontend/db_worker.cljs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/frontend/db_worker.cljs b/src/main/frontend/db_worker.cljs index 23d5fe2a02..d66093ad50 100644 --- a/src/main/frontend/db_worker.cljs +++ b/src/main/frontend/db_worker.cljs @@ -155,7 +155,6 @@ [repo] (when-not (worker-state/get-sqlite-conn repo) (p/let [[db search-db] (get-db-and-search-db repo) - _ (prn :debug :db db :search-db search-db) storage (new-sqlite-storage repo {})] (swap! *sqlite-conns assoc repo {:db db :search search-db})