Merge branch 'master' into refactor/core

This commit is contained in:
Tienson Qin
2021-03-21 14:14:22 +08:00
57 changed files with 796 additions and 565 deletions

View File

@@ -3,9 +3,10 @@
[electron.updater :refer [init-updater]]
[electron.utils :refer [mac? win32? prod? dev? logger open]]
[clojure.string :as string]
["fs" :as fs]
[promesa.core :as p]
["fs-extra" :as fs]
["path" :as path]
["electron" :refer [BrowserWindow app protocol ipcMain] :as electron]
["electron" :refer [BrowserWindow app protocol ipcMain dialog] :as electron]
[clojure.core.async :as async]
[electron.state :as state]))
@@ -54,10 +55,44 @@
(callback #js {:path path}))))
#(.unregisterProtocol protocol "assets"))
(defn- handle-export-publish-assets [_event html]
(let [app-path (. app getAppPath)
paths (js->clj (. dialog showOpenDialogSync (clj->js {:properties ["openDirectory" "createDirectory" "promptToCreate", "multiSelections"]})))]
(when (seq paths)
(let [root-dir (first paths)
static-dir (path/join root-dir "static")
path (path/join root-dir "index.html")]
(p/let [_ (. fs ensureDir static-dir)
_ (p/all (concat
[(. fs writeFile path html)
(. fs copy (path/join app-path "404.html") (path/join root-dir "404.html"))]
(map
(fn [part]
(. fs copy (path/join app-path part) (path/join static-dir part)))
["css" "fonts" "icons" "img" "js"])))
js-files ["main.js" "code-editor.js" "excalidraw.js"]
_ (p/all (map (fn [file]
(. fs removeSync (path/join static-dir "js" file)))
js-files))
_ (p/all (map (fn [file]
(. fs moveSync
(path/join static-dir "js" "publishing" file)
(path/join static-dir "js" file)))
js-files))
_ (. fs removeSync (path/join static-dir "js" "publishing"))
;; remove source map files
;; TODO: ugly, replace with ls-files and filter with ".map"
_ (p/all (map (fn [file]
(. fs removeSync (path/join static-dir "js" (str file ".map"))))
["main.js" "code-editor.js" "excalidraw.js" "age-encryption.js"]))]
(. dialog showMessageBox (clj->js {:message (str "Export publish assets to " root-dir " successfully")})))))))
(defn setup-app-manager!
[^js win]
(let [toggle-win-channel "toggle-max-or-min-active-win"
call-app-channel "call-application"
export-publish-assets "export-publish-assets"
web-contents (. win -webContents)]
(doto ipcMain
(.handle toggle-win-channel
@@ -70,6 +105,9 @@
(if (.isMaximized active-win)
(.unmaximize active-win)
(.maximize active-win))))))
(.handle export-publish-assets handle-export-publish-assets)
(.handle call-app-channel
(fn [_ type & args]
(try
@@ -91,10 +129,12 @@
(.on "leave-full-screen" #(.send web-contents "full-screen" "leave")))
#(do (.removeHandler ipcMain toggle-win-channel)
(.removeHandler ipcMain export-publish-assets)
(.removeHandler ipcMain call-app-channel))))
(defonce *win (atom nil))
(defn- destroy-window!
[^js win]
(.destroy win))

View File

@@ -71,7 +71,7 @@
;; TODO: Is it going to be slow if it's a huge directory
(defmethod handle :openDir [^js window _messages]
(let [result (.showOpenDialogSync dialog (bean/->js
{:properties ["openDirectory"]}))
{:properties ["openDirectory" "createDirectory" "promptToCreate"]}))
path (first result)]
(.. ^js window -webContents
(send "open-dir-confirmed"

View File

@@ -48,7 +48,8 @@
[lambdaisland.glogi :as log]
[frontend.context.i18n :as i18n]
[frontend.template :as template]
[shadow.loader :as loader]))
[shadow.loader :as loader]
[frontend.search :as search]))
;; TODO: remove rum/with-context because it'll make reactive queries not working
@@ -638,7 +639,7 @@
[:span.warning {:title "Invalid link"} full_text]
;; image
(some (fn [fmt] (re-find (re-pattern (str "(?i)\\." fmt)) s)) img-formats)
(text/image-link? img-formats s)
(image-link config url s label metadata full_text)
(= \# (first s))
@@ -676,7 +677,7 @@
(block-reference config (:link (second url)))
(= protocol "file")
(if (some (fn [fmt] (re-find (re-pattern (str "(?i)\\." fmt)) href)) img-formats)
(if (text/image-link? img-formats href)
(image-link config url href label metadata full_text)
(let [label-text (get-label-text label)
page (if (string/blank? label-text)
@@ -701,7 +702,7 @@
(map-inline config label)))))
;; image
(some (fn [fmt] (re-find (re-pattern (str "(?i)\\." fmt)) href)) img-formats)
(text/image-link? img-formats href)
(image-link config url href label metadata full_text)
:else
@@ -803,7 +804,7 @@
[:iframe
{:allow-full-screen "allowfullscreen"
:allow
"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope"
:frame-border "0"
:src (str "https://www.youtube.com/embed/" youtube-id)
:height height
@@ -820,7 +821,7 @@
[:iframe
{:allow-full-screen "allowfullscreen"
:allow
"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope"
:frame-border "0"
:src (str "https://player.vimeo.com/video/" vimeo-id)
:height height
@@ -889,13 +890,50 @@
(get name))
(get (state/get-macros) name)
(get (state/get-macros) (keyword name)))
macro-content (if (and (seq arguments) macro-content)
macro-content (cond
(= (str name) "img")
(case (count arguments)
1
(util/format "[:img {:src \"%s\"}]" (first arguments))
4
(if (and (util/safe-parse-int (nth arguments 1))
(util/safe-parse-int (nth arguments 2)))
(util/format "[:img.%s {:src \"%s\" :style {:width %s :height %s}}]"
(nth arguments 3)
(first arguments)
(util/safe-parse-int (nth arguments 1))
(util/safe-parse-int (nth arguments 2))))
3
(if (and (util/safe-parse-int (nth arguments 1))
(util/safe-parse-int (nth arguments 2)))
(util/format "[:img {:src \"%s\" :style {:width %s :height %s}}]"
(first arguments)
(util/safe-parse-int (nth arguments 1))
(util/safe-parse-int (nth arguments 2))))
2
(cond
(and (util/safe-parse-int (nth arguments 1)))
(util/format "[:img {:src \"%s\" :style {:width %s}}]"
(first arguments)
(util/safe-parse-int (nth arguments 1)))
(contains? #{"left" "right" "center"} (string/lower-case (nth arguments 1)))
(util/format "[:img.%s {:src \"%s\"}]"
(string/lower-case (nth arguments 1))
(first arguments))
:else
macro-content)
macro-content)
(and (seq arguments) macro-content)
(block/macro-subs macro-content arguments)
:else
macro-content)
macro-content (when macro-content
(template/resolve-dynamic-template! macro-content))]
(render-macro config name arguments macro-content format))
(when-let [macro-txt (macro->text name arguments)]
(let [macro-txt (when macro-txt
(template/resolve-dynamic-template! macro-txt))
@@ -1747,7 +1785,15 @@
[state]
(let [[config query] (:rum/args state)
query-atom (if (:dsl-query? config)
(query-dsl/query (state/get-current-repo) (:query query))
(let [result (query-dsl/query (state/get-current-repo) (:query query))]
(if (string? result) ; full-text search
(atom
(if (string/blank? result)
[]
(let [blocks (search/block-search result 50)]
(when (seq blocks)
(db/pull-many (state/get-current-repo) '[*] (map (fn [b] [:block/uuid (uuid (:block/uuid b))]) blocks))))))
result))
(db/custom-query query))]
(assoc state :query-atom query-atom)))
@@ -2041,6 +2087,7 @@
(fn [acc block]
(let [block (dissoc block :block/meta)
level (:block/level block)
config (assoc config :block/uuid (:block/uuid block))
block-cp (if build-block-fn
(build-block-fn config block)
(rum/with-key

View File

@@ -321,6 +321,10 @@
38 (editor-handler/keydown-up-down-handler input true)
;; down
40 (editor-handler/keydown-up-down-handler input false)
;; left
37 (editor-handler/keydown-arrow-handler input :left)
;; right
39 (editor-handler/keydown-arrow-handler input :right)
;; backspace
8 (editor-handler/keydown-backspace-handler repo input input-id)
;; tab

View File

@@ -0,0 +1,30 @@
(ns frontend.components.export
(:require [rum.core :as rum]
[frontend.ui :as ui]
[frontend.util :as util]
[frontend.handler.export :as export]
[frontend.state :as state]
[frontend.context.i18n :as i18n]))
(rum/defc export
[]
(when-let [current-repo (state/get-current-repo)]
(rum/with-context [[t] i18n/*tongue-context*]
[:div.export.w-96
[:h1.title "Export"]
[:ul.mr-1
(when (util/electron?)
[:li.mb-4
[:a.font-medium {:on-click #(export/export-repo-as-html! current-repo)}
(t :export-public-pages)]])
[:li.mb-4
[:a.font-medium {:on-click #(export/export-repo-as-markdown! current-repo)}
(t :export-markdown)]]
[:li.mb-4
[:a.font-medium {:on-click #(export/export-repo-as-edn! current-repo)}
(t :export-edn)]]]
[:a#download-as-edn.hidden]
[:a#download-as-html.hidden]
[:a#download-as-zip.hidden]
[:a#export-as-markdown.hidden]])))

View File

@@ -11,10 +11,10 @@
[frontend.context.i18n :as i18n]
[frontend.handler.ui :as ui-handler]
[frontend.handler.user :as user-handler]
[frontend.handler.export :as export]
[frontend.components.svg :as svg]
[frontend.components.repo :as repo]
[frontend.components.search :as search]
[frontend.components.export :as export]
[frontend.handler.project :as project-handler]
[frontend.handler.page :as page-handler]
[frontend.handler.web.nfs :as nfs]
@@ -128,9 +128,9 @@
(when current-repo
{:title (t :export)
:options {:on-click (fn []
(export/export-repo-as-html! current-repo))}
:options {:on-click #(state/set-modal! export/export)}
:icon nil})
(when current-repo
{:title (t :import)
:options {:href (rfe/href :import)}
@@ -148,7 +148,7 @@
(remove nil?))
;; {:links-footer (when (and (util/electron?) (not logged?))
;; [:div.px-2.py-2 (login logged?)])}
)))
)))
(rum/defc header
< rum/reactive
@@ -212,7 +212,4 @@
(dropdown-menu {:me me
:t t
:current-repo current-repo
:default-home default-home})
[:a#download-as-html.hidden]
[:a#download-as-zip.hidden]])))
:default-home default-home})])))

View File

@@ -70,7 +70,6 @@
(let [;; Don't edit the journal title
page (string/lower-case title)
repo (state/sub :git/current-repo)
encoded-page-name (util/encode-str page)
today? (= (string/lower-case title)
(string/lower-case (date/journal-name)))
intro? (and (not (state/logged?))

View File

@@ -241,8 +241,8 @@
[:tr [:td (t :help/new-line-in-block)] [:td "Shift-Enter"]]
[:tr [:td (t :undo)] [:td (util/->platform-shortcut "Ctrl-z")]]
[:tr [:td (t :redo)] [:td (util/->platform-shortcut "Ctrl-y")]]
[:tr [:td (t :help/zoom-in)] [:td (util/->platform-shortcut (if util/mac? "Alt-." "Alt-Right"))]]
[:tr [:td (t :help/zoom-out)] [:td (util/->platform-shortcut (if util/mac? "Alt-," "Alt-left"))]]
[:tr [:td (t :help/zoom-in)] [:td (util/->platform-shortcut (if util/mac? "Cmd-." "Alt-Right"))]]
[:tr [:td (t :help/zoom-out)] [:td (util/->platform-shortcut (if util/mac? "Cmd-," "Alt-left"))]]
[:tr [:td (t :help/follow-link-under-cursor)] [:td (util/->platform-shortcut "Ctrl-o")]]
[:tr [:td (t :help/open-link-in-sidebar)] [:td (util/->platform-shortcut "Ctrl-shift-o")]]
[:tr [:td (t :expand)] [:td (util/->platform-shortcut "Ctrl-Down")]]
@@ -268,7 +268,7 @@
[:tr [:td (t :help/toggle-right-sidebar)] [:td "t r"]]
[:tr [:td (t :help/toggle-settings)] [:td "t s"]]
[:tr [:td (t :help/toggle-insert-new-block)] [:td "t e"]]
[:tr [:td (t :help/jump-to-journals)] [:td (util/->platform-shortcut "Ctrl-j")]]]]
[:tr [:td (t :help/jump-to-journals)] [:td (if util/mac? "Cmd-j" "Alt-j")]]]]
[:table
[:thead
[:tr

View File

@@ -173,14 +173,14 @@
(rum/defcs rename-page-dialog-inner <
(rum/local "" ::input)
[state page-name close-fn]
[state title page-name close-fn]
(let [input (get state ::input)]
(rum/with-context [[t] i18n/*tongue-context*]
[:div.w-full.sm:max-w-lg.sm:w-96
[:div.sm:flex.sm:items-start
[:div.mt-3.text-center.sm:mt-0.sm:text-left
[:h3#modal-headline.text-lg.leading-6.font-medium
(t :page/rename-to page-name)]]]
(t :page/rename-to title)]]]
[:input.form-input.block.w-full.sm:text-sm.sm:leading-5.my-2
{:auto-focus true
@@ -193,11 +193,10 @@
[:button.inline-flex.justify-center.w-full.rounded-md.border.border-transparent.px-4.py-2.bg-indigo-600.text-base.leading-6.font-medium.text-white.shadow-sm.hover:bg-indigo-500.focus:outline-none.focus:border-indigo-700.focus:shadow-outline-indigo.transition.ease-in-out.duration-150.sm:text-sm.sm:leading-5
{:type "button"
:on-click (fn []
(let [value @input]
(let [value (string/trim value)]
(when-not (string/blank? value)
(page-handler/rename! page-name value)
(state/close-modal!)))))}
(let [value (string/trim @input)]
(when-not (string/blank? value)
(page-handler/rename! page-name value)
(state/close-modal!))))}
(t :submit)]]
[:span.mt-3.flex.w-full.rounded-md.shadow-sm.sm:mt-0.sm:w-auto
[:button.inline-flex.justify-center.w-full.rounded-md.border.border-gray-300.px-4.py-2.bg-white.text-base.leading-6.font-medium.text-gray-700.shadow-sm.hover:text-gray-500.focus:outline-none.focus:border-blue-300.focus:shadow-outline-blue.transition.ease-in-out.duration-150.sm:text-sm.sm:leading-5
@@ -206,9 +205,9 @@
(t :cancel)]]]])))
(defn rename-page-dialog
[page-name]
[title page-name]
(fn [close-fn]
(rename-page-dialog-inner page-name close-fn)))
(rename-page-dialog-inner title page-name close-fn)))
(defn tagged-pages
[repo tag]
@@ -235,9 +234,8 @@
[state {:keys [repo] :as option}]
(let [current-repo (state/sub :git/current-repo)
repo (or repo current-repo)
encoded-page-name (or (get-page-name state)
(state/get-current-page))
path-page-name (util/url-decode encoded-page-name)
path-page-name (or (get-page-name state)
(state/get-current-page))
page-name (string/lower-case path-page-name)
marker-page? (util/marker? page-name)
priority-page? (contains? #{"a" "b" "c"} page-name)
@@ -303,7 +301,7 @@
(when-not contents?
{:title (t :page/rename)
:options {:on-click #(state/set-modal! (rename-page-dialog page-name))}})
:options {:on-click #(state/set-modal! (rename-page-dialog title page-name))}})
(when (and file-path (util/electron?))
[{:title (t :page/open-in-finder)
@@ -315,38 +313,14 @@
{:title (t :page/delete)
:options {:on-click #(state/set-modal! (delete-page-dialog page-name))}})
{:title (t :page/action-publish)
:options {:on-click
(fn []
(state/set-modal!
(fn []
[:div.cp__page-publish-actions
(mapv (fn [{:keys [title options]}]
(when title
[:div.it
(apply (partial ui/button title) (flatten (seq options)))]))
[(if published?
{:title (t :page/unpublish)
:options {:on-click (fn []
(page-handler/unpublish-page! page-name))}}
{:title (t :page/publish)
:options {:on-click (fn []
(page-handler/publish-page!
page-name project/add-project
html-export/export-page))}})
(when-not published?
{:title (t :page/publish-as-slide)
:options {:on-click (fn []
(page-handler/publish-page-as-slide!
page-name project/add-project
html-export/export-page))}})
{:title (t (if public? :page/make-private :page/make-public))
:options {:background (if public? "gray" "indigo")
:on-click (fn []
(page-handler/update-public-attribute!
page-name
(if public? false true))
(state/close-modal!))}}])])))}}
(when (util/electron?)
{:title (t (if public? :page/make-private :page/make-public))
:options {:on-click
(fn []
(page-handler/update-public-attribute!
page-name
(if public? false true))
(state/close-modal!))}})
(when file
{:title (t :page/re-index)
@@ -437,7 +411,7 @@
(block/block-parents config repo block-id format)]))
;; blocks
(page-blocks-cp repo page file-path page-name page-original-name encoded-page-name sidebar? journal? block? block-id format)]]
(page-blocks-cp repo page file-path page-name page-original-name page-name sidebar? journal? block? block-id format)]]
(when-not block?
(today-queries repo today? sidebar?))
@@ -516,21 +490,20 @@
[:th (t :file/last-modified-at)]]]
[:tbody
(for [page pages]
(let [encoded-page (util/encode-str page)]
[:tr {:key encoded-page}
[:td [:a {:on-click (fn [e]
(let [repo (state/get-current-repo)
page (db/pull repo '[*] [:block/name (string/lower-case page)])]
(when (gobj/get e "shiftKey")
(state/sidebar-add-block!
repo
(:db/id page)
:page
{:page page}))))
:href (rfe/href :page {:name encoded-page})}
page]]
[:td [:span.text-gray-500.text-sm
(t :file/no-data)]]]))]]))])))
[:tr {:key page}
[:td [:a {:on-click (fn [e]
(let [repo (state/get-current-repo)
page (db/pull repo '[*] [:block/name (string/lower-case page)])]
(when (gobj/get e "shiftKey")
(state/sidebar-add-block!
repo
(:db/id page)
:page
{:page page}))))
:href (rfe/href :page {:name page})}
page]]
[:td [:span.text-gray-500.text-sm
(t :file/no-data)]]])]]))])))
(rum/defcs new < rum/reactive
(rum/local "" ::title)

View File

@@ -78,16 +78,10 @@
:on-click (fn []
(repo-handler/re-index! nfs-handler/rebuild-index!))}
"Re-index"]
;; [:a.control.ml-4 {:title "Export as JSON"
;; :on-click (fn []
;; (export-handler/export-repo-as-json! (:url repo)))}
;; "Export as JSON"]
[:a.text-gray-400.ml-4 {:title "No worries, unlink this graph will clear its cache only, it does not remove your files on the disk."
:on-click (fn []
(repo-handler/remove-repo! repo))}
"Unlink"]]]))]
[:a#download-as-json.hidden]]
"Unlink"]]]))]]
(widgets/add-graph)))))
(rum/defc sync-status < rum/reactive

View File

@@ -56,7 +56,8 @@
(defn recent-pages
[]
(let [pages (db/get-key-value :recent/pages)]
(let [pages (->> (db/get-key-value :recent/pages)
(remove #(= (string/lower-case %) "contents")))]
[:div.recent-pages.text-sm.flex-col.flex.ml-3.mt-2
(if (seq pages)
(for [page pages]
@@ -200,7 +201,7 @@
(date/journal-name))]
(if page
(util/url-decode (string/lower-case page)))))
(string/lower-case page))))
(defn get-current-page
[]

View File

@@ -244,7 +244,7 @@
search-q (state/sub :search/q)
show-result? (boolean (seq search-result))
blocks-count (or (db/blocks-count) 0)
timeout (if (> blocks-count 2000) 500 100)]
timeout (if (> blocks-count 2000) 500 300)]
(rum/with-context [[t] i18n/*tongue-context*]
[:div#search.flex-1.flex
[:div.inner

View File

@@ -131,7 +131,8 @@
(ui/loading (t :loading))]]
:else
[:div.max-w-7xl.mx-auto {:style {:margin-bottom (if global-graph-pages? 0 120)}}
[:div {:class (if global-graph-pages? "" (util/hiccup->class "max-w-7xl.mx-auto"))
:style {:margin-bottom (if global-graph-pages? 0 120)}}
main-content])]]
(right-sidebar/sidebar)]))
@@ -184,6 +185,11 @@
(route-handler/redirect! {:to :page
:path-params {:name (:page default-home)}})
(and config/publishing?
(not default-home)
(empty? latest-journals))
(route-handler/redirect! {:to :all-pages})
importing-to-db?
(ui/loading (t :parsing-files))

View File

@@ -28,10 +28,17 @@
(def asset-domain (util/format "https://asset.%s.com"
app-name))
;; TODO: Remove this, switch to lazy loader
(defn asset-uri
[path]
(if (util/file-protocol?)
(cond
publishing?
path
(util/file-protocol?)
(string/replace path "/static/" "./")
:else
(if dev? path
(str asset-domain path))))

View File

@@ -30,7 +30,7 @@
remove-conn!]
[frontend.db.utils
date->int db->json db->string get-max-tx-id get-tx-id
date->int db->json db->edn-str db->string get-max-tx-id get-tx-id
group-by-page seq-flatten sort-by-pos
string->db with-repo

View File

@@ -570,7 +570,8 @@
(->> (string/split-lines content)
(take-while (fn [line]
(or (string/blank? line)
(string/starts-with? line "#+"))))
(string/starts-with? line "#+")
(re-find #"^:.+?:" line))))
(string/join "\n"))
:markdown

View File

@@ -46,16 +46,17 @@
(defn query-wrapper
[where blocks?]
(let [q (if blocks? ; FIXME: it doesn't need to be either blocks or pages
'[:find (pull ?b [*])
:where]
'[:find (pull ?p [*])
:where])
result (if (coll? (first where))
(apply conj q where)
(conj q where))]
(prn "Datascript query: " result)
result))
(when where
(let [q (if blocks? ; FIXME: it doesn't need to be either blocks or pages
'[:find (pull ?b [*])
:where]
'[:find (pull ?p [*])
:where])
result (if (coll? (first where))
(apply conj q where)
(conj q where))]
(prn "Datascript query: " result)
result)))
;; (between -7d +7d)
(defn- ->journal-day-int [input]
@@ -151,7 +152,7 @@
(contains? #{'and 'or 'not} fe)
(let [clauses (->> (map (fn [form]
(build-query repo form (assoc env :current-filter fe) (inc level)))
(rest e))
(rest e))
remove-nil?
(distinct))]
(when (seq clauses)
@@ -221,7 +222,7 @@
(text/page-ref-un-brackets!))
sym (if (= current-filter 'or)
'?v
(uniq-symbol counter "?v"))]
(uniq-symbol counter "?v"))]
[['?b :block/properties '?prop]
[(list 'get '?prop (name (nth e 1))) sym]
(list
@@ -354,39 +355,47 @@
(try
(let [form (some-> s
(pre-transform)
(reader/read-string))
sort-by (atom nil)
blocks? (atom nil)
result (when form (build-query repo form {:sort-by sort-by
:blocks? blocks?
:counter counter}))
result (when (seq result)
(let [key (if (coll? (first result))
(keyword (ffirst result))
(keyword (first result)))
result (case key
:and
(rest result)
(reader/read-string))]
(if (symbol? form)
(str form)
(let [sort-by (atom nil)
blocks? (atom nil)
result (when form (build-query repo form {:sort-by sort-by
:blocks? blocks?
:counter counter}))]
(if (string? result)
result
(let [result (when (seq result)
(let [key (if (coll? (first result))
(keyword (ffirst result))
(keyword (first result)))
result (case key
:and
(rest result)
result)]
(add-bindings! result)))]
{:query result
:sort-by @sort-by
:blocks? (boolean @blocks?)})
result)]
(add-bindings! result)))]
{:query result
:sort-by @sort-by
:blocks? (boolean @blocks?)})))))
(catch js/Error e
(log/error :query-dsl/parse-error e))))))
(defn query
[repo query-string]
(when (string? query-string)
(let [query-string (template/resolve-dynamic-template! query-string)
{:keys [query sort-by blocks?]} (parse repo query-string)]
(when query
(let [query (query-wrapper query blocks?)]
(react/react-query repo
{:query query}
(if sort-by
{:transform-fn sort-by})))))))
(let [query-string (template/resolve-dynamic-template! query-string)]
(when-not (string/blank? query-string)
(let [{:keys [query sort-by blocks?] :as result} (parse repo query-string)]
(if (string? result)
(if (= "\"" (first result) (last result))
(subs result 1 (dec (count result)))
result)
(when-let [query (query-wrapper query blocks?)]
(react/react-query repo
{:query query}
(if sort-by
{:transform-fn sort-by})))))))))
(defn custom-query
[repo query-m query-opts]
@@ -395,7 +404,7 @@
query-string (template/resolve-dynamic-template! query-string)
{:keys [query sort-by blocks?]} (parse repo query-string)]
(when query
(let [query (query-wrapper query blocks?)]
(when-let [query (query-wrapper query blocks?)]
(react/react-query repo
(merge
query-m

View File

@@ -99,5 +99,5 @@
k [:custom query']]
(apply react/q repo k query-opts query inputs))
(catch js/Error e
(println "Custom query failed: ")
(println "Custom query failed: " {:query query'})
(js/console.dir e))))

View File

@@ -174,7 +174,7 @@
(date/journal-name))]
(when page
(let [page-name (util/url-decode (string/lower-case page))]
(let [page-name (string/lower-case page)]
(db-utils/entity [:block/name page-name])))))
(defn get-current-priority

View File

@@ -20,6 +20,9 @@
(for [d (d/datoms db :eavt)]
#js [(:e d) (name (:a d)) (:v d)]))))
(defn db->edn-str [db]
(pr-str db))
(defn string->db [s]
(dt/read-transit-str s))

View File

@@ -42,7 +42,7 @@ some changes on the right sidebar, those referenced blocks will be changed too!
[:iframe
{:allowFullScreen \"allowfullscreen\"
:allow
\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\"
\"accelerometer; autoplay; encrypted-media; gyroscope\"
:frameBorder \"0\"
:src \"https://www.youtube.com/embed/Afmqowr0qEQ\"
:height \"367\"
@@ -50,7 +50,7 @@ some changes on the right sidebar, those referenced blocks will be changed too!
### DONE Create a page
### CANCELED [#C] Write a page with more than 1000 blocks
## That's it! You can create more bullets or open a local directory to import some notes now!
##
## You can also download our desktop app at https://github.com/logseq/logseq/releases
"
:tutorial/dummy-notes "---
title: How to take dummy notes?
@@ -229,7 +229,7 @@ title: How to take dummy notes?
:page/open-in-finder "Open in directory"
:page/open-with-default-app "Open with default app"
:page/action-publish "Publish"
:page/make-public "Publish it when exporting to an html file"
:page/make-public "Make it public for publishing"
:page/make-private "Make it private"
:page/delete "Delete page"
:page/publish "Publish this page on Logseq"
@@ -310,7 +310,6 @@ title: How to take dummy notes?
:cancel "Cancel"
:close "Close"
:re-index "Re-index"
:export-json "Export as JSON"
:unlink "unlink"
:search (if config/publishing?
"Search"
@@ -320,7 +319,11 @@ title: How to take dummy notes?
:graph "Graph"
:graph-view "View Graph"
:publishing "Publishing"
:export "Export public pages"
:export "Export"
:export-json "Export as JSON"
:export-markdown "Export as Markdown"
:export-public-pages "Export public pages"
:export-edn "Export as EDN"
:all-graphs "All graphs"
:all-pages "All pages"
:all-files "All files"
@@ -1033,6 +1036,7 @@ title: How to take dummy notes?
:cancel "取消"
:re-index "重新建立索引"
:export-json "以 JSON 格式导出"
:export-markdown "以 Markdown 格式导出"
:unlink "解除绑定"
:search (if config/publishing?
"搜索"
@@ -1297,6 +1301,7 @@ title: How to take dummy notes?
:cancel "取消"
:re-index "重新建立索引"
:export-json "以 JSON 格式導出"
:export-markdown "以 Markdown 格式導出"
:unlink "解除綁定"
:search (if config/publishing?
"搜索"

View File

@@ -16,6 +16,7 @@
["codemirror/mode/clojure/clojure"]
["codemirror/mode/powershell/powershell"]
["codemirror/mode/javascript/javascript"]
["codemirror/mode/jsx/jsx"]
["codemirror/mode/clike/clike"]
["codemirror/mode/vue/vue"]
["codemirror/mode/commonlisp/commonlisp"]
@@ -100,6 +101,10 @@
"csharp" "text/x-csharp"
"objective-c" "text/x-objectivec"
"scala" "text/x-scala"
"js" "text/javascript"
"typescript" "text/typescript"
"ts" "text/typescript"
"tsx" "text/typescript-jsx"
mode))))
(defn render!

View File

@@ -5,7 +5,8 @@
[medley.core :as medley]
[clojure.walk :as walk]
[clojure.string :as string]
[frontend.util :as util]))
[frontend.util :as util]
[frontend.text :as text]))
(defonce all-refed-uids (atom #{}))
(defonce uid->uuid (atom {}))
@@ -34,12 +35,9 @@
(defn macro-transform
[text]
(string/replace text macro-pattern (fn [[original text]]
(let [[name arg] (-> (string/replace text #" " "")
(string/split #":"))]
(let [[name arg] (util/split-first ":" text)]
(if name
(let [name (case name
"[[embed]]" "embed"
name)]
(let [name (text/page-ref-un-brackets! name)]
(util/format "{{%s %s}}" name arg))
original)))))

View File

@@ -33,8 +33,10 @@
;; html
(defn get-default-config
[format]
(mldoc/default-config format))
([format]
(mldoc/default-config format))
([format heading-to-list?]
(mldoc/default-config format heading-to-list?)))
(defn to-html
([content format]
@@ -62,7 +64,7 @@
(protocol/loaded? record)))
(def marker-pattern
#"^(NOW|LATER|TODO|DOING|DONE|WAIT|WAITING|CANCELED|CANCELLED|STARTED|IN-PROGRESS)?\s?")
#"^(NOW|LATER|TODO|DOING|DONE|WAITING|WAIT|CANCELED|CANCELLED|STARTED|IN-PROGRESS)?\s?")
(def bare-marker-pattern
#"^(NOW|LATER|TODO|DOING|DONE|WAIT|WAITING|CANCELED|CANCELLED|STARTED|IN-PROGRESS){1}\s+")
#"^(NOW|LATER|TODO|DOING|DONE|WAITING|WAIT|CANCELED|CANCELLED|STARTED|IN-PROGRESS){1}\s+")

View File

@@ -26,4 +26,6 @@
(lazyLoad [this ok-handler]
(loader/load
"https://cdnjs.cloudflare.com/ajax/libs/asciidoctor.js/1.5.9/asciidoctor.min.js"
ok-handler)))
ok-handler))
(exportMarkdown [this content config references]
(throw "not support")))

View File

@@ -60,11 +60,11 @@
(and (vector? block)
(= "Macro" (first block)))
(let [{:keys [name arguments]} (second block)]
(when (and (= name "embed")
(string? (first arguments))
(string/starts-with? (first arguments) "[[")
(string/ends-with? (first arguments) "]]"))
(subs (first arguments) 2 (- (count (first arguments)) 2))))
(let [argument (string/join ", " arguments)]
(when (and (= name "embed")
(string? argument)
(text/page-ref? argument))
(text/page-ref-un-brackets! argument))))
:else
nil)]
(when (and
@@ -234,8 +234,15 @@
(swap! ref-pages conj tag)))
form)
(concat title body))
(let [ref-pages (remove string/blank? @ref-pages)]
(assoc block :ref-pages (vec ref-pages)))))
(let [ref-pages (remove string/blank? @ref-pages)
children-pages (->> (mapcat (fn [p]
(if (string/includes? p "/")
;; Don't create the last page for now
(butlast (string/split p #"/"))))
ref-pages)
(remove string/blank?))
ref-pages (distinct (concat ref-pages children-pages))]
(assoc block :ref-pages ref-pages))))
(defn with-block-refs
[{:keys [title body] :as block}]

View File

@@ -14,16 +14,26 @@
(defonce parseInlineJson (gobj/get Mldoc "parseInlineJson"))
(defonce parseHtml (gobj/get Mldoc "parseHtml"))
(defonce anchorLink (gobj/get Mldoc "anchorLink"))
(defonce parseAndExportMarkdown (gobj/get Mldoc "parseAndExportMarkdown"))
(defn default-config
[format]
(let [format (string/capitalize (name (or format :markdown)))]
(js/JSON.stringify
(bean/->js
(assoc {:toc false
:heading_number false
:keep_line_break true}
:format format)))))
([format]
(default-config format false))
([format export-heading-to-list?]
(let [format (string/capitalize (name (or format :markdown)))]
(js/JSON.stringify
(bean/->js
{:toc false
:heading_number false
:keep_line_break true
:format format
:heading_to_list export-heading-to-list?})))))
(def default-references
(js/JSON.stringify
(clj->js {:embed_blocks []
:embed_pages []
:refer_blocks []})))
(defn parse-json
[content config]
@@ -33,6 +43,12 @@
[text config]
(parseInlineJson text (or config default-config)))
(defn parse-export-markdown
[content config references]
(parseAndExportMarkdown content
(or config default-config)
(or references default-references)))
;; Org-roam
(defn get-tags-from-definition
[ast]
@@ -82,8 +98,12 @@
(if (seq ast)
(let [original-ast ast
ast (map first ast) ; without position meta
directive? (fn [item] (= "directive" (string/lower-case (first item))))
properties (->> (take-while directive? ast)
directive?
(fn [[item _]] (= "directive" (string/lower-case (first item))))
grouped-ast (group-by directive? original-ast)
[directive-ast other-ast]
[(get grouped-ast true) (get grouped-ast false)]
properties (->> (map first directive-ast)
(map (fn [[_ k v]]
(let [k (keyword (string/lower-case k))
comma? (contains? #{:tags :alias :roam_tags} k)
@@ -91,6 +111,7 @@
v
(text/split-page-refs-without-brackets v comma?))]
[k v])))
(reverse)
(into {}))
macro-properties (filter (fn [x] (= :macro (first x))) properties)
macros (if (seq macro-properties)
@@ -134,8 +155,7 @@
(update :roam_alias ->vec)
(update :roam_tags (constantly roam-tags))
(update :filetags (constantly filetags)))
properties (medley/filter-kv (fn [k v] (not (empty? v))) properties)
other-ast (drop-while (fn [[item _pos]] (directive? item)) original-ast)]
properties (medley/filter-kv (fn [k v] (not (empty? v))) properties)]
(if (seq properties)
(cons [["Properties" properties] nil] other-ast)
original-ast))
@@ -174,7 +194,10 @@
(loaded? [this]
true)
(lazyLoad [this ok-handler]
true))
true)
(exportMarkdown [this content config references]
(parse-export-markdown content config references))
)
(defn plain->text
[plains]

View File

@@ -4,4 +4,5 @@
(toEdn [this content config])
(toHtml [this content config])
(loaded? [this])
(lazyLoad [this ok-handler]))
(lazyLoad [this ok-handler])
(exportMarkdown [this content config references]))

View File

@@ -152,7 +152,7 @@
(when file
(nfs-saved-handler repo path file))))
(do
(js/alert (str "The file has been modified in your local disk! File path: " path
(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
(->

View File

@@ -28,7 +28,7 @@
(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)
(js/alert (str "The file has been modified in your local disk! File path: " path
(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."))
(->
(p/let [result (ipc/ipc "writeFile" path content)

View File

@@ -31,7 +31,8 @@
[]
(let [f (fn []
(when-not (state/nfs-refreshing?)
(repo-handler/create-today-journal!))
;; Don't create the journal file until user writes something
(repo-handler/create-today-journal! false))
(when-let [repo (state/get-current-repo)]
(when (and (search-db/empty? repo)
(state/input-idle? repo))
@@ -155,8 +156,8 @@
(defn on-load-events
[]
(let [f (fn []
(init-sentry))]
(set! js/window.onload f)))
(when-not config/dev? (init-sentry)))]
(set! js/window.onload f)))
(defn start!
[render]

View File

@@ -2336,6 +2336,47 @@
(not (in-auto-complete? input)))
(on-up-down state e up?))))
(defn- move-to-block-when-cross-boundrary
[state e direction]
(let [up? (= :left direction)
pos (if up? :max 0)
{:keys [id block-id block block-parent-id dummy? value format] :as block-state} (get-state state)
element (gdom/getElement id)]
(when block-id
(let [f (if up? get-prev-block-non-collapsed get-next-block-non-collapsed)
sibling-block (f (gdom/getElement block-parent-id))]
(when sibling-block
(when-let [sibling-block-id (d/attr sibling-block "blockid")]
(let [state (get-state state)
content (:block/content block)
value (:value state)]
(when (not= (-> content
(text/remove-level-spaces format)
text/remove-properties!
string/trim)
(string/trim value))
(save-block! state (:value state))))
(let [block (db/pull (state/get-current-repo) '[*] [:block/uuid (uuid sibling-block-id)])]
(edit-block! block pos format id)
(util/stop e))))))))
(defn- on-arrow-move-to-boundray
[state input e direction]
(when (or (and (= :left direction) (util/input-start? input))
(and (= :right direction) (util/input-end? input)))
(move-to-block-when-cross-boundrary state e direction)))
(defn keydown-arrow-handler
[input direction]
(fn [state e]
(when (and
input
(not (gobj/get e "shiftKey"))
(not (gobj/get e "ctrlKey"))
(not (gobj/get e "metaKey"))
(not (in-auto-complete? input)))
(on-arrow-move-to-boundray state input e direction))))
(defn keydown-backspace-handler
[repo input id]
(fn [state e]

View File

@@ -1,6 +1,9 @@
(ns frontend.handler.export
(:require [frontend.state :as state]
[frontend.db :as db]
[frontend.format.protocol :as fp]
[frontend.format :as f]
[datascript.core :as d]
[frontend.util :as util]
[cljs-bean.core :as bean]
[clojure.string :as string]
@@ -44,6 +47,16 @@
(.setAttribute anchor "download" (str (last (string/split repo #"/")) ".json"))
(.click anchor)))))
(defn export-repo-as-edn!
[repo]
(when-let [db (db/get-conn repo)]
(let [db-edn (db/db->edn-str db)
data-str (str "data:text/edn;charset=utf-8," (js/encodeURIComponent db-edn))]
(when-let [anchor (gdom/getElement "download-as-edn")]
(.setAttribute anchor "href" data-str)
(.setAttribute anchor "download" (str (last (string/split repo #"/")) ".edn"))
(.click anchor)))))
(defn download-file!
[file-path]
(when-let [repo (state/get-current-repo)]
@@ -59,24 +72,27 @@
(defn export-repo-as-html!
[repo]
(when-let [db (db/get-conn repo)]
(let [db (if (state/all-pages-public?)
(db/clean-export! db)
(db/filter-only-public-pages-and-blocks db))
db-str (db/db->string db)
state (select-keys @state/state
[:ui/theme :ui/cycle-collapse
:ui/collapsed-blocks
:ui/sidebar-collapsed-blocks
:ui/show-recent?
:config])
state (update state :config (fn [config]
{"local" (get config repo)}))
html-str (str "data:text/html;charset=UTF-8,"
(js/encodeURIComponent (html/publishing-html db-str (pr-str state))))]
(when-let [anchor (gdom/getElement "download-as-html")]
(.setAttribute anchor "href" html-str)
(.setAttribute anchor "download" "index.html")
(.click anchor)))))
(let [db (if (state/all-pages-public?)
(db/clean-export! db)
(db/filter-only-public-pages-and-blocks db))
db-str (db/db->string db)
state (select-keys @state/state
[:ui/theme :ui/cycle-collapse
:ui/collapsed-blocks
:ui/sidebar-collapsed-blocks
:ui/show-recent?
:config])
state (update state :config (fn [config]
{"local" (get config repo)}))
raw-html-str (html/publishing-html db-str (pr-str state))
html-str (str "data:text/html;charset=UTF-8,"
(js/encodeURIComponent raw-html-str))]
(if (util/electron?)
(js/window.apis.exportPublishAssets raw-html-str)
(when-let [anchor (gdom/getElement "download-as-html")]
(.setAttribute anchor "href" html-str)
(.setAttribute anchor "download" "index.html")
(.click anchor))))))
(defn export-repo-as-zip!
[repo]
@@ -89,3 +105,117 @@
(.setAttribute anchor "href" (js/window.URL.createObjectURL zipfile))
(.setAttribute anchor "download" (.-name zipfile))
(.click anchor))))))
(defn- get-file-contents-with-suffix
[repo]
(let [conn (db/get-conn repo)]
(->>
(filterv (fn [[path _]]
(or (string/ends-with? path ".md")))
(db/get-file-contents repo))
(mapv (fn [[path content]] {:path path :content content
:names (d/q '[:find [?n ?n2]
:in $ ?p
:where [?e :file/path ?p]
[?e2 :block/file ?e]
[?e2 :block/name ?n]
[?e2 :block/original-name ?n2]] conn path)
:format (f/get-format path)})))))
(defn- get-embed-and-refs-blocks-pages-aux
[repo page-or-block is-block? exclude-blocks exclude-pages]
(let [[ref-blocks ref-pages]
(->> (if is-block?
[page-or-block]
(db/get-page-blocks
repo page-or-block {:use-cache? false
:pull-keys '[:block/ref-pages :block/ref-blocks]}))
(filterv #(or (:block/ref-blocks %) (:block/ref-pages %)))
(mapv (fn [b] [(:block/ref-blocks b), (:block/ref-pages b)]))
(apply mapv vector)
(mapv #(vec (distinct (flatten (remove nil? %))))))
ref-block-ids
(->> ref-blocks
(#(remove (fn [b] (contains? exclude-blocks (:db/id b))) %))
(mapv #(:db/id %)))
ref-page-ids
(->> ref-pages
(#(remove (fn [b] (contains? exclude-pages (:db/id b))) %))
(mapv #(:db/id %)))
ref-blocks
(->> ref-block-ids
(db/pull-many repo '[*])
(flatten))
ref-pages
(->> ref-page-ids
(db/pull-many repo '[*])
(flatten))
[next-ref-blocks1 next-ref-pages1]
(->> ref-blocks
(mapv #(get-embed-and-refs-blocks-pages-aux repo % true
(set (concat ref-block-ids exclude-blocks)) exclude-pages))
(apply mapv vector))
[next-ref-blocks2 next-ref-pages2]
(->> ref-pages
(mapv #(get-embed-and-refs-blocks-pages-aux repo (:block/name %) false
exclude-blocks (set (concat ref-page-ids exclude-pages))))
(apply mapv vector))]
[(->> (concat ref-block-ids next-ref-blocks1 next-ref-blocks2)
(flatten)
(distinct))
(->> (concat ref-page-ids next-ref-pages1 next-ref-pages2)
(flatten)
(distinct))]))
(defn- get-embed-and-refs-blocks-pages
[repo page]
(let [[block-ids page-ids]
(get-embed-and-refs-blocks-pages-aux repo page false #{} #{})
blocks
(db/pull-many repo '[*] block-ids)
pages-name-and-content
(->> page-ids
(d/q '[:find ?n (pull ?p [:file/path])
:in $ [?e ...]
:where
[?e :block/file ?p]
[?e :block/name ?n]] (db/get-conn repo))
(mapv (fn [[page-name file-path]] [page-name (:file/path file-path)]))
(d/q '[:find ?n ?c
:in $ [[?n ?p] ...]
:where
[?e :file/path ?p]
[?e :file/content ?c]] @(db/get-files-conn repo)))
embed-blocks
(mapv (fn [b] [(str (:block/uuid b))
[(apply str
(mapv #(:block/content %)
(db/get-block-and-children repo (:block/uuid b))))
(:block/title b)]])
blocks)]
{:embed_blocks embed-blocks
:embed_pages pages-name-and-content}))
(defn export-repo-as-markdown!
[repo]
(when-let [repo (state/get-current-repo)]
(when-let [files (get-file-contents-with-suffix repo)]
(let [heading-to-list? (state/export-heading-to-list?)
files
(->> files
(mapv (fn [{:keys [path content names format]}]
(when (first names)
[path (fp/exportMarkdown f/mldoc-record content
(f/get-default-config format heading-to-list?)
(js/JSON.stringify
(clj->js (get-embed-and-refs-blocks-pages repo (first names)))))])))
(remove nil?))
zip-file-name (str repo "_markdown_" (quot (util/time-ms) 1000))]
(p/let [zipfile (zip/make-zip zip-file-name files)]
(when-let [anchor (gdom/getElement "export-as-markdown")]
(.setAttribute anchor "href" (js/window.URL.createObjectURL zipfile))
(.setAttribute anchor "download" (.-name zipfile))
(.click anchor)))))))

View File

@@ -36,9 +36,11 @@
(defn- get-file-name
[journal? title]
(if journal?
(date/journal-title->default title)
(util/page-name-sanity (string/lower-case title))))
(when-let [s (if journal?
(date/journal-title->default title)
(util/page-name-sanity (string/lower-case title)))]
;; Win10 file path has a length limit of 260 chars
(util/safe-subs s 0 200)))
(defn create!
([title]
@@ -100,7 +102,9 @@
file (db/entity (:db/id (:block/file page)))
file-path (:file/path file)
file-content (db/get-file file-path)
after-content (subs file-content (inc (count properties-content)))
after-content (if (empty? properties-content)
file-content
(subs file-content (inc (count properties-content))))
new-properties-content (db/add-properties! page-format properties-content properties)
full-content (str new-properties-content "\n\n" (string/trim after-content))]
(file-handler/alter-file (state/get-current-repo)
@@ -430,27 +434,27 @@
(defn get-page-ref-text
[page]
(when-let [edit-block (state/get-edit-block)]
(let [page-name (string/lower-case page)
edit-block-file-path (-> (:db/id (:block/file edit-block))
(db/entity)
:file/path)]
(if (and edit-block-file-path
(state/org-mode-file-link? (state/get-current-repo)))
(if-let [ref-file-path (:file/path (:block/file (db/entity [:block/name page-name])))]
(let [edit-block-file-path (some-> (state/get-edit-block)
(get-in [:block/file :db/id])
db/entity
:file/path)
page-name (string/lower-case page)]
(if (and edit-block-file-path
(state/org-mode-file-link? (state/get-current-repo)))
(if-let [ref-file-path (:file/path (:file/file (db/entity [:file/name page-name])))]
(util/format "[[file:%s][%s]]"
(util/get-relative-path edit-block-file-path ref-file-path)
page)
(let [journal? (date/valid-journal-title? page)
ref-file-path (str (get-directory journal?)
"/"
(get-file-name journal? page)
".org")]
(create! page {:redirect? false})
(util/format "[[file:%s][%s]]"
(util/get-relative-path edit-block-file-path ref-file-path)
page)
(let [journal? (date/valid-journal-title? page)
ref-file-path (str (get-directory journal?)
"/"
(get-file-name journal? page)
".org")]
(create! page {:redirect? false})
(util/format "[[file:%s][%s]]"
(util/get-relative-path edit-block-file-path ref-file-path)
page)))
(util/format "[[%s]]" page)))))
page)))
(util/format "[[%s]]" page))))
(defn init-commands!
[]

View File

@@ -111,7 +111,8 @@
(defn create-today-journal-if-not-exists
([repo-url]
(create-today-journal-if-not-exists repo-url nil))
([repo-url content]
([repo-url {:keys [content write-file?]
:or {write-file? true}}]
(spec/validate :repos/url repo-url)
(when (state/enable-journals? repo-url)
(let [repo-dir (config/get-repo-dir repo-url)
@@ -144,22 +145,28 @@
file-exists? (fs/file-exists? repo-dir file-path)]
(when-not file-exists?
(file-handler/reset-file! repo-url path content)
(p/let [_ (fs/create-if-not-exists repo-url repo-dir file-path content)]
(if write-file?
(p/let [_ (fs/create-if-not-exists repo-url repo-dir file-path content)]
(when-not (state/editing?)
(ui-handler/re-render-root!))
(git-handler/git-add repo-url path))
(when-not (state/editing?)
(ui-handler/re-render-root!))))))))))
(defn create-today-journal!
[]
(state/set-today! (date/today))
(when-let [repo (state/get-current-repo)]
(when (or (db/cloned? repo)
(and (config/local-db? repo)
;; config file exists
(let [path (config/get-config-path)]
(db/get-file path))))
(let [today-page (string/lower-case (date/today))]
(when (empty? (db/get-page-blocks-no-cache repo today-page))
(create-today-journal-if-not-exists repo))))))
([]
(create-today-journal! true))
([write-file?]
(state/set-today! (date/today))
(when-let [repo (state/get-current-repo)]
(when (or (db/cloned? repo)
(and (config/local-db? repo)
;; config file exists
(let [path (config/get-config-path)]
(db/get-file path))))
(let [today-page (string/lower-case (date/today))]
(when (empty? (db/get-page-blocks-no-cache repo today-page))
(create-today-journal-if-not-exists repo {:write-file? write-file?})))))))
(defn create-default-files!
([repo-url]
@@ -169,7 +176,7 @@
(file-handler/create-metadata-file repo-url encrypted?)
;; TODO: move to frontend.handler.file
(create-config-file-if-not-exists repo-url)
(create-today-journal-if-not-exists repo-url)
(create-today-journal-if-not-exists repo-url {:write-file? false})
(create-contents-file repo-url)
(create-custom-theme repo-url)))
@@ -611,7 +618,7 @@
(when-not config/publishing?
(let [tutorial (get-in dicts/dicts [:en :tutorial/text])
tutorial (string/replace-first tutorial "$today" (date/today))]
(create-today-journal-if-not-exists repo tutorial)))
(create-today-journal-if-not-exists repo {:content tutorial})))
(create-config-file-if-not-exists repo)
(create-contents-file repo)
(create-custom-theme repo)

View File

@@ -41,7 +41,7 @@
:all-journals
"All journals"
:file
(str "File " (util/url-decode (:path path-params)))
(str "File " (:path path-params))
:new-page
"Create a new page"
:page
@@ -55,13 +55,12 @@
(str (subs content 0 48) "...")
content))
"Page no longer exists!!")
(let [page (util/url-decode name)
page (db/pull [:block/name (string/lower-case page)])]
(let [page (db/pull [:block/name (string/lower-case name)])]
(or (:block/original-name page)
(:block/name page)
"Logseq"))))
:tag
(str "#" (util/url-decode (:name path-params)))
(str "#" (:name path-params))
:diff
"Git diff"
:draw

View File

@@ -84,4 +84,4 @@
;; TODO: should make this configurable
[:script {:src "/static/js/highlight.min.js"}]
[:script {:src "/static/js/interact.min.js"}]
[:script {:src "/static/js/publishing/main.js"}]]))))
[:script {:src "/static/js/main.js"}]]))))

View File

@@ -38,8 +38,10 @@
indice (fuse. blocks
(clj->js {:keys ["uuid" "content"]
:shouldSort true
:tokenize true
:minMatchCharLength 2
:threshold 0.2}))]
:distance 1000
:threshold 0.35}))]
(swap! indices assoc-in [repo :blocks] indice)
indice)))
@@ -53,8 +55,10 @@
indice (fuse. pages
(clj->js {:keys ["name"]
:shouldSort true
:tokenize true
:minMatchCharLength 2
:threshold 0.2
:distance 1000
:threshold 0.35
}))]
(swap! indices assoc-in [repo :pages] indice)
indice)))

View File

@@ -198,6 +198,11 @@
(not (false? (:feature/enable-journals?
(get (sub-config) repo)))))
(defn export-heading-to-list?
[]
(not (false? (:export/heading-to-list?
(get (sub-config) (get-current-repo))))))
(defn enable-encryption?
[repo]
(:feature/enable-encryption?

View File

@@ -249,3 +249,7 @@
(let [items (map (fn [item] (str "\"" item "\"")) col)]
(util/format "[%s]"
(string/join ", " items))))
(defn image-link?
[img-formats s]
(some (fn [fmt] (re-find (re-pattern (str "(?i)\\." fmt "(?:\\?([^#]*))?(?:#(.*))?$")) s)) img-formats))

View File

@@ -32,7 +32,7 @@
.ui__toggle {
.wrapper {
@apply relative inline-block flex-shrink-0
@apply relative flex-shrink-0
h-6 w-11 border-2 border-transparent flex
rounded-full cursor-pointer focus:outline-none focus:shadow-outline;
}

View File

@@ -1,4 +1,5 @@
(ns frontend.util
#?(:clj (:refer-clojure :exclude [format]))
(:require
#?(:cljs [cljs-bean.core :as bean])
#?(:cljs [cljs-time.coerce :as tc])
@@ -749,6 +750,18 @@
[input]
(and input (.-selectionStart input))))
#?(:cljs
(defn input-start?
[input]
(and input (zero? (.-selectionStart input)))))
#?(:cljs
(defn input-end?
[input]
(and input
(= (count (.-value input))
(.-selectionStart input)))))
#?(:cljs
(defn get-selected-text
[]
@@ -1025,6 +1038,7 @@
(defn page-name-sanity
[page-name]
(-> page-name
(string/replace #"/" ".")
;; Windows reserved path characters
(string/replace #"[\\/:\\*\\?\"<>|]+" "_")))

View File

@@ -1,3 +1,3 @@
(ns frontend.version)
(defonce version "0.0.12")
(defonce version "0.0.13-1")