diff --git a/package.json b/package.json index ca56e68f90..7427579e61 100644 --- a/package.json +++ b/package.json @@ -137,7 +137,6 @@ "@js-joda/core": "3.2.0", "@js-joda/locale_en-us": "3.1.1", "@js-joda/timezone": "2.5.0", - "@logseq/diff-merge": "^0.2.2", "@logseq/react-tweet-embed": "1.3.1-1", "@logseq/simple-wave-record": "^0.0.3", "@radix-ui/colors": "^0.1.8", diff --git a/src/main/frontend/components/editor.cljs b/src/main/frontend/components/editor.cljs index 10f7899ed0..dacdc68a81 100644 --- a/src/main/frontend/components/editor.cljs +++ b/src/main/frontend/components/editor.cljs @@ -31,7 +31,6 @@ [logseq.common.util.page-ref :as page-ref] [logseq.db :as ldb] [logseq.db.frontend.class :as db-class] - [logseq.graph-parser.property :as gp-property] [logseq.shui.hooks :as hooks] [logseq.shui.ui :as shui] [promesa.core :as p] @@ -426,41 +425,6 @@ :item-render (fn [property] property) :class "black"}))))) -(rum/defc property-value-search-aux - [id property q] - (let [[values set-values!] (rum/use-state nil)] - (hooks/use-effect! - (fn [] - (p/let [result (editor-handler/get-matched-property-values property q)] - (set-values! result))) - [property q]) - (ui/auto-complete - values - {:on-chosen (editor-handler/property-value-on-chosen-handler id q) - :on-enter (fn [_state] - ((editor-handler/property-value-on-chosen-handler id q) nil)) - :empty-placeholder [:div.px-4.py-2.text-sm (str "Create a new property value: " q)] - :header [:div.px-4.py-2.text-sm.font-medium "Matched property values: "] - :item-render (fn [property-value] property-value) - :class "black"}))) - -(rum/defc property-value-search < rum/reactive - [id] - (let [property (:property (state/get-editor-action-data)) - input (gdom/getElement id)] - (when (and input - (not (string/blank? property))) - (let [current-pos (cursor/pos input) - edit-content (state/sub-edit-content) - start-idx (string/last-index-of (subs edit-content 0 current-pos) - gp-property/colons) - q (or - (when (>= current-pos (+ start-idx 2)) - (subs edit-content (+ start-idx 2) current-pos)) - "") - q (string/triml q)] - (property-value-search-aux id property q))))) - (rum/defc code-block-mode-keyup-listener [_q _edit-content last-pos current-pos] (hooks/use-effect! @@ -723,10 +687,9 @@ (open-editor-popup! :template-search (template-search id format) {}) - (:property-search :property-value-search) + :property-search (open-editor-popup! action - (if (= :property-search action) - (property-search id) (property-value-search id)) + (property-search id) {}) ;; TODO: try remove local model state @@ -756,7 +719,7 @@ (or (contains? #{:commands :page-search :page-search-hashtag :block-search :template-search - :property-search :property-value-search :datepicker} + :property-search :datepicker} action) (and (keyword? action) (= (namespace action) "editor.action"))) diff --git a/src/main/frontend/components/file.cljs b/src/main/frontend/components/file.cljs index 9331b24642..a156ed2708 100644 --- a/src/main/frontend/components/file.cljs +++ b/src/main/frontend/components/file.cljs @@ -9,7 +9,7 @@ [frontend.date :as date] [frontend.db :as db] [frontend.db.async :as db-async] - [frontend.db.file-based.model :as file-model] + [frontend.db.model :as db-model] [frontend.fs :as fs] [frontend.state :as state] [frontend.ui :as ui] @@ -103,7 +103,7 @@ (let [repo-dir (config/get-repo-dir (state/get-current-repo)) rel-path (when (string/starts-with? path repo-dir) (path/trim-dir-prefix repo-dir path)) - title (file-model/get-file-page (or path rel-path)) + title (db-model/get-file-page (or path rel-path)) in-db? (when-not (path/absolute? path) (boolean (db/get-file (or path rel-path)))) file-path (cond diff --git a/src/main/frontend/components/query/builder.cljs b/src/main/frontend/components/query/builder.cljs index 4bbd925e9e..c6839544aa 100644 --- a/src/main/frontend/components/query/builder.cljs +++ b/src/main/frontend/components/query/builder.cljs @@ -7,7 +7,6 @@ [frontend.db :as db] [frontend.db-mixins :as db-mixins] [frontend.db.async :as db-async] - [frontend.db.file-based.model :as file-model] [frontend.db.model :as db-model] [frontend.db.query-dsl :as query-dsl] [frontend.handler.editor :as editor-handler] @@ -21,27 +20,12 @@ [logseq.common.util.page-ref :as page-ref] [logseq.db :as ldb] [logseq.db.frontend.property :as db-property] - [logseq.db.sqlite.util :as sqlite-util] [logseq.graph-parser.db :as gp-db] [logseq.shui.hooks :as hooks] [logseq.shui.ui :as shui] [promesa.core :as p] [rum.core :as rum])) -(rum/defc page-block-selector - [*find] - [:div.filter-item {:on-pointer-down (fn [e] (util/stop-propagation e))} - (ui/select [{:label "Blocks" - :value "block" - :selected (not= @*find :page)} - {:label "Pages" - :value "page" - :selected (= @*find :page)}] - (fn [e v] - ;; Prevent opening the current block's editor - (util/stop e) - (reset! *find (keyword v))))]) - (defn- select ([items on-chosen] (select items on-chosen {})) @@ -162,26 +146,20 @@ properties) (fn [{value :value db-ident :db/ident}] (reset! *mode "property-value") - (reset! *property (if (config/db-based-graph? (state/get-current-repo)) - db-ident - (keyword value)))))])) + (reset! *property db-ident)))])) (rum/defc property-value-select-inner < rum/reactive db-mixins/query - [*property *private-property? *find *tree opts loc values {:keys [db-graph?]}] + [*property *private-property? *tree opts loc values] (let [values' (cons {:label "Select all" :value "Select all"} (map #(hash-map :value (str (:value %)) ;; Preserve original-value as non-string values like boolean do not display in select :original-value (:value %)) - values)) - find' (rum/react *find)] + values))] (select values' (fn [{:keys [value original-value]}] - (let [k (cond - db-graph? (if @*private-property? :private-property :property) - (= find' :page) :page-property - :else :property) + (let [k (if @*private-property? :private-property :property) x (if (= value "Select all") [k @*property] [k @*property original-value])] @@ -189,25 +167,18 @@ (append-tree! *tree opts loc x)))))) (rum/defc property-value-select - [repo *property *private-property? *find *tree opts loc] - (let [db-graph? (sqlite-util/db-based-graph? repo) - [values set-values!] (rum/use-state nil)] + [*property *private-property? *tree opts loc] + (let [[values set-values!] (rum/use-state nil)] (hooks/use-effect! (fn [_property] - (p/let [result (if db-graph? - (p/let [result (db-async/ - (when-not @*find - [:div.flex.flex-row.items-center.p-2.justify-between - [:div.ml-2 "Find: "] - (page-block-selector *find)]) - (when-not @*find - [:hr.m-0])]) (select (map name filters-and-ops) (fn [{:keys [value]}] diff --git a/src/main/frontend/db/async.cljs b/src/main/frontend/db/async.cljs index 0d2c27d6c7..7ea593acb5 100644 --- a/src/main/frontend/db/async.cljs +++ b/src/main/frontend/db/async.cljs @@ -8,8 +8,6 @@ [frontend.date :as date] [frontend.db :as db] [frontend.db.async.util :as db-async-util] - [frontend.db.file-based.async :as file-async] - [frontend.db.file-based.model :as file-model] [frontend.db.model :as db-model] [frontend.db.react :as react] [frontend.db.utils :as db-utils] @@ -62,12 +60,6 @@ (when-let [graph (state/get-current-repo)] (db-model/get-all-properties graph opts))) -(defn utc-ms date) future-time (tc/to-long future-date)] (when-let [repo (and future-day (state/get-current-repo))] - (p/let [result - (if (config/db-based-graph? repo) - (= ?n ?start-time)] - [(<= ?n ?end-time)] - [?block :logseq.property/status ?status] - [?status :db/ident ?status-ident] - [(not= ?status-ident :logseq.property/status.done)] - [(not= ?status-ident :logseq.property/status.canceled)]] - start-time - future-time - '[*]) - (= ?d ?day)])] - date - future-day - file-model/file-graph-block-attrs))] + (p/let [result (= ?n ?start-time)] + [(<= ?n ?end-time)] + [?block :logseq.property/status ?status] + [?status :db/ident ?status-ident] + [(not= ?status-ident :logseq.property/status.done)] + [(not= ?status-ident :logseq.property/status.canceled)]] + start-time + future-time + '[*])] (->> result db-model/sort-by-order-recursive db-utils/group-by-page)))))) diff --git a/src/main/frontend/db/file_based/async.cljs b/src/main/frontend/db/file_based/async.cljs deleted file mode 100644 index 02d4358cf9..0000000000 --- a/src/main/frontend/db/file_based/async.cljs +++ /dev/null @@ -1,58 +0,0 @@ -(ns frontend.db.file-based.async - "File based async queries" - (:require [promesa.core :as p] - [frontend.db.async.util :as db-async-util] - [clojure.string :as string] - [logseq.common.util.page-ref :as page-ref])) - -(def > (map keys properties) - (apply concat) - distinct - sort - (map name) - (map #(hash-map :block/title %))))) - -(defn- property-value-for-refs-and-text - "Given a property value's refs and full text, determines the value to - autocomplete" - [[refs text]] - (if (or (not (coll? refs)) (= 1 (count refs))) - text - (map #(cond - (string/includes? text (page-ref/->page-ref %)) - (page-ref/->page-ref %) - (string/includes? text (str "#" %)) - (str "#" %) - :else - %) - refs))) - -(defn > - result - (map property-value-for-refs-and-text) - (map (fn [x] (if (coll? x) x [x]))) - (apply concat) - (map str) - (remove string/blank?) - distinct - sort))) diff --git a/src/main/frontend/db/model.cljs b/src/main/frontend/db/model.cljs index 66acdb3ced..a4b49b5221 100644 --- a/src/main/frontend/db/model.cljs +++ b/src/main/frontend/db/model.cljs @@ -553,6 +553,31 @@ independent of format as format specific heading characters are stripped" (:block/_tags class)) (remove ldb/hidden?)))) +(defn get-file-page + ([file-path] + (get-file-page file-path true)) + ([file-path title?] + (when-let [repo (state/get-current-repo)] + (when-let [db (conn/get-db repo)] + (some-> + (d/q + (if title? + '[:find ?page-name + :in $ ?path + :where + [?file :file/path ?path] + [?page :block/file ?file] + [?page :block/title ?page-name]] + '[:find ?page-name + :in $ ?path + :where + [?file :file/path ?path] + [?page :block/file ?file] + [?page :block/name ?page-name]]) + db file-path) + db-utils/seq-flatten + first))))) + (comment ;; For debugging (defn get-all-blocks diff --git a/src/main/frontend/fs/diff_merge.cljs b/src/main/frontend/fs/diff_merge.cljs deleted file mode 100644 index 573e171faf..0000000000 --- a/src/main/frontend/fs/diff_merge.cljs +++ /dev/null @@ -1,194 +0,0 @@ -(ns frontend.fs.diff-merge - "Implementation of text (file) based content diff & merge for conflict resolution" - (:require ["@logseq/diff-merge" :refer [attach_uuids Differ Merger]] - [cljs-bean.core :as bean] - [clojure.string :as string] - [frontend.db.file-based.model :as file-model] - [frontend.db.utils :as db-utils] - [logseq.graph-parser.block :as gp-block] - [logseq.graph-parser.mldoc :as gp-mldoc] - [logseq.graph-parser.property :as gp-property] - [logseq.graph-parser.utf8 :as utf8])) - -(defn diff - "2-ways diff - Accept: blocks in the struct with the required info - Please refer to the `Block` struct in the link below - https://github.com/logseq/diff-merge/blob/master/lib/mldoc.ts" - [base incoming] - (let [differ (Differ.)] - (.diff_logseqMode differ (bean/->js base) (bean/->js incoming)))) - -;; (defonce getHTML visualizeAsHTML) - -(defonce attachUUID attach_uuids) - -(defn db->diff-blocks - "db: datascript db - page-name: string" - [page-name] - {:pre (string? page-name)} - (let [walked (file-model/get-sorted-page-block-ids-and-levels page-name) - blocks (db-utils/pull-many [:block/uuid :block/title :block/level] (map :id walked)) - levels (map :level walked) - blocks (map (fn [block level] - {:uuid (str (:block/uuid block)) ;; Force to be string - :body (:block/title block) - :level level}) - blocks levels)] - blocks)) - -;; TODO: Switch to ast->diff-blocks-alt -;; Diverged from gp-block/extract-blocks for decoupling -;; The process of doing 2 way diff is like: -;; 1. Given a base ver. of page (AST in DB), and a branch ver. of page (externally modified file content) -;; 2. Transform both base ver (done by THIS fn). & branch ver. into the same format (diff-blocks) -;; 3. Apply diff-merge/diff on them, which returns the resolved uuids of the branch ver -;; 4. Attach these resolved uuids into the blocks newly parsed by graph-parser -;; Keep all the diff-merge fns, including diff-merge/ast->diff-blocks out of the graph-parser, -;; Only inject the step 4 into graph-parser as a hook -(defn ast->diff-blocks - "Prepare the blocks for diff-merge - blocks: ast of blocks - content: corresponding raw content" - [blocks content format {:keys [user-config block-pattern]}] - {:pre [(string? content) (contains? #{:markdown :org} format)]} - (let [encoded-content (utf8/encode content)] - (loop [headings [] - blocks (reverse blocks) - properties {} - end-pos (.-length encoded-content)] - (if (seq blocks) - (let [[block pos-meta] (first blocks) - ;; fix start_pos - pos-meta (assoc pos-meta :end_pos end-pos)] - (cond - (gp-block/heading-block? block) - (let [content (gp-block/get-block-content encoded-content (second block) format pos-meta block-pattern)] - (recur (conj headings {:body content - :level (:level (second block)) - :uuid (:id properties)}) - (rest blocks) {} (:start_pos pos-meta))) ;; The current block's start pos is the next block's end pos - - (gp-property/properties-ast? block) - (let [new-props (:properties (gp-block/extract-properties (second block) (assoc user-config :format format)))] - ;; sending the current end pos to next, as it's not finished yet - ;; supports multiple properties sub-block possible in future - (recur headings (rest blocks) (merge properties new-props) (:end_pos pos-meta))) - - :else - (recur headings (rest blocks) properties (:end_pos pos-meta)))) - (if (empty? properties) - (reverse headings) - ;; Add pre-blocks - (let [[block _] (first blocks) - pos-meta {:start_pos 0 :end_pos end-pos} - content (gp-block/get-block-content encoded-content block format pos-meta block-pattern) - uuid (:id properties)] - (cons {:body content - :level 1 - :uuid uuid} - (reverse headings)))))))) - -(defn- get-sub-content-from-pos-meta - "Replace gp-block/get-block-content, return bare content, without any trim" - [raw-content pos-meta] - (let [{:keys [start_pos end_pos]} pos-meta] - (utf8/substring raw-content start_pos end_pos))) - -;; Diverged from ast->diff-blocks -;; Add :meta :raw-body to the block -(defn- ast->diff-blocks-alt - "Prepare the blocks for diff-merge - blocks: ast of blocks - content: corresponding raw content" - [blocks content format {:keys [user-config block-pattern]}] - {:pre [(string? content) (contains? #{:markdown :org} format)]} - (let [utf8-encoded-content (utf8/encode content)] - (loop [headings [] - blocks (reverse blocks) - properties {} - end-pos (.-length utf8-encoded-content)] - (cond - (seq blocks) - (let [[block pos-meta] (first blocks) - ;; fix start_pos for properties - fixed-pos-meta (assoc pos-meta :end_pos end-pos)] - (cond - (gp-block/heading-block? block) - (let [content (gp-block/get-block-content utf8-encoded-content (second block) format fixed-pos-meta block-pattern) - content-raw (get-sub-content-from-pos-meta utf8-encoded-content fixed-pos-meta)] - (recur (conj headings {:body content - :meta {:raw-body (string/trimr content-raw)} - :level (:level (second block)) - :uuid (:id properties)}) - (rest blocks) - {} - (:start_pos fixed-pos-meta))) ;; The current block's start pos is the next block's end pos - - (gp-property/properties-ast? block) - (let [new-props (:properties (gp-block/extract-properties (second block) (assoc user-config :format format)))] - ;; sending the current end pos to next, as it's not finished yet - ;; supports multiple properties sub-block possible in future - (recur headings (rest blocks) (merge properties new-props) (:end_pos fixed-pos-meta))) - - :else - (recur headings (rest blocks) properties (:end_pos fixed-pos-meta)))) - - (empty? properties) - (reverse headings) - - ;; Add pre-blocks - :else ;; ??? unreachable - (let [[block _] (first blocks) - pos-meta {:start_pos 0 :end_pos end-pos} - content (gp-block/get-block-content utf8-encoded-content block format pos-meta block-pattern) - content-raw (get-sub-content-from-pos-meta utf8-encoded-content pos-meta) - uuid (:id properties)] - (cons {:body content - :meta {:raw-body (string/trimr content-raw)} - :level 1 - :uuid uuid} - (reverse headings))))))) - -(defn- rebuild-content - "translate [[[op block]]] to merged content" - [_base-diffblocks diffs _format] - ;; [[[0 {:body "attrib:: xxx", :level 1, :uuid nil}] ...] ...] - (let [ops-fn (fn [ops] - (map (fn [[op {:keys [meta]}]] - (when (or (= op 0) (= op 1)) ;; equal or insert - (:raw-body meta))) - ops))] - (->> diffs - (mapcat ops-fn) - (filter seq) - (string/join "\n")))) - -(defn three-way-merge - [base income current format] - (let [->ast (fn [text] (if (= format :org) - (gp-mldoc/->edn text (gp-mldoc/default-config :org)) - (gp-mldoc/->edn text (gp-mldoc/default-config :markdown)))) - options (if (= format :org) - {:block-pattern "*"} - {:block-pattern "-"}) - merger (Merger.) - base-ast (->ast base) - base-diffblocks (ast->diff-blocks-alt base-ast base format options) - income-ast (->ast income) - income-diffblocks (ast->diff-blocks-alt income-ast income format options) - current-ast (->ast current) - current-diffblocks (ast->diff-blocks-alt current-ast current format options) - branch-diffblocks [current-diffblocks income-diffblocks] - merged (.mergeBlocks merger (bean/->js base-diffblocks) (bean/->js branch-diffblocks)) - ;; For extracting diff-merge test cases - ;; _ (prn "input:") - ;; _ (prn (js/JSON.stringify (bean/->js base-diffblocks))) - ;; _ (prn (js/JSON.stringify (bean/->js branch-diffblocks))) - ;; _ (prn "logseq diff merge version: " version) - ;; _ (prn "output:") - ;; _ (prn (js/JSON.stringify merged)) - merged-diff (bean/->clj merged) - merged-content (rebuild-content base-diffblocks merged-diff format)] - merged-content)) diff --git a/src/main/frontend/handler/editor.cljs b/src/main/frontend/handler/editor.cljs index a194e960e7..365674371b 100644 --- a/src/main/frontend/handler/editor.cljs +++ b/src/main/frontend/handler/editor.cljs @@ -10,7 +10,6 @@ [frontend.date :as date] [frontend.db :as db] [frontend.db.async :as db-async] - [frontend.db.file-based.model :as file-model] [frontend.db.model :as db-model] [frontend.db.utils :as db-utils] [frontend.diff :as diff] @@ -1393,7 +1392,7 @@ (log/error :save-block-failed error))))))) (defn delete-asset-of-block! - [{:keys [repo asset-block href full-text block-id local? delete-local?] :as _opts}] + [{:keys [repo asset-block full-text block-id local? delete-local?] :as _opts}] (let [block (db-model/query-block-by-uuid block-id) _ (or block (throw (ex-info (str block-id " not exists") {:block-id block-id}))) @@ -1403,17 +1402,8 @@ (string/replace text full-text ""))] (save-block! repo block content) (when (and local? delete-local?) - (if asset-block - (delete-block-aux! asset-block) - (when-let [href (if (util/electron?) href - (second (re-find #"\((.+)\)$" full-text)))] - (let [block-file-rpath (file-model/get-block-file-path block) - asset-fpath (if (string/starts-with? href "assets://") - (path/url-to-path href) - (config/get-repo-fpath - repo - (path/resolve-relative-path block-file-rpath href)))] - (fs/unlink! repo asset-fpath nil))))))) + (when asset-block + (delete-block-aux! asset-block))))) (defn db-based-write-asset! [repo dir file file-rpath] @@ -1667,10 +1657,6 @@ [q] (search/property-search q)) -(defn get-matched-property-values - [property q] - (search/property-value-search property q)) - (defn get-last-command [input] (try diff --git a/src/main/frontend/search.cljs b/src/main/frontend/search.cljs index b57656be91..70aae1cfa0 100644 --- a/src/main/frontend/search.cljs +++ b/src/main/frontend/search.cljs @@ -73,21 +73,6 @@ (let [result (fuzzy/fuzzy-search properties q :limit limit)] (vec result)))))))) -;; file-based graph only -(defn property-value-search - ([property q] - (property-value-search property q 100)) - ([property q limit] - (when-let [repo (state/get-current-repo)] - (when q - (p/let [q (fuzzy/clean-str q) - result (db-async/