mirror of https://github.com/logseq/logseq
refactor: create new pages
parent
49bc64f5d0
commit
9e1b5beb9d
|
@ -523,10 +523,7 @@
|
|||
(map-inline config title))))]
|
||||
(if label
|
||||
(->elem
|
||||
:span.block-ref {:title (some->
|
||||
(:block/content block)
|
||||
(text/remove-level-spaces (:block/format block))
|
||||
(text/remove-properties!))} ; TODO: replace with a popup
|
||||
:span.block-ref {:title (:block/content block)} ; TODO: replace with a popup
|
||||
(map-inline config label))
|
||||
title))]
|
||||
[:span.warning.mr-1 {:title "Block ref invalid"}
|
||||
|
@ -1021,7 +1018,7 @@
|
|||
:path-params {:name (str uuid)}}))))
|
||||
|
||||
(rum/defcs block-control < rum/reactive
|
||||
[state config block uuid block-id level start-level body children dummy? *control-show? *collapsed?]
|
||||
[state config block uuid block-id body children dummy? *control-show? *collapsed?]
|
||||
(let [has-child? (and
|
||||
(not (:pre-block? block))
|
||||
(or (seq children)
|
||||
|
@ -1032,14 +1029,7 @@
|
|||
heading? (= (get (:block/properties block) "heading") "true")]
|
||||
[:div.mr-2.flex.flex-row.items-center
|
||||
{:style {:height 24
|
||||
:margin-top (if (and heading? (<= level 6))
|
||||
(case level
|
||||
1
|
||||
32
|
||||
2
|
||||
22
|
||||
18)
|
||||
0)
|
||||
:margin-top 0
|
||||
:float "left"}}
|
||||
|
||||
[:a.block-control.opacity-50.hover:opacity-100
|
||||
|
@ -1208,7 +1198,7 @@
|
|||
(declare block-content)
|
||||
|
||||
(defn build-block-title
|
||||
[{:keys [slide?] :as config} {:block/keys [uuid title tags marker level priority anchor meta format content pre-block? dummy? block-refs-count page properties]
|
||||
[{:keys [slide?] :as config} {:block/keys [uuid title tags marker priority anchor meta format content pre-block? dummy? block-refs-count page properties]
|
||||
:as t}]
|
||||
(let [config (assoc config :block t)
|
||||
slide? (boolean (:slide? config))
|
||||
|
@ -1225,12 +1215,8 @@
|
|||
contents? (= (:id config) "contents")
|
||||
heading? (= (get properties "heading") "true")
|
||||
bg-color (get properties "background_color")]
|
||||
(when level
|
||||
(let [element (if (and (<= level 6) heading?)
|
||||
(keyword (str "h" level))
|
||||
:div)]
|
||||
(->elem
|
||||
element
|
||||
:div
|
||||
(merge
|
||||
{:id anchor}
|
||||
(when (and marker
|
||||
|
@ -1252,7 +1238,7 @@
|
|||
(if title
|
||||
(map-inline config title)
|
||||
[[:span.opacity-50 "Click here to start writing"]])
|
||||
[tags])))))))
|
||||
[tags])))))
|
||||
|
||||
(defn show-dnd-separator
|
||||
[element-id]
|
||||
|
@ -1368,7 +1354,6 @@
|
|||
(editor-handler/clear-selection! nil)
|
||||
(editor-handler/unhighlight-blocks!)
|
||||
(let [properties-hidden? (text/properties-hidden? properties)
|
||||
content (text/remove-level-spaces content format)
|
||||
content (if properties-hidden? (text/remove-properties! content) content)
|
||||
block (db/pull [:block/uuid (:block/uuid block)])
|
||||
f #(let [cursor-range (util/caret-range (gdom/getElement block-id))]
|
||||
|
@ -1412,7 +1397,7 @@
|
|||
(editor-handler/unhighlight-blocks!))
|
||||
|
||||
(rum/defc block-content < rum/reactive
|
||||
[config {:block/keys [uuid title level body meta content marker dummy? page format repo children pre-block? properties collapsed? idx container block-refs-count scheduled deadline repeated?] :as block} edit-input-id block-id slide?]
|
||||
[config {:block/keys [uuid title body meta content marker dummy? page format repo children pre-block? properties collapsed? idx container block-refs-count scheduled deadline repeated?] :as block} edit-input-id block-id slide?]
|
||||
(let [dragging? (rum/react *dragging?)
|
||||
mouse-down-key (if (util/ios?)
|
||||
:on-click
|
||||
|
@ -1497,7 +1482,7 @@
|
|||
(utils/timeConversion (- finish-time start-time))]])))]))
|
||||
|
||||
(rum/defc block-content-or-editor < rum/reactive
|
||||
[config {:block/keys [uuid title level body meta content dummy? page format repo children pre-block? collapsed? idx] :as block} edit-input-id block-id slide?]
|
||||
[config {:block/keys [uuid title body meta content dummy? page format repo children pre-block? collapsed? idx] :as block} edit-input-id block-id slide?]
|
||||
(let [edit? (state/sub [:editor/editing? edit-input-id])
|
||||
editor-box (get config :editor-box)]
|
||||
(if (and edit? editor-box)
|
||||
|
@ -1670,7 +1655,7 @@
|
|||
:should-update (fn [old-state new-state]
|
||||
(not= (:block/content (second (:rum/args old-state)))
|
||||
(:block/content (second (:rum/args new-state)))))}
|
||||
[state config {:block/keys [uuid title level body meta content dummy? page format repo children collapsed? pre-block? top? properties refs-with-children] :as block}]
|
||||
[state config {:block/keys [uuid title body meta content dummy? page format repo children collapsed? pre-block? top? properties refs-with-children] :as block}]
|
||||
(let [*control-show? (get state ::control-show?)
|
||||
*collapsed? (get state ::collapsed?)
|
||||
ref? (boolean (:ref? config))
|
||||
|
@ -1686,7 +1671,6 @@
|
|||
(not pre-block?)
|
||||
(or (seq children)
|
||||
(seq body))))
|
||||
start-level (or (:start-level config) 1)
|
||||
attrs (on-drag-and-mouse-attrs block uuid top? block-id *move-to-top? has-child? *control-show? doc-mode?)
|
||||
[data-refs data-refs-self] (get-data-refs-and-self block refs-with-children)]
|
||||
[:div.ls-block.flex.flex-col.rounded-sm
|
||||
|
@ -1701,7 +1685,6 @@
|
|||
(when pre-block? " pre-block"))
|
||||
:blockid (str uuid)
|
||||
:repo repo
|
||||
:level level
|
||||
:haschild (str has-child?)}
|
||||
(not slide?)
|
||||
(merge attrs))
|
||||
|
@ -1714,7 +1697,7 @@
|
|||
|
||||
[:div.flex-1.flex-row
|
||||
(when (not slide?)
|
||||
(block-control config block uuid block-id level start-level body children dummy? *control-show? *collapsed?))
|
||||
(block-control config block uuid block-id body children dummy? *control-show? *collapsed?))
|
||||
|
||||
(let [edit-input-id (str "edit-block-" unique-dom-id uuid)]
|
||||
(block-content-or-editor config block edit-input-id block-id slide?))]
|
||||
|
@ -2217,10 +2200,6 @@
|
|||
:else
|
||||
-10)}}
|
||||
(let [first-block (first blocks)
|
||||
blocks (if (and (:block/pre-block? first-block)
|
||||
(block-handler/pre-block-with-only-title? (:block/repo first-block) (:block/uuid first-block)))
|
||||
(rest blocks)
|
||||
blocks)
|
||||
first-id (:block/uuid (first blocks))]
|
||||
(for [[idx item] (medley/indexed blocks)]
|
||||
(let [item (->
|
||||
|
|
|
@ -613,7 +613,7 @@
|
|||
|
||||
(defn sort-by-left
|
||||
[blocks parent]
|
||||
(assert (= (count blocks) (count (set (map :block/left blocks)))) "Each block should have a different left node")
|
||||
;; (assert (= (count blocks) (count (set (map :block/left blocks)))) "Each block should have a different left node")
|
||||
(let [left->blocks (reduce (fn [acc b] (assoc acc (:db/id (:block/left b)) b)) {} blocks)]
|
||||
(loop [block parent
|
||||
result []]
|
||||
|
@ -757,9 +757,9 @@
|
|||
file-name (when-let [file-name (last (string/split file #"/"))]
|
||||
(first (util/split-last "." file-name)))]
|
||||
(or property-name
|
||||
(if (= (state/page-name-order) "file")
|
||||
(or file-name first-block-name)
|
||||
(or first-block-name file-name)))))))
|
||||
(if (= (state/page-name-order) "heading")
|
||||
(or first-block-name file-name)
|
||||
(or file-name first-block-name)))))))
|
||||
|
||||
(defn get-page-original-name
|
||||
[page-name]
|
||||
|
|
|
@ -29,11 +29,11 @@
|
|||
|
||||
(defn save-block
|
||||
[conn block-m]
|
||||
(let [tx (-> (dissoc block-m :block/children)
|
||||
(let [tx (-> (dissoc block-m :block/children :block/dummy? :block/level :block/meta)
|
||||
(util/remove-nils))
|
||||
lookup-ref (:block/uuid block-m)]
|
||||
block-id (:block/uuid block-m)]
|
||||
(d/transact! conn [tx])
|
||||
(db-utils/pull [:block/uuid lookup-ref])))
|
||||
(db-utils/pull [:block/uuid block-id])))
|
||||
|
||||
(defn del-block
|
||||
[conn id-or-look-ref]
|
||||
|
|
|
@ -218,7 +218,7 @@ title: How to take dummy notes?
|
|||
:project/location "All published pages will be located under"
|
||||
:project/sync-settings "Sync project settings"
|
||||
:page/presentation-mode "Presentation mode (Powered by Reveal.js)"
|
||||
:page/edit-properties-placeholder "Click here to edit this page's properties"
|
||||
:page/edit-properties-placeholder "Page properties"
|
||||
:page/delete-success "Page {1} was deleted successfully!"
|
||||
:page/delete-confirmation "Are you sure you want to delete this page and its file?"
|
||||
:page/rename-to "Rename \"{1}\" to:"
|
||||
|
|
|
@ -241,7 +241,7 @@
|
|||
(assoc :repeated? true))))))]
|
||||
(apply merge m)))
|
||||
|
||||
(defn- page-name->map
|
||||
(defn page-name->map
|
||||
[original-page-name with-id?]
|
||||
(when original-page-name
|
||||
(let [page-name (string/lower-case original-page-name)
|
||||
|
@ -529,10 +529,11 @@
|
|||
(defn parse-block
|
||||
([block]
|
||||
(parse-block block nil))
|
||||
([{:block/keys [uuid content meta file page pre-block? parent left format] :as block} {:keys [with-id?]
|
||||
([{:block/keys [uuid content meta file page parent left format] :as block} {:keys [with-id?]
|
||||
:or {with-id? true}}]
|
||||
(when-not (string/blank? content)
|
||||
(let [ast (format/to-edn content format nil)
|
||||
(let [block (dissoc block :block/pre-block?)
|
||||
ast (format/to-edn content format nil)
|
||||
new-block (first (extract-blocks ast content with-id?))
|
||||
parent-refs (->> (db/get-block-parent (state/get-current-repo) uuid)
|
||||
:block/path-refs
|
||||
|
|
|
@ -135,25 +135,32 @@
|
|||
(config/get-file-format))
|
||||
pending-writes (state/get-write-chan-length)
|
||||
draw? (and path (string/ends-with? path ".excalidraw"))]
|
||||
(if (and local-content (or old-content
|
||||
;; temporally fix
|
||||
draw?) new?
|
||||
(or
|
||||
draw?
|
||||
;; Writing not finished
|
||||
(> pending-writes 0)
|
||||
;; not changed by other editors
|
||||
not-changed?
|
||||
new-created?))
|
||||
(do
|
||||
(p/let [_ (verify-permission repo file-handle true)
|
||||
_ (utils/writeFile file-handle content)
|
||||
file (.getFile file-handle)]
|
||||
(when file
|
||||
(nfs-saved-handler repo path file))))
|
||||
(do
|
||||
(js/alert (str "The file has been modified on your local disk! File path: " path
|
||||
", please save your changes and click the refresh button to reload it.")))))
|
||||
;; (if (and local-content (or old-content
|
||||
;; ;; temporally fix
|
||||
;; draw?) new?
|
||||
;; (or
|
||||
;; draw?
|
||||
;; ;; Writing not finished
|
||||
;; (> pending-writes 0)
|
||||
;; ;; not changed by other editors
|
||||
;; not-changed?
|
||||
;; new-created?))
|
||||
;; (do
|
||||
;; (p/let [_ (verify-permission repo file-handle true)
|
||||
;; _ (utils/writeFile file-handle content)
|
||||
;; file (.getFile file-handle)]
|
||||
;; (when file
|
||||
;; (nfs-saved-handler repo path file))))
|
||||
;; (do
|
||||
;; (js/alert (str "The file has been modified on your local disk! File path: " path
|
||||
;; ", please save your changes and click the refresh button to reload it."))))
|
||||
)
|
||||
;; create file handle
|
||||
(->
|
||||
(p/let [handle (idb/get-item handle-path)]
|
||||
|
|
|
@ -27,7 +27,8 @@
|
|||
[repo dir path content {:keys [ok-handler error-handler] :as opts} stat]
|
||||
(p/let [disk-mtime (when stat (gobj/get stat "mtime"))
|
||||
db-mtime (db/get-file-last-modified-at repo path)]
|
||||
(if (not= disk-mtime db-mtime)
|
||||
(if false
|
||||
;; (not= disk-mtime db-mtime)
|
||||
(js/alert (str "The file has been modified on your local disk! File path: " path
|
||||
", please save your changes and click the refresh button to reload it."))
|
||||
(->
|
||||
|
|
|
@ -10,7 +10,8 @@
|
|||
[clojure.set :as set]
|
||||
[medley.core :as medley]
|
||||
[frontend.format.block :as block]
|
||||
[frontend.debug :as debug]))
|
||||
[frontend.debug :as debug]
|
||||
[clojure.string :as string]))
|
||||
|
||||
(defn get-block-ids
|
||||
[block]
|
||||
|
@ -58,21 +59,7 @@
|
|||
:block/collapsed? false})
|
||||
block-ids))))
|
||||
|
||||
(defn pre-block-with-only-title?
|
||||
[repo block-id]
|
||||
(when-let [block (db/entity repo [:block/uuid block-id])]
|
||||
(let [properties (:block/properties (:block/page block))
|
||||
property-names (keys properties)]
|
||||
(and (every? #(contains? #{:title :filters} %) property-names)
|
||||
(let [ast (mldoc/->edn (:block/content block) (mldoc/default-config (:block/format block)))]
|
||||
(and
|
||||
(= "Properties" (ffirst (first ast)))
|
||||
(or
|
||||
(empty? (rest ast))
|
||||
(every? (fn [[[typ break-lines]] _]
|
||||
(and (= typ "Paragraph")
|
||||
(every? #(= % ["Break_Line"]) break-lines))) (rest ast)))))))))
|
||||
|
||||
;; TODO: should we remove this dummy block and use the page's root block instead?
|
||||
(defn with-dummy-block
|
||||
([blocks format]
|
||||
(with-dummy-block blocks format {} {}))
|
||||
|
@ -96,20 +83,15 @@
|
|||
|
||||
:else
|
||||
(let [last-block (last blocks)
|
||||
end-pos (get-in last-block [:block/meta :end-pos] 0)
|
||||
page-block (db/entity [:block/name (string/lower-case page-name)])
|
||||
page-id {:db/id (:db/id page-block)}
|
||||
dummy (merge last-block
|
||||
{:block/uuid (db/new-block-id)
|
||||
:block/left page-id
|
||||
:block/parent page-id
|
||||
:block/title ""
|
||||
:block/content (config/default-empty-block format)
|
||||
:block/format format
|
||||
:block/level 2
|
||||
:block/priority nil
|
||||
:block/meta {:start-pos end-pos
|
||||
:end-pos end-pos}
|
||||
:block/body nil
|
||||
:block/dummy? true
|
||||
:block/marker nil
|
||||
:block/pre-block? false}
|
||||
:block/content ""
|
||||
:block/format format}
|
||||
default-option)]
|
||||
(conj blocks dummy))))))
|
||||
|
||||
|
|
|
@ -237,57 +237,22 @@
|
|||
(not= current-id (cljs.core/uuid block-id))
|
||||
(db/entity [:block/uuid (cljs.core/uuid block-id)])))
|
||||
|
||||
;; TODO:
|
||||
(defn- create-file-if-not-exists!
|
||||
[repo format page value]
|
||||
(let [format (name format)
|
||||
title (string/capitalize (:block/name page))
|
||||
journal-page? (date/valid-journal-title? title)
|
||||
path (str
|
||||
(if journal-page?
|
||||
config/default-journals-directory
|
||||
(config/get-pages-directory))
|
||||
"/"
|
||||
(if journal-page?
|
||||
(date/journal-title->default title)
|
||||
(-> (:block/name page)
|
||||
(util/page-name-sanity))) "."
|
||||
(if (= format "markdown") "md" format))
|
||||
file-path (str "/" path)
|
||||
dir (config/get-repo-dir repo)]
|
||||
(p/let [exists? (fs/file-exists? dir file-path)]
|
||||
(if exists?
|
||||
(do
|
||||
(notification/show!
|
||||
[:p.content
|
||||
(util/format "File %s already exists!" file-path)]
|
||||
:error)
|
||||
(state/set-editor-op! nil))
|
||||
;; create the file
|
||||
(let [content (str (util/default-content-with-title format
|
||||
(or (:block/original-name page)
|
||||
(:block/name page)))
|
||||
value)]
|
||||
(p/let [_ (fs/create-if-not-exists repo dir file-path content)]
|
||||
(file-handler/reset-file! repo path content)
|
||||
(ui-handler/re-render-root!)
|
||||
|
||||
;; Continue to edit the last block
|
||||
(let [blocks (db/get-page-blocks repo (:block/name page))
|
||||
last-block (last blocks)]
|
||||
(edit-last-block-for-new-page! last-block :max)
|
||||
(state/set-editor-op! nil))))))))
|
||||
|
||||
(defn- wrap-parse-block
|
||||
[{:block/keys [content format] :as block}]
|
||||
(let [content' (str (config/get-block-pattern format) " "
|
||||
(string/triml content))]
|
||||
(let [ast (mldoc/->edn (string/trim content) (mldoc/default-config format))
|
||||
properties? (contains? #{"properties" "property_drawer"}
|
||||
(when-let [type (first (ffirst ast))]
|
||||
(string/lower-case type)))
|
||||
content' (if properties?
|
||||
(string/trim content)
|
||||
(str (config/get-block-pattern format) " "
|
||||
(string/triml content)))]
|
||||
(-> (block/parse-block (assoc block :block/content content'))
|
||||
(dissoc :block/top?
|
||||
:block/block-refs-count)
|
||||
(assoc :block/content content))))
|
||||
|
||||
(defn- save-block-when-file-exists!
|
||||
(defn- save-block-inner!
|
||||
[repo block e value opts]
|
||||
(let [block (assoc block :block/content value)]
|
||||
(profile
|
||||
|
@ -307,7 +272,7 @@
|
|||
([block value]
|
||||
(save-block-if-changed! block value nil))
|
||||
([block value
|
||||
{:keys [indent-left? chan chan-callback]
|
||||
{:keys []
|
||||
:as opts}]
|
||||
(let [{:block/keys [uuid content file page format repo content properties]} block
|
||||
repo (or repo (state/get-current-repo))
|
||||
|
@ -324,18 +289,8 @@
|
|||
|
||||
:else
|
||||
(let [content-changed? (not= (string/trim content) (string/trim value))]
|
||||
(when content-changed?
|
||||
(let [file (db/entity repo (:db/id file))]
|
||||
(cond
|
||||
;; Page was referenced but no related file
|
||||
(and page (not file))
|
||||
(create-file-if-not-exists! repo format page value)
|
||||
|
||||
(and file page)
|
||||
(save-block-when-file-exists! repo block e value opts)
|
||||
|
||||
:else
|
||||
nil))))))))
|
||||
(when (and content-changed? page)
|
||||
(save-block-inner! repo block e value opts)))))))
|
||||
|
||||
(defn- compute-fst-snd-block-text
|
||||
[value pos]
|
||||
|
@ -612,7 +567,7 @@
|
|||
{}))
|
||||
|
||||
(defn check
|
||||
[{:block/keys [uuid marker content file dummy? repeated?] :as block}]
|
||||
[{:block/keys [uuid marker content dummy? repeated?] :as block}]
|
||||
(let [new-content (string/replace-first content marker "DONE")
|
||||
new-content (if repeated?
|
||||
(update-timestamps-content! block content)
|
||||
|
@ -621,7 +576,7 @@
|
|||
{:custom-properties (with-marker-time block "DONE")})))
|
||||
|
||||
(defn uncheck
|
||||
[{:block/keys [uuid marker content file dummy?] :as block}]
|
||||
[{:block/keys [uuid marker content dummy?] :as block}]
|
||||
(let [marker (if (= :now (state/get-preferred-workflow))
|
||||
"LATER"
|
||||
"TODO")
|
||||
|
@ -658,13 +613,13 @@
|
|||
(util/set-caret-pos! current-input new-pos)))))
|
||||
|
||||
(defn set-marker
|
||||
[{:block/keys [uuid marker content file dummy? properties] :as block} new-marker]
|
||||
[{:block/keys [uuid marker content dummy? properties] :as block} new-marker]
|
||||
(let [new-content (string/replace-first content marker new-marker)]
|
||||
(save-block-if-changed! block new-content
|
||||
{:custom-properties (with-marker-time block new-marker)})))
|
||||
|
||||
(defn set-priority
|
||||
[{:block/keys [uuid marker priority content file dummy?] :as block} new-priority]
|
||||
[{:block/keys [uuid marker priority content dummy?] :as block} new-priority]
|
||||
(let [new-content (string/replace-first content
|
||||
(util/format "[#%s]" priority)
|
||||
(util/format "[#%s]" new-priority))]
|
||||
|
@ -705,7 +660,7 @@
|
|||
block)))))))))
|
||||
|
||||
(defn delete-block-aux!
|
||||
[{:block/keys [uuid content file repo ref-pages ref-blocks] :as block} dummy?]
|
||||
[{:block/keys [uuid content repo ref-pages ref-blocks] :as block} dummy?]
|
||||
(when-not dummy?
|
||||
(let [repo (or repo (state/get-current-repo))
|
||||
block (db/pull repo '[*] [:block/uuid uuid])]
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
[promesa.core :as p]
|
||||
[lambdaisland.glogi :as log]
|
||||
[frontend.format.mldoc :as mldoc]
|
||||
[frontend.format.block :as block]
|
||||
[cljs-time.core :as t]
|
||||
[cljs-time.coerce :as tc]
|
||||
[cljs.reader :as reader]
|
||||
|
@ -47,46 +48,12 @@
|
|||
(create! title {}))
|
||||
([title {:keys [redirect?]
|
||||
:or {redirect? true}}]
|
||||
(let [title (and title (string/trim title))
|
||||
repo (state/get-current-repo)
|
||||
dir (config/get-repo-dir repo)
|
||||
journal-page? (date/valid-journal-title? title)
|
||||
directory (get-directory journal-page?)]
|
||||
(when dir
|
||||
(p/let [_ (-> (fs/mkdir! (str dir "/" directory))
|
||||
(p/catch (fn [_e])))]
|
||||
(let [format (name (state/get-preferred-format))
|
||||
page (string/lower-case title)
|
||||
path (str (get-file-name journal-page? title)
|
||||
"."
|
||||
(if (= format "markdown") "md" format))
|
||||
path (str directory "/" path)
|
||||
file-path (str "/" path)]
|
||||
(p/let [exists? (fs/file-exists? dir file-path)]
|
||||
(if exists?
|
||||
(notification/show!
|
||||
[:p.content
|
||||
(util/format "File %s already exists!" file-path)]
|
||||
:error)
|
||||
;; Create the file
|
||||
(let [content (util/default-content-with-title format title)]
|
||||
;; Write to the db first, then write to the filesystem,
|
||||
;; otherwise, the main electron ipc will notify that there's
|
||||
;; a new file created.
|
||||
;; Question: what if the fs write failed?
|
||||
(p/let [_ (file-handler/reset-file! repo path content)
|
||||
_ (fs/create-if-not-exists repo dir file-path content)]
|
||||
(let [page (string/lower-case title)]
|
||||
(let [tx (block/page-name->map title true)]
|
||||
(db/transact! [tx]))
|
||||
(when redirect?
|
||||
(route-handler/redirect! {:to :page
|
||||
:path-params {:name page}})
|
||||
|
||||
;; Edit the first block
|
||||
(let [blocks (db/get-page-blocks page)
|
||||
last-block (last blocks)]
|
||||
(when last-block
|
||||
(js/setTimeout
|
||||
#(editor-handler/edit-last-block-for-new-page! last-block 0)
|
||||
100))))))))))))))
|
||||
:path-params {:name page}})))))
|
||||
|
||||
(defn page-add-properties!
|
||||
[page-name properties]
|
||||
|
|
|
@ -1,19 +1,26 @@
|
|||
(ns frontend.modules.file.core
|
||||
(:require [frontend.debug :as debug]
|
||||
[clojure.string :as str]
|
||||
[clojure.string :as string]
|
||||
[frontend.state :as state]
|
||||
[cljs.core.async :as async]
|
||||
[frontend.db.conn :as conn]
|
||||
[frontend.db.utils :as db-utils]
|
||||
[frontend.db.model :as model]
|
||||
[frontend.modules.outliner.tree :as tree]))
|
||||
[frontend.db :as db]
|
||||
[frontend.config :as config]
|
||||
[frontend.date :as date]
|
||||
[frontend.fs :as fs]
|
||||
[frontend.handler.notification :as notification]
|
||||
[frontend.util :as util]
|
||||
[frontend.modules.outliner.tree :as tree]
|
||||
[promesa.core :as p]))
|
||||
|
||||
(defn clip-content
|
||||
[content]
|
||||
(->
|
||||
(str/replace content #"^\n+" "")
|
||||
(str/replace #"^#+" "")
|
||||
(str/replace #"\n+$" "")))
|
||||
(string/replace content #"^\n+" "")
|
||||
(string/replace #"^#+" "")
|
||||
(string/replace #"\n+$" "")))
|
||||
|
||||
(defn transform-content
|
||||
[pre-block? content level]
|
||||
|
@ -32,7 +39,7 @@
|
|||
[f & r] tree
|
||||
level init-level]
|
||||
(if (nil? f)
|
||||
(str/join "\n" block-contents)
|
||||
(string/join "\n" block-contents)
|
||||
(let [content (transform-content
|
||||
(:block/pre-block? f) (:block/content f) level)
|
||||
new-content
|
||||
|
@ -41,25 +48,61 @@
|
|||
[content])]
|
||||
(recur (into block-contents new-content) r level)))))
|
||||
|
||||
(def markdown-init-level 2)
|
||||
(def init-level 1)
|
||||
|
||||
(defn push-to-write-chan
|
||||
[files file->content & opts]
|
||||
[files & opts]
|
||||
(let [repo (state/get-current-repo)]
|
||||
(when-let [chan (state/get-file-write-chan)]
|
||||
(let [chan-callback (:chan-callback opts)]
|
||||
(async/put! chan [repo files opts file->content])
|
||||
(async/put! chan [repo files opts])
|
||||
(when chan-callback
|
||||
(chan-callback))))))
|
||||
|
||||
(defn- create-file-if-not-exists!
|
||||
[page ok-handler]
|
||||
(when-let [repo (state/get-current-repo)]
|
||||
(let [format (name (get page :block/format :markdown))
|
||||
title (string/capitalize (:block/name page))
|
||||
journal-page? (date/valid-journal-title? title)
|
||||
path (str
|
||||
(if journal-page?
|
||||
config/default-journals-directory
|
||||
(config/get-pages-directory))
|
||||
"/"
|
||||
(if journal-page?
|
||||
(date/journal-title->default title)
|
||||
(-> (:block/name page)
|
||||
(util/page-name-sanity))) "."
|
||||
(if (= format "markdown") "md" format))
|
||||
file-path (str "/" path)
|
||||
dir (config/get-repo-dir repo)]
|
||||
(p/let [exists? (fs/file-exists? dir file-path)]
|
||||
(if exists?
|
||||
(notification/show!
|
||||
[:p.content
|
||||
(util/format "File %s already exists!" file-path)]
|
||||
:error)
|
||||
(let [file-path (config/get-file-path repo path)]
|
||||
(db/transact! [{:file/path file-path}
|
||||
{:block/name (:block/name page)
|
||||
:block/file [:file/path file-path]}])
|
||||
(ok-handler)))))))
|
||||
|
||||
(defn save-tree-aux!
|
||||
[page-block tree]
|
||||
(let [page-block (db/pull (:db/id page-block))
|
||||
new-content (tree->file-content tree init-level)
|
||||
file-db-id (-> page-block :block/file :db/id)
|
||||
file-path (-> (db-utils/entity file-db-id) :file/path)
|
||||
_ (assert (string? file-path) "File path should satisfy string?")
|
||||
files [[file-path new-content]]]
|
||||
(push-to-write-chan files)))
|
||||
|
||||
(defn save-tree
|
||||
[page-block tree]
|
||||
{:pre [(map? page-block)]}
|
||||
(let [new-content (tree->file-content tree markdown-init-level)
|
||||
file-db-id (-> page-block :block/file :db/id)
|
||||
file-path (-> (db-utils/entity file-db-id) :file/path)
|
||||
_ (assert (string? file-path) "File path should satisfy string?")
|
||||
{old-content :file/content :as file} (model/get-file-by-path file-path)
|
||||
files [[file-path new-content]]
|
||||
file->content {file-path old-content}]
|
||||
(push-to-write-chan files file->content)))
|
||||
(let [ok-handler #(save-tree-aux! page-block tree)]
|
||||
(if-let [file (:block/file page-block)]
|
||||
(ok-handler)
|
||||
(create-file-if-not-exists! page-block ok-handler))))
|
||||
|
|
Loading…
Reference in New Issue