theme.cljs 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. (ns frontend.components.theme
  2. (:require [electron.ipc :as ipc]
  3. [frontend.components.settings :as settings]
  4. [frontend.config :as config]
  5. [frontend.context.i18n :refer [t]]
  6. [frontend.extensions.pdf.core :as pdf]
  7. [frontend.handler.plugin :as plugin-handler]
  8. [frontend.handler.plugin-config :as plugin-config-handler]
  9. [frontend.handler.route :as route-handler]
  10. [frontend.handler.ui :as ui-handler]
  11. [frontend.rum :refer [use-mounted]]
  12. [frontend.state :as state]
  13. [frontend.storage :as storage]
  14. [frontend.ui :as ui]
  15. [frontend.util :as util]
  16. [logseq.shui.hooks :as hooks]
  17. [logseq.shui.ui :as shui]
  18. [rum.core :as rum]))
  19. (rum/defc scrollbar-measure
  20. []
  21. (let [*el (rum/use-ref nil)]
  22. (hooks/use-effect!
  23. (fn []
  24. (when-let [el (rum/deref *el)]
  25. (let [w (- (.-offsetWidth el) (.-clientWidth el))
  26. c "custom-scrollbar"
  27. l (.-classList js/document.documentElement)]
  28. (if (or (not util/mac?) (> w 2))
  29. (.add l c) (.remove l c)))))
  30. [])
  31. [:div.fixed.w-16.h-16.overflow-scroll.opacity-0
  32. {:ref *el
  33. :class "top-1/2 -left-1/2 z-[-999]"}]))
  34. (defonce *once-theme-loaded? (volatile! false))
  35. (rum/defc ^:large-vars/cleanup-todo container < rum/static
  36. [{:keys [route theme accent-color editor-font on-click current-repo db-restoring?
  37. settings-open? sidebar-open? system-theme? sidebar-blocks-len onboarding-state preferred-language]} child]
  38. (let [mounted-fn (use-mounted)
  39. [restored-sidebar? set-restored-sidebar?] (rum/use-state false)]
  40. (hooks/use-effect!
  41. #(let [^js doc js/document.documentElement
  42. ^js cls (.-classList doc)
  43. ^js cls-body (.-classList js/document.body)]
  44. (.setAttribute doc "data-theme" theme)
  45. (if (= theme "dark") ;; for tailwind dark mode
  46. ; The white-theme is for backward compatibility. See: https://github.com/logseq/logseq/pull/4652.
  47. (do (.add cls "dark") (doto cls-body (.remove "white-theme" "light-theme") (.add "dark-theme")))
  48. (do (.remove cls "dark") (doto cls-body (.remove "dark-theme") (.add "white-theme" "light-theme"))))
  49. (ui/apply-custom-theme-effect! theme)
  50. (plugin-handler/hook-plugin-app :theme-mode-changed {:mode theme}))
  51. [theme])
  52. ;; theme color
  53. (hooks/use-effect!
  54. #(some-> js/document.documentElement
  55. (.setAttribute "data-color"
  56. (or accent-color "logseq")))
  57. [accent-color])
  58. (hooks/use-effect!
  59. #(some-> js/document.documentElement
  60. (.setAttribute "data-font" (or editor-font "default")))
  61. [editor-font])
  62. (hooks/use-effect!
  63. #(let [doc js/document.documentElement]
  64. (.setAttribute doc "lang" preferred-language)))
  65. (hooks/use-effect!
  66. #(js/setTimeout
  67. (fn [] (when-not @*once-theme-loaded?
  68. (ipc/ipc :theme-loaded)
  69. (vreset! *once-theme-loaded? true))) 100) ; Wait for the theme to be applied
  70. [])
  71. (hooks/use-effect!
  72. #(when (and restored-sidebar?
  73. (mounted-fn))
  74. (plugin-handler/hook-plugin-app :sidebar-visible-changed {:visible sidebar-open?})
  75. (ui-handler/persist-right-sidebar-state!))
  76. [sidebar-open? restored-sidebar? sidebar-blocks-len])
  77. (hooks/use-effect!
  78. #(when config/lsp-enabled?
  79. (plugin-handler/load-plugin-preferences)
  80. (comp
  81. (plugin-handler/setup-install-listener!)
  82. (plugin-config-handler/setup-install-listener!)))
  83. [])
  84. (hooks/use-effect!
  85. (fn []
  86. (ui-handler/reset-custom-css!)
  87. (pdf/reset-current-pdf!)
  88. (plugin-handler/hook-plugin-app :current-graph-changed {}))
  89. [current-repo])
  90. (hooks/use-effect!
  91. #(let [db-restored? (false? db-restoring?)]
  92. (if db-restoring?
  93. (util/set-title! (t :loading))
  94. (when db-restored?
  95. (route-handler/update-page-title! route))))
  96. [db-restoring? route])
  97. (hooks/use-effect!
  98. (fn []
  99. (when-not db-restoring?
  100. (let [repos (state/get-repos)]
  101. (if-not (or
  102. ;; not in publishing mode
  103. config/publishing?
  104. ;; other graphs exists
  105. (seq repos))
  106. (route-handler/redirect! {:to :graphs})
  107. (do
  108. (ui-handler/restore-right-sidebar-state!)
  109. (set-restored-sidebar? true))))))
  110. [db-restoring?])
  111. (hooks/use-effect!
  112. #(when system-theme?
  113. (ui/setup-system-theme-effect!))
  114. [system-theme?])
  115. (hooks/use-effect!
  116. (fn []
  117. (if settings-open?
  118. (shui/dialog-open!
  119. (fn [] [:div.settings-modal (settings/settings settings-open?)])
  120. {:label "app-settings"
  121. :align :top
  122. :content-props {:onOpenAutoFocus #(.preventDefault %)}
  123. :id :app-settings})
  124. (shui/dialog-close! :app-settings)))
  125. [settings-open?])
  126. (hooks/use-effect!
  127. #(storage/set :file-sync/onboarding-state onboarding-state)
  128. [onboarding-state])
  129. [:div#root-container.theme-container
  130. {:on-click on-click
  131. :tab-index -1}
  132. child
  133. (pdf/default-embed-playground)
  134. (scrollbar-measure)]))