handler.cljs 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. (ns frontend.handler
  2. (:require [electron.ipc :as ipc]
  3. [electron.listener :as el]
  4. [frontend.components.page :as page]
  5. [frontend.components.reference :as reference]
  6. [frontend.config :as config]
  7. [frontend.context.i18n :as i18n]
  8. [frontend.db :as db]
  9. [logseq.db.schema :as db-schema]
  10. [frontend.db.conn :as conn]
  11. [frontend.db.react :as react]
  12. [frontend.error :as error]
  13. [frontend.handler.command-palette :as command-palette]
  14. [frontend.handler.events :as events]
  15. [frontend.handler.file :as file-handler]
  16. [frontend.handler.notification :as notification]
  17. [frontend.handler.page :as page-handler]
  18. [frontend.handler.repo :as repo-handler]
  19. [frontend.handler.ui :as ui-handler]
  20. [frontend.handler.user :as user-handler]
  21. [frontend.extensions.srs :as srs]
  22. [frontend.mobile.util :as mobile-util]
  23. [frontend.idb :as idb]
  24. [frontend.modules.instrumentation.core :as instrument]
  25. [frontend.modules.shortcut.core :as shortcut]
  26. [frontend.state :as state]
  27. [frontend.storage :as storage]
  28. [frontend.util :as util]
  29. [frontend.util.persist-var :as persist-var]
  30. [cljs.reader :refer [read-string]]
  31. [goog.object :as gobj]
  32. [lambdaisland.glogi :as log]
  33. [promesa.core :as p]
  34. [frontend.db.persist :as db-persist]
  35. [frontend.modules.outliner.datascript :as outliner-db]))
  36. (defn set-global-error-notification!
  37. []
  38. (set! js/window.onerror
  39. (fn [message, _source, _lineno, _colno, error]
  40. (when-not (error/ignored? message)
  41. (log/error :exception error)
  42. ;; (notification/show!
  43. ;; (str "message=" message "\nsource=" source "\nlineno=" lineno "\ncolno=" colno "\nerror=" error)
  44. ;; :error
  45. ;; ;; Don't auto-hide
  46. ;; false)
  47. ))))
  48. (defn- watch-for-date!
  49. []
  50. (let [f (fn []
  51. #_:clj-kondo/ignore
  52. (let [repo (state/get-current-repo)]
  53. (when (and (not (state/nfs-refreshing?))
  54. (not (contains? (:file/unlinked-dirs @state/state)
  55. (config/get-repo-dir repo))))
  56. (srs/update-cards-due-count!)
  57. ;; Don't create the journal file until user writes something
  58. (page-handler/create-today-journal!))))]
  59. (f)
  60. (js/setInterval f 5000)))
  61. (defn- instrument!
  62. []
  63. (let [total (srs/get-srs-cards-total)]
  64. (state/set-state! :srs/cards-due-count total)
  65. (state/pub-event! [:instrument {:type :flashcards/count
  66. :payload {:total (or total 0)}}])
  67. (state/pub-event! [:instrument {:type :blocks/count
  68. :payload {:total (db/blocks-count)}}])))
  69. (defn store-schema!
  70. []
  71. (storage/set :db-schema (assoc db-schema/schema
  72. :db/version db-schema/version)))
  73. (defn restore-and-setup!
  74. [repos old-db-schema]
  75. (-> (db/restore!
  76. {:repos repos}
  77. old-db-schema
  78. (fn [repo]
  79. (file-handler/restore-config! repo false)))
  80. (p/then
  81. (fn []
  82. ;; try to load custom css only for current repo
  83. (ui-handler/add-style-if-exists!)
  84. ;; install after config is restored
  85. (shortcut/unlisten-all)
  86. (shortcut/refresh!)
  87. (cond
  88. (and (not (seq (db/get-files config/local-repo)))
  89. ;; Not native local directory
  90. (not (some config/local-db? (map :url repos)))
  91. (not (mobile-util/native-platform?)))
  92. ;; will execute `(state/set-db-restoring! false)` inside
  93. (repo-handler/setup-local-repo-if-not-exists!)
  94. :else
  95. (state/set-db-restoring! false))))
  96. (p/then
  97. (fn []
  98. (prn "db restored, setting up repo hooks")
  99. (store-schema!)
  100. (state/pub-event! [:modal/nfs-ask-permission])
  101. (page-handler/init-commands!)
  102. (watch-for-date!)
  103. (file-handler/watch-for-current-graph-dir!)
  104. (state/pub-event! [:graph/ready (state/get-current-repo)])
  105. (state/pub-event! [:graph/restored (state/get-current-repo)])))
  106. (p/catch (fn [error]
  107. (log/error :exception error)))))
  108. (defn- handle-connection-change
  109. [e]
  110. (let [online? (= (gobj/get e "type") "online")]
  111. (state/set-online! online?)))
  112. (defn set-network-watcher!
  113. []
  114. (js/window.addEventListener "online" handle-connection-change)
  115. (js/window.addEventListener "offline" handle-connection-change))
  116. (defn enable-datalog-console
  117. "Enables datalog console in browser provided by https://github.com/homebaseio/datalog-console"
  118. []
  119. (js/document.documentElement.setAttribute "__datalog-console-remote-installed__" true)
  120. (.addEventListener js/window "message"
  121. (fn [event]
  122. (let [db (conn/get-db)]
  123. (when-let [devtool-message (gobj/getValueByKeys event "data" ":datalog-console.client/devtool-message")]
  124. (let [msg-type (:type (read-string devtool-message))]
  125. (case msg-type
  126. :datalog-console.client/request-whole-database-as-string
  127. (.postMessage js/window #js {":datalog-console.remote/remote-message" (pr-str db)} "*")
  128. nil)))))))
  129. (defn- get-repos
  130. []
  131. (p/let [nfs-dbs (db-persist/get-all-graphs)
  132. nfs-dbs (map (fn [db]
  133. {:url db :nfs? true}) nfs-dbs)]
  134. (cond
  135. (seq nfs-dbs)
  136. nfs-dbs
  137. :else
  138. [{:url config/local-repo
  139. :example? true}])))
  140. (defn clear-cache!
  141. []
  142. (notification/show! "Clearing..." :warning false)
  143. (p/let [_ (when (util/electron?)
  144. (ipc/ipc "clearCache"))
  145. _ (idb/clear-local-storage-and-idb!)]
  146. (js/setTimeout
  147. (fn [] (if (util/electron?)
  148. (ipc/ipc :reloadWindowPage)
  149. (js/window.location.reload)))
  150. 2000)))
  151. (defn- register-components-fns!
  152. []
  153. (state/set-page-blocks-cp! page/page-blocks-cp)
  154. (state/set-component! :block/linked-references reference/block-linked-references)
  155. (command-palette/register-global-shortcut-commands))
  156. (reset! db/*db-listener outliner-db/after-transact-pipelines)
  157. (defn start!
  158. [render]
  159. (set-global-error-notification!)
  160. (let [db-schema (storage/get :db-schema)]
  161. (register-components-fns!)
  162. (state/set-db-restoring! true)
  163. (render)
  164. (i18n/start)
  165. (instrument/init)
  166. (set-network-watcher!)
  167. (util/indexeddb-check?
  168. (fn [_error]
  169. (notification/show! "Sorry, it seems that your browser doesn't support IndexedDB, we recommend to use latest Chrome(Chromium) or Firefox(Non-private mode)." :error false)
  170. (state/set-indexedb-support! false)))
  171. (react/run-custom-queries-when-idle!)
  172. (events/run!)
  173. (p/let [repos (get-repos)]
  174. (state/set-repos! repos)
  175. (restore-and-setup! repos db-schema)
  176. (when (mobile-util/native-platform?)
  177. (p/do! (mobile-util/hide-splash))))
  178. (db/run-batch-txs!)
  179. (file-handler/run-writes-chan!)
  180. (when config/dev?
  181. (enable-datalog-console))
  182. (when (util/electron?)
  183. (el/listen!))
  184. (persist-var/load-vars)
  185. (user-handler/refresh-tokens-loop)
  186. (js/setTimeout instrument! (* 60 1000))))
  187. (defn stop! []
  188. (prn "stop!"))
  189. (defn quit-and-install-new-version!
  190. []
  191. (p/let [_ (el/persist-dbs!)
  192. _ (ipc/invoke "set-quit-dirty-state" false)]
  193. (ipc/ipc :quitAndInstall)))