listener.cljs 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. (ns electron.listener
  2. (:require [frontend.state :as state]
  3. [frontend.context.i18n :refer [t]]
  4. [frontend.date :as date]
  5. [frontend.handler.route :as route-handler]
  6. [frontend.handler.editor :as editor-handler]
  7. [frontend.handler.ui :as ui-handler]
  8. [frontend.handler.file-sync :as file-sync-handler]
  9. [frontend.config :as config]
  10. [clojure.string :as string]
  11. [cljs-bean.core :as bean]
  12. [frontend.fs.watcher-handler :as watcher-handler]
  13. [frontend.fs.sync :as sync]
  14. [frontend.db :as db]
  15. [frontend.db.model :as db-model]
  16. [datascript.core :as d]
  17. [electron.ipc :as ipc]
  18. [frontend.ui :as ui]
  19. [frontend.handler.notification :as notification]
  20. [frontend.handler.repo :as repo-handler]
  21. [frontend.handler.user :as user]
  22. [dommy.core :as dom]))
  23. (defn persist-dbs!
  24. []
  25. ;; only persist current db!
  26. ;; TODO rename the function and event to persist-db
  27. (repo-handler/persist-db! {:before #(notification/show!
  28. (ui/loading (t :graph/persist))
  29. :warning)
  30. :on-success #(ipc/ipc "persistent-dbs-saved")
  31. :on-error #(ipc/ipc "persistent-dbs-error")}))
  32. (defn listen-persistent-dbs!
  33. []
  34. ;; TODO: move "file-watcher" to electron.ipc.channels
  35. (js/window.apis.on
  36. "persistent-dbs"
  37. (fn [_req]
  38. (persist-dbs!))))
  39. (defn ^:large-vars/cleanup-todo listen-to-electron!
  40. []
  41. ;; TODO: move "file-watcher" to electron.ipc.channels
  42. (js/window.apis.on "file-watcher"
  43. (fn [data]
  44. (let [{:keys [type payload]} (bean/->clj data)]
  45. (watcher-handler/handle-changed! type payload)
  46. (when (file-sync-handler/enable-sync?)
  47. (sync/file-watch-handler type payload)))))
  48. (js/window.apis.on "notification"
  49. (fn [data]
  50. (let [{:keys [type payload]} (bean/->clj data)
  51. type (keyword type)
  52. comp [:div (str payload)]]
  53. (notification/show! comp type false))))
  54. (js/window.apis.on "graphUnlinked"
  55. (fn [data]
  56. (let [repo (bean/->clj data)]
  57. (repo-handler/remove-repo! repo))))
  58. (js/window.apis.on "setGitUsernameAndEmail"
  59. (fn []
  60. (state/pub-event! [:modal/set-git-username-and-email])))
  61. (js/window.apis.on "getCurrentGraph"
  62. (fn []
  63. (when-let [graph (state/get-current-repo)]
  64. (ipc/ipc "setCurrentGraph" graph))))
  65. (js/window.apis.on "redirect"
  66. (fn [data]
  67. (let [{:keys [payload]} (bean/->clj data)
  68. payload (update payload :to keyword)]
  69. (route-handler/redirect! payload))))
  70. (js/window.apis.on "redirectWhenExists"
  71. ;; Redirect to the given page or block when the provided page or block exists.
  72. ;; Either :page-name or :block-id is required.
  73. ;; :page-name : the original-name of the page.
  74. ;; :block-id : uuid.
  75. (fn [data]
  76. (let [{:keys [page-name block-id file]} (bean/->clj data)]
  77. (cond
  78. page-name
  79. (let [db-page-name (db-model/get-redirect-page-name page-name)]
  80. ;; No error handling required, as a page name is always valid
  81. ;; Open new page if the page does not exist
  82. (editor-handler/insert-first-page-block-if-not-exists! db-page-name))
  83. block-id
  84. (if (db-model/get-block-by-uuid block-id)
  85. (route-handler/redirect-to-page! block-id)
  86. (notification/show! (str "Open link failed. Block-id `" block-id "` doesn't exist in the graph.") :error false))
  87. file
  88. (if-let [db-page-name (db-model/get-file-page file false)]
  89. (route-handler/redirect-to-page! db-page-name)
  90. (notification/show! (str "Open link failed. File `" file "` doesn't exist in the graph.") :error false))))))
  91. (js/window.apis.on "dbsync"
  92. (fn [data]
  93. (let [{:keys [graph tx-data]} (bean/->clj data)
  94. tx-data (db/string->db (:data tx-data))]
  95. (when-let [conn (db/get-db graph false)]
  96. (d/transact! conn tx-data {:dbsync? true}))
  97. (ui-handler/re-render-root!))))
  98. (js/window.apis.on "persistGraph"
  99. ;; electron is requesting window for persisting a graph in it's db
  100. ;; fire back "broadcastPersistGraphDone" on done
  101. (fn [data]
  102. (let [repo (bean/->clj data)
  103. before-f #(notification/show!
  104. (ui/loading (t :graph/persist))
  105. :warning)
  106. after-f #(ipc/ipc "broadcastPersistGraphDone")
  107. error-f (fn []
  108. (after-f)
  109. (notification/show!
  110. (t :graph/persist-error)
  111. :error))
  112. handlers {:before before-f
  113. :on-success after-f
  114. :on-error error-f}]
  115. (repo-handler/persist-db! repo handlers))))
  116. (js/window.apis.on "foundInPage"
  117. (fn [data]
  118. (let [data' (bean/->clj data)]
  119. (state/set-state! [:ui/find-in-page :matches] data')
  120. (dom/remove-style! (dom/by-id "search-in-page-input") :visibility)
  121. (dom/set-text! (dom/by-id "search-in-page-placeholder") "")
  122. (ui/focus-element "search-in-page-input")
  123. true)))
  124. (js/window.apis.on "loginCallback"
  125. (fn [code]
  126. (user/login-callback code)))
  127. (js/window.apis.on "quickCapture"
  128. (fn [args]
  129. (let [{:keys [url title content]} (bean/->clj args)
  130. page (or (state/get-current-page)
  131. (string/lower-case (date/journal-name)))
  132. format (db/get-page-format page)
  133. time (date/get-current-time)
  134. text (or (and content (not-empty (string/trim content))) "")
  135. link (if (not-empty title) (config/link-format format title url) url)
  136. template (get-in (state/get-config)
  137. [:quick-capture-templates :text]
  138. "**{time}** [[quick capture]]: {text} {url}")
  139. content (-> template
  140. (string/replace "{time}" time)
  141. (string/replace "{url}" link)
  142. (string/replace "{text}" text))]
  143. (if (and (state/get-edit-block) (state/editing?))
  144. (editor-handler/insert content)
  145. (editor-handler/api-insert-new-block! content {:page page
  146. :edit-block? false
  147. :replace-empty-target? true})))))
  148. (js/window.apis.on "openNewWindowOfGraph"
  149. ;; Handle open new window in renderer, until the destination graph doesn't rely on setting local storage
  150. ;; No db cache persisting ensured. Should be handled by the caller
  151. (fn [repo]
  152. (ui-handler/open-new-window! repo))))
  153. (defn listen!
  154. []
  155. (listen-to-electron!)
  156. (listen-persistent-dbs!))