Right sidebar wip

pull/645/head
Tienson Qin 2020-05-18 18:50:08 +08:00
parent fd798c1f90
commit 02821613b0
12 changed files with 266 additions and 95 deletions

View File

@ -76,9 +76,10 @@
(state/hide-custom-context-menu!) (state/hide-custom-context-menu!)
;; enable scroll ;; enable scroll
(let [main (d/by-id "main")] (let [main (d/by-id "main-content")]
(d/remove-class! main "overflow-hidden") (d/remove-class! main "overflow-hidden")
(d/add-class! main "overflow-y-scroll")) (d/add-class! main "overflow-y-auto")
)
(handler/clear-selection!))) (handler/clear-selection!)))
@ -88,9 +89,9 @@
(util/stop e) (util/stop e)
(let [client-x (gobj/get e "clientX") (let [client-x (gobj/get e "clientX")
client-y (gobj/get e "clientY")] client-y (gobj/get e "clientY")]
(let [main (d/by-id "main")] (let [main (d/by-id "main-content")]
;; disable scroll ;; disable scroll
(d/remove-class! main "overflow-y-scroll") (d/remove-class! main "overflow-y-auto")
(d/add-class! main "overflow-hidden")) (d/add-class! main "overflow-hidden"))
(state/show-custom-context-menu!) (state/show-custom-context-menu!)

View File

@ -176,10 +176,8 @@
["Target" s] ["Target" s]
[:a {:id s} s] [:a {:id s} s]
["Radio_Target" s] ["Radio_Target" s]
[:a {:id s} s] [:a {:id s} s]
;; [:a {:href (str "/page/" (util/url-encode s))} (str "<<<" s ">>>")]
["Email" address] ["Email" address]
(let [{:keys [local_part domain]} address (let [{:keys [local_part domain]} address
@ -194,7 +192,13 @@
(when-let [heading (db/get-heading-by-uuid (uuid id))] (when-let [heading (db/get-heading-by-uuid (uuid id))]
[:span [:span
[:span.text-gray-500 "(("] [:span.text-gray-500 "(("]
[:a {:href (str "/page/" id)} [:a {:href (str "/page/" id)
:on-click (fn [e]
(util/stop e)
(when (gobj/get e "shiftKey")
(state/sidebar-add-block! :heading-ref {:heading (:heading config)
:ref-heading heading})
(handler/show-right-sidebar)))}
(->elem :span.block-ref (->elem :span.block-ref
(map-inline config (:heading/title heading)))] (map-inline config (:heading/title heading)))]
[:span.text-gray-500 "))"]]))) [:span.text-gray-500 "))"]])))
@ -212,7 +216,14 @@
;; page reference ;; page reference
[:span.page-reference [:span.page-reference
[:span.text-gray-500 "[["] [:span.text-gray-500 "[["]
[:a {:href (str "/page/" (util/url-encode s))} s] [:a {:href (str "/page/" (util/url-encode s))
:on-click (fn [e]
(util/stop e)
(when (gobj/get e "shiftKey")
(state/sidebar-add-block! :page-ref
{:heading (:heading config)
:ref-page s})
(handler/show-right-sidebar)))} s]
[:span.text-gray-500 "]]"]]) [:span.text-gray-500 "]]"]])
:else :else
(let [href (string-of-url url) (let [href (string-of-url url)
@ -222,8 +233,8 @@
(->elem (->elem
:a :a
(cond-> (cond->
{:href href {:href href
:target "_blank"} :target "_blank"}
title title
(assoc :title title)) (assoc :title title))
(map-inline config label)))))) (map-inline config label))))))
@ -344,10 +355,15 @@
[:span ""])] [:span ""])]
[:a.flex.flex-row.items-center.justify-center [:a.flex.flex-row.items-center.justify-center
(cond-> (cond->
{:style {:width 14 {:style {:width 14
:height 24}} :height 24}}
(not dummy?) (not dummy?)
(assoc :href (str "/page/" uuid))) (assoc :href (str "/page/" uuid)
:on-click (fn [e]
(util/stop e)
(when (gobj/get e "shiftKey")
(state/sidebar-add-block! :heading (:heading config))
(handler/show-right-sidebar)))))
[:svg {:height 10 [:svg {:height 10
:width 10 :width 10
:fill "currentColor" :fill "currentColor"
@ -359,7 +375,8 @@
(rum/defcs heading-cp < rum/reactive (rum/defcs heading-cp < rum/reactive
(rum/local false ::collapsed?) (rum/local false ::collapsed?)
[state {:heading/keys [uuid idx level children meta content dummy? lock? show-page? page format] :as heading} heading-part config] [state {:heading/keys [uuid idx level children meta content dummy? lock? show-page? page format] :as heading} heading-part config]
(let [ref? (boolean (:ref? config)) (let [config (assoc config :heading heading)
ref? (boolean (:ref? config))
edit-input-id (str "edit-heading-" (if ref? (:id config)) uuid) edit-input-id (str "edit-heading-" (if ref? (:id config)) uuid)
edit? (state/sub [:editor/editing? edit-input-id]) edit? (state/sub [:editor/editing? edit-input-id])
heading-id (str "ls-heading-parent-" (if ref? (:id config)) uuid) heading-id (str "ls-heading-parent-" (if ref? (:id config)) uuid)
@ -417,8 +434,7 @@
(swap! state/state assoc (swap! state/state assoc
:edit-content content :edit-content content
:edit-heading heading) :edit-heading heading)
(state/set-edit-input-id! edit-input-id) (state/set-edit-input-id! edit-input-id)))}
))}
heading-part heading-part
;; non-heading children ;; non-heading children
@ -452,7 +468,8 @@
(defn heading (defn heading
[config {:heading/keys [uuid title tags marker level priority anchor meta numbering children format] [config {:heading/keys [uuid title tags marker level priority anchor meta numbering children format]
:as t}] :as t}]
(let [agenda? (= (:id config) "agenda") (let [config (assoc config :heading t)
agenda? (= (:id config) "agenda")
checkbox (heading-checkbox t checkbox (heading-checkbox t
(str "mr-1 cursor")) (str "mr-1 cursor"))
marker-cp (if (contains? #{"DOING" "IN-PROGRESS" "WAIT"} marker) marker-cp (if (contains? #{"DOING" "IN-PROGRESS" "WAIT"} marker)

View File

@ -3,13 +3,15 @@
[frontend.util :as util] [frontend.util :as util]
[frontend.handler :as handler] [frontend.handler :as handler]
[frontend.db :as db] [frontend.db :as db]
[frontend.state :as state]
[clojure.string :as string] [clojure.string :as string]
[frontend.ui :as ui] [frontend.ui :as ui]
[frontend.format :as format] [frontend.format :as format]
[frontend.components.content :as content] [frontend.components.content :as content]
[frontend.components.hiccup :as hiccup] [frontend.components.hiccup :as hiccup]
[frontend.components.reference :as reference] [frontend.components.reference :as reference]
[frontend.utf8 :as utf8])) [frontend.utf8 :as utf8]
[goog.object :as gobj]))
(rum/defc journal-cp (rum/defc journal-cp
[[title headings format]] [[title headings format]]
@ -20,7 +22,12 @@
encoded-page-name (util/url-encode (string/capitalize title))] encoded-page-name (util/url-encode (string/capitalize title))]
[:div.flex-1 [:div.flex-1
[:a.initial-color {:href (str "/page/" encoded-page-name)} [:a.initial-color {:href (str "/page/" encoded-page-name)
:on-click (fn [e]
(util/stop e)
(when (gobj/get e "shiftKey")
(state/sidebar-add-block! :page {:name title})
(handler/show-right-sidebar)))}
[:h1.title [:h1.title
title]] title]]
(content/content encoded-page-name (content/content encoded-page-name

View File

@ -12,7 +12,8 @@
[frontend.format :as format] [frontend.format :as format]
[frontend.components.content :as content] [frontend.components.content :as content]
[frontend.config :as config] [frontend.config :as config]
[frontend.db :as db])) [frontend.db :as db]
[goog.object :as gobj]))
(defn- get-page-name (defn- get-page-name
[state] [state]
@ -31,7 +32,7 @@
;; A page is just a logical heading ;; A page is just a logical heading
(rum/defcs page < rum/reactive (rum/defcs page < rum/reactive
[state] [state option]
(let [encoded-page-name (get-page-name state) (let [encoded-page-name (get-page-name state)
page-name (string/capitalize (util/url-decode encoded-page-name)) page-name (string/capitalize (util/url-decode encoded-page-name))
format (db/get-page-format page-name) format (db/get-page-format page-name)
@ -46,13 +47,6 @@
hiccup (hiccup/->hiccup page-headings {:id encoded-page-name hiccup (hiccup/->hiccup page-headings {:id encoded-page-name
:start-level start-level}) :start-level start-level})
ref-headings (if heading-id
(db/get-heading-referenced-headings heading-id)
(db/get-page-referenced-headings page-name))
ref-headings (mapv (fn [heading] (assoc heading :heading/show-page? true)) ref-headings)
ref-hiccup (hiccup/->hiccup ref-headings {:id encoded-page-name
:start-level start-level})
page-name (string/capitalize page-name)
page-name (if heading? page-name (if heading?
(:page/name (db/entity (:db/id (:heading/page (first page-headings))))) (:page/name (db/entity (:db/id (:heading/page (first page-headings)))))
page-name) page-name)
@ -60,28 +54,30 @@
starred? (contains? (set starred? (contains? (set
(some->> (state/sub [:config repo :starred]) (some->> (state/sub [:config repo :starred])
(map string/capitalize))) (map string/capitalize)))
page-name)] page-name)
sidebar? (:sidebar? option)]
[:div.flex-1 [:div.flex-1
[:div.flex.flex-row (when-not sidebar?
[:h1.title [:div.flex.flex-row
page-name] [:a {:on-click (fn [e]
[:a.ml-1.text-gray-500.hover:text-gray-700 (util/stop e)
{:class (if starred? "text-gray-800") (when (gobj/get e "shiftKey")
:on-click (fn [] (state/sidebar-add-block! :page {:name page-name})
(handler/star-page! page-name starred?))} (handler/show-right-sidebar)))}
(if starred? [:h1.title
(svg/star-solid "stroke-current") page-name]]
(svg/star-outline "stroke-current h-5 w-5"))]] [:a.ml-1.text-gray-500.hover:text-gray-700
{:class (if starred? "text-gray-800")
:on-click (fn []
(handler/star-page! page-name starred?))}
(if starred?
(svg/star-solid "stroke-current")
(svg/star-outline "stroke-current h-5 w-5"))]])
(content/content encoded-page-name (content/content encoded-page-name
{:hiccup hiccup}) {:hiccup hiccup})
(let [n-ref (count ref-headings)] (reference/references page-name)]))
(if (> n-ref 0)
[:h2.font-bold.text-gray-400.mt-6 (let []
(str n-ref " Linked References"))]))
(content/content encoded-page-name
{:hiccup ref-hiccup})]))
(rum/defc all-pages < rum/reactive (rum/defc all-pages < rum/reactive
[] []

View File

@ -14,9 +14,13 @@
(rum/defc references < rum/reactive (rum/defc references < rum/reactive
[page-name] [page-name]
(let [page-name (string/capitalize page-name) (let [heading? (util/uuid-string? page-name)
heading-id (and heading? (uuid page-name))
page-name (string/capitalize page-name)
encoded-page-name (util/url-encode page-name) encoded-page-name (util/url-encode page-name)
ref-headings (db/get-page-referenced-headings page-name) ref-headings (if heading-id
(db/get-heading-referenced-headings heading-id)
(db/get-page-referenced-headings page-name))
ref-headings (mapv (fn [heading] (assoc heading :heading/show-page? true)) ref-headings) ref-headings (mapv (fn [heading] (assoc heading :heading/show-page? true)) ref-headings)
ref-hiccup (hiccup/->hiccup ref-headings {:id encoded-page-name ref-hiccup (hiccup/->hiccup ref-headings {:id encoded-page-name
:start-level 2 :start-level 2

View File

@ -0,0 +1,48 @@
(ns frontend.components.right-sidebar
(:require [rum.core :as rum]
[frontend.ui :as ui]
[frontend.components.svg :as svg]
[frontend.components.page :as page]
[frontend.handler :as handler]
[frontend.state :as state]
[medley.core :as medley]))
(defn sidebar-item
[block-type block-data]
(case block-type
:page-ref
["Page reference" (str block-data)]
:heading-ref
["Block reference" (str block-data)]
:heading
["Block " (str block-data)]
:page
(let [page-name (:name block-data)]
[page-name (page/page {:parameters {:path {:name page-name}}
:sidebar? true})])
["" [:span]]))
(rum/defc sidebar < rum/reactive
[]
(let [blocks (state/sub :sidebar/blocks)]
[:div#right-sidebar.flex.flex-col.p-2.shadow-xs.overflow-y-auto {:style {:padding-bottom 300}}
(for [[idx [block-type block-data]] (medley/indexed blocks)]
[:div.sidebar-item {:key (str "sidebar-block-" idx)}
(let [[title component] (sidebar-item block-type block-data)]
[:div.flex.flex-col
[:div.flex.flex-row.justify-between
[:div.flex.flex-row.justify-center
[:a.hover:text-gray-900.text-gray-500.flex.items-center
svg/plus]
[:div.ml-2 {:style {:font-size "1.5rem"}} title]]
[:a.close.hover:text-gray-900.text-gray-500.flex.items-center
{:on-click (fn []
(state/sidebar-remove-block! idx)
(when (empty? (state/get-sidebar-blocks))
(handler/hide-right-sidebar)))}
svg/close]]
[:div component]])])]))

View File

@ -8,6 +8,7 @@
[frontend.components.search :as search] [frontend.components.search :as search]
[frontend.components.settings :as settings] [frontend.components.settings :as settings]
[frontend.components.svg :as svg] [frontend.components.svg :as svg]
[frontend.components.right-sidebar :as right-sidebar]
[goog.crypt.base64 :as b64] [goog.crypt.base64 :as b64]
[frontend.util :as util] [frontend.util :as util]
[frontend.state :as state] [frontend.state :as state]
@ -29,25 +30,25 @@
(if current-repo (if current-repo
(let [repos (state/sub [:me :repos])] (let [repos (state/sub [:me :repos])]
(if (> (count repos) 1) (if (> (count repos) 1)
(ui/dropdown-with-links (ui/dropdown-with-links
(fn [{:keys [toggle-fn]}] (fn [{:keys [toggle-fn]}]
[:a.hover:text-gray-200.text-gray-500.font-bold {:on-click toggle-fn} [:a.hover:text-gray-200.text-gray-500.font-bold {:on-click toggle-fn}
[:span (string/capitalize (util/take-at-most (db/get-repo-name current-repo) 20))] [:span (string/capitalize (util/take-at-most (db/get-repo-name current-repo) 20))]
[:span.dropdown-caret.ml-1 {:style {:border-top-color "#6b7280"}}]]) [:span.dropdown-caret.ml-1 {:style {:border-top-color "#6b7280"}}]])
(mapv (mapv
(fn [{:keys [id url]}] (fn [{:keys [id url]}]
{:title (db/get-repo-name url) {:title (db/get-repo-name url)
:options {:on-click (fn [] :options {:on-click (fn []
(state/set-current-repo! url))}}) (state/set-current-repo! url))}})
(remove (fn [repo] (remove (fn [repo]
(= current-repo (:url repo))) (= current-repo (:url repo)))
repos)) repos))
(util/hiccup->class (util/hiccup->class
"origin-top-right.absolute.left-0.mt-2.w-48.rounded-md.shadow-lg ")) "origin-top-right.absolute.left-0.mt-2.w-48.rounded-md.shadow-lg "))
[:a.hover:text-gray-300.text-gray-400.font-bold [:a.hover:text-gray-300.text-gray-400.font-bold
{:href current-repo {:href current-repo
:target "_blank"} :target "_blank"}
(string/capitalize (util/take-at-most (db/get-repo-name current-repo) 20))])))) (string/capitalize (util/take-at-most (db/get-repo-name current-repo) 20))]))))
(defn nav-item (defn nav-item
[title href svg-d active? close-modal-fn] [title href svg-d active? close-modal-fn]
@ -187,15 +188,7 @@
[:a.hover:text-gray-200.text-gray-500 [:a.hover:text-gray-200.text-gray-500
{:style {:margin-right 13 {:style {:margin-right 13
:margin-top -1} :margin-top -1}
:on-click (fn [] :on-click handler/hide-left-sidebar}
(d/add-class! (d/by-id "menu")
"md:block")
(d/remove-class! (d/by-id "left-sidebar")
"enter")
(d/remove-class! (d/by-id "search")
"sidebar-open")
(d/remove-class! (d/by-id "main")
"sidebar-open"))}
(svg/menu "currentColor")] (svg/menu "currentColor")]
(repos current-repo close-fn) (repos current-repo close-fn)
]] ]]
@ -212,7 +205,8 @@
me (state/sub :me) me (state/sub :me)
current-repo (state/sub :git/current-repo) current-repo (state/sub :git/current-repo)
status (db/sub-key-value :git/status) status (db/sub-key-value :git/status)
pulling? (= :pulling status)] pulling? (= :pulling status)
right-sidebar? false]
[:div.h-screen.flex.overflow-hidden.bg-base-3 [:div.h-screen.flex.overflow-hidden.bg-base-3
[:div.md:hidden [:div.md:hidden
[:div.fixed.inset-0.z-30.bg-gray-600.opacity-0.pointer-events-none.transition-opacity.ease-linear.duration-300 [:div.fixed.inset-0.z-30.bg-gray-600.opacity-0.pointer-events-none.transition-opacity.ease-linear.duration-300
@ -291,28 +285,38 @@
(when (:email me) (when (:email me)
{:title "Sign out" {:title "Sign out"
:options {:on-click handler/sign-out!}})] :options {:on-click handler/sign-out!}})]
(remove nil?)))]]] (remove nil?)))
[:main#main.flex-1.relative.z-0.overflow-y-scroll.py-6.focus:outline-none.sidebar-open
{:tabIndex "0"} [:a.hover:text-gray-900.text-gray-500.ml-3
[:div.flex.justify-center {:on-click (fn []
[:div.flex-1.m-6 {:style {:position "relative" (let [sidebar (d/by-id "right-sidebar")]
:max-width 700 (if (d/has-class? sidebar "enter")
:margin-bottom 500}} (handler/hide-right-sidebar)
main-content]]] (handler/show-right-sidebar))))}
(svg/menu)]]]]
[:main#main.flex-1.relative.z-0.py-6.focus:outline-none.sidebar-open.overflow-hidden
{:tabIndex "0"
:style {:width "100%"
:height "100%"}}
[:div#main-content
{:style {:width "100%"
:height "100%"
:overflow-y "scroll"
:padding-right 17
:box-sizing "content-box"}}
[:div.flex.justify-center
[:div.flex-1.m-6#main-content-container
{:style {:position "relative"
:max-width 700
:margin-bottom 200}}
main-content]]]
(right-sidebar/sidebar)]
[:a#menu.mr-4.hover:text-gray-700.text-gray-500.absolute.hidden [:a#menu.mr-4.hover:text-gray-700.text-gray-500.absolute.hidden
{:style {:position "absolute" {:style {:position "absolute"
:top 6 :top 6
:left 16 :left 16
:z-index 111} :z-index 111}
:on-click (fn [] :on-click handler/show-left-sidebar}
(d/remove-class! (d/by-id "menu")
"md:block")
(d/add-class! (d/by-id "left-sidebar")
"enter")
(d/add-class! (d/by-id "search")
"sidebar-open")
(d/add-class! (d/by-id "main")
"sidebar-open"))}
(svg/menu "currentColor")] (svg/menu "currentColor")]
(ui/notification) (ui/notification)
(custom-context-menu)]])) (custom-context-menu)]]))

View File

@ -29,6 +29,42 @@
{:d "M7.5 8l-5 5L1 11.5 4.75 8 1 4.5 2.5 3l5 5z", {:d "M7.5 8l-5 5L1 11.5 4.75 8 1 4.5 2.5 3l5 5z",
:fill-rule "evenodd"}]]) :fill-rule "evenodd"}]])
(rum/defc big-arrow-right
[]
[:svg
{:fill "none", :view-box "0 0 24 24", :height "24", :width "24"}
[:path
{:stroke-linejoin "round",
:stroke-linecap "round",
:stroke-width "2",
:stroke "currentColor",
:d "M14 5L21 12M21 12L14 19M21 12L3 12"}]])
(rum/defc big-arrow-left
[]
[:svg
{:fill "none", :view-box "0 0 24 24", :height "24", :width "24"}
[:path
{:stroke-linejoin "round",
:stroke-linecap "round",
:stroke-width "2",
:stroke "currentColor",
:d "M10 19L3 12M3 12L10 5M3 12L21 12"}]])
(defn- hero-icon
[d]
[:svg
{:fill "none", :view-box "0 0 24 24", :height "24", :width "24"}
[:path
{:stroke-linejoin "round"
:stroke-linecap "round"
:stroke-width "2"
:stroke "currentColor"
:d d}]])
(def close (hero-icon "M6 18L18 6M6 6L18 18"))
(def plus (hero-icon "M12 4v16m8-8H4"))
(rum/defc caret-down (rum/defc caret-down
[] []
[:svg [:svg

View File

@ -990,6 +990,44 @@
(p/let [_ (clone docs-repo)] (p/let [_ (clone docs-repo)]
(load-db-and-journals! docs-repo nil true))))) (load-db-and-journals! docs-repo nil true)))))
;; sidebars
(defn hide-left-sidebar
[]
(dom/add-class! (dom/by-id "menu")
"md:block")
(dom/remove-class! (dom/by-id "left-sidebar")
"enter")
(dom/remove-class! (dom/by-id "search")
"sidebar-open")
(dom/remove-class! (dom/by-id "main")
"sidebar-open"))
(defn show-left-sidebar
[]
(dom/remove-class! (dom/by-id "menu")
"md:block")
(dom/add-class! (dom/by-id "left-sidebar")
"enter")
(dom/add-class! (dom/by-id "search")
"sidebar-open")
(dom/add-class! (dom/by-id "main")
"sidebar-open"))
(defn hide-right-sidebar
[]
(let [sidebar (dom/by-id "right-sidebar")]
(dom/remove-class! (dom/by-id "main-content-container")
"right-sidebar-open")
(dom/remove-class! sidebar "enter")))
(defn show-right-sidebar
[]
(let [sidebar (dom/by-id "right-sidebar")]
(hide-left-sidebar)
(dom/add-class! sidebar "enter")
(dom/add-class! (dom/by-id "main-content-container")
"right-sidebar-open")))
(comment (comment
(defn debug-latest-commits (defn debug-latest-commits

View File

@ -2,7 +2,8 @@
(:require [frontend.storage :as storage] (:require [frontend.storage :as storage]
[rum.core :as rum] [rum.core :as rum]
[frontend.util :as util] [frontend.util :as util]
[clojure.string :as string])) [clojure.string :as string]
[medley.core :as medley]))
;; TODO: move git/latest-commit, git/status, git/error to corresponding datascript ;; TODO: move git/latest-commit, git/status, git/error to corresponding datascript
;; dbs. ;; dbs.
@ -45,6 +46,9 @@
;; encrypted github token ;; encrypted github token
:encrypt/token (storage/get :encrypt/token) :encrypt/token (storage/get :encrypt/token)
;; pages or headings in the right sidebar
:sidebar/blocks '()
})) }))
(defn sub (defn sub
@ -258,3 +262,16 @@
(when encrypted (when encrypted
(set-state! :encrypt/token encrypted) (set-state! :encrypt/token encrypted)
(storage/set :encrypt/token encrypted))) (storage/set :encrypt/token encrypted)))
(defn sidebar-add-block!
[block-type block-data]
(update-state! :sidebar/blocks #(cons [block-type block-data] %)))
(defn sidebar-remove-block!
[idx]
(update-state! :sidebar/blocks #(util/drop-nth idx %)))
(defn sidebar-clear!
[]
(set-state! :sidebar/blocks '()))
(defn get-sidebar-blocks
[]
(:sidebar/blocks @state))

View File

@ -154,7 +154,7 @@
;; scroll ;; scroll
(defn main-node (defn main-node
[] []
(first (array-seq (js/document.querySelectorAll "main")))) (gdom/getElement "main-content"))
(defn get-scroll-top [] (defn get-scroll-top []
(.-scrollTop (main-node))) (.-scrollTop (main-node)))

View File

@ -576,3 +576,6 @@
(defn uuid-string? (defn uuid-string?
[s] [s]
(re-find uuid-pattern s)) (re-find uuid-pattern s))
(defn drop-nth [n coll]
(keep-indexed #(if (not= %1 n) %2) coll))