Merge remote-tracking branch 'origin/master' into zotero/poc

pull/2456/head
Weihua Lu 2021-07-27 13:19:37 +08:00
commit 21cc484fe2
21 changed files with 248 additions and 153 deletions

View File

@ -82,7 +82,7 @@
"ignore": "^5.1.8",
"is-svg": "4.2.2",
"jszip": "^3.5.0",
"mldoc": "0.9.0",
"mldoc": "0.9.1",
"path": "^0.12.7",
"pixi-graph-fork": "^0.1.3",
"posthog-js": "^1.10.2",

View File

@ -1,6 +1,6 @@
{
"name": "Logseq",
"version": "0.2.8",
"version": "0.2.10",
"main": "electron.js",
"author": "Logseq",
"description": "A privacy-first, open-source platform for knowledge management and collaboration.",

View File

@ -17,6 +17,7 @@
[frontend.context.i18n :as i18n]
[frontend.date :as date]
[frontend.db :as db]
[frontend.db.utils :as db-utils]
[frontend.db-mixins :as db-mixins]
[frontend.db.model :as model]
[frontend.db.query-dsl :as query-dsl]
@ -76,11 +77,8 @@
(atom nil))
(def *move-to (atom nil))
;; TODO: Improve blocks grouped by pages
(defonce max-blocks-per-page 500)
(defonce virtual-list-scroll-step 450)
(defonce virtual-list-previous 50)
;; TODO: dynamic
(defonce max-blocks-per-page 200)
(defonce *blocks-container-id (atom 0))
;; TODO:
@ -863,8 +861,9 @@
(and (= "File" (first url))
"file"))]
(cond
(and (= "Complex" (first url))
(= protocol "id")
(and (= (get-in config [:block :block/format]) :org)
(= "Complex" (first url))
(= (string/lower-case protocol) "id")
(string? (:link (second url)))
(util/uuid-string? (:link (second url)))) ; org mode id
(let [id (uuid (:link (second url)))
@ -872,7 +871,7 @@
(if (:block/pre-block? block)
(let [page (:block/page block)]
(page-reference html-export? (:block/name page) config label))
(block-reference config (:link (second url)) nil)))
(block-reference config (:link (second url)) label)))
(= protocol "file")
(if (show-link? config metadata href full_text)
@ -996,7 +995,7 @@
[:div.dsl-query
(let [query (string/join ", " arguments)]
(custom-query (assoc config :dsl-query? true)
{:title [:span.font-medium.p-1.query-title
{:title [:span.font-medium.px-2.py-1.query-title.text-sm.rounded-md.shadow-xs
(str "Query: " query)]
:query query}))]
@ -1253,7 +1252,10 @@
dark? (= "dark" (state/sub :ui/theme))
ref? (:ref? config)
collapsed? (if ref? ref-collapsed? collapsed?)
empty-content? (string/blank? (:block/content block))
empty-content? (string/blank?
(property/remove-built-in-properties
(:block/format block)
(:block/content block)))
edit? (state/sub [:editor/editing? edit-input-id])]
[:div.mr-2.flex.flex-row.items-center
{:style {:height 24
@ -1882,10 +1884,12 @@
{:init (fn [state]
(let [[config block] (:rum/args state)
ref-collpased? (boolean
(and (:ref? config)
(seq (:block/children block))
(>= (:ref/level block)
(state/get-ref-open-blocks-level))))]
(and
(seq (:block/children block))
(or (:custom-query? config)
(and (:ref? config)
(>= (:ref/level block)
(state/get-ref-open-blocks-level))))))]
(assoc state
::control-show? (atom false)
::ref-collapsed? (atom ref-collpased?))))
@ -2158,10 +2162,13 @@
query-result (and query-atom (rum/react query-atom))
table? (or (get-in current-block [:block/properties :query-table])
(and (string? query) (string/ends-with? (string/trim query) "table")))
transformed-query-result (when query-result
(db/custom-query-result-transform query-result remove-blocks q))
not-grouped-by-page? (or table?
(and (string? query) (string/includes? query "(by-page false)")))
result (when query-result
(db/custom-query-result-transform query-result remove-blocks q not-grouped-by-page?))
result (if (and (:block/uuid (first transformed-query-result)) (not not-grouped-by-page?))
(db-utils/group-by-page transformed-query-result)
transformed-query-result)
_ (when-let [query-result (:query-result config)]
(let [result (remove (fn [b] (some? (get-in b [:block/properties :template]))) result)]
(reset! query-result result)))
@ -2181,6 +2188,9 @@
(ui/foldable
[:div.custom-query-title
title
[:span.opacity-60.text-sm.ml-2
(str (count transformed-query-result) " results")]]
[:div
(when current-block
[:div.flex.flex-row.align-items.mt-2 {:on-mouse-down (fn [e] (util/stop e))}
(when-not page-list?
@ -2200,47 +2210,46 @@
(state/pub-event! [:modal/set-query-properties current-block all-keys])))}
[:span.table-query-properties
[:span.text-sm.mr-1 "Set properties"]
svg/settings-sm]]])]
(cond
(and (seq result) view-f)
(let [result (try
(sci/call-fn view-f result)
(catch js/Error error
(log/error :custom-view-failed {:error error
:result result})
[:div "Custom view failed: "
(str error)]))]
(util/hiccup-keywordize result))
svg/settings-sm]]])
(cond
(and (seq result) view-f)
(let [result (try
(sci/call-fn view-f result)
(catch js/Error error
(log/error :custom-view-failed {:error error
:result result})
[:div "Custom view failed: "
(str error)]))]
(util/hiccup-keywordize result))
page-list?
(query-table/result-table config current-block result {:page? true} map-inline page-cp ->elem inline-text)
page-list?
(query-table/result-table config current-block result {:page? true} map-inline page-cp ->elem inline-text)
table?
(query-table/result-table config current-block result {:page? false} map-inline page-cp ->elem inline-text)
table?
(query-table/result-table config current-block result {:page? false} map-inline page-cp ->elem inline-text)
(and (seq result) (or only-blocks? blocks-grouped-by-page?))
(->hiccup result (cond-> (assoc config
:custom-query? true
;; :breadcrumb-show? true
:group-by-page? blocks-grouped-by-page?
;; :ref? true
)
children?
(assoc :ref? true))
{:style {:margin-top "0.25rem"
:margin-left "0.25rem"}})
(and (seq result) (or only-blocks? blocks-grouped-by-page?))
(->hiccup result (cond-> (assoc config
:custom-query? true
:breadcrumb-show? true
:group-by-page? blocks-grouped-by-page?
:ref? true)
children?
(assoc :ref? true))
{:style {:margin-top "0.25rem"
:margin-left "0.25rem"}})
(seq result)
(let [result (->>
(for [record result]
(if (map? record)
(str (util/pp-str record) "\n")
record))
(remove nil?))]
[:pre result])
(seq result)
(let [result (->>
(for [record result]
(if (map? record)
(str (util/pp-str record) "\n")
record))
(remove nil?))]
[:pre result])
:else
[:div.text-sm.mt-2.ml-2.font-medium.opacity-50 "Empty"])
:else
[:div.text-sm.mt-2.ml-2.font-medium.opacity-50 "Empty"])]
collapsed?))]))))
(defn admonition
@ -2478,6 +2487,51 @@
blocks)]
sections))))
(defn- block-list
[config blocks]
(for [[idx item] (medley/indexed blocks)]
(let [item (->
(dissoc item :block/meta)
(assoc :block/top? (zero? idx)
:block/bottom? (= (count blocks) (inc idx))))
config (assoc config :block/uuid (:block/uuid item))]
(rum/with-key
(block-container config item)
(:block/uuid item)))))
(defonce ignore-scroll? (atom false))
(rum/defcs lazy-blocks <
(rum/local 1 ::page)
[state config blocks]
(let [*page (get state ::page)
segment (->> blocks
(drop (* (dec @*page) max-blocks-per-page))
(take max-blocks-per-page))
bottom-reached (fn []
(when (and (= (count segment) max-blocks-per-page)
(> (count blocks) (* @*page max-blocks-per-page))
(not @ignore-scroll?))
(swap! *page inc)
(util/scroll-to-top))
(reset! ignore-scroll? false))
top-reached (fn []
(when (> @*page 1)
(swap! *page dec)
(reset! ignore-scroll? true)
(js/setTimeout #(util/scroll-to
(.-scrollHeight (js/document.getElementById "lazy-blocks"))) 100)))]
[:div#lazy-blocks
(when (> @*page 1)
[:div.ml-4.mb-4 [:a#prev.opacity-60.opacity-100.text-sm.font-medium {:on-click top-reached}
"Prev"]])
(ui/infinite-list
"main-container"
(block-list config segment)
{:on-load bottom-reached})
(when (> (count blocks) (* @*page max-blocks-per-page))
[:div.ml-4.mt-4 [:a#more.opacity-60.opacity-100.text-sm.font-medium {:on-click bottom-reached}
"More"]])]))
(rum/defcs blocks-container <
{:init (fn [state]
(assoc state ::init-blocks-container-id (atom nil)))}
@ -2504,17 +2558,7 @@
0
:else
-10)}}
(let [first-block (first blocks)
first-id (:block/uuid (first blocks))]
(for [[idx item] (medley/indexed blocks)]
(let [item (->
(dissoc item :block/meta)
(assoc :block/top? (zero? idx)
:block/bottom? (= (count blocks) (inc idx))))
config (assoc config :block/uuid (:block/uuid item))]
(rum/with-key
(block-container config item)
(:block/uuid item)))))])))
(lazy-blocks config blocks)])))
;; headers to hiccup
(defn ->hiccup

View File

@ -87,6 +87,7 @@
(case type
:text (export/export-blocks-as-markdown current-repo root-block-id text-indent-style)
:opml (export/export-blocks-as-opml current-repo root-block-id)
:html (export/export-blocks-as-html current-repo root-block-id)
(export/export-blocks-as-markdown current-repo root-block-id text-indent-style))]
[:div.export.w-96.resize
[:div
@ -95,8 +96,11 @@
:class "mr-2 w-20"
:on-click #(reset! *export-block-type :text))
(ui/button "OPML"
:class "mr-2 w-20"
:on-click #(reset! *export-block-type :opml))
(ui/button "HTML"
:class "w-20"
:on-click #(reset! *export-block-type :opml))]
:on-click #(reset! *export-block-type :html))]
[:textarea.overflow-y-auto.h-96 {:value content}]
(let [options (->> text-indent-style-options
(mapv (fn [opt]
@ -113,8 +117,8 @@
(#(reset! *export-block-text-indent-style %) value)))}
(for [{:keys [label value selected]} options]
[:option (cond->
{:key label
:value (or value label)}
{:key label
:value (or value label)}
selected
(assoc :selected selected))
label])]])

View File

@ -414,18 +414,20 @@
page)]
(page-blocks-cp repo page {:sidebar? sidebar?}))]]
(when-not block?
(today-queries repo today? sidebar?))
(when-not block?
(tagged-pages repo page-name))
;; referenced blocks
[:div {:key "page-references"}
(rum/with-key
(reference/references route-page-name false)
(str route-page-name "-refs"))]
(when-not block?
[:div
(today-queries repo today? sidebar?)
(tagged-pages repo page-name)
;; referenced blocks
[:div {:key "page-references"}
(rum/with-key
(reference/references route-page-name false)
(str route-page-name "-refs"))]
(when (text/namespace-page? route-page-name)
(hierarchy/structures route-page-name))

View File

@ -27,7 +27,7 @@
[]
(conj
#{"do MMM yyyy"
"do MMMM yyyy"
"do MMMM yyyy"
"MMM do, yyyy"
"MMMM do, yyyy"
"E, dd-MM-yyyy"
@ -188,15 +188,10 @@
(defn journal-title->
[journal-title then-fn]
(when-not (string/blank? journal-title)
(when-let [time (->> (map
(fn [formatter]
(try
(tf/parse (tf/formatter formatter) (util/capitalize-all journal-title))
(catch js/Error _e
nil)))
(journal-title-formatters))
(filter some?)
first)]
(when-let [time (try
(tf/parse (tf/formatter (state/get-date-formatter)) (util/capitalize-all journal-title))
(catch js/Error _e
nil))]
(then-fn time))))
(defn journal-title->int

View File

@ -6,6 +6,7 @@
[clojure.string :as string]
[frontend.text :as text]
[frontend.db.query-react :as react]
[frontend.db.model :as model]
[frontend.date :as date]
[cljs-time.core :as t]
[cljs-time.coerce :as tc]
@ -50,15 +51,15 @@
[where blocks?]
(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)))
`[:find (~'pull ~'?b ~model/block-attrs)
: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]

View File

@ -49,8 +49,17 @@
:else
input))
(defn- remove-nested-children-blocks
[blocks]
(let [ids (set (map :db/id blocks))]
(->> blocks
(remove
(fn [block]
(let [id (:db/id (:block/parent block))]
(contains? ids id)))))))
(defn custom-query-result-transform
[query-result remove-blocks q not-grouped-by-page?]
[query-result remove-blocks q]
(try
(let [repo (state/get-current-repo)
result (db-utils/seq-flatten query-result)
@ -63,6 +72,8 @@
result))
result)]
(some->> result
remove-nested-children-blocks
(model/sort-by-left-recursive)
(db-utils/with-repo repo)
(model/with-block-refs-count repo)
(model/with-pages)))
@ -75,9 +86,7 @@
(log/error :sci/call-error e)
result))
result)
(if (and block? (not not-grouped-by-page?))
(db-utils/group-by-page result)
result))))
result)))
(catch js/Error e
(log/error :query/failed e))))

View File

@ -4,7 +4,8 @@
["diff-match-patch" :as diff-match-patch]
[goog.object :as gobj]
[lambdaisland.glogi :as log]
[cljs-bean.core :as bean]))
[cljs-bean.core :as bean]
[frontend.util :as util]))
;; TODO: replace with diff-match-patch
(defn diff
@ -33,24 +34,29 @@
(defn find-position
[markup text]
(try
(loop [t1 (-> markup string/lower-case seq)
t2 (-> text string/lower-case seq)
i1 0
i2 0]
(let [[h1 & r1] t1
[h2 & r2] t2]
(cond
(or (empty? t1) (empty? t2))
i1
(let [pos (loop [t1 (-> markup string/lower-case seq)
t2 (-> text string/lower-case seq)
i1 0
i2 0]
(let [[h1 & r1] t1
[h2 & r2] t2]
(cond
(or (empty? t1) (empty? t2))
i1
(= h1 h2)
(recur r1 r2 (inc i1) (inc i2))
(= h1 h2)
(recur r1 r2 (inc i1) (inc i2))
(#{\[ \space \]} h2)
(recur t1 r2 i1 (inc i2))
(#{\[ \space \]} h2)
(recur t1 r2 i1 (inc i2))
:else
(recur r1 t2 (inc i1) i2))))
:else
(recur r1 t2 (inc i1) i2))))]
(if (and (= (util/nth-safe markup pos)
(util/nth-safe markup (inc pos))
"]"))
(+ pos 2)
pos))
(catch js/Error e
(log/error :diff/find-position {:error e})
(count markup))))

View File

@ -46,7 +46,7 @@
(if (string/blank? content)
""
(if-let [record (get-format-record format)]
(protocol/toHtml record content config)
(protocol/toHtml record content config mldoc/default-references)
content)))))
(defn to-edn

View File

@ -13,7 +13,7 @@
protocol/Format
(toEdn [this content config]
(->edn content config))
(toHtml [this content config]
(toHtml [this content config references]
(when (loaded?)
(let [config {:attributes {:showTitle false
:hardbreaks true

View File

@ -252,8 +252,8 @@
protocol/Format
(toEdn [this content config]
(->edn content config))
(toHtml [this content config]
(exportToHtml content config))
(toHtml [this content config references]
(exportToHtml content config references))
(loaded? [this]
true)
(lazyLoad [this ok-handler]

View File

@ -2,7 +2,7 @@
(defprotocol Format
(toEdn [this content config])
(toHtml [this content config])
(toHtml [this content config references])
(loaded? [this])
(lazyLoad [this ok-handler])
(exportMarkdown [this content config references])

View File

@ -41,16 +41,17 @@
db-mtime (db/get-file-last-modified-at repo path)
disk-content (-> (protocol/read-file this dir path nil)
(p/catch (fn [error] nil)))
disk-content (or disk-content "")
ext (string/lower-case (util/get-file-ext path))
file-page (db/get-file-page-id path)
page-empty? (and file-page (db/page-empty? repo file-page))]
(cond
(and (not page-empty?) (nil? disk-content))
(notification/show!
(str "The file has been renamed or deleted on your local disk! File path: " path
", please save your changes and click the refresh button to reload it.")
:error
false)
;; (and (not page-empty?) (nil? disk-content) )
;; (notification/show!
;; (str "The file has been renamed or deleted on your local disk! File path: " path
;; ", please save your changes and click the refresh button to reload it.")
;; :error
;; false)
(and
(not= disk-mtime db-mtime)

View File

@ -1513,15 +1513,19 @@
"`" "`"
"~" "~"
"*" "*"
;; "_" "_"
"_" "_"
"^" "^"
;; ":" ":" ; TODO: only properties editing and org mode tag
;; "^" "^"
})
(def reversed-autopair-map
(zipmap (vals autopair-map)
(keys autopair-map)))
(defonce autopair-when-selected
#{"^" "_"})
(def delete-map
(assoc autopair-map
"$" "$"
@ -2146,8 +2150,7 @@
[state]
(when-not (auto-complete?)
(let [{:keys [block config]} (get-state)]
(when (and block
(not (:custom-query? config)))
(when block
(let [content (state/get-edit-content)
current-node (outliner-core/block block)
has-right? (-> (tree/-get-right current-node)
@ -2493,6 +2496,9 @@
(util/stop e)
(cursor/move-cursor-forward input))
(and (autopair-when-selected key) (string/blank? (util/get-selected-text)))
nil
(contains? (set (keys autopair-map)) key)
(do
(util/stop e)
@ -2676,7 +2682,8 @@
(if (and
(:copy/content copied-blocks)
(not (string/blank? text))
(= (string/trim text) (string/trim (:copy/content copied-blocks))))
(= (string/replace (string/trim text) "\r" "")
(string/replace (string/trim (:copy/content copied-blocks)) "\r" "")))
(do
;; copy from logseq internally
(paste-block-vec-tree-at-target copied-block-tree [])

View File

@ -460,7 +460,18 @@
(f/get-default-config format {:export-md-indent-style indent-style})
(js/JSON.stringify (clj->js refs)))))
(defn export-blocks-as-html
[repo root-block-uuid]
(let [get-page&block-refs-by-query-aux (get-embed-and-refs-blocks-pages-aux)
f #(get-page&block-refs-by-query repo % get-page&block-refs-by-query-aux {:is-block? true})
root-block (db/entity [:block/uuid root-block-uuid])
blocks (db/get-block-and-children repo root-block-uuid)
refs (f blocks)
content (get-blocks-contents repo root-block-uuid)
format (or (:block/format root-block) (state/get-preferred-format))]
(fp/toHtml f/mldoc-record content
(f/get-default-config format)
(js/JSON.stringify (clj->js refs)))))
(defn- convert-md-files-unordered-list-or-heading
[repo files heading-to-list?]

View File

@ -43,7 +43,10 @@
(string? title)
title))
file-name (when-let [file-name (last (string/split file #"/"))]
(first (util/split-last "." file-name)))]
(let [result (first (util/split-last "." file-name))]
(if (config/mldoc-support? (string/lower-case (util/get-file-ext file)))
(string/replace result "." "/")
result)))]
(or property-name
(if (= (state/page-name-order) "heading")
(or first-block-name file-name)

View File

@ -347,7 +347,7 @@
(rum/defcs infinite-list <
(mixins/event-mixin attach-listeners)
"Render an infinite list."
[state list-element-id body {:keys [on-load has-more]}]
[state list-element-id body {:keys [on-load has-more on-top-reached]}]
(rum/with-context [[t] i18n/*tongue-context*]
(rum/fragment
body
@ -585,7 +585,8 @@
(if (fn? header)
(header @collapsed?)
header)]]]
[:div {:class (if @collapsed? "hidden" "initial")}
[:div {:class (if @collapsed? "hidden" "initial")
:on-mouse-down (fn [e] (.stopPropagation e))}
(if (fn? content)
(if (not @collapsed?) (content) nil)
content)]]))

View File

@ -402,6 +402,15 @@
(- top 80)))
:behavior "smooth"}))))))
#?(:cljs
(defn scroll-to-element-v2
[elem-id]
(when elem-id
(when-let [elem (gdom/getElement elem-id)]
(.scroll (app-scroll-container-node)
#js {:top (element-top elem 0)
:behavior "auto"})))))
#?(:cljs
(defn scroll-to
([pos]
@ -414,11 +423,6 @@
#js {:top pos
:behavior (if animate? "smooth" "auto")})))))
#?(:cljs
(defn scroll-to-top
[]
(scroll-to (app-scroll-container-node) 0 false)))
#?(:cljs
(defn scroll-top
"Returns the scroll top position of the `node`. If `node` is not specified,
@ -428,6 +432,18 @@
([node]
(when node (.-scrollTop node)))))
#?(:cljs
(defn scroll-to-top
[]
(scroll-to (app-scroll-container-node) 0 false)))
#?(:cljs
(defn scroll-to-bottom
[node]
(when-let [node ^js (or node (app-scroll-container-node))]
(let [bottom (.-scrollHeight node)]
(scroll-to node bottom false)))))
(defn url-encode
[string]
#?(:cljs (some-> string str (js/encodeURIComponent) (.replace "+" "%20"))))
@ -763,7 +779,7 @@
(js/document.body.removeChild el))))
(def uuid-pattern "[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}")
(defonce exactly-uuid-pattern (re-pattern (str "^" uuid-pattern "$")))
(defonce exactly-uuid-pattern (re-pattern (str "(?i)^" uuid-pattern "$")))
(defn uuid-string?
[s]
(safe-re-find exactly-uuid-pattern s))

View File

@ -1,3 +1,3 @@
(ns frontend.version)
(defonce version "0.2.8")
(defonce version "0.2.10")

View File

@ -6165,10 +6165,10 @@ mkdirp@^0.5.0, mkdirp@^0.5.4, mkdirp@~0.5.1:
dependencies:
minimist "^1.2.5"
mldoc@0.9.0:
version "0.9.0"
resolved "https://registry.yarnpkg.com/mldoc/-/mldoc-0.9.0.tgz#5eee9b22c5eafa7262dd5564ae28fdd0be798dc6"
integrity sha512-cmQnBVUKGTNnMYT9jvof7FSc6Kdw3cz1C1AGUbf0vqexX3+iWxNNbxH62jw/dMY9Bh2HbaBsDw5ILV4fD6vUuw==
mldoc@0.9.1:
version "0.9.1"
resolved "https://registry.yarnpkg.com/mldoc/-/mldoc-0.9.1.tgz#dfcdcf52614a27ce83b9318c551246398e13f0e7"
integrity sha512-4BL8Fu6+izd9iJ3JhqEU57K9W8MHUD29V51eOXa/pTpmkXi1GFSy0c9nYLkd8KjAPkI6nFVmjl7A9rcfbGe+/g==
dependencies:
yargs "^12.0.2"
@ -7598,11 +7598,6 @@ react-grid-layout@^0.16.6:
react-draggable "3.x"
react-resizable "1.x"
react-icon-base@2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/react-icon-base/-/react-icon-base-2.1.0.tgz#a196e33fdf1e7aaa1fda3aefbb68bdad9e82a79d"
integrity sha1-oZbjP98eeqof2jrvu2i9rZ6Cp50=
react-icons@^2.2.7:
version "2.2.7"
resolved "https://registry.yarnpkg.com/react-icons/-/react-icons-2.2.7.tgz#d7860826b258557510dac10680abea5ca23cf650"