header.cljs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. (ns frontend.components.header
  2. (:require [cljs-bean.core :as bean]
  3. [frontend.components.export :as export]
  4. [frontend.components.page-menu :as page-menu]
  5. [frontend.components.plugins :as plugins]
  6. [frontend.components.server :as server]
  7. [frontend.components.right-sidebar :as sidebar]
  8. [frontend.components.svg :as svg]
  9. [frontend.config :as config]
  10. [frontend.context.i18n :refer [t]]
  11. [frontend.handler :as handler]
  12. [frontend.handler.file-sync :as file-sync-handler]
  13. [frontend.components.file-sync :as fs-sync]
  14. [frontend.handler.plugin :as plugin-handler]
  15. [frontend.handler.route :as route-handler]
  16. [frontend.handler.user :as user-handler]
  17. [frontend.handler.web.nfs :as nfs]
  18. [frontend.mobile.util :as mobile-util]
  19. [frontend.state :as state]
  20. [frontend.ui :as ui]
  21. [frontend.util :as util]
  22. [frontend.version :refer [version]]
  23. [reitit.frontend.easy :as rfe]
  24. [rum.core :as rum]
  25. [clojure.string :as string]))
  26. (rum/defc home-button
  27. < {:key-fn #(identity "home-button")}
  28. []
  29. (ui/with-shortcut :go/home "left"
  30. [:button.button.icon.inline
  31. {:title "Home"
  32. :on-click #(do
  33. (when (mobile-util/native-iphone?)
  34. (state/set-left-sidebar-open! false))
  35. (route-handler/redirect-to-home!))}
  36. (ui/icon "home" {:size ui/icon-size})]))
  37. (rum/defc login < rum/reactive
  38. < {:key-fn #(identity "login-button")}
  39. []
  40. (let [_ (state/sub :auth/id-token)
  41. loading? (state/sub [:ui/loading? :login])
  42. sync-enabled? (file-sync-handler/enable-sync?)
  43. logged? (user-handler/logged-in?)]
  44. (when-not (or config/publishing?
  45. logged?
  46. (not sync-enabled?))
  47. [:a.button.text-sm.font-medium.block {:on-click #(js/window.open config/LOGIN-URL)}
  48. [:span (t :login)]
  49. (when loading?
  50. [:span.ml-2 (ui/loading "")])])))
  51. (rum/defc left-menu-button < rum/reactive
  52. < {:key-fn #(identity "left-menu-toggle-button")}
  53. [{:keys [on-click]}]
  54. (ui/with-shortcut :ui/toggle-left-sidebar "bottom"
  55. [:button.#left-menu.cp__header-left-menu.button.icon
  56. {:title "Toggle left menu"
  57. :on-click on-click}
  58. (ui/icon "menu-2" {:size ui/icon-size})]))
  59. (def bug-report-url
  60. (let [ua (.-userAgent js/navigator)
  61. safe-ua (string/replace ua #"[^_/a-zA-Z0-9\.\(\)]+" " ")
  62. platform (str "App Version: " version "\n"
  63. "Git Revision: " config/REVISION "\n"
  64. "Platform: " safe-ua "\n"
  65. "Language: " (.-language js/navigator))]
  66. (str "https://github.com/logseq/logseq/issues/new?"
  67. "title=&"
  68. "template=bug_report.yaml&"
  69. "labels=from:in-app&"
  70. "platform="
  71. (js/encodeURIComponent platform))))
  72. (rum/defc dropdown-menu < rum/reactive
  73. < {:key-fn #(identity "repos-dropdown-menu")}
  74. [{:keys [current-repo t]}]
  75. (let [page-menu (page-menu/page-menu nil)
  76. page-menu-and-hr (when (seq page-menu)
  77. (concat page-menu [{:hr true}]))]
  78. (ui/dropdown-with-links
  79. (fn [{:keys [toggle-fn]}]
  80. [:button.button.icon.toolbar-dots-btn
  81. {:on-click toggle-fn
  82. :title "More"}
  83. (ui/icon "dots" {:size ui/icon-size})])
  84. (->>
  85. [(when (state/enable-editing?)
  86. {:title (t :settings)
  87. :options {:on-click state/open-settings!}
  88. :icon (ui/icon "settings")})
  89. (when config/lsp-enabled?
  90. {:title (t :plugins)
  91. :options {:on-click #(plugin-handler/goto-plugins-dashboard!)}
  92. :icon (ui/icon "apps")})
  93. (when config/lsp-enabled?
  94. {:title (t :themes)
  95. :options {:on-click #(plugins/open-select-theme!)}
  96. :icon (ui/icon "palette")})
  97. (when current-repo
  98. {:title (t :export-graph)
  99. :options {:on-click #(state/set-modal! export/export)}
  100. :icon (ui/icon "database-export")})
  101. (when (and current-repo (state/enable-editing?))
  102. {:title (t :import)
  103. :options {:href (rfe/href :import)}
  104. :icon (ui/icon "file-upload")})
  105. {:title [:div.flex-row.flex.justify-between.items-center
  106. [:span (t :join-community)]]
  107. :options {:href "https://discuss.logseq.com"
  108. :title (t :discourse-title)
  109. :target "_blank"}
  110. :icon (ui/icon "brand-discord")}
  111. {:title [:div.flex-row.flex.justify-between.items-center
  112. [:span (t :help/bug)]]
  113. :options {:href (rfe/href :bug-report)}
  114. :icon (ui/icon "bug")}
  115. (when (and (state/sub :auth/id-token) (user-handler/logged-in?))
  116. {:title (str (t :logout) " (" (user-handler/email) ")")
  117. :options {:on-click #(user-handler/logout)}
  118. :icon (ui/icon "logout")})]
  119. (concat page-menu-and-hr)
  120. (remove nil?))
  121. {})))
  122. (rum/defc back-and-forward
  123. < {:key-fn #(identity "nav-history-buttons")}
  124. []
  125. [:div.flex.flex-row
  126. (ui/with-shortcut :go/backward "bottom"
  127. [:button.it.navigation.nav-left.button.icon
  128. {:title "Go back" :on-click #(js/window.history.back)}
  129. (ui/icon "arrow-left" {:size ui/icon-size})])
  130. (ui/with-shortcut :go/forward "bottom"
  131. [:button.it.navigation.nav-right.button.icon
  132. {:title "Go forward" :on-click #(js/window.history.forward)}
  133. (ui/icon "arrow-right" {:size ui/icon-size})])])
  134. (rum/defc updater-tips-new-version
  135. [t]
  136. (let [[downloaded, set-downloaded] (rum/use-state nil)
  137. _ (rum/use-effect!
  138. (fn []
  139. (when-let [channel (and (util/electron?) "auto-updater-downloaded")]
  140. (let [callback (fn [_ args]
  141. (js/console.debug "[new-version downloaded] args:" args)
  142. (let [args (bean/->clj args)]
  143. (set-downloaded args)
  144. (state/set-state! :electron/auto-updater-downloaded args))
  145. nil)]
  146. (js/apis.addListener channel callback)
  147. #(js/apis.removeListener channel callback))))
  148. [])]
  149. (when downloaded
  150. [:div.cp__header-tips
  151. [:p (t :updater/new-version-install)
  152. [:a.restart.ml-2
  153. {:on-click #(handler/quit-and-install-new-version!)}
  154. (svg/reload 16) [:strong (t :updater/quit-and-install)]]]])))
  155. (rum/defc ^:large-vars/cleanup-todo header < rum/reactive
  156. [{:keys [open-fn current-repo default-home new-block-mode]}]
  157. (let [repos (->> (state/sub [:me :repos])
  158. (remove #(= (:url %) config/local-repo)))
  159. _ (state/sub [:user/info :UserGroups])
  160. electron-mac? (and util/mac? (util/electron?))
  161. show-open-folder? (and (nfs/supported?)
  162. (or (empty? repos)
  163. (nil? (state/sub :git/current-repo)))
  164. (not (mobile-util/native-platform?))
  165. (not config/publishing?))
  166. left-menu (left-menu-button {:on-click (fn []
  167. (open-fn)
  168. (state/set-left-sidebar-open!
  169. (not (:ui/left-sidebar-open? @state/state))))})
  170. custom-home-page? (and (state/custom-home-page?)
  171. (= (state/sub-default-home-page) (state/get-current-page)))
  172. sync-enabled? (file-sync-handler/enable-sync?)]
  173. [:div.cp__header.drag-region#head
  174. {:class (util/classnames [{:electron-mac electron-mac?
  175. :native-ios (mobile-util/native-ios?)
  176. :native-android (mobile-util/native-android?)}])
  177. :on-double-click (fn [^js e]
  178. (when-let [target (.-target e)]
  179. (cond
  180. (and (util/electron?)
  181. (.. target -classList (contains "drag-region")))
  182. (js/window.apis.toggleMaxOrMinActiveWindow)
  183. (mobile-util/native-platform?)
  184. (util/scroll-to-top true))))
  185. :style {:fontSize 50}}
  186. [:div.l.flex.drag-region
  187. [left-menu
  188. (if (mobile-util/native-platform?)
  189. ;; back button for mobile
  190. (when-not (or (state/home?) custom-home-page? (state/whiteboard-dashboard?))
  191. (ui/with-shortcut :go/backward "bottom"
  192. [:button.it.navigation.nav-left.button.icon.opacity-70
  193. {:title "Go back" :on-click #(js/window.history.back)}
  194. (ui/icon "chevron-left" {:size 26})]))
  195. ;; search button for non-mobile
  196. (when current-repo
  197. (ui/with-shortcut :go/search "right"
  198. [:button.button.icon#search-button
  199. {:title "Search"
  200. :on-click #(do (when (or (mobile-util/native-android?)
  201. (mobile-util/native-iphone?))
  202. (state/set-left-sidebar-open! false))
  203. (state/pub-event! [:go/search]))}
  204. (ui/icon "search" {:size ui/icon-size})])))
  205. (when (state/feature-http-server-enabled?)
  206. (server/server-indicator (state/sub :electron/server)))]]
  207. [:div.r.flex.drag-region
  208. (when (and current-repo
  209. (not (config/demo-graph? current-repo))
  210. (user-handler/alpha-or-beta-user?))
  211. (fs-sync/indicator))
  212. (when (and (not= (state/get-current-route) :home)
  213. (not custom-home-page?))
  214. (home-button))
  215. (when sync-enabled?
  216. (login))
  217. (when config/lsp-enabled?
  218. (plugins/hook-ui-items :toolbar))
  219. (when (util/electron?)
  220. (back-and-forward))
  221. (when-not (mobile-util/native-platform?)
  222. (new-block-mode))
  223. (when show-open-folder?
  224. [:a.text-sm.font-medium.button.icon.add-graph-btn.flex.items-center
  225. {:on-click #(route-handler/redirect! {:to :repo-add})}
  226. (ui/icon "folder-plus")
  227. (when-not config/mobile?
  228. [:span.ml-1 {:style {:margin-top (if electron-mac? 0 2)}}
  229. (t :on-boarding/add-graph)])])
  230. (when config/publishing?
  231. [:a.text-sm.font-medium.button {:href (rfe/href :graph)}
  232. (t :graph)])
  233. (dropdown-menu {:t t
  234. :current-repo current-repo
  235. :default-home default-home})
  236. (when (not (state/sub :ui/sidebar-open?))
  237. (sidebar/toggle))
  238. (updater-tips-new-version t)]]))