mirror of
https://github.com/logseq/logseq.git
synced 2026-05-23 20:24:15 +00:00
205 lines
7.6 KiB
Clojure
205 lines
7.6 KiB
Clojure
(ns mobile.components.header
|
|
"App top header"
|
|
(:require [clojure.string :as string]
|
|
[frontend.common.missionary :as c.m]
|
|
[frontend.components.repo :as repo]
|
|
[frontend.components.rtc.indicator :as rtc-indicator]
|
|
[frontend.date :as date]
|
|
[frontend.db :as db]
|
|
[frontend.db.async :as db-async]
|
|
[frontend.db.conn :as db-conn]
|
|
[frontend.handler.page :as page-handler]
|
|
[frontend.handler.route :as route-handler]
|
|
[frontend.handler.user :as user-handler]
|
|
[frontend.mobile.util :as mobile-util]
|
|
[frontend.state :as state]
|
|
[frontend.ui :as ui]
|
|
[frontend.util :as util]
|
|
[goog.date :as gdate]
|
|
[logseq.common.util :as common-util]
|
|
[logseq.db :as ldb]
|
|
[logseq.shui.hooks :as hooks]
|
|
[logseq.shui.ui :as shui]
|
|
[missionary.core :as m]
|
|
[mobile.components.ui :as ui-component]
|
|
[mobile.state :as mobile-state]
|
|
[promesa.core :as p]
|
|
[rum.core :as rum]))
|
|
|
|
(defonce native-top-bar-listener? (atom false))
|
|
|
|
(defn- open-journal-calendar! []
|
|
(let [apply-date! (fn [date]
|
|
(let [page-name (date/journal-name (gdate/Date. (js/Date. date)))]
|
|
(if-let [journal (db/get-page page-name)]
|
|
(route-handler/redirect-to-page! (:block/uuid journal))
|
|
(p/let [page (page-handler/<create! page-name {:redirect? false})]
|
|
(route-handler/redirect-to-page! (:block/uuid page))))))]
|
|
(-> (.showDatePicker mobile-util/ui-local)
|
|
(p/then (fn [^js e] (some-> e (.-value) (apply-date!)))))))
|
|
|
|
(rum/defc log
|
|
[]
|
|
(let [[error-only? set-error-only!] (hooks/use-state false)
|
|
[reversed? set-reversed!] (hooks/use-state false)
|
|
[show-worker-log? set-show-worker-log!] (hooks/use-state false)
|
|
[worker-records set-worker-records!] (hooks/use-state [])]
|
|
(hooks/use-effect!
|
|
#(c.m/run-task*
|
|
(m/sp
|
|
(set-worker-records! (c.m/<? (state/<invoke-db-worker :thread-api/mobile-logs)))))
|
|
[])
|
|
[:div.flex.flex-col.gap-1.p-2.ls-debug-log
|
|
[:div.flex.flex-row.justify-between
|
|
[:div.text-lg.font-medium.mb-2 "Full log: "]
|
|
|
|
(shui/button
|
|
{:variant :ghost
|
|
:size :sm
|
|
:on-click (fn []
|
|
(util/copy-to-clipboard! (str (string/join "\n\n" @mobile-state/*log)
|
|
"\n\n================================================================\n\n"
|
|
(string/join "\n\n" worker-records))))}
|
|
"Copy")]
|
|
|
|
[:div.flex.flex-row.gap-2
|
|
(shui/button
|
|
{:size :sm
|
|
:on-click (fn []
|
|
(set-error-only! (not error-only?)))}
|
|
(if error-only?
|
|
"All"
|
|
"Errors only"))
|
|
|
|
(shui/button
|
|
{:size :sm
|
|
:on-click (fn []
|
|
(set-reversed! (not reversed?)))}
|
|
(if reversed?
|
|
"New record first"
|
|
"Old record first"))
|
|
|
|
(shui/button
|
|
{:size :sm
|
|
:on-click (fn []
|
|
(set-show-worker-log! (not show-worker-log?)))}
|
|
(if show-worker-log?
|
|
"UI logs"
|
|
"worker logs"))]
|
|
|
|
(let [records (cond->> (if show-worker-log? worker-records @mobile-state/*log)
|
|
error-only?
|
|
(filter (fn [record] (contains? #{:error :severe} (:level record))))
|
|
reversed?
|
|
reverse)]
|
|
[:ul
|
|
(for [record records]
|
|
[:li (str (:level record) " " (:message record))])])]))
|
|
|
|
(defn- open-settings-actions! []
|
|
(ui-component/open-popup!
|
|
(fn []
|
|
[:div
|
|
(when (user-handler/logged-in?)
|
|
(ui/menu-link {:on-click #(user-handler/logout)}
|
|
[:span.text-lg.flex.gap-2.items-center.text-red-700
|
|
(shui/tabler-icon "logout" {:class "opacity-80" :size 22})
|
|
"Logout"]))
|
|
(ui/menu-link {:on-click #(js/window.open "https://github.com/logseq/db-test/issues")}
|
|
[:span.text-lg.flex.gap-2.items-center
|
|
(shui/tabler-icon "bug" {:class "opacity-70" :size 22})
|
|
"Report bug"])
|
|
(ui/menu-link {:on-click (fn []
|
|
(shui/popup-show! nil (fn [] (log)) {}))}
|
|
[:span.text-lg.flex.gap-2.items-center
|
|
"Check log"])])
|
|
{:title "Actions"
|
|
:default-height false}))
|
|
|
|
(defn- open-graph-switcher! []
|
|
(ui-component/open-popup!
|
|
(fn []
|
|
[:div.px-1
|
|
(repo/repos-dropdown-content {})])
|
|
{:title "Select a Graph"
|
|
:default-height false}))
|
|
|
|
(defn- register-native-top-bar-events! []
|
|
(when (and (mobile-util/native-ios?)
|
|
(not @native-top-bar-listener?))
|
|
(.addListener mobile-util/native-top-bar "buttonTapped"
|
|
(fn [^js e]
|
|
(case (.-id e)
|
|
"title" (open-graph-switcher!)
|
|
"calendar" (open-journal-calendar!)
|
|
"settings-actions" (open-settings-actions!)
|
|
nil)))
|
|
(reset! native-top-bar-listener? true)))
|
|
|
|
(defn- configure-native-top-bar!
|
|
[{:keys [tab title route-name]}]
|
|
(when (mobile-util/native-ios?)
|
|
(let [hidden? (and (= tab "search")
|
|
(not= route-name :page))
|
|
base {:title title
|
|
:hidden (boolean hidden?)}
|
|
right-buttons (cond
|
|
(= tab "home")
|
|
[{:id "calendar" :systemIcon "calendar"}]
|
|
|
|
(= tab "settings")
|
|
[{:id "settings-actions" :systemIcon "ellipsis"}]
|
|
|
|
:else nil)
|
|
header (cond-> base
|
|
right-buttons (assoc :rightButtons right-buttons)
|
|
(= tab "home") (assoc :titleClickable true))]
|
|
(.configure mobile-util/native-top-bar
|
|
(clj->js header)))))
|
|
|
|
(rum/defc rtc-indicator-btn
|
|
[]
|
|
(let [repo (state/get-current-repo)]
|
|
[:div.flex.flex-row.items-center.gap-2
|
|
(when (and repo
|
|
(ldb/get-graph-rtc-uuid (db/get-db))
|
|
(user-handler/logged-in?))
|
|
(rtc-indicator/indicator))]))
|
|
|
|
(rum/defc header-inner
|
|
[current-repo tab route-match]
|
|
(let [short-repo-name (if current-repo
|
|
(db-conn/get-short-repo-name current-repo)
|
|
"Select a Graph")
|
|
route-name (get-in route-match [:data :name])]
|
|
(hooks/use-effect!
|
|
(fn []
|
|
(when (mobile-util/native-ios?)
|
|
(register-native-top-bar-events!)
|
|
(p/let [block (when (= route-name :page)
|
|
(let [id (get-in route-match [:parameters :path :name])]
|
|
(when (common-util/uuid-string? id)
|
|
(db-async/<get-block current-repo (uuid id) {:children? false}))))
|
|
title (cond block
|
|
(:block/title block)
|
|
(= tab "home")
|
|
short-repo-name
|
|
:else
|
|
(string/capitalize tab))]
|
|
(configure-native-top-bar!
|
|
{:tab tab
|
|
:title title
|
|
:hidden? (and (= tab "search")
|
|
(not= route-name :page))
|
|
:route-name route-name})))
|
|
nil)
|
|
[tab short-repo-name route-match])
|
|
|
|
[:<>]))
|
|
|
|
(rum/defc header < rum/reactive
|
|
[current-repo tab]
|
|
(let [route-match (state/sub :route-match)]
|
|
(header-inner current-repo tab
|
|
route-match)))
|