header.cljs 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. (ns frontend.components.header
  2. (:require [frontend.components.export :as export]
  3. [frontend.components.plugins :as plugins]
  4. [frontend.components.repo :as repo]
  5. [frontend.components.page :as page]
  6. [clojure.string :as str]
  7. [frontend.components.page-menu :as page-menu]
  8. [frontend.components.right-sidebar :as sidebar]
  9. [frontend.components.search :as search]
  10. [frontend.components.svg :as svg]
  11. [frontend.config :as config]
  12. [frontend.context.i18n :as i18n]
  13. [frontend.handler :as handler]
  14. [frontend.handler.page :as page-handler]
  15. [frontend.handler.plugin :as plugin-handler]
  16. [frontend.handler.user :as user-handler]
  17. [frontend.handler.route :as route-handler]
  18. [frontend.handler.web.nfs :as nfs]
  19. [frontend.modules.shortcut.core :as shortcut]
  20. [frontend.state :as state]
  21. [frontend.ui :as ui]
  22. [frontend.util :as util]
  23. [cljs-bean.core :as bean]
  24. [reitit.frontend.easy :as rfe]
  25. [rum.core :as rum]
  26. [frontend.mobile.util :as mobile-util]
  27. [frontend.components.widgets :as widgets]))
  28. (rum/defc home-button []
  29. (ui/with-shortcut :go/home "left"
  30. [:a.button
  31. {:href (rfe/href :home)
  32. :on-click route-handler/go-to-journals!}
  33. (ui/icon "home" {:style {:fontSize 20}})]))
  34. (rum/defc login
  35. [logged?]
  36. (rum/with-context [[t] i18n/*tongue-context*]
  37. (when (and (not logged?)
  38. (not config/publishing?))
  39. (ui/dropdown-with-links
  40. (fn [{:keys [toggle-fn]}]
  41. [:a.button.text-sm.font-medium.block {:on-click toggle-fn}
  42. [:span (t :login)]])
  43. (let [list [;; {:title (t :login-google)
  44. ;; :url (str config/website "/login/google")}
  45. {:title (t :login-github)
  46. :url (str config/website "/login/github")}]]
  47. (mapv
  48. (fn [{:keys [title url]}]
  49. {:title title
  50. :options
  51. {:on-click
  52. (fn [_] (set! (.-href js/window.location) url))}})
  53. list))
  54. nil))))
  55. (rum/defc left-menu-button < rum/reactive
  56. [{:keys [on-click]}]
  57. (ui/with-shortcut :ui/toggle-left-sidebar "bottom"
  58. [:a#left-menu.cp__header-left-menu.button
  59. {:on-click on-click
  60. :style {:margin-left 12}}
  61. (ui/icon "menu-2" {:style {:fontSize 20}})]))
  62. (rum/defc dropdown-menu < rum/reactive
  63. [{:keys [me current-repo t default-home]}]
  64. (let [projects (state/sub [:me :projects])
  65. developer-mode? (state/sub [:ui/developer-mode?])
  66. logged? (state/logged?)
  67. page-menu (page-menu/page-menu nil)
  68. page-menu-and-hr (when (seq page-menu)
  69. (concat page-menu [{:hr true}]))]
  70. (ui/dropdown-with-links
  71. (fn [{:keys [toggle-fn]}]
  72. [:a.button
  73. {:on-click toggle-fn}
  74. (ui/icon "dots" {:style {:fontSize 20}})])
  75. (->>
  76. [(when-not (state/publishing-enable-editing?)
  77. {:title (t :settings)
  78. :options {:on-click state/open-settings!}
  79. :icon svg/settings-sm})
  80. (when (and developer-mode? (util/electron?))
  81. {:title (t :plugins)
  82. :options {:href (rfe/href :plugins)}})
  83. (when developer-mode?
  84. {:title (t :themes)
  85. :options {:on-click #(plugins/open-select-theme!)}})
  86. (when current-repo
  87. {:title (t :export-graph)
  88. :options {:on-click #(state/set-modal! export/export)}
  89. :icon nil})
  90. (when current-repo
  91. {:title (t :import)
  92. :options {:href (rfe/href :import)}
  93. :icon svg/import-sm})
  94. {:title [:div.flex-row.flex.justify-between.items-center
  95. [:span (t :join-community)]]
  96. :options {:href "https://discord.gg/KpN4eHY"
  97. :title (t :discord-title)
  98. :target "_blank"}
  99. :icon svg/discord}
  100. (when logged?
  101. {:title (t :sign-out)
  102. :options {:on-click user-handler/sign-out!}
  103. :icon svg/logout-sm})]
  104. (concat page-menu-and-hr)
  105. (remove nil?))
  106. {}
  107. ;; {:links-footer (when (and (util/electron?) (not logged?))
  108. ;; [:div.px-2.py-2 (login logged?)])}
  109. )))
  110. (rum/defc back-and-forward
  111. []
  112. [:div.flex.flex-row
  113. (ui/with-shortcut :go/backward "bottom"
  114. [:a.it.navigation.nav-left.button
  115. {:title "Go back" :on-click #(js/window.history.back)}
  116. (ui/icon "arrow-left")])
  117. (ui/with-shortcut :go/forward "bottom"
  118. [:a.it.navigation.nav-right.button
  119. {:title "Go forward" :on-click #(js/window.history.forward)}
  120. (ui/icon "arrow-right")])])
  121. (rum/defc updater-tips-new-version
  122. [t]
  123. (let [[downloaded, set-downloaded] (rum/use-state nil)
  124. _ (rum/use-effect!
  125. (fn []
  126. (when-let [channel (and (util/electron?) "auto-updater-downloaded")]
  127. (let [callback (fn [_ args]
  128. (js/console.debug "[new-version downloaded] args:" args)
  129. (let [args (bean/->clj args)]
  130. (set-downloaded args)
  131. (state/set-state! :electron/auto-updater-downloaded args))
  132. nil)]
  133. (js/apis.addListener channel callback)
  134. #(js/apis.removeListener channel callback))))
  135. [])]
  136. (when downloaded
  137. [:div.cp__header-tips
  138. [:p (t :updater/new-version-install)
  139. [:a.ui__button.restart
  140. {:on-click #(handler/quit-and-install-new-version!)}
  141. (svg/reload 16) [:strong (t :updater/quit-and-install)]]]])))
  142. (rum/defc header < rum/reactive
  143. [{:keys [open-fn current-repo white? logged? page? route-match me default-home new-block-mode]}]
  144. (let [local-repo? (= current-repo config/local-repo)
  145. repos (->> (state/sub [:me :repos])
  146. (remove #(= (:url %) config/local-repo)))
  147. electron-mac? (and util/mac? (util/electron?))
  148. show-open-folder? (and (or (nfs/supported?)
  149. (mobile-util/is-native-platform?))
  150. (empty? repos)
  151. (not config/publishing?))
  152. refreshing? (state/sub :nfs/refreshing?)]
  153. (rum/with-context [[t] i18n/*tongue-context*]
  154. [:div.cp__header#head
  155. {:class (when electron-mac? "electron-mac")
  156. :on-double-click (fn [^js e]
  157. (when-let [target (.-target e)]
  158. (when (and (util/electron?)
  159. (or (.. target -classList (contains "cp__header"))))
  160. (js/window.apis.toggleMaxOrMinActiveWindow))))}
  161. [:div.l.flex
  162. (left-menu-button {:on-click (fn []
  163. (open-fn)
  164. (state/set-left-sidebar-open!
  165. (not (:ui/left-sidebar-open? @state/state))))})
  166. (when current-repo ;; this is for the Search button
  167. (ui/with-shortcut :go/search "right"
  168. [:a.button#search-button
  169. {:on-click #(state/pub-event! [:go/search])}
  170. (ui/icon "search" {:style {:fontSize 20}})]))]
  171. [:div.r.flex
  172. (when (and
  173. (not (mobile-util/is-native-platform?))
  174. (not (util/electron?)))
  175. (login logged?))
  176. (when plugin-handler/lsp-enabled?
  177. (plugins/hook-ui-items :toolbar))
  178. (when (not= (state/get-current-route) :home)
  179. (home-button))
  180. (when (util/electron?) (back-and-forward))
  181. (new-block-mode)
  182. (when refreshing?
  183. [:div {:class "animate-spin-reverse"}
  184. svg/refresh])
  185. (repo/sync-status current-repo)
  186. (when show-open-folder?
  187. [:a.text-sm.font-medium.button
  188. {:on-click #(page-handler/ls-dir-files! shortcut/refresh!)}
  189. [:div.flex.flex-row.text-center.open-button__inner.items-center
  190. (ui/icon "folder-plus")
  191. (when-not config/mobile?
  192. [:span.ml-1 {:style {:margin-top (if electron-mac? 0 2)}}
  193. (t :open)])]])
  194. (when config/publishing?
  195. [:a.text-sm.font-medium.button {:href (rfe/href :graph)}
  196. (t :graph)])
  197. (dropdown-menu {:me me
  198. :t t
  199. :current-repo current-repo
  200. :default-home default-home})
  201. (when (not (state/sub :ui/sidebar-open?))
  202. (sidebar/toggle))
  203. (updater-tips-new-version t)]])))