fix(fs): use normalized relative path for mobile platform

Fix #9378
This commit is contained in:
Andelf
2023-05-17 01:02:19 +08:00
parent 51201124ff
commit c917f2e087
3 changed files with 42 additions and 14 deletions

View File

@@ -10,6 +10,8 @@ import android.net.Uri;
import java.io.*; import java.io.*;
import java.net.URI;
import java.text.Normalizer;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Stack; import java.util.Stack;
@@ -90,8 +92,11 @@ public class FsWatcher extends Plugin {
shouldRead = true; shouldRead = true;
} }
obj.put("path", Uri.fromFile(f)); URI dir = (new File(mPath)).toURI();
obj.put("dir", Uri.fromFile(new File(mPath))); URI fpath = f.toURI();
obj.put("path", Normalizer.normalize(dir.relativize(fpath).toString(), Normalizer.Form.NFC));
obj.put("dir", Uri.fromFile(new File(mPath))); // Uri is for Android. URI is for RFC compatible
JSObject stat; JSObject stat;
switch (event) { switch (event) {

View File

@@ -46,12 +46,16 @@ public class FsWatcher: CAPPlugin, PollingWatcherDelegate {
} }
public func receivedNotification(_ url: URL, _ event: PollingWatcherEvent, _ metadata: SimpleFileMetadata?) { public func receivedNotification(_ url: URL, _ event: PollingWatcherEvent, _ metadata: SimpleFileMetadata?) {
guard let baseUrl = baseUrl else {
// unwatch, ignore incoming
return
}
// NOTE: Event in js {dir path content stat{mtime}} // NOTE: Event in js {dir path content stat{mtime}}
switch event { switch event {
case .Unlink: case .Unlink:
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
self.notifyListeners("watcher", data: ["event": "unlink", self.notifyListeners("watcher", data: ["event": "unlink",
"dir": self.baseUrl?.description as Any, "dir": baseUrl.description as Any,
"path": url.description "path": url.description
]) ])
} }
@@ -61,8 +65,8 @@ public class FsWatcher: CAPPlugin, PollingWatcherDelegate {
content = try? String(contentsOf: url, encoding: .utf8) content = try? String(contentsOf: url, encoding: .utf8)
} }
self.notifyListeners("watcher", data: ["event": event.description, self.notifyListeners("watcher", data: ["event": event.description,
"dir": baseUrl?.description as Any, "dir": baseUrl.description as Any,
"path": url.description, "path": url.relativePath(from: baseUrl)?.precomposedStringWithCanonicalMapping as Any,
"content": content as Any, "content": content as Any,
"stat": ["mtime": metadata?.contentModificationTimestamp ?? 0, "stat": ["mtime": metadata?.contentModificationTimestamp ?? 0,
"ctime": metadata?.creationTimestamp ?? 0, "ctime": metadata?.creationTimestamp ?? 0,
@@ -265,3 +269,29 @@ public class PollingWatcher {
self.metaDb = newMetaDb self.metaDb = newMetaDb
} }
} }
extension URL {
func relativePath(from base: URL) -> String? {
// Ensure that both URLs represent files:
guard self.isFileURL && base.isFileURL else {
return nil
}
// Remove/replace "." and "..", make paths absolute:
let destComponents = self.standardizedFileURL.pathComponents
let baseComponents = base.standardizedFileURL.pathComponents
// Find number of common path components:
var i = 0
while i < destComponents.count && i < baseComponents.count
&& destComponents[i] == baseComponents[i] {
i += 1
}
// Build relative path:
var relComponents = Array(repeating: "..", count: baseComponents.count - i)
relComponents.append(contentsOf: destComponents[i...])
return relComponents.joined(separator: "/")
}
}

View File

@@ -69,8 +69,7 @@
[logseq.db.schema :as db-schema] [logseq.db.schema :as db-schema]
[logseq.graph-parser.config :as gp-config] [logseq.graph-parser.config :as gp-config]
[promesa.core :as p] [promesa.core :as p]
[rum.core :as rum] [rum.core :as rum]))
[logseq.common.path :as path]))
;; TODO: should we move all events here? ;; TODO: should we move all events here?
@@ -622,13 +621,7 @@
(defmethod handle :mobile-file-watcher/changed [[_ ^js event]] (defmethod handle :mobile-file-watcher/changed [[_ ^js event]]
(let [type (.-event event) (let [type (.-event event)
payload (js->clj event :keywordize-keys true) payload (js->clj event :keywordize-keys true)]
dir (:dir payload)
payload (-> payload
(update :path
(fn [path]
(when (string? path)
(path/relative-path dir path)))))]
(fs-watcher/handle-changed! type payload) (fs-watcher/handle-changed! type payload)
(when (file-sync-handler/enable-sync?) (when (file-sync-handler/enable-sync?)
(sync/file-watch-handler type payload)))) (sync/file-watch-handler type payload))))