header.cljs 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  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.right-sidebar :as sidebar]
  6. [frontend.components.search :as search]
  7. [frontend.components.svg :as svg]
  8. [frontend.config :as config]
  9. [frontend.context.i18n :as i18n]
  10. [frontend.handler.page :as page-handler]
  11. [frontend.handler.plugin :as plugin-handler]
  12. [frontend.handler.user :as user-handler]
  13. [frontend.handler.web.nfs :as nfs]
  14. [frontend.modules.shortcut.core :as shortcut]
  15. [frontend.state :as state]
  16. [frontend.ui :as ui]
  17. [frontend.util :as util]
  18. [reitit.frontend.easy :as rfe]
  19. [rum.core :as rum]))
  20. (rum/defc logo < rum/reactive
  21. [{:keys [white? electron-mac?]}]
  22. [:a.cp__header-logo
  23. {:class (when electron-mac? "button")
  24. :href (rfe/href :home)
  25. :on-click (fn []
  26. (util/scroll-to-top)
  27. (state/set-journals-length! 2))}
  28. (if electron-mac?
  29. svg/home
  30. (if-let [logo (and config/publishing?
  31. (get-in (state/get-config) [:project :logo]))]
  32. [:img.cp__header-logo-img {:src logo}]
  33. (svg/logo (not white?))))])
  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.fade-link.block.p-2 {: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. [:button#left-menu.cp__header-left-menu
  58. {:on-click on-click}
  59. [:svg.h-6.w-6
  60. {:viewBox "0 0 24 24", :fill "none", :stroke "currentColor"}
  61. [:path
  62. {:d "M4 6h16M4 12h16M4 18h7"
  63. :stroke-width "2"
  64. :stroke-linejoin "round"
  65. :stroke-linecap "round"}]]])
  66. (rum/defc dropdown-menu < rum/reactive
  67. [{:keys [me current-repo t default-home]}]
  68. (let [projects (state/sub [:me :projects])
  69. developer-mode? (state/sub [:ui/developer-mode?])
  70. logged? (state/logged?)]
  71. (ui/dropdown-with-links
  72. (fn [{:keys [toggle-fn]}]
  73. [:a.cp__right-menu-button.button
  74. {:on-click toggle-fn}
  75. (svg/horizontal-dots nil)])
  76. (->>
  77. [(when-not (util/mobile?)
  78. {:title (t :command.ui/toggle-right-sidebar)
  79. :options {:on-click state/toggle-sidebar-open?!}})
  80. {:hr true}
  81. (when current-repo
  82. {:title (t :cards-view)
  83. :options {:on-click #(state/pub-event! [:modal/show-cards])}})
  84. (when current-repo
  85. {:title (t :graph-view)
  86. :options {:href (rfe/href :graph)}
  87. :icon svg/graph-sm})
  88. (when current-repo
  89. {:title (t :all-pages)
  90. :options {:href (rfe/href :all-pages)}
  91. :icon svg/pages-sm})
  92. (when (and current-repo (not config/publishing?))
  93. {:title (t :all-files)
  94. :options {:href (rfe/href :all-files)}
  95. :icon svg/folder-sm})
  96. (when (and default-home current-repo)
  97. {:title (t :all-journals)
  98. :options {:href (rfe/href :all-journals)}
  99. :icon svg/calendar-sm})
  100. {:hr true}
  101. (when-not (state/publishing-enable-editing?)
  102. {:title (t :settings)
  103. :options {:on-click state/open-settings!}
  104. :icon svg/settings-sm})
  105. (when (and developer-mode? (util/electron?))
  106. {:title (t :plugins)
  107. :options {:href (rfe/href :plugins)}})
  108. (when developer-mode?
  109. {:title (t :themes)
  110. :options {:on-click #(plugins/open-select-theme!)}})
  111. (when current-repo
  112. {:title (t :export)
  113. :options {:on-click #(state/set-modal! export/export)}
  114. :icon nil})
  115. (when current-repo
  116. {:title (t :import)
  117. :options {:href (rfe/href :import)}
  118. :icon svg/import-sm})
  119. {:title [:div.flex-row.flex.justify-between.items-center
  120. [:span (t :join-community)]]
  121. :options {:href "https://discord.gg/KpN4eHY"
  122. :title (t :discord-title)
  123. :target "_blank"}
  124. :icon svg/discord}
  125. (when logged?
  126. {:title (t :sign-out)
  127. :options {:on-click user-handler/sign-out!}
  128. :icon svg/logout-sm})]
  129. (remove nil?))
  130. ;; {:links-footer (when (and (util/electron?) (not logged?))
  131. ;; [:div.px-2.py-2 (login logged?)])}
  132. )))
  133. (rum/defc back-and-forward
  134. [electron-mac?]
  135. [:div.flex.flex-row
  136. [:a.it.navigation.nav-left.button
  137. {:title "Go Back" :on-click #(js/window.history.back)}
  138. svg/arrow-narrow-left]
  139. [:a.it.navigation.nav-right.button
  140. {:title "Go Forward" :on-click #(js/window.history.forward)}
  141. svg/arrow-narrow-right]])
  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. electron-not-mac? (and (util/electron?) (not electron-mac?))
  149. show-open-folder? (and (nfs/supported?) (empty? repos)
  150. (not config/publishing?))
  151. refreshing? (state/sub :nfs/refreshing?)]
  152. (rum/with-context [[t] i18n/*tongue-context*]
  153. [:div.cp__header#head
  154. {:class (when electron-mac? "electron-mac")
  155. :on-double-click (fn [^js e]
  156. (when-let [target (.-target e)]
  157. (when (and (util/electron?)
  158. (or (.. target -classList (contains "cp__header"))))
  159. (js/window.apis.toggleMaxOrMinActiveWindow))))}
  160. (left-menu-button {:on-click (fn []
  161. (open-fn)
  162. (state/set-left-sidebar-open! true))})
  163. (when-not electron-mac?
  164. (logo {:white? white?}))
  165. (when electron-not-mac? (back-and-forward))
  166. (if current-repo
  167. (search/search)
  168. [:div.flex-1])
  169. (when plugin-handler/lsp-enabled?
  170. (plugins/hook-ui-items :toolbar))
  171. [:a (when refreshing?
  172. [:div {:class "animate-spin-reverse"}
  173. svg/refresh])]
  174. (when electron-mac?
  175. (logo {:white? white?
  176. :electron-mac? true}))
  177. (when electron-mac? (back-and-forward true))
  178. (new-block-mode)
  179. (when refreshing?
  180. [:div {:class "animate-spin-reverse"}
  181. svg/refresh])
  182. (when-not (util/electron?)
  183. (login logged?))
  184. (repo/sync-status current-repo)
  185. [:div.repos
  186. (repo/repos-dropdown nil)]
  187. (when show-open-folder?
  188. [:a.text-sm.font-medium.button
  189. {:on-click #(page-handler/ls-dir-files! shortcut/refresh!)}
  190. [:div.flex.flex-row.text-center.open-button__inner.items-center
  191. [:span.inline-block.open-button__icon-wrapper svg/folder-add]
  192. (when-not config/mobile?
  193. [:span.ml-1 {:style {:margin-top (if electron-mac? 0 2)}}
  194. (t :open)])]])
  195. (when config/publishing?
  196. [:a.text-sm.font-medium.button {:href (rfe/href :graph)}
  197. (t :graph)])
  198. (dropdown-menu {:me me
  199. :t t
  200. :current-repo current-repo
  201. :default-home default-home})
  202. (when (not (state/sub :ui/sidebar-open?)) (sidebar/toggle))])))