|
@@ -1,37 +1,39 @@
|
|
|
(ns frontend.components.settings
|
|
|
(:require [clojure.string :as string]
|
|
|
- [frontend.components.svg :as svg]
|
|
|
- [frontend.components.plugins :as plugins]
|
|
|
+ [electron.ipc :as ipc]
|
|
|
[frontend.components.assets :as assets]
|
|
|
+ [frontend.components.conversion :as conversion-component]
|
|
|
+ [frontend.components.file-sync :as fs]
|
|
|
+ [frontend.components.plugins :as plugins]
|
|
|
+ [frontend.components.svg :as svg]
|
|
|
[frontend.config :as config]
|
|
|
[frontend.context.i18n :refer [t]]
|
|
|
- [frontend.storage :as storage]
|
|
|
- [frontend.spec.storage :as storage-spec]
|
|
|
[frontend.date :as date]
|
|
|
+ [frontend.db :as db]
|
|
|
[frontend.dicts :as dicts]
|
|
|
[frontend.handler :as handler]
|
|
|
[frontend.handler.config :as config-handler]
|
|
|
+ [frontend.handler.file-sync :as file-sync-handler]
|
|
|
+ [frontend.handler.global-config :as global-config-handler]
|
|
|
[frontend.handler.notification :as notification]
|
|
|
+ [frontend.handler.plugin :as plugin-handler]
|
|
|
[frontend.handler.route :as route-handler]
|
|
|
[frontend.handler.ui :as ui-handler]
|
|
|
[frontend.handler.user :as user-handler]
|
|
|
- [frontend.handler.plugin :as plugin-handler]
|
|
|
- [frontend.handler.file-sync :as file-sync-handler]
|
|
|
- [frontend.handler.global-config :as global-config-handler]
|
|
|
+ [frontend.mobile.util :as mobile-util]
|
|
|
[frontend.modules.instrumentation.core :as instrument]
|
|
|
[frontend.modules.shortcut.data-helper :as shortcut-helper]
|
|
|
+ [frontend.spec.storage :as storage-spec]
|
|
|
[frontend.state :as state]
|
|
|
+ [frontend.storage :as storage]
|
|
|
[frontend.ui :as ui]
|
|
|
- [electron.ipc :as ipc]
|
|
|
- [promesa.core :as p]
|
|
|
[frontend.util :refer [classnames web-platform?] :as util]
|
|
|
[frontend.version :refer [version]]
|
|
|
[goog.object :as gobj]
|
|
|
+ [goog.string :as gstring]
|
|
|
+ [promesa.core :as p]
|
|
|
[reitit.frontend.easy :as rfe]
|
|
|
- [rum.core :as rum]
|
|
|
- [frontend.mobile.util :as mobile-util]
|
|
|
- [frontend.db :as db]
|
|
|
- [frontend.components.conversion :as conversion-component]))
|
|
|
+ [rum.core :as rum]))
|
|
|
|
|
|
(defn toggle
|
|
|
[label-for name state on-toggle & [detail-text]]
|
|
@@ -57,19 +59,19 @@
|
|
|
[:div (cond
|
|
|
(mobile-util/native-android?)
|
|
|
(ui/button
|
|
|
- "Check for updates"
|
|
|
+ (t :settings-page/check-for-updates)
|
|
|
:class "text-sm p-1 mr-1"
|
|
|
- :href "https://github.com/logseq/logseq/releases" )
|
|
|
+ :href "https://github.com/logseq/logseq/releases")
|
|
|
|
|
|
(mobile-util/native-ios?)
|
|
|
(ui/button
|
|
|
- "Check for updates"
|
|
|
+ (t :settings-page/check-for-updates)
|
|
|
:class "text-sm p-1 mr-1"
|
|
|
- :href "https://apps.apple.com/app/logseq/id1601013908" )
|
|
|
+ :href "https://apps.apple.com/app/logseq/id1601013908")
|
|
|
|
|
|
(util/electron?)
|
|
|
(ui/button
|
|
|
- (if update-pending? "Checking ..." "Check for updates")
|
|
|
+ (if update-pending? (t :settings-page/checking) (t :settings-page/check-for-updates))
|
|
|
:class "text-sm p-1 mr-1"
|
|
|
:disabled update-pending?
|
|
|
:on-click #(js/window.apis.checkForUpdates false))
|
|
@@ -78,7 +80,7 @@
|
|
|
nil)]
|
|
|
|
|
|
[:div.text-sm.cursor
|
|
|
- {:title (str "Revision: " config/revision)
|
|
|
+ {:title (str (t :settings-page/revision) config/revision)
|
|
|
:on-click (fn []
|
|
|
(notification/show! [:div "Current Revision: "
|
|
|
[:a {:target "_blank"
|
|
@@ -91,18 +93,18 @@
|
|
|
[:a.text-sm.fade-link.underline.inline
|
|
|
{:target "_blank"
|
|
|
:href "https://docs.logseq.com/#/page/changelog"}
|
|
|
- "What's new?"]]]
|
|
|
+ (t :settings-page/changelog)]]]
|
|
|
|
|
|
(when-not (or update-pending?
|
|
|
(string/blank? type))
|
|
|
[:div.update-state.text-sm
|
|
|
(case type
|
|
|
"update-not-available"
|
|
|
- [:p "Your app is up-to-date 🎉"]
|
|
|
+ [:p (t :settings-page/app-updated)]
|
|
|
|
|
|
"update-available"
|
|
|
(let [{:keys [name url]} payload]
|
|
|
- [:p (str "Found new release ")
|
|
|
+ [:p (str (t :settings-page/update-available))
|
|
|
[:a.link
|
|
|
{:on-click
|
|
|
(fn [e]
|
|
@@ -111,7 +113,7 @@
|
|
|
svg/external-link name " 🎉"]])
|
|
|
|
|
|
"error"
|
|
|
- [:p "⚠️ Oops, Something Went Wrong!" [:br] " Please check out the "
|
|
|
+ [:p (t :settings-page/update-error-1) [:br] (t :settings-page/update-error-2)
|
|
|
[:a.link
|
|
|
{:on-click
|
|
|
(fn [e]
|
|
@@ -125,10 +127,10 @@
|
|
|
{:style {:box-shadow "0 4px 20px 4px rgba(0, 20, 60, .1), 0 4px 80px -8px rgba(0, 20, 60, .2)"}}
|
|
|
[:div {:style {:margin "12px" :max-width "500px"}}
|
|
|
[:p.text-sm
|
|
|
- "The left side shows outdenting with the default setting, and the right shows outdenting with logical outdenting enabled. "
|
|
|
+ (t :settings-page/preferred-outdenting-tip)
|
|
|
[:a.text-sm
|
|
|
{:target "_blank" :href "https://discuss.logseq.com/t/whats-your-preferred-outdent-behavior-the-direct-one-or-the-logical-one/978"}
|
|
|
- "→ Learn more"]]
|
|
|
+ (t :settings-page/preferred-outdenting-tip-more)]]
|
|
|
[:img {:src "https://discuss.logseq.com/uploads/default/original/1X/e8ea82f63a5e01f6d21b5da827927f538f3277b9.gif"
|
|
|
:width 500
|
|
|
:height 500}]]])
|
|
@@ -139,7 +141,7 @@
|
|
|
{:style {:box-shadow "0 4px 20px 4px rgba(0, 20, 60, .1), 0 4px 80px -8px rgba(0, 20, 60, .2)"}}
|
|
|
[:div {:style {:margin "12px" :max-width "500px"}}
|
|
|
[:p.text-sm
|
|
|
- "This option controls whether to expand the block references automatically when zoom-in."]
|
|
|
+ (t :settings-page/auto-expand-block-refs-tip)]
|
|
|
[:img {:src "https://user-images.githubusercontent.com/28241963/225818326-118deda9-9d1e-477d-b0ce-771ca0bcd976.gif"
|
|
|
:width 500
|
|
|
:height 500}]]])
|
|
@@ -293,12 +295,12 @@
|
|
|
|
|
|
(defn theme-modes-row [t switch-theme system-theme? dark?]
|
|
|
(let [pick-theme [:ul.theme-modes-options
|
|
|
- [:li {:on-click (partial state/use-theme-mode! "light")
|
|
|
- :class (classnames [{:active (and (not system-theme?) (not dark?))}])} [:i.mode-light] [:strong "light"]]
|
|
|
- [:li {:on-click (partial state/use-theme-mode! "dark")
|
|
|
- :class (classnames [{:active (and (not system-theme?) dark?)}])} [:i.mode-dark] [:strong "dark"]]
|
|
|
- [:li {:on-click (partial state/use-theme-mode! "system")
|
|
|
- :class (classnames [{:active system-theme?}])} [:i.mode-system] [:strong "system"]]]]
|
|
|
+ [:li {:on-click (partial state/use-theme-mode! (t :settings-page/theme-light))
|
|
|
+ :class (classnames [{:active (and (not system-theme?) (not dark?))}])} [:i.mode-light] [:strong (t :settings-page/theme-light)]]
|
|
|
+ [:li {:on-click (partial state/use-theme-mode! (t :settings-page/theme-dark))
|
|
|
+ :class (classnames [{:active (and (not system-theme?) dark?)}])} [:i.mode-dark] [:strong (t :settings-page/theme-dark)]]
|
|
|
+ [:li {:on-click (partial state/use-theme-mode! (t :settings-page/theme-system))
|
|
|
+ :class (classnames [{:active system-theme?}])} [:i.mode-system] [:strong (t :settings-page/theme-system)]]]]
|
|
|
(row-with-button-action {:left-label (t :right-side-bar/switch-theme (string/capitalize switch-theme))
|
|
|
:-for "toggle_theme"
|
|
|
:action pick-theme
|
|
@@ -340,7 +342,7 @@
|
|
|
(when-not (string/blank? format)
|
|
|
(config-handler/set-config! :journal/page-title-format format)
|
|
|
(notification/show!
|
|
|
- [:div "You must re-index your graph for this change to take effect"]
|
|
|
+ [:div (t :settings-page/custom-date-format-notification)]
|
|
|
:warning false)
|
|
|
(state/close-modal!)
|
|
|
(route-handler/redirect! {:to :repos}))))}
|
|
@@ -385,8 +387,13 @@
|
|
|
|
|
|
(defn preferred-pasting-file [t preferred-pasting-file?]
|
|
|
(toggle "preferred_pasting_file"
|
|
|
- (t :settings-page/preferred-pasting-file)
|
|
|
- preferred-pasting-file?
|
|
|
+ [(t :settings-page/preferred-pasting-file)
|
|
|
+ (ui/tippy {:html (t :settings-page/preferred-pasting-file-hint)
|
|
|
+ :class "tippy-hover ml-2"
|
|
|
+ :interactive true
|
|
|
+ :disabled false}
|
|
|
+ (svg/info))]
|
|
|
+ preferred-pasting-file?
|
|
|
config-handler/toggle-preferred-pasting-file!))
|
|
|
|
|
|
(defn auto-expand-row [t auto-expand-block-refs?]
|
|
@@ -610,6 +617,19 @@
|
|
|
(fn [_] (conversion-component/files-breaking-changed))
|
|
|
{:id :filename-format-panel :center? true})}))
|
|
|
|
|
|
+(rum/defcs native-titlebar-row < rum/reactive
|
|
|
+ [state t]
|
|
|
+ (let [enabled? (state/sub [:electron/user-cfgs :window/native-titlebar?])]
|
|
|
+ (toggle
|
|
|
+ "native-titlebar"
|
|
|
+ (t :settings-page/native-titlebar)
|
|
|
+ enabled?
|
|
|
+ #(when (js/confirm (t :relaunch-confirm-to-work))
|
|
|
+ (state/set-state! [:electron/user-cfgs :window/native-titlebar?] (not enabled?))
|
|
|
+ (ipc/ipc :userAppCfgs :window/native-titlebar? (not enabled?))
|
|
|
+ (js/logseq.api.relaunch))
|
|
|
+ [:span.text-sm.opacity-50 (t :settings-page/native-titlebar-desc)])))
|
|
|
+
|
|
|
(rum/defcs settings-general < rum/reactive
|
|
|
[_state current-repo]
|
|
|
(let [preferred-language (state/sub [:preferred-language])
|
|
@@ -621,6 +641,7 @@
|
|
|
(version-row t version)
|
|
|
(language-row t preferred-language)
|
|
|
(theme-modes-row t switch-theme system-theme? dark?)
|
|
|
+ (when (and (util/electron?) (not util/mac?)) (native-titlebar-row t))
|
|
|
(when (config/global-config-enabled?) (edit-global-config-edn))
|
|
|
(when current-repo (edit-config-edn))
|
|
|
(when current-repo (edit-custom-css))
|
|
@@ -669,18 +690,16 @@
|
|
|
[:div.text-sm.my-4
|
|
|
(ui/admonition
|
|
|
:tip
|
|
|
- [:p "If you have Logseq Sync enabled, you can view a page's edit history directly. This section is for tech-savvy only."])
|
|
|
+ [:p (t :settings-page/git-tip)])
|
|
|
[:span.text-sm.opacity-50.my-4
|
|
|
- "To view page's edit history, click the three horizontal dots in the top-right corner and select \"View page history\"."]
|
|
|
+ (t :settings-page/git-desc-1)]
|
|
|
[:br][:br]
|
|
|
[:span.text-sm.opacity-50.my-4
|
|
|
- "For professional users, Logseq also supports using "]
|
|
|
+ (t :settings-page/git-desc-2)]
|
|
|
[:a {:href "https://git-scm.com/" :target "_blank"}
|
|
|
"Git"]
|
|
|
[:span.text-sm.opacity-50.my-4
|
|
|
- " for version control."]
|
|
|
- [:span.text-sm.opacity-50.my-4
|
|
|
- "Use Git at your own risk as general Git issues are not supported by the Logseq team"]]
|
|
|
+ (t :settings-page/git-desc-3)]]
|
|
|
[:br]
|
|
|
(switch-git-auto-commit-row t)
|
|
|
(git-auto-commit-seconds t)
|
|
@@ -731,6 +750,196 @@
|
|
|
{:left-label (t :settings-page/enable-whiteboards)
|
|
|
:action (whiteboards-enabled-switcher enabled?)}))
|
|
|
|
|
|
+(rum/defc settings-account-usage-description [pro-account? graph-usage]
|
|
|
+ (let [count-usage (count graph-usage)
|
|
|
+ count-limit (if pro-account? 10 1)
|
|
|
+ count-percent (js/Math.round (/ count-usage count-limit 0.01))
|
|
|
+ storage-usage (->> (map :used-gbs graph-usage)
|
|
|
+ (reduce + 0))
|
|
|
+ storage-usage-formatted (cond
|
|
|
+ (zero? storage-usage) "0.0"
|
|
|
+ (< storage-usage 0.01) "Less than 0.01"
|
|
|
+ :else (gstring/format "%.2f" storage-usage))
|
|
|
+ ;; TODO: check logic on this. What are the rules around storage limits?
|
|
|
+ ;; do we, and should we be able to, give individual users more storage?
|
|
|
+ ;; should that be on a per graph or per user basis?
|
|
|
+ default-storage-limit (if pro-account? 10 0.05)
|
|
|
+ storage-limit (->> (range 0 count-limit)
|
|
|
+ (map #(get-in graph-usage [% :limit-gbs] default-storage-limit))
|
|
|
+ (reduce + 0))
|
|
|
+ storage-percent (/ storage-usage storage-limit 0.01)
|
|
|
+ storage-percent-formatted (gstring/format "%.1f" storage-percent)]
|
|
|
+ [:div.text-sm
|
|
|
+ (when pro-account?
|
|
|
+ [:<>
|
|
|
+ (gstring/format "%s of %s synced graphs " count-usage count-limit)
|
|
|
+ [:strong.text-white (gstring/format "(%s%%)" count-percent)]
|
|
|
+ ", "])
|
|
|
+ (gstring/format "%sGB of %sGB total storage " storage-usage-formatted storage-limit)
|
|
|
+ [:strong.text-white (gstring/format "(%s%%)" storage-percent-formatted)]]))
|
|
|
+ ; storage-usage-formatted "GB of " storage-limit "GB total storage"
|
|
|
+ ; [:strong.text-white " (" storage-percent-formatted "%)"]]))
|
|
|
+
|
|
|
+
|
|
|
+(rum/defc settings-account-usage-graphs [_pro-account? graph-usage]
|
|
|
+ (when (< 0 (count graph-usage))
|
|
|
+ [:div.grid.gap-3 {:style {:grid-template-columns (str "repeat(" (count graph-usage) ", 1fr)")}}
|
|
|
+ (for [{:keys [name used-percent]} graph-usage
|
|
|
+ :let [color (if (<= 100 used-percent) "bg-red-500" "bg-blue-500")]]
|
|
|
+ [:div.rounded-full.w-full.h-2 {:class "bg-black/50"
|
|
|
+ :tooltip name}
|
|
|
+ [:div.rounded-full.h-2 {:class color
|
|
|
+ :style {:width (str used-percent "%")
|
|
|
+ :min-width "0.5rem"
|
|
|
+ :max-width "100%"}}]])]))
|
|
|
+
|
|
|
+(rum/defc ^:large-vars/cleanup-todo settings-account < rum/reactive
|
|
|
+ []
|
|
|
+ (let [current-graph-uuid (state/sub-current-file-sync-graph-uuid)
|
|
|
+ graph-usage (state/get-remote-graph-usage)
|
|
|
+ current-graph-is-remote? ((set (map :uuid graph-usage)) current-graph-uuid)
|
|
|
+ logged-in? (user-handler/logged-in?)
|
|
|
+ user-info (state/get-user-info)
|
|
|
+ paid-user? (#{"active" "on_trial" "cancelled"} (:LemonStatus user-info))
|
|
|
+ gift-user? (some #{"pro"} (:UserGroups user-info))
|
|
|
+ pro-account? (or paid-user? gift-user?)
|
|
|
+ expiration-date (some-> user-info :LemonEndsAt date/parse-iso)
|
|
|
+ renewal-date (some-> user-info :LemonRenewsAt date/parse-iso)
|
|
|
+ has-subscribed? (some? (:LemonStatus user-info))]
|
|
|
+ [:div.panel-wrap.is-features.mb-8
|
|
|
+ [:div.mt-1.sm:mt-0.sm:col-span-2
|
|
|
+ (cond
|
|
|
+ logged-in?
|
|
|
+ [:div.grid.grid-cols-3.gap-8.pt-2
|
|
|
+ [:div "Current plan"]
|
|
|
+ [:div.col-span-2
|
|
|
+ [:div {:class "w-full bg-gray-500/10 rounded-lg p-4 flex flex-col gap-4"}
|
|
|
+ [:div.flex.gap-4.items-center
|
|
|
+ (if pro-account?
|
|
|
+ [:div.flex-1 "Pro"]
|
|
|
+ [:div.flex-1 "Free"])
|
|
|
+ (cond
|
|
|
+ has-subscribed?
|
|
|
+ (ui/button "Manage plan" {:class "p-1 h-8 justify-center"
|
|
|
+ :disabled true
|
|
|
+ :icon "upload"})
|
|
|
+ ; :on-click user-handler/upgrade})
|
|
|
+ (not pro-account?)
|
|
|
+ (ui/button "Upgrade plan" {:class "p-1 h-8 justify-center"
|
|
|
+ :icon "upload"
|
|
|
+ :on-click user-handler/upgrade})
|
|
|
+ :else nil)]
|
|
|
+ (settings-account-usage-graphs pro-account? graph-usage)
|
|
|
+ (settings-account-usage-description pro-account? graph-usage)
|
|
|
+ (if current-graph-is-remote?
|
|
|
+ (ui/button "Deactivate syncing" {:class "p-1 h-8 justify-center"
|
|
|
+ :disabled true
|
|
|
+ :background "gray"
|
|
|
+ :icon "cloud-off"})
|
|
|
+ (ui/button "Activate syncing" {:class "p-1 h-8 justify-center"
|
|
|
+ :background "blue"
|
|
|
+ :icon "cloud"
|
|
|
+ :on-click #(fs/maybe-onboarding-show :sync-initiate)}))]]
|
|
|
+ (when has-subscribed?
|
|
|
+ [:<>
|
|
|
+ [:div "Billing"]
|
|
|
+ [:div.col-span-2.flex.flex-col.gap-4
|
|
|
+ (cond
|
|
|
+ ;; If there is no expiration date, print the renewal date
|
|
|
+ (and renewal-date (nil? expiration-date))
|
|
|
+ [:div
|
|
|
+ [:strong.font-semibold "Next billing date: "
|
|
|
+ (date/get-locale-string renewal-date)]]
|
|
|
+ ;; If the expiration date is in the future, word it as such
|
|
|
+ (< (js/Date.) expiration-date)
|
|
|
+ [:div
|
|
|
+ [:strong.font-semibold "Pro plan expires on: "
|
|
|
+ (date/get-locale-string expiration-date)]]
|
|
|
+ ;; Otherwise, ind
|
|
|
+ :else
|
|
|
+ [:div
|
|
|
+ [:strong.font-semibold "Pro plan expired on: "
|
|
|
+ (date/get-locale-string expiration-date)]])
|
|
|
+
|
|
|
+ [:div (ui/button "Open invoices" {:class "w-full h-8 p-1 justify-center"
|
|
|
+ :disabled true
|
|
|
+ :background "gray"
|
|
|
+ :icon "receipt"})]]])
|
|
|
+ [:div "Profile"]
|
|
|
+ [:div.col-span-2.grid.grid-cols-2.gap-4
|
|
|
+ [:div.flex.flex-col.gap-2.box-border {:class "basis-1/2"}
|
|
|
+ [:label.text-sm.font-semibold "First name"]
|
|
|
+ [:input.rounded.border.px-2.py-1.box-border {:class "border-blue-500 bg-black/25 w-full"}]]
|
|
|
+ [:div.flex.flex-col.gap-2 {:class "basis-1/2"}
|
|
|
+ [:label.text-sm.font-semibold "Last name"]
|
|
|
+ [:input.rounded.border.px-2.py-1.box-border {:class "border-blue-500 bg-black/25 w-full"}]]
|
|
|
+ [:div.flex-1.flex.flex-col.gap-2.col-span-2
|
|
|
+ [:label.text-sm.font-semibold "Username"]
|
|
|
+ [:input.rounded.border.px-2.py-1.box-border {:class "border-blue-500 bg-black/25"
|
|
|
+ :value (user-handler/email)}]]]
|
|
|
+ [:div "Authentication"]
|
|
|
+ [:div.col-span-2
|
|
|
+ [:div.grid.grid-cols-2.gap-4
|
|
|
+ [:div (ui/button (t :logout) {:class "p-1 h-8 justify-center w-full"
|
|
|
+ :background "gray"
|
|
|
+ :icon "logout"
|
|
|
+ :on-click user-handler/logout})]
|
|
|
+ [:div (ui/button "Reset password" {:class "p-1 h-8 justify-center w-full"
|
|
|
+ :disabled true
|
|
|
+ :background "gray"
|
|
|
+ :icon "key"
|
|
|
+ :on-click user-handler/logout})]
|
|
|
+ [:div.col-span-2 (ui/button "Delete Account" {:class "p-1 h-8 justify-center w-full"
|
|
|
+ :disabled true
|
|
|
+ :background "red"})]]]]
|
|
|
+
|
|
|
+ (not logged-in?)
|
|
|
+ [:div.grid.grid-cols-3.gap-8.pt-2
|
|
|
+ [:div "Authentication"]
|
|
|
+ [:div.col-span-2.flex.flex-wrap.gap-4
|
|
|
+ [:div.w-full.text-white "With a Logseq account, you can access cloud-based services like Logseq Sync and alpha/beta features."]
|
|
|
+ [:div.flex-1 (ui/button "Sign up" {:class "h-8 w-full text-center justify-center"
|
|
|
+ :on-click (fn []
|
|
|
+ (state/close-settings!)
|
|
|
+ (state/pub-event! [:user/login]))})]
|
|
|
+ [:div.flex-1 (ui/button (t :login) {:icon "login"
|
|
|
+ :class "h-8 w-full text-center justify-center"
|
|
|
+ :background "gray"
|
|
|
+ :on-click (fn []
|
|
|
+ (state/close-settings!)
|
|
|
+ (state/pub-event! [:user/login]))})]]
|
|
|
+ [:div.col-span-3.flex.flex-col.gap-4 {:class "bg-black/20 p-4 rounded-lg"}
|
|
|
+ [:div.flex.w-full.items-center
|
|
|
+ [:div {:class "w-1/2 text-lg"}
|
|
|
+ "Discover the power of "
|
|
|
+ [:strong {:class "text-white/80"} "Logseq Sync"]]
|
|
|
+ [:div {:class "w-1/2 bg-gradient-to-r from-white/10 to-transparent p-3 rounded-lg flex items-center gap-2 px-5 ml-5"}
|
|
|
+ [:div.w-3.h-3.rounded-full.bg-green-500]
|
|
|
+ "Synced"]]
|
|
|
+ [:div.flex.w-full.gap-4
|
|
|
+ [:div {:class "w-1/2 bg-black/50 rounded-lg p-4 pt-10 relative flex flex-col gap-4"}
|
|
|
+ [:div.absolute.top-0.left-4.bg-gray-700.uppercase.px-2.py-1.rounded-b-lg.font-bold.text-xs "Free"]
|
|
|
+ [:div
|
|
|
+ [:strong.text-white.text-xl.font-normal "$0"]]
|
|
|
+ [:div.text-white.font-bold {:class "h-[2.5rem] "} "Get started with basic syncing"]
|
|
|
+ [:ul.text-xs.list-none.m-0.flex.flex-col.gap-0.5
|
|
|
+ [:li "Unlimited unsynced graphs"]
|
|
|
+ [:li "1 synced graph (up to 50MB, notes only)"]
|
|
|
+ [:li "No asset syncing"]
|
|
|
+ [:li "Access to core Logseq features"]]]
|
|
|
+ [:div {:class "w-1/2 bg-black/50 rounded-lg p-4 pt-10 relative flex flex-col gap-4"}
|
|
|
+ [:div.absolute.top-0.left-4.bg-blue-700.uppercase.px-2.py-1.rounded-b-lg.font-bold.text-xs "Pro"]
|
|
|
+ [:div
|
|
|
+ [:strong.text-white.text-xl.font-normal "$10"]
|
|
|
+ [:span.text-xs.font-base {:class "ml-0.5"} "/ month"]]
|
|
|
+ [:div.text-white.font-bold {:class "h-[2.5rem]"} "Unlock advanced syncing and more"]
|
|
|
+ [:ul.text-xs.list-none.m-0.flex.flex-col.gap-0.5
|
|
|
+ [:li "Unlimited unsynced graphs"]
|
|
|
+ [:li "10 synced graphs (up to 5GB each)"]
|
|
|
+ [:li "Sync assets up to 100MB per file"]
|
|
|
+ [:li "Early access to alpha/beta features"]
|
|
|
+ [:li "Upcoming cloud-based features, including Logseq Publish"]]]]]])]]))
|
|
|
+
|
|
|
(rum/defc settings-features < rum/reactive
|
|
|
[]
|
|
|
(let [current-repo (state/get-current-repo)
|
|
@@ -786,11 +995,11 @@
|
|
|
{:class (when-not user-handler/alpha-or-beta-user? "opacity-50 pointer-events-none cursor-not-allowed")}
|
|
|
(sync-switcher-row enable-sync?)
|
|
|
[:div.text-sm
|
|
|
- "Click"
|
|
|
+ (t :settings-page/sync-desc-1)
|
|
|
[:a.mx-1 {:href "https://blog.logseq.com/how-to-setup-and-use-logseq-sync/"
|
|
|
:target "_blank"}
|
|
|
- "here"]
|
|
|
- "for instructions on how to set up and use Sync."]]])
|
|
|
+ (t :settings-page/sync-desc-2)]
|
|
|
+ (t :settings-page/sync-desc-3)]]])]))
|
|
|
|
|
|
;; (when-not web-platform?
|
|
|
;; [:<>
|
|
@@ -801,10 +1010,12 @@
|
|
|
;; {:class (when-not user-handler/alpha-user? "opacity-50 pointer-events-none cursor-not-allowed")}
|
|
|
;; ;; features
|
|
|
;; ]])
|
|
|
- ]))
|
|
|
+
|
|
|
+
|
|
|
+(def DEFAULT-ACTIVE-TAB-STATE (if config/ENABLE-SETTINGS-ACCOUNT-TAB [:account :account] [:general :general]))
|
|
|
|
|
|
(rum/defcs settings
|
|
|
- < (rum/local [:general :general] ::active)
|
|
|
+ < (rum/local DEFAULT-ACTIVE-TAB-STATE ::active)
|
|
|
{:will-mount
|
|
|
(fn [state]
|
|
|
(state/load-app-user-cfgs)
|
|
@@ -822,15 +1033,18 @@
|
|
|
*active (::active state)]
|
|
|
|
|
|
[:div#settings.cp__settings-main
|
|
|
- [:header
|
|
|
- [:h1.title (t :settings)]]
|
|
|
|
|
|
[:div.cp__settings-inner
|
|
|
|
|
|
[:aside.md:w-64 {:style {:min-width "10rem"}}
|
|
|
+ [:header.cp__settings-header
|
|
|
+ (ui/icon "settings")
|
|
|
+ [:h1.cp__settings-modal-title (t :settings)]]
|
|
|
[:ul.settings-menu
|
|
|
(for [[label id text icon]
|
|
|
- [[:general "general" (t :settings-page/tab-general) (ui/icon "adjustments")]
|
|
|
+ [(when config/ENABLE-SETTINGS-ACCOUNT-TAB
|
|
|
+ [:account "account" (t :settings-page/tab-account) (ui/icon "user-circle")])
|
|
|
+ [:general "general" (t :settings-page/tab-general) (ui/icon "adjustments")]
|
|
|
[:editor "editor" (t :settings-page/tab-editor) (ui/icon "writing")]
|
|
|
|
|
|
(when (util/electron?)
|
|
@@ -852,11 +1066,13 @@
|
|
|
:on-click #(reset! *active [label (first @*active)])}
|
|
|
|
|
|
[:a.flex.items-center.settings-menu-link
|
|
|
- {:data-id id}
|
|
|
+ {:data-id id}
|
|
|
icon
|
|
|
[:strong text]]]))]]
|
|
|
|
|
|
[:article
|
|
|
+ [:header.cp__settings-header
|
|
|
+ [:h1.cp__settings-category-title (name (first @*active))]]
|
|
|
|
|
|
(case (first @*active)
|
|
|
|
|
@@ -866,6 +1082,9 @@
|
|
|
(reset! *active [label label])
|
|
|
nil)
|
|
|
|
|
|
+ :account
|
|
|
+ (settings-account)
|
|
|
+
|
|
|
:general
|
|
|
(settings-general current-repo)
|
|
|
|