diff --git a/src/localdb.ts b/src/localdb.ts index e559e31..8d37e4a 100644 --- a/src/localdb.ts +++ b/src/localdb.ts @@ -330,7 +330,7 @@ export const clearDeleteRenameHistoryOfKeyAndVault = async ( export const insertDeleteRecordByVault = async ( db: InternalDBs, - fileOrFolder: TAbstractFile, + fileOrFolder: TAbstractFile | string, vaultRandomID: string ) => { // log.info(fileOrFolder); @@ -347,6 +347,7 @@ export const insertDeleteRecordByVault = async ( renameTo: "", vaultRandomID: vaultRandomID, }; + await db.fileHistoryTbl.setItem(`${vaultRandomID}\t${k.key}`, k); } else if (fileOrFolder instanceof TFolder) { // key should endswith "/" const key = fileOrFolder.path.endsWith("/") @@ -365,8 +366,57 @@ export const insertDeleteRecordByVault = async ( renameTo: "", vaultRandomID: vaultRandomID, }; + await db.fileHistoryTbl.setItem(`${vaultRandomID}\t${k.key}`, k); + } else if (typeof fileOrFolder === "string") { + // always the deletions in .obsidian folder + // so annoying that the path doesn't exists + // and we have to guess whether the path is folder or file + k = { + key: fileOrFolder, + ctime: 0, + mtime: 0, + size: 0, + actionWhen: Date.now(), + actionType: "delete", + keyType: "file", + renameTo: "", + vaultRandomID: vaultRandomID, + }; + await db.fileHistoryTbl.setItem(`${vaultRandomID}\t${k.key}`, k); + for (const ext of [ + "json", + "js", + "mjs", + "ts", + "md", + "txt", + "css", + "png", + "gif", + "jpg", + "jpeg", + "gitignore", + "gitkeep", + ]) { + if (fileOrFolder.endsWith(`.${ext}`)) { + // stop here, no more need to insert the folder record later + return; + } + } + // also add a deletion record as folder if not ending with special exts + k = { + key: `${fileOrFolder}/`, + ctime: 0, + mtime: 0, + size: 0, + actionWhen: Date.now(), + actionType: "delete", + keyType: "folder", + renameTo: "", + vaultRandomID: vaultRandomID, + }; + await db.fileHistoryTbl.setItem(`${vaultRandomID}\t${k.key}`, k); } - await db.fileHistoryTbl.setItem(`${vaultRandomID}\t${k.key}`, k); }; /** diff --git a/src/main.ts b/src/main.ts index da8add5..1751fd3 100644 --- a/src/main.ts +++ b/src/main.ts @@ -7,6 +7,8 @@ import { setIcon, FileSystemAdapter, Platform, + TFile, + TFolder, } from "obsidian"; import cloneDeep from "lodash/cloneDeep"; import { createElement, RotateCcw, RefreshCcw, FileText } from "lucide"; @@ -496,6 +498,31 @@ export default class RemotelySavePlugin extends Plugin { }) ); + function getMethods(obj: any) { + var result = []; + for (var id in obj) { + try { + if (typeof obj[id] == "function") { + result.push(id + ": " + obj[id].toString()); + } + } catch (err) { + result.push(id + ": inaccessible"); + } + } + return result.join("\n"); + } + this.registerEvent( + this.app.vault.on("raw" as any, async (fileOrFolder) => { + // special track on .obsidian folder + const name = `${fileOrFolder}`; + if (name.startsWith(this.app.vault.configDir)) { + if (!(await this.app.vault.adapter.exists(name))) { + await insertDeleteRecordByVault(this.db, name, this.vaultRandomID); + } + } + }) + ); + this.registerObsidianProtocolHandler(COMMAND_URI, async (inputParams) => { const parsed = importQrCodeUri(inputParams, this.app.vault.getName()); if (parsed.status === "error") { diff --git a/src/misc.ts b/src/misc.ts index 897d3ba..406eeef 100644 --- a/src/misc.ts +++ b/src/misc.ts @@ -427,3 +427,31 @@ export const statFix = async (vault: Vault, path: string) => { } return s; }; + +export const isFolderToSkip = (x: string, more: string[] | undefined) => { + let specialFolders = [ + ".git", + ".github", + ".gitlab", + ".svn", + "node_modules", + ".DS_Store", + "__MACOSX ", + "Icon\r", // https://superuser.com/questions/298785/icon-file-on-os-x-desktop + "desktop.ini", + "Desktop.ini", + "thumbs.db", + "Thumbs.db", + ].concat(more !== undefined ? more : []); + for (const iterator of specialFolders) { + if ( + x === iterator || + x === `${iterator}/` || + x.endsWith(`/${iterator}`) || + x.endsWith(`/${iterator}/`) + ) { + return true; + } + } + return false; +}; diff --git a/src/obsFolderLister.ts b/src/obsFolderLister.ts index ce1671b..668d0ea 100644 --- a/src/obsFolderLister.ts +++ b/src/obsFolderLister.ts @@ -2,7 +2,7 @@ import { Vault, Stat, ListedFiles } from "obsidian"; import { Queue } from "@fyears/tsqueue"; import chunk from "lodash/chunk"; import flatten from "lodash/flatten"; -import { statFix } from "./misc"; +import { statFix, isFolderToSkip } from "./misc"; export interface ObsConfigDirFileType { key: string; @@ -12,28 +12,6 @@ export interface ObsConfigDirFileType { type: "folder" | "file"; } -const isFolderToSkip = (x: string) => { - let specialFolders = [ - ".git", - ".github", - ".gitlab", - ".svn", - "node_modules", - ".DS_Store", - ]; - for (const iterator of specialFolders) { - if ( - x === iterator || - x === `${iterator}/` || - x.endsWith(`/${iterator}`) || - x.endsWith(`/${iterator}/`) - ) { - return true; - } - } - return false; -}; - const isPluginDirItself = (x: string, pluginId: string) => { return ( x === pluginId || @@ -106,7 +84,7 @@ export const listFilesInObsFolder = async ( const isInsideSelfPlugin = isPluginDirItself(iter.itself.key, pluginId); if (iter.children !== undefined) { for (const iter2 of iter.children.folders) { - if (isFolderToSkip(iter2)) { + if (isFolderToSkip(iter2, ["workspace", "workspace.json"])) { continue; } if (isInsideSelfPlugin && !isLikelyPluginSubFiles(iter2)) { @@ -116,7 +94,7 @@ export const listFilesInObsFolder = async ( q.push(iter2); } for (const iter2 of iter.children.files) { - if (isFolderToSkip(iter2)) { + if (isFolderToSkip(iter2, ["workspace", "workspace.json"])) { continue; } if (isInsideSelfPlugin && !isLikelyPluginSubFiles(iter2)) {