mirror of https://github.com/logseq/logseq
refactor: diff instead a alerting when a file has been modified
parent
f7fcffe6e4
commit
6f2a86e79d
|
@ -181,6 +181,11 @@ textarea {
|
|||
font-weight: inherit;
|
||||
letter-spacing: inherit;
|
||||
text-size-adjust: 100%;
|
||||
background: var(--ls-primary-background-color);
|
||||
}
|
||||
|
||||
.dark-theme textarea {
|
||||
background: var(--ls-tertiary-background-color);
|
||||
}
|
||||
|
||||
ul {
|
||||
|
|
|
@ -230,3 +230,78 @@
|
|||
|
||||
:else
|
||||
[:div "No diffs"])]))
|
||||
|
||||
(rum/defcs local-file < rum/reactive
|
||||
[state repo path disk-content local-content]
|
||||
(let [content disk-content
|
||||
edit? (util/react *edit?)]
|
||||
[:div.cp__diff-file
|
||||
[:div.cp__diff-file-header
|
||||
[:span.cp__diff-file-header-content {:style {:word-break "break-word"}}
|
||||
path]]
|
||||
(when (not= content local-content)
|
||||
(let [local-content (or local-content "")
|
||||
content (or content "")
|
||||
diff (medley/indexed (diff/diff local-content content))
|
||||
diff? (some (fn [[_idx {:keys [added removed]}]]
|
||||
(or added removed))
|
||||
diff)
|
||||
diff-cp [:div.overflow-y-scroll
|
||||
[:div {:style {:max-height "65vh"}}
|
||||
(diff-cp diff)]]]
|
||||
[:div.pre-line-white-space.p-2.overflow-y-hidden
|
||||
(if edit?
|
||||
[:div.grid.grid-cols-2.gap-1
|
||||
diff-cp
|
||||
(ui/textarea
|
||||
{:default-value local-content
|
||||
:auto-focus true
|
||||
:style {:border "1px solid"}
|
||||
:on-change (fn [e]
|
||||
(reset! *edit-content (util/evalue e)))})]
|
||||
diff-cp)
|
||||
|
||||
(cond
|
||||
edit?
|
||||
[:div.mt-2
|
||||
(ui/button "Save"
|
||||
:on-click
|
||||
(fn []
|
||||
(reset! *edit? false)
|
||||
(let [new-content @*edit-content]
|
||||
(file/alter-file repo path new-content
|
||||
{:re-render-root? true
|
||||
:skip-compare? true})
|
||||
(state/close-modal!))))]
|
||||
|
||||
diff?
|
||||
[:div.mt-2
|
||||
(ui/button "Use latest changes from the disk"
|
||||
:on-click
|
||||
(fn []
|
||||
(file/alter-file repo path content
|
||||
{:re-render-root? true
|
||||
:skip-compare? true})
|
||||
(state/close-modal!))
|
||||
:background "green")
|
||||
|
||||
[:span.pl-2.pr-2 "or"]
|
||||
|
||||
(ui/button "Keep local changes in Logseq"
|
||||
:on-click
|
||||
(fn []
|
||||
(file/alter-file repo path local-content
|
||||
{:re-render-root? true
|
||||
:skip-compare? true})
|
||||
(state/close-modal!))
|
||||
:background "pink")
|
||||
|
||||
[:span.pl-2.pr-2 "or"]
|
||||
|
||||
(ui/button "Edit"
|
||||
:on-click
|
||||
(fn []
|
||||
(reset! *edit? true)))]
|
||||
|
||||
:else
|
||||
nil)]))]))
|
||||
|
|
|
@ -70,7 +70,7 @@
|
|||
(let [repo-cur (state/get-current-repo)
|
||||
repo-dir (config/get-repo-dir repo-cur)
|
||||
data (pr-str {:highlights highlights})]
|
||||
(fs/write-file! repo-cur repo-dir hls-file data {:skip-mtime? true}))))
|
||||
(fs/write-file! repo-cur repo-dir hls-file data {:skip-compare? true}))))
|
||||
|
||||
(defn resolve-hls-data-by-key$
|
||||
[target-key]
|
||||
|
@ -115,7 +115,7 @@
|
|||
new-fpath (str fdir "/" fname "_" fstamp ".png")
|
||||
old-fpath (and old-fstamp (str fdir "/" fname "_" old-fstamp ".png"))
|
||||
_ (and old-fpath (apply fs/rename! repo-cur (map #(util/node-path.join repo-dir %) [old-fpath new-fpath])))
|
||||
_ (fs/write-file! repo-cur repo-dir new-fpath png {:skip-mtime? true})]
|
||||
_ (fs/write-file! repo-cur repo-dir new-fpath png {:skip-compare? true})]
|
||||
|
||||
(js/console.timeEnd :write-area-image))
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
[frontend.config :as config]
|
||||
[frontend.state :as state]
|
||||
[frontend.handler.notification :as notification]
|
||||
[frontend.encrypt :as encrypt]
|
||||
["/frontend/utils" :as utils]))
|
||||
|
||||
;; We need to cache the file handles in the memory so that
|
||||
|
@ -54,6 +55,14 @@
|
|||
(when handle
|
||||
(verify-permission repo handle true)))))
|
||||
|
||||
(defn- contents-matched?
|
||||
[disk-content db-content]
|
||||
(when (and (string? disk-content) (string? db-content))
|
||||
(if (encrypt/encrypted-db? (state/get-current-repo))
|
||||
(p/let [decrypted-content (encrypt/decrypt disk-content)]
|
||||
(= (string/trim decrypted-content) (string/trim db-content)))
|
||||
(p/resolved (= (string/trim disk-content) (string/trim db-content))))))
|
||||
|
||||
(defrecord Nfs []
|
||||
protocol/Fs
|
||||
(mkdir! [this dir]
|
||||
|
@ -155,35 +164,25 @@
|
|||
(if file-handle
|
||||
(-> (p/let [local-file (.getFile file-handle)
|
||||
local-content (.text local-file)
|
||||
local-last-modified-at (gobj/get local-file "lastModified")
|
||||
current-time (util/time-ms)
|
||||
new? (> current-time local-last-modified-at)
|
||||
new-created? (nil? last-modified-at)
|
||||
not-changed? (= last-modified-at local-last-modified-at)
|
||||
format (-> (util/get-file-ext path)
|
||||
(config/get-file-format))
|
||||
pending-writes (state/get-write-chan-length)
|
||||
draw? (and path (string/ends-with? path ".excalidraw"))
|
||||
config? (and path (string/ends-with? path "/config.edn"))]
|
||||
(p/let [_ (verify-permission repo file-handle true)
|
||||
_ (utils/writeFile file-handle content)
|
||||
file (.getFile file-handle)]
|
||||
(if (and local-content new?
|
||||
(or
|
||||
draw?
|
||||
config?
|
||||
;; Writing not finished
|
||||
(> pending-writes 0)
|
||||
;; not changed by other editors
|
||||
not-changed?
|
||||
new-created?))
|
||||
ext (string/lower-case (util/get-file-ext path))
|
||||
db-content (db/get-file repo path)]
|
||||
(when local-content
|
||||
(if (and
|
||||
(not (string/blank? db-content))
|
||||
(not (:skip-compare? opts))
|
||||
(not (contents-matched? local-content (or db-content "")))
|
||||
(not (contains? #{"excalidraw" "edn"} ext)))
|
||||
(state/pub-event! [:file/not-matched-from-disk path local-content content])
|
||||
(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)))
|
||||
(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 [content (if (encrypt/encrypted-db? (state/get-current-repo))
|
||||
(encrypt/decrypt content)
|
||||
content)]
|
||||
(db/set-file-content! repo path content))
|
||||
(nfs-saved-handler repo path file))))))
|
||||
(p/catch (fn [e]
|
||||
(js/console.error e))))
|
||||
;; create file handle
|
||||
|
|
|
@ -36,8 +36,8 @@
|
|||
(p/resolved (= (string/trim disk-content) (string/trim db-content))))))
|
||||
|
||||
(defn- write-file-impl!
|
||||
[this repo dir path content {:keys [ok-handler error-handler skip-mtime?] :as opts} stat]
|
||||
(if skip-mtime?
|
||||
[this repo dir path content {:keys [ok-handler error-handler skip-compare?] :as opts} stat]
|
||||
(if skip-compare?
|
||||
(p/catch
|
||||
(p/let [result (ipc/ipc "writeFile" path content)]
|
||||
(when ok-handler
|
||||
|
@ -56,22 +56,10 @@
|
|||
db-content (or (db/get-file repo path) "")
|
||||
contents-matched? (contents-matched? disk-content db-content)]
|
||||
(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 contents-matched?)
|
||||
;; FIXME:
|
||||
(not (contains? #{"excalidraw" "edn"} ext)))
|
||||
(notification/show!
|
||||
(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.")
|
||||
:warning
|
||||
false)
|
||||
(state/pub-event! [:file/not-matched-from-disk path disk-content content])
|
||||
|
||||
:else
|
||||
(->
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
[frontend.components.encryption :as encryption]
|
||||
[frontend.components.shell :as shell]
|
||||
[frontend.components.git :as git-component]
|
||||
[frontend.components.diff :as diff]
|
||||
[frontend.fs.nfs :as nfs]
|
||||
[frontend.db.conn :as conn]
|
||||
[frontend.extensions.srs :as srs]
|
||||
|
@ -152,6 +153,11 @@
|
|||
(defmethod handle :page/create-today-journal [[_ repo]]
|
||||
(page-handler/create-today-journal!))
|
||||
|
||||
(defmethod handle :file/not-matched-from-disk [[_ path disk-content db-content]]
|
||||
(state/clear-edit!)
|
||||
(when-let [repo (state/get-current-repo)]
|
||||
(state/set-modal! #(diff/local-file repo path disk-content db-content))))
|
||||
|
||||
(defmethod handle :after-db-restore [[_ repos]]
|
||||
(mapv (fn [{url :url} repo]
|
||||
;; compare :ast/version
|
||||
|
|
|
@ -158,17 +158,20 @@
|
|||
|
||||
;; TODO: Remove this function in favor of `alter-files`
|
||||
(defn alter-file
|
||||
[repo path content {:keys [reset? re-render-root? add-history? update-status? from-disk?]
|
||||
[repo path content {:keys [reset? re-render-root? add-history? update-status? from-disk? skip-compare?]
|
||||
:or {reset? true
|
||||
re-render-root? false
|
||||
add-history? true
|
||||
update-status? false
|
||||
from-disk? false}}]
|
||||
from-disk? false
|
||||
skip-compare? false}}]
|
||||
(let [edit-block (state/get-edit-block)
|
||||
original-content (db/get-file-no-sub repo path)
|
||||
write-file! (if from-disk?
|
||||
#(p/resolved nil)
|
||||
#(fs/write-file! repo (config/get-repo-dir repo) path content (when original-content {:old-content original-content})))]
|
||||
#(fs/write-file! repo (config/get-repo-dir repo) path content
|
||||
(assoc (when original-content {:old-content original-content})
|
||||
:skip-compare? skip-compare?)))]
|
||||
(p/let [_ (if reset?
|
||||
(do
|
||||
(when-let [page-id (db/get-file-page-id path)]
|
||||
|
|
|
@ -94,7 +94,7 @@
|
|||
(fn [path ^js data]
|
||||
(let [repo ""
|
||||
path (util/node-path.join path "package.json")]
|
||||
(fs/write-file! repo "" path (js/JSON.stringify data nil 2) {:skip-mtime? true}))))
|
||||
(fs/write-file! repo "" path (js/JSON.stringify data nil 2) {:skip-compare? true}))))
|
||||
|
||||
(defn ^:private write_dotdir_file
|
||||
[file content sub-root]
|
||||
|
@ -109,7 +109,7 @@
|
|||
user-path-root (util/node-path.dirname user-path)
|
||||
exist? (fs/file-exists? user-path-root "")
|
||||
_ (when-not exist? (fs/mkdir-recur! user-path-root))
|
||||
_ (fs/write-file! repo "" user-path content {:skip-mtime? true})]
|
||||
_ (fs/write-file! repo "" user-path content {:skip-compare? true})]
|
||||
user-path))
|
||||
|
||||
(defn ^:private read_dotdir_file
|
||||
|
@ -191,7 +191,7 @@
|
|||
(p/let [repo ""
|
||||
path (plugin-handler/get-ls-dotdir-root)
|
||||
path (util/node-path.join path "preferences.json")]
|
||||
(fs/write-file! repo "" path (js/JSON.stringify data nil 2) {:skip-mtime? true})))))
|
||||
(fs/write-file! repo "" path (js/JSON.stringify data nil 2) {:skip-compare? true})))))
|
||||
|
||||
(def ^:export load_plugin_user_settings
|
||||
(fn [key]
|
||||
|
@ -209,7 +209,7 @@
|
|||
(p/let [repo ""
|
||||
path (plugin-handler/get-ls-dotdir-root)
|
||||
path (util/node-path.join path "settings" (str key ".json"))]
|
||||
(fs/write-file! repo "" path (js/JSON.stringify data nil 2) {:skip-mtime? true}))))
|
||||
(fs/write-file! repo "" path (js/JSON.stringify data nil 2) {:skip-compare? true}))))
|
||||
|
||||
(def ^:export register_plugin_slash_command
|
||||
(fn [pid ^js cmd-actions]
|
||||
|
|
Loading…
Reference in New Issue