Add contents

Resolves #63
This commit is contained in:
Tienson Qin
2020-07-21 15:50:13 +08:00
parent c8727b106c
commit d73e405b9e
9 changed files with 254 additions and 84 deletions

View File

@@ -6,3 +6,11 @@
-/.shadow-cljs/
-/resources/static/js/cljs-runtime/
-/resources/static/js/main.js
-/resources/static/js/sentry.min.js
-/resources/static/js/highlight.min.js
-/resources/static/js/katex.min.js
-/resources/static/js/mldoc.min.js
-/resources/static/js/reveal.min.js
-/resources/static/js/sci.min.js
-/resources/static/js/excalidraw.min.js
-/resources/static/js/react-force-graph.min.js

View File

@@ -107,6 +107,17 @@
nil))
)))
(defn surround-by?
[input before after]
(when input
(let [value (gobj/get input "value")
pos (:pos (util/get-caret-pos input))
start-pos (- pos (count before))
end-pos (+ pos (count after))]
(when (>= (count value) end-pos)
(= (str before after)
(subs value start-pos end-pos))))))
(defn- upload-image
[id files format uploading? drop?]
(image/upload
@@ -683,6 +694,7 @@
selected-start (gobj/get node "selectionStart")
selected-end (gobj/get node "selectionEnd")]
(cond
(not= selected-start selected-end)
nil
@@ -713,7 +725,16 @@
(do
(util/stop e)
(commands/delete-pair! id))
(commands/delete-pair! id)
(cond
(and (= deleted "[") (state/get-editor-show-page-search))
(state/set-editor-show-page-search false)
(and (= deleted "(") (state/get-editor-show-block-search))
(state/set-editor-show-block-search false)
:else
nil))
:else
nil)))
@@ -728,6 +749,16 @@
(fn [e key-code]
(let [key (gobj/get e "key")]
(cond
(surround-by? input "[[" "]]")
(do
(commands/handle-step [:editor/search-page])
(reset! commands/*slash-caret-pos (util/get-caret-pos input)))
(surround-by? input "((" "))")
(do
(commands/handle-step [:editor/search-block :reference])
(reset! commands/*slash-caret-pos (util/get-caret-pos input)))
(and
(contains? (set (keys reversed-autopair-map)) key)
(= (get-previous-input-chars input 2) (str key key)))
@@ -753,7 +784,8 @@
state
{}
(fn [e key-code]
(let [format (:format (get-state state))]
(let [k (gobj/get e "key")
format (:format (get-state state))]
(when (and @*show-commands (not= key-code 191)) ; not /
(let [matched-commands (get-matched-commands input)]
(if (seq matched-commands)

View File

@@ -749,7 +749,7 @@
(merge drag-attrs))
(if pre-heading?
[:div.pre-heading.pre-white-space
[:div.pre-heading.pre-line-white-space
(string/trim content)]
(build-heading-part config heading))

View File

@@ -33,11 +33,12 @@
(defn- get-headings
[repo page-name heading? heading-id]
(if heading?
(db/get-heading-and-children repo heading-id)
(do
(db/add-page-to-recent! repo page-name)
(db/get-page-headings repo page-name))))
(when page-name
(if heading?
(db/get-heading-and-children repo heading-id)
(do
(db/add-page-to-recent! repo page-name)
(db/get-page-headings repo page-name)))))
(rum/defc page-headings-cp < rum/reactive
[repo page file-path page-name encoded-page-name sidebar? journal? heading? heading-id format]
@@ -114,7 +115,21 @@
[repo :heading/block (uuid page-name)]
(when-let [page-id (db/entity repo [:page/name page-name])]
[repo :page/headings page-id])))))))
{:did-mount handler/scroll-and-highlight!
{:did-mount (fn [state]
(handler/scroll-and-highlight! state)
(let [page-name (get-page-name state)]
(when (= (string/lower-case page-name) "contents")
(when-let [first-heading (first (db/get-page-headings "contents"))]
(let [edit-id (str "edit-heading-" (:heading/uuid first-heading))]
(handler/edit-heading!
(:heading/uuid first-heading)
:max
(:heading/format first-heading)
edit-id)
(when (string/ends-with? (:heading/content first-heading) "[[]]" )
(js/setTimeout #(util/cursor-move-back (gdom/getElement edit-id) 2)
50))))))
state)
:did-update handler/scroll-and-highlight!}
[state {:keys [repo] :as option}]
(let [current-repo (state/sub :git/current-repo)
@@ -176,16 +191,16 @@
(when file
[(when-not journal?
{:title "Publish this page on Logseq"
:options {:on-click (fn []
(page-handler/publish-page! page-name))}})
:options {:on-click (fn []
(page-handler/publish-page! page-name))}})
(when-not journal?
{:title "Publish this page as a slide on Logseq"
:options {:on-click (fn []
(page-handler/publish-page-as-slide! page-name))}})
:options {:on-click (fn []
(page-handler/publish-page-as-slide! page-name))}})
(when-not journal?
{:title "Un-publish this page on Logseq"
:options {:on-click (fn []
(page-handler/unpublish-page! page-name))}})
:options {:on-click (fn []
(page-handler/unpublish-page! page-name))}})
{:title "Re-index this page"
:options {:on-click (fn []
(handler/re-index-file! file))}}])

View File

@@ -196,9 +196,78 @@
:href (str "/page/" page)}
(util/capitalize-all page)]))]))
(rum/defcs foldable-list <
(rum/local false ::fold?)
[state page l]
(let [fold? (get state ::fold?)]
[:div
[:div.flex.flex-row.items-center.mb-1
[:a.control {:on-click #(swap! fold? not)
:style {:width "0.75rem"}}
(when (seq l)
[:svg.h-3.w-3
{:version "1.1",
:view-box "0 0 128 128"
:fill "currentColor"
:display "inline-block"
:style {:margin-top -3}}
[:path
{:d
(if @fold?
"M64.177 100.069a7.889 7.889 0 01-5.6-2.316l-55.98-55.98a7.92 7.92 0 010-11.196c3.086-3.085 8.105-3.092 11.196 0l50.382 50.382 50.382-50.382a7.92 7.92 0 0111.195 0c3.086 3.086 3.092 8.104 0 11.196l-55.98 55.98a7.892 7.892 0 01-5.595 2.316z"
"M99.069 64.173c0 2.027-.77 4.054-2.316 5.6l-55.98 55.98a7.92 7.92 0 01-11.196 0c-3.085-3.086-3.092-8.105 0-11.196l50.382-50.382-50.382-50.382a7.92 7.92 0 010-11.195c3.086-3.085 8.104-3.092 11.196 0l55.98 55.98a7.892 7.892 0 012.316 5.595z")}]])]
[:a.ml-2 {:key (str "contents-" page)
:href (str "/page/" page)}
(util/capitalize-all page)]]
(when (and (seq l) (not @fold?))
[:div.contents-list.ml-4
(for [{:keys [page list]} l]
(rum/with-key
(foldable-list page list)
(str "toc-item-" page)))])]))
(rum/defc contents < rum/reactive
[]
(let [l (db/get-contents)]
[:div.contents.text-sm.flex-col.flex.ml-3.mt-2
(if (seq l)
(for [{:keys [page list]} l]
(rum/with-key
(foldable-list page list)
(str "toc-item-" page)))
(let [page (db/entity [:page/name "contents"])]
(if page
[:div
[:p.text-base "No contents yet, you can click the button below to edit it."]
(ui/button
"Edit the contents"
:on-click (fn [e]
(util/stop e)
(handler/redirect! {:to :page
:path-params {:name "contents"}})))]
[:div
[:p.text-base
[:i.font-medium "Contents"] " (similar to book contents) is a way to structure your pages, please click the button below to start!"]
(ui/button
"Create the contents"
:on-click (fn [e]
(util/stop e)
(handler/create-new-page! "contents")))])))]))
(defn build-sidebar-item
[repo idx db-id block-type block-data]
(case block-type
:contents
[[:a {:on-click (fn [e]
(util/stop e)
(if-not (db/entity [:page/name "contents"])
(handler/create-new-page! "contents")
(handler/redirect! {:to :page
:path-params {:name "contents"}})))}
"Contents (edit)"]
(contents)]
:recent
["Recent" (recent-pages)]
@@ -313,16 +382,16 @@
[:div#theme-selector.ml-3.mb-2
[:div.flex.flex-row
[:div.flex.flex-row {:key "right-sidebar-settings"}
[:div.mr-4.text-sm
[:a {:on-click (fn [e]
(state/sidebar-add-block! repo "contents" :contents nil))}
"Contents"]]
[:div.mr-4.text-sm
[:a {:on-click (fn [_e]
(state/sidebar-add-block! repo "recent" :recent nil))}
"Recent"]]
[:div.mr-4.text-sm
[:a {:on-click (fn [e]
(prn "Clicked Contents"))}
"Contents"]]
[:div.mr-4.text-sm
[:a {:on-click (fn []
(when-let [page (get-current-page)]

View File

@@ -142,15 +142,10 @@
[]
[:svg.h-4.w-4
{:aria-hidden "true",
:height "12",
:width "10",
:version "1.1",
:view-box "0 0 192 512"
:fill "currentColor"
:display "inline-block"
:style {
:margin-left -3
:margin-top -1}}
:display "inline-block"}
[:path
{:d "M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z",
:fill-rule "evenodd"}]])
@@ -159,13 +154,11 @@
[]
[:svg.h-4.w-4
{:aria-hidden "true",
:height "12",
:width "10",
:version "1.1",
:view-box "0 0 192 512"
:fill "currentColor"
:display "inline-block"
:style {:margin-top -1}}
:style {:margin-left 2}}
[:path
{:d "M0 384.662V127.338c0-17.818 21.543-26.741 34.142-14.142l128.662 128.662c7.81 7.81 7.81 20.474 0 28.284L34.142 398.804C21.543 411.404 0 402.48 0 384.662z",
:fill-rule "evenodd"}]])

View File

@@ -142,6 +142,7 @@
:page/name {:db/unique :db.unique/identity}
:page/file {:db/valueType :db.type/ref}
:page/directives {}
:page/links {}
:page/alias {:db/valueType :db.type/ref
:db/cardinality :db.cardinality/many}
:page/tags {:db/valueType :db.type/ref
@@ -318,6 +319,7 @@
:heading/change
(when (seq data)
(let [headings data
pre-heading? (:heading/pre-heading? (first headings))
current-priority (get-current-priority)
current-marker (get-current-marker)
current-page-id (:page/id (get-current-page))
@@ -332,6 +334,9 @@
[:page/ref-pages page-id]]))
headings)
(when pre-heading?
[[:contents]])
;; affected priority
(when current-priority
[[:priority/headings current-priority]])
@@ -565,7 +570,7 @@
(let [handler-key (vec (cons repo-url handler-key))]
(when-let [cache (get @query-state handler-key)]
(let [{:keys [query inputs transform-fn query-fn]} cache]
(when (or (and query inputs) query-fn)
(when (or query query-fn)
(let [new-result (->
(cond
query-fn
@@ -576,8 +581,11 @@
(keyword? query)
(get-key-value repo-url query)
(seq inputs)
(apply d/q query db inputs)
:else
(apply d/q query db inputs))
(d/q query db))
transform-fn)]
(set-new-result! handler-key new-result)))))))))))
@@ -647,31 +655,31 @@
[repo]
(let [now-long (tc/to-long (t/now))]
(->> (q repo [:pages] {:use-cache? false}
'[:find ?page-name ?modified-at
:where
[?page :page/name ?page-name]
[(get-else $ ?page :page/journal? false) ?journal]
[(get-else $ ?page :page/last-modified-at 0) ?modified-at]
;; (or
;; ;; journal pages, can't be empty
;; (and [(true? ?journal)]
;; [?h :heading/page ?page]
;; [?h :heading/level ?level]
;; [(> ?level 1)])
;; ;; non-journals, might be empty pages
;; (and [(false? ?journal)]
;; [?h :heading/page]
;; [?h :heading/level ?level]))
])
(react)
(seq)
(sort-by (fn [[page modified-at]]
[modified-at page]))
(reverse)
(remove (fn [[page modified-at]]
(or (util/file-page? page)
(and modified-at
(> modified-at now-long))))))))
'[:find ?page-name ?modified-at
:where
[?page :page/name ?page-name]
[(get-else $ ?page :page/journal? false) ?journal]
[(get-else $ ?page :page/last-modified-at 0) ?modified-at]
;; (or
;; ;; journal pages, can't be empty
;; (and [(true? ?journal)]
;; [?h :heading/page ?page]
;; [?h :heading/level ?level]
;; [(> ?level 1)])
;; ;; non-journals, might be empty pages
;; (and [(false? ?journal)]
;; [?h :heading/page]
;; [?h :heading/level ?level]))
])
(react)
(seq)
(sort-by (fn [[page modified-at]]
[modified-at page]))
(reverse)
(remove (fn [[page modified-at]]
(or (util/file-page? page)
(and modified-at
(> modified-at now-long))))))))
(defn get-page-alias
[repo page-name]
@@ -1079,6 +1087,15 @@
(utf8/substring utf8-content
(:pos meta)))))
(defn extract-page-list
[content]
(when-not (string/blank? content)
(->> (re-seq #"\[\[([^\]]+)]]" content)
(map last)
(remove nil?)
(map string/lower-case)
(distinct))))
;; file
(defn extract-pages-and-headings
[format ast directives file content utf8-content journal? pages-fn]
@@ -1119,20 +1136,25 @@
(conj other-alias (string/lower-case file)))
(remove nil?)))
journal-date-long (if journal?
(date/journal-title->long (string/capitalize page)))]
(date/journal-title->long (string/capitalize page)))
page-list (when-let [list-content (:list directives)]
(extract-page-list list-content))]
(cond->
(util/remove-nils
{:page/name page
:page/file [:file/path file]
:page/journal? journal?
:page/journal-day (if journal?
(date/journal-title->int (string/capitalize page))
0)
:page/created-at journal-date-long
:page/last-modified-at journal-date-long})
(util/remove-nils
{:page/name page
:page/file [:file/path file]
:page/journal? journal?
:page/journal-day (if journal?
(date/journal-title->int (string/capitalize page))
0)
:page/created-at journal-date-long
:page/last-modified-at journal-date-long})
(seq directives)
(assoc :page/directives directives)
(seq page-list)
(assoc :page/list page-list)
other-alias
(assoc :page/alias
(map
@@ -1255,10 +1277,10 @@
file-content)
tx (concat tx [(let [t (tc/to-long (t/now))]
(cond->
{:file/path file
:file/last-modified-at t}
new?
(assoc :file/created-at t)))])]
{:file/path file
:file/last-modified-at t}
new?
(assoc :file/created-at t)))])]
(transact! repo-url tx))))
(defn get-current-journal-path
@@ -1876,9 +1898,34 @@
new-pages (take 12 (distinct (cons page pages)))]
(set-key-value repo :recent/pages new-pages)))
(defn build-content-list
[m l]
(map
(fn [page]
(if-let [page-list (get m page)]
{:page page
:list (build-content-list m page-list)}
{:page page}))
l))
(defn get-contents
([]
(get-contents (state/get-current-repo)))
([repo]
(when-let [conn (get-conn repo)]
(let [lists (some->>
(q repo [:contents] {}
'[:find ?page-name ?list
:where
[?page :page/list ?list]
[?page :page/name ?page-name]])
react
(into {}))]
(when (seq lists)
(when-let [l (get lists "contents")]
(build-content-list lists l)))))))
(comment
(defn debug!
[]
(let [repos (->> (get-in @state/state [:me :repos])

View File

@@ -937,12 +937,17 @@
(defn- default-content-with-title
[format title]
(case format
"org"
(util/format "#+TITLE: %s\n#+TAGS:\n\n** " title)
"markdown"
(util/format "---\ntitle: %s\ntags:\n---\n\n## " title)
""))
(let [contents? (= (string/lower-case title) "contents")]
(case format
"org"
(if contents?
(util/format "#+TITLE: %s\n#+LIST: [[]]" title)
(util/format "#+TITLE: %s\n#+TAGS:\n\n** " title))
"markdown"
(if contents?
(util/format "---\ntitle: %s\nlist: [[]]" title)
(util/format "---\ntitle: %s\ntags:\n---\n\n## " title))
"")))
(defn create-new-page!
[title]
@@ -1017,6 +1022,8 @@
[old-directives new-directives] (when pre-heading?
[(:page/directives (db/entity (:db/id page)))
(db/parse-directives value format)])
page-list (when-let [content (:list new-directives)]
(db/extract-page-list content))
permalink-changed? (when (and pre-heading? (:permalink old-directives))
(not= (:permalink old-directives)
(:permalink new-directives)))
@@ -1050,7 +1057,9 @@
[[:db/add (:db/id page) :page/last-modified-at modified-at]
[:db/add (:db/id file) :file/last-modified-at modified-at]])
page-directives (when pre-heading?
[(assoc page :page/directives new-directives)])]
[(assoc page :page/directives new-directives)])
page-list (when pre-heading?
[(assoc page :page/list page-list)])]
(profile
"Save heading: "
(transact-react-and-alter-file!
@@ -1059,6 +1068,7 @@
pages
headings
page-directives
page-list
after-headings
modified-time)
{:key :heading/change
@@ -1376,6 +1386,7 @@
content
(subs content 0 prev-pos))]
(state/set-editing! edit-input-id content heading text-range)))
(defn clear-selection!
[e]
(when (state/in-selection-mode?)
@@ -1605,7 +1616,6 @@
(when-let [edit-id (state/get-edit-input-id)]
(when-let [input (gdom/getElement edit-id)]
(when-let [pos (:pos (util/get-caret-pos input))]
(prn {:pos pos})
(let [value (gobj/get input "value")
page-pattern #"\[\[([^\]]+)]]"
block-pattern #"\(\(([^\)]+)\)\)"

View File

@@ -264,10 +264,6 @@
(fn [m]
(and input-id {input-id true}))))
(defn disable-edit!
[]
(swap! state assoc :editor/editing? nil))
(defn set-selection-headings!
[headings]
(when (seq headings)