diff --git a/ios/App/App/Info.plist b/ios/App/App/Info.plist index 5d61338b2..fe610ce5c 100644 --- a/ios/App/App/Info.plist +++ b/ios/App/App/Info.plist @@ -107,5 +107,7 @@ UIViewControllerBasedStatusBarAppearance + ITSAppUsesNonExemptEncryption + diff --git a/src/main/electron/listener.cljs b/src/main/electron/listener.cljs index 86e18ba3c..d389609d8 100644 --- a/src/main/electron/listener.cljs +++ b/src/main/electron/listener.cljs @@ -158,10 +158,10 @@ (fn [args] (let [{:keys [url title content page append]} (bean/->clj args) insert-today? (get-in (state/get-config) - [:quick-capture-options :insert-today] + [:quick-capture-options :insert-today?] false) redirect-page? (get-in (state/get-config) - [:quick-capture-options :redirect-page] + [:quick-capture-options :redirect-page?] false) today-page (when (state/enable-journals?) (string/lower-case (date/today))) diff --git a/src/main/frontend/components/editor.cljs b/src/main/frontend/components/editor.cljs index 714b9d85b..a768994b7 100644 --- a/src/main/frontend/components/editor.cljs +++ b/src/main/frontend/components/editor.cljs @@ -76,9 +76,7 @@ (not (contains? #{"Date picker" "Template" "Deadline" "Scheduled" "Upload an image"} command))))] (editor-handler/insert-command! id command-steps format - {:restore? restore-slash?}) - (state/pub-event! [:instrument {:type :editor/command-triggered - :payload {:command command}}])))) + {:restore? restore-slash?})))) :class "black"})))) diff --git a/src/main/frontend/config.cljs b/src/main/frontend/config.cljs index 5afb226b7..64dca512c 100644 --- a/src/main/frontend/config.cljs +++ b/src/main/frontend/config.cljs @@ -112,7 +112,8 @@ ([input] (extname-of-supported? input [image-formats doc-formats audio-formats - video-formats markup-formats html-render-formats])) + video-formats markup-formats html-render-formats + (gp-config/text-formats)])) ([input formats] (when-let [input (some-> (cond-> input diff --git a/src/main/frontend/fs.cljs b/src/main/frontend/fs.cljs index 602f09f8b..6a0bf569e 100644 --- a/src/main/frontend/fs.cljs +++ b/src/main/frontend/fs.cljs @@ -82,13 +82,11 @@ (p/let [opts (assoc opts :error-handler (fn [error] - (state/pub-event! [:instrument {:type :write-file/failed - :payload {:fs (type fs-record) - :user-agent (when js/navigator js/navigator.userAgent) - :path path - :content-length (count content) - :error-str (str error) - :error error}}]))) + (state/pub-event! [:capture-error {:error error + :payload {:type :write-file/failed + :fs (type fs-record) + :user-agent (when js/navigator js/navigator.userAgent) + :content-length (count content)}}]))) _ (protocol/write-file! (get-fs dir) repo dir path content opts)] (when (= bfs-record fs-record) (db/set-file-last-modified-at! repo (config/get-file-path repo path) (js/Date.)))) diff --git a/src/main/frontend/fs/capacitor_fs.cljs b/src/main/frontend/fs/capacitor_fs.cljs index d39d7c8de..65ed2b3a7 100644 --- a/src/main/frontend/fs/capacitor_fs.cljs +++ b/src/main/frontend/fs/capacitor_fs.cljs @@ -229,9 +229,9 @@ :else (do - (state/pub-event! [:instrument {:type :error/ios-path-missing-slashes - ;; respect user's privacy - :path (gp-util/safe-subs path 10)}]) + (state/pub-event! [:capture-error {:error (js/Error. "ios path missing slashes") + :payload {:type :error/ios-path-missing-slashes + :path (gp-util/safe-subs (str path) 12)}}]) path)) path)) diff --git a/src/main/frontend/fs/sync.cljs b/src/main/frontend/fs/sync.cljs index 59a6bf233..b2c2afbd7 100644 --- a/src/main/frontend/fs/sync.cljs +++ b/src/main/frontend/fs/sync.cljs @@ -1782,7 +1782,9 @@ ;; add 2 simulated file-watcher events (>! ch (->FileChangeEvent "unlink" repo-dir (:old-path rename-event*) nil nil)) (>! ch (->FileChangeEvent "add" repo-dir (:new-path rename-event*) - {:mtime (tc/to-long (t/now))} "fake-checksum")) + {:mtime (tc/to-long (t/now)) + :size 1 ; add a fake size + } "fake-checksum")) (recur)) local-change (cond @@ -2023,11 +2025,6 @@ (chan 1)) (def full-sync-mult (async/mult full-sync-chan)) -(def stop-sync-chan - "offer `true` to this chan will stop current `SyncManager`" - (chan 1)) -(def stop-sync-mult (async/mult stop-sync-chan)) - (def remote->local-sync-chan "offer `true` to this chan will trigger a remote->local sync" (chan 1)) @@ -2659,7 +2656,7 @@ *txid ^:mutable state ^:mutable remote-change-chan ^:mutable *ws *stopped? *paused? ^:mutable ops-chan ;; control chans - private-full-sync-chan private-stop-sync-chan private-remote->local-sync-chan + private-full-sync-chan private-remote->local-sync-chan private-remote->local-full-sync-chan private-pause-resume-chan] Object (schedule [this next-state args reason] @@ -2694,30 +2691,30 @@ (set! ratelimit-local-changes-chan (remote-syncer local-changes-revised-chan)) (setup-local->remote! local->remote-syncer) (async/tap full-sync-mult private-full-sync-chan) - (async/tap stop-sync-mult private-stop-sync-chan) (async/tap remote->local-sync-mult private-remote->local-sync-chan) (async/tap remote->local-full-sync-mult private-remote->local-full-sync-chan) (async/tap pause-resume-mult private-pause-resume-chan) (go-loop [] - (let [{:keys [stop remote->local remote->local-full-sync local->remote-full-sync local->remote resume pause]} + (let [{:keys [remote->local remote->local-full-sync local->remote-full-sync local->remote resume pause stop]} (async/alt! - private-stop-sync-chan {:stop true} private-remote->local-full-sync-chan {:remote->local-full-sync true} private-remote->local-sync-chan {:remote->local true} private-full-sync-chan {:local->remote-full-sync true} private-pause-resume-chan ([v] (if v {:resume true} {:pause true})) remote-change-chan ([v] (println "remote change:" v) {:remote->local v}) ratelimit-local-changes-chan ([v] - (let [rest-v (util/drain-chan ratelimit-local-changes-chan) - vs (cons v rest-v)] - (println "local changes:" vs) - {:local->remote vs})) + (if (nil? v) + {:stop true} + (let [rest-v (util/drain-chan ratelimit-local-changes-chan) + vs (cons v rest-v)] + (println "local changes:" vs) + {:local->remote vs}))) (timeout (* 20 60 1000)) {:local->remote-full-sync true} :priority true)] (cond stop - (do (util/drain-chan ops-chan) - (>! ops-chan {:stop true})) + nil + remote->local-full-sync (do (util/drain-chan ops-chan) (>! ops-chan {:remote->local-full-sync true}) @@ -2772,8 +2769,9 @@ :data {:graph-uuid graph-uuid :epoch (tc/to-epoch (t/now))}}) (go-loop [] - (let [{:keys [resume]} (local remote->local-full-sync local->remote local->remote-full-sync] :as resume-state} (get @*resume-state graph-uuid)] (resume-state--reset graph-uuid) @@ -2795,6 +2793,11 @@ :resume-state resume-state :epoch (tc/to-epoch (t/now))}}) (local local->remote local->remote-full-sync remote->local-full-sync pause] :as result} (local (local {:remote remote->local} {:remote-changed remote->local})) @@ -2816,10 +2819,11 @@ (remote-full-sync-failed - :user-id user-uuid - :graph-uuid graph-uuid}}]) + (state/pub-event! [:capture-error {:error unknown + :payload {:type :sync/unknown + :event :local->remote-full-sync-failed + :user-id user-uuid + :graph-uuid graph-uuid}}]) (put-sync-event! {:event :local->remote-full-sync-failed :data {:graph-uuid graph-uuid :epoch (tc/to-epoch (t/now))}}) @@ -2877,18 +2881,18 @@ (.schedule this ::pause nil nil)) unknown (do - (state/pub-event! [:instrument {:type :sync/unknown - :payload {:event :remote->local-full-sync-failed - :graph-uuid graph-uuid - :user-id user-uuid - :error unknown}}]) + (state/pub-event! [:capture-error {:error unknown + :payload {:event :remote->local-full-sync-failed + :type :sync/unknown + :graph-uuid graph-uuid + :user-id user-uuid}}]) (put-sync-event! {:event :remote->local-full-sync-failed :data {:graph-uuid graph-uuid :exp unknown :epoch (tc/to-epoch (t/now))}}) (let [next-state (if (string/includes? (str (ex-cause unknown)) "404 Not Found") ;; TODO: this should never happen - ::pause + ::stop ;; if any other exception occurred, re-exec remote->local-full-sync ::remote->local-full-sync)] (.schedule this next-state nil nil))))))) @@ -2922,11 +2926,11 @@ (.schedule this ::pause nil nil)) unknown (do (prn "remote->local err" unknown) - (state/pub-event! [:instrument {:type :sync/unknown - :payload {:event :remote->local - :user-id user-uuid - :graph-uuid graph-uuid - :error unknown}}]) + (state/pub-event! [:capture-error {:error unknown + :payload {:type :sync/unknown + :event :remote->local + :user-id user-uuid + :graph-uuid graph-uuid}}]) (.schedule this ::idle nil nil))))))) (local->remote [this {local-changes :local}] @@ -2986,11 +2990,11 @@ unknown (do (debug/pprint "local->remote" unknown) - (state/pub-event! [:instrument {:type :sync/unknown - :payload {:event :local->remote - :user-id user-uuid - :graph-uuid graph-uuid - :error unknown}}]) + (state/pub-event! [:capture-error {:error unknown + :payload {:event :local->remote + :type :sync/unknown + :user-id user-uuid + :graph-uuid graph-uuid}}]) (.schedule this ::idle nil nil)))))) IStoppable (-stop! [_] @@ -2998,9 +3002,7 @@ (when-not @*stopped? (vreset! *stopped? true) (ws-stop! *ws) - (offer! private-stop-sync-chan true) (async/untap full-sync-mult private-full-sync-chan) - (async/untap stop-sync-mult private-stop-sync-chan) (async/untap remote->local-sync-mult private-remote->local-sync-chan) (async/untap remote->local-full-sync-mult private-remote->local-full-sync-chan) (async/untap pause-resume-mult private-pause-resume-chan) @@ -3008,14 +3010,9 @@ (stop-local->remote! local->remote-syncer) (stop-remote->local! remote->local-syncer) (remote-syncer! remote->local-syncer local->remote-syncer) (swap! *sync-state sync-state--update-current-syncing-graph-uuid graph-uuid) (->SyncManager user-uuid graph-uuid base-path *sync-state local->remote-syncer remote->local-syncer remoteapi-with-stop - nil *txid nil nil nil *stopped? *paused? nil (chan 1) (chan 1) (chan 1) (chan 1) (chan 1)))) + nil *txid nil nil nil *stopped? *paused? nil (chan 1) (chan 1) (chan 1) (chan 1)))) (defn sync-manager-singleton [user-uuid graph-uuid base-path repo txid *sync-state] diff --git a/src/main/frontend/handler.cljs b/src/main/frontend/handler.cljs index 6e8102f7c..052fc4e84 100644 --- a/src/main/frontend/handler.cljs +++ b/src/main/frontend/handler.cljs @@ -73,11 +73,7 @@ (defn- instrument! [] (let [total (srs/get-srs-cards-total)] - (state/set-state! :srs/cards-due-count total) - (state/pub-event! [:instrument {:type :flashcards/count - :payload {:total (or total 0)}}]) - (state/pub-event! [:instrument {:type :blocks/count - :payload {:total (db/blocks-count)}}]))) + (state/set-state! :srs/cards-due-count total))) (defn restore-and-setup! [repos] diff --git a/src/main/frontend/handler/events.cljs b/src/main/frontend/handler/events.cljs index ae3f3fb3a..4d468045d 100644 --- a/src/main/frontend/handler/events.cljs +++ b/src/main/frontend/handler/events.cljs @@ -59,7 +59,9 @@ [logseq.db.schema :as db-schema] [promesa.core :as p] [rum.core :as rum] - [logseq.graph-parser.config :as gp-config])) + [logseq.graph-parser.config :as gp-config] + [cljs-bean.core :as bean] + ["@sentry/react" :as Sentry])) ;; TODO: should we move all events here? @@ -408,6 +410,10 @@ (js/console.error "instrument data-map should only contains [:type :payload]")) (posthog/capture type payload)) +(defmethod handle :capture-error [[_ {:keys [error payload]}]] + (Sentry/captureException error + (bean/->js {:extra payload}))) + (defmethod handle :exec-plugin-cmd [[_ {:keys [pid cmd action]}]] (commands/exec-plugin-simple-command! pid cmd action)) @@ -860,8 +866,8 @@ :else (do - (state/pub-event! [:instrument {:type :file/parse-and-load-error - :payload error}]) + (state/pub-event! [:capture-error {:error error + :payload {:type :file/parse-and-load-error}}]) [:li.my-1 {:key file} [:a {:on-click #(js/window.apis.openPath file)} file] [:p (.-message error)]]))))] @@ -878,9 +884,9 @@ (catch :default error (let [type :handle-system-events/failed] (js/console.error (str type) (clj->js payload) "\n" error) - (state/pub-event! [:instrument {:type type - :payload payload - :error error}]))))) + (state/pub-event! [:capture-error {:error error + :payload {:type type + :payload payload}}]))))) (recur)) chan)) diff --git a/src/main/frontend/handler/file.cljs b/src/main/frontend/handler/file.cljs index aa317b71d..279f45518 100644 --- a/src/main/frontend/handler/file.cljs +++ b/src/main/frontend/handler/file.cljs @@ -149,11 +149,9 @@ (println "Write file failed, path: " path ", content: " content) (log/error :write/failed error) - (state/pub-event! [:instrument {:type :write-file/failed-for-alter-file - :payload {:path path - :content-length (count content) - :error-str (str error) - :error error}}]))) + (state/pub-event! [:capture-error + {:error error + :payload {:type :write-file/failed-for-alter-file}}]))) result)) (defn set-file-content! @@ -178,11 +176,9 @@ (str error)) :status :error :clear? false}]) - (state/pub-event! [:instrument {:type :write-file/failed - :payload {:path path - :content-length (count content) - :error-str (str error) - :error error}}]) + (state/pub-event! [:capture-error + {:error error + :payload {:type :write-file/failed}}]) (log/error :write-file/failed {:path path :content content :error error}))))))) diff --git a/src/main/frontend/handler/repo.cljs b/src/main/frontend/handler/repo.cljs index 1ba872312..62f94eccd 100644 --- a/src/main/frontend/handler/repo.cljs +++ b/src/main/frontend/handler/repo.cljs @@ -424,9 +424,9 @@ (on-success))) (p/catch (fn [error] (js/console.error error) - (state/pub-event! [:instrument {:type :db/persist-failed - :payload {:error-str (str error) - :error error}}]) + (state/pub-event! [:capture-error + {:error error + :payload {:type :db/persist-failed}}]) (when on-error (on-error))))))) diff --git a/src/main/frontend/modules/instrumentation/sentry.cljs b/src/main/frontend/modules/instrumentation/sentry.cljs index c75c2027b..1a351ca5f 100644 --- a/src/main/frontend/modules/instrumentation/sentry.cljs +++ b/src/main/frontend/modules/instrumentation/sentry.cljs @@ -3,8 +3,6 @@ [frontend.util :as util] [frontend.config :as config] ["@sentry/react" :as Sentry] - ["@sentry/tracing" :refer [BrowserTracing]] - ["posthog-js" :as posthog] [frontend.mobile.util :as mobile-util])) (def config @@ -21,8 +19,8 @@ (mobile-util/native-platform?) "mobile" :else "web") :publishing config/publishing?}} - :integrations [(new posthog/SentryIntegration posthog "logseq" 5311485) - (new BrowserTracing)] + ;; :integrations [(new posthog/SentryIntegration posthog "logseq" 5311485) + ;; (new BrowserTracing)] :debug config/dev? :tracesSampleRate 1.0 :beforeSend (fn [^js event] diff --git a/src/main/frontend/modules/outliner/core.cljs b/src/main/frontend/modules/outliner/core.cljs index 1b7b2b3a8..3cf8030ca 100644 --- a/src/main/frontend/modules/outliner/core.cljs +++ b/src/main/frontend/modules/outliner/core.cljs @@ -511,11 +511,12 @@ tx (insert-blocks-aux blocks' target-block' insert-opts)] (if (some (fn [b] (or (nil? (:block/parent b)) (nil? (:block/left b)))) tx) (do - (state/pub-event! [:instrument {:type :outliner/invalid-structure - :payload {:blocks blocks - :target-block target-block' - :opt opts - :data (mapv #(dissoc % :block/content) tx)}}]) + (state/pub-event! [:capture-error {:error "Outliner invalid structure" + :payload {:type :outliner/invalid-structure + :blocks blocks + :target-block target-block' + :opt opts + :data (mapv #(dissoc % :block/content) tx)}}]) (throw (ex-info "Invalid outliner data" {:opts insert-opts :tx (vec tx) diff --git a/src/main/frontend/util.cljc b/src/main/frontend/util.cljc index db3a49a5b..2c1cee963 100644 --- a/src/main/frontend/util.cljc +++ b/src/main/frontend/util.cljc @@ -11,6 +11,7 @@ ["remove-accents" :as removeAccents] ["sanitize-filename" :as sanitizeFilename] ["check-password-strength" :refer [passwordStrength]] + ["path-complete-extname" :as pathCompleteExtname] [frontend.loader :refer [load]] [cljs-bean.core :as bean] [cljs-time.coerce :as tc] @@ -43,7 +44,7 @@ (-write writer (str "\"" (.toString sym) "\""))))) #?(:cljs (defonce ^js node-path utils/nodePath)) -#?(:cljs (defonce ^js full-path-extname utils/fullPathExtname)) +#?(:cljs (defonce ^js full-path-extname pathCompleteExtname)) #?(:cljs (defn app-scroll-container-node ([] (gdom/getElement "main-content-container")) diff --git a/templates/config.edn b/templates/config.edn index faa2c7da6..df4c5e26a 100644 --- a/templates/config.edn +++ b/templates/config.edn @@ -254,7 +254,7 @@ ;; ignore #+keyword: for parsing page references in orgmode ;; :ignored-page-references-keywords #{"author" "startup"} - ;; Quick capture templates on mobile for recieving contents from other apps. + ;; Quick capture templates for recieving contents from other apps. ;; Each template contains three elements {time}, {text} and {url}, which can be auto-expanded ;; by received contents from other apps. Note: the {} cannot be omitted. ;; - {time}: capture time @@ -266,6 +266,9 @@ ;; {:text "[[quick capture]] **{time}**: {text} from {url}" ;; :media "[[quick capture]] **{time}**: {url}"} + ;; Quick capture options + ;; :quick-capture-options {:insert-today? false :redirect-page? false} + ;; File sync options ;; Ignore these files when syncing, regexp is supported. ;; :file-sync/ignore-files [] @@ -284,7 +287,7 @@ ;; Decide the way to escape the special characters in the page title. ;; Warning: ;; This is a dangerous operation. If you want to change the setting, - ;; should access the setting `Filename format` and follow the instructions. + ;; should access the setting `Filename format` and follow the instructions. ;; Or you have to rename all the affected files manually then re-index on all ;; clients after the files are synced. Wrong handling may cause page titles ;; containing special characters to be messy.