diff --git a/src/baseTypes.ts b/src/baseTypes.ts index 1a1be04..9fc09e1 100644 --- a/src/baseTypes.ts +++ b/src/baseTypes.ts @@ -94,17 +94,22 @@ export interface RemotelySavePluginSettings { autoRunEveryMilliseconds?: number; initRunAfterMilliseconds?: number; syncOnSaveAfterMilliseconds?: number; - agreeToUploadExtraMetadata?: boolean; + concurrency?: number; syncConfigDir?: boolean; syncUnderscoreItems?: boolean; lang?: LangTypeAndAuto; - + agreeToUseSyncV3?: boolean; skipSizeLargerThan?: number; ignorePaths?: string[]; enableStatusBarInfo?: boolean; deleteToWhere?: "system" | "obsidian"; + /** + * @deprecated + */ + agreeToUploadExtraMetadata?: boolean; + /** * @deprecated */ @@ -131,32 +136,6 @@ export interface UriParams { // 80 days export const OAUTH2_FORCE_EXPIRE_MILLISECONDS = 1000 * 60 * 60 * 24 * 80; -type DecisionTypeForFile = - | "skipUploading" // special, mtimeLocal === mtimeRemote - | "uploadLocalDelHistToRemote" // "delLocalIfExists && delRemoteIfExists && cleanLocalDelHist && uploadLocalDelHistToRemote" - | "keepRemoteDelHist" // "delLocalIfExists && delRemoteIfExists && cleanLocalDelHist && keepRemoteDelHist" - | "uploadLocalToRemote" // "skipLocal && uploadLocalToRemote && cleanLocalDelHist && cleanRemoteDelHist" - | "downloadRemoteToLocal"; // "downloadRemoteToLocal && skipRemote && cleanLocalDelHist && cleanRemoteDelHist" - -type DecisionTypeForFileSize = - | "skipUploadingTooLarge" - | "skipDownloadingTooLarge" - | "skipUsingLocalDelTooLarge" - | "skipUsingRemoteDelTooLarge" - | "errorLocalTooLargeConflictRemote" - | "errorRemoteTooLargeConflictLocal"; - -type DecisionTypeForFolder = - | "createFolder" - | "uploadLocalDelHistToRemoteFolder" - | "keepRemoteDelHistFolder" - | "skipFolder"; - -export type DecisionType = - | DecisionTypeForFile - | DecisionTypeForFileSize - | DecisionTypeForFolder; - export type EmptyFolderCleanType = "skip" | "clean_both"; export type ConflictActionType = "keep_newer" | "keep_larger" | "rename_both"; @@ -233,7 +212,7 @@ export interface FileOrFolderMixedState { sizeRemoteEnc?: number; changeRemoteMtimeUsingMapping?: boolean; changeLocalMtimeUsingMapping?: boolean; - decision?: DecisionType; + decision?: string; // old DecisionType is deleted, fallback to string decisionBranch?: number; syncDone?: "done"; remoteEncryptedKey?: string; diff --git a/src/langs/en.json b/src/langs/en.json index 4e36c3e..cd75af2 100644 --- a/src/langs/en.json +++ b/src/langs/en.json @@ -284,10 +284,8 @@ "settings_resetcache_desc": "Reset local internal caches/databases (for debugging purposes). You would want to reload the plugin after resetting this. This option will not empty the {s3, password...} settings.", "settings_resetcache_button": "Reset", "settings_resetcache_notice": "Local internal cache/databases deleted. Please manually reload the plugin.", - "syncalgov2_title": "Remotely Save has a better sync algorithm", - "syncalgov2_texts": "Welcome to use Remotely Save!\nFrom version 0.3.0, a new algorithm has been developed, but it needs uploading extra meta data files _remotely-save-metadata-on-remote.{json,bin} to YOUR configured cloud destinations, besides your notes.\nSo that, for example, the second device can know that what files/folders have been deleted on the first device by reading those files.\nIf you agree, plase click the button \"Agree\", and enjoy the plugin! AND PLEASE REMEMBER TO BACKUP YOUR VAULT FIRSTLY!\nIf you do not agree, you should stop using the current and later versions of Remotely Save. You could consider manually install the old version 0.2.14 which uses old algorithm and does not upload any extra meta data files. By clicking the \"Do Not Agree\" button, the plugin will unload itself, and you need to manually disable it in Obsidian settings.", - "syncalgov2_button_agree": "Agree", - "syncalgov2_button_disagree": "Do Not Agree", - - "official_notice_2024_first_party": "Plugin Remotely-Save is back to the party and get a HUGE update!🎉🎉🎉 Try it yourself or see the release note on https://github.com/remotely-save/remotely-save/releases." + "syncalgov3_title": "Remotely Save has HUGE update on sync algorithm", + "syncalgov3_texts": "Welcome to use Remotely Save!\nFrom this version, a new algorithm has been developed. If you agree, plase click the button \"Agree\", and enjoy the plugin! AND PLEASE REMEMBER TO BACKUP YOUR VAULT FIRSTLY!\nIf you do not agree, you should stop using the current and later versions of Remotely Save. By clicking the \"Do Not Agree\" button, the plugin will unload itself, and you need to manually disable it in Obsidian settings.", + "syncalgov3_button_agree": "Agree", + "syncalgov3_button_disagree": "Do Not Agree" } diff --git a/src/langs/zh_cn.json b/src/langs/zh_cn.json index a61d17a..cb128af 100644 --- a/src/langs/zh_cn.json +++ b/src/langs/zh_cn.json @@ -284,10 +284,8 @@ "settings_resetcache_desc": "(出于调试原因)重设本地缓存和数据库。您需要在重设之后重新载入此插件。本重设不会删除 s3,密码……等设定。", "settings_resetcache_button": "重设", "settings_resetcache_notice": "本地同步缓存和数据库已被删除。请手动重新载入此插件。", - "syncalgov2_title": "Remotely Save 的同步算法得到优化", - "syncalgov2_texts": "欢迎使用 Remotely Save!\n从版本 0.3.0 开始,它带来了新的同步算法,但是,除了您的笔记之外,它还需要上传额外的带有元信息的文件 _remotely-save-metadata-on-remote.{json,bin} 到您的云服务目的地上。\n从而,比如说,通过读取这些信息,另一台设备可以知道什么文件或文件夹在第一台设备上被删除了。\n如果您同意此策略,请点击按钮 \"同意\",然后开始享用此插件!且特别要注意:使用插件之前,请首先备份好您的库(Vault)!\n如果您不同意此策略,您应该停止使用此版本和之后版本的 Remotely Save。您可以考虑手动安装旧版 0.2.14,它使用旧的同步算法,并不上传额外元信息文件。点击 \"不同意\" 之后,插件会自动停止运行(unload),然后您需要 Obsidian 设置里手动停用(disable)此插件。", - "syncalgov2_button_agree": "同意", - "syncalgov2_button_disagree": "不同意", - - "official_notice_2024_first_party": "插件 Remotely-Save 回来了,更新了一大堆功能!🎉🎉🎉请自行使用,或参阅更新文档: https://github.com/remotely-save/remotely-save/releases 。" + "syncalgov3_title": "Remotely Save 的同步算法重大优化", + "syncalgov3_texts": "欢迎使用 Remotely Save!\n从这个版本 0.3.0 开始,它带来了新的同步算法\n如果您同意使用,请点击按钮 \"同意\",然后开始享用此插件!且特别要注意:使用插件之前,请首先备份好您的库(Vault)!\n如果您不同意此策略,您应该停止使用此版本和之后版本的 Remotely Save。点击 \"不同意\" 之后,插件会自动停止运行(unload),然后您需要 Obsidian 设置里手动停用(disable)此插件。", + "syncalgov3_button_agree": "同意", + "syncalgov3_button_disagree": "不同意" } diff --git a/src/langs/zh_tw.json b/src/langs/zh_tw.json index 25771be..cb81eff 100644 --- a/src/langs/zh_tw.json +++ b/src/langs/zh_tw.json @@ -284,9 +284,8 @@ "settings_resetcache_desc": "(出於除錯原因)重設本地快取和資料庫。您需要在重設之後重新載入此外掛。本重設不會刪除 s3,密碼……等設定。", "settings_resetcache_button": "重設", "settings_resetcache_notice": "本地同步快取和資料庫已被刪除。請手動重新載入此外掛。", - "syncalgov2_title": "Remotely Save 的同步演算法得到最佳化", - "syncalgov2_texts": "歡迎使用 Remotely Save!\n從版本 0.3.0 開始,它帶來了新的同步演算法,但是,除了您的筆記之外,它還需要上傳額外的帶有元資訊的檔案 _remotely-save-metadata-on-remote.{json,bin} 到您的雲服務目的地上。\n從而,比如說,透過讀取這些資訊,另一臺裝置可以知道什麼檔案或資料夾在第一臺裝置上被刪除了。\n如果您同意此策略,請點選按鈕 \"同意\",然後開始享用此外掛!且特別要注意:使用外掛之前,請首先備份好您的儲存庫(Vault)!\n如果您不同意此策略,您應該停止使用此版本和之後版本的 Remotely Save。您可以考慮手動安裝舊版 0.2.14,它使用舊的同步演算法,並不上傳額外元資訊檔案。點選 \"不同意\" 之後,外掛會自動停止執行(unload),然後您需要 Obsidian 設定裡手動停用(disable)此外掛。", - "syncalgov2_button_agree": "同意", - "syncalgov2_button_disagree": "不同意", - "official_notice_2024_first_party": "外掛 Remotely-Save 回來了,更新了一大堆功能!🎉🎉🎉請自行使用,或參閱更新文件: https://github.com/remotely-save/remotely-save/releases 。" + "syncalgov3_title": "Remotely Save 的同步演算法重大最佳化", + "syncalgov3_texts": "歡迎使用 Remotely Save!\n從這個版本 0.3.0 開始,它帶來了新的同步演算法\n如果您同意使用,請點選按鈕 \"同意\",然後開始享用此外掛!且特別要注意:使用外掛之前,請首先備份好您的庫(Vault)!\n如果您不同意此策略,您應該停止使用此版本和之後版本的 Remotely Save。點選 \"不同意\" 之後,外掛會自動停止執行(unload),然後您需要 Obsidian 設定裡手動停用(disable)此外掛。", + "syncalgov3_button_agree": "同意", + "syncalgov3_button_disagree": "不同意" } diff --git a/src/main.ts b/src/main.ts index 8cda974..938cb0b 100644 --- a/src/main.ts +++ b/src/main.ts @@ -15,7 +15,6 @@ import { import cloneDeep from "lodash/cloneDeep"; import { createElement, RotateCcw, RefreshCcw, FileText } from "lucide"; import type { - FileOrFolderMixedState, RemotelySavePluginSettings, SyncTriggerSourceType, } from "./baseTypes"; @@ -29,10 +28,7 @@ import { } from "./baseTypes"; import { importQrCodeUri } from "./importExport"; import { - insertDeleteRecordByVault, - insertRenameRecordByVault, insertSyncPlanRecordByVault, - loadFileHistoryTableByVault, prepareDBs, InternalDBs, clearExpiredSyncPlanRecords, @@ -57,15 +53,15 @@ import { import { DEFAULT_S3_CONFIG } from "./remoteForS3"; import { DEFAULT_WEBDAV_CONFIG } from "./remoteForWebdav"; import { RemotelySaveSettingTab } from "./settings"; -import { fetchMetadataFile, parseRemoteItems, SyncStatusType } from "./sync"; +import { parseRemoteItems, SyncStatusType } from "./sync"; import { doActualSync, getSyncPlan, isPasswordOk } from "./sync"; import { messyConfigToNormal, normalConfigToMessy } from "./configPersist"; -import { ObsConfigDirFileType, listFilesInObsFolder } from "./obsFolderLister"; +import { getLocalEntityList } from "./local"; import { I18n } from "./i18n"; import type { LangType, LangTypeAndAuto, TransItemType } from "./i18n"; import { DeletionOnRemote, MetadataOnRemote } from "./metadataOnRemote"; -import { SyncAlgoV2Modal } from "./syncAlgoV2Notice"; +import { SyncAlgoV3Modal } from "./syncAlgoV3Notice"; import { applyLogWriterInplace, log } from "./moreOnLog"; import AggregateError from "aggregate-error"; @@ -271,12 +267,6 @@ export default class RemotelySavePlugin extends Plugin { client.serviceType, this.settings.password ); - const origMetadataOnRemote = await fetchMetadataFile( - metadataFile, - client, - this.app.vault, - this.settings.password - ); if (this.settings.currLogLevel === "info") { // pass @@ -285,10 +275,6 @@ export default class RemotelySavePlugin extends Plugin { } this.syncStatus = "getting_local_meta"; const local = this.app.vault.getAllLoadedFiles(); - const localHistory = await loadFileHistoryTableByVault( - this.db, - this.vaultRandomID - ); let localConfigDirContents: ObsConfigDirFileType[] | undefined = undefined; if (this.settings.syncConfigDir) { @@ -345,21 +331,12 @@ export default class RemotelySavePlugin extends Plugin { plan, sortedKeys, metadataFile, - origMetadataOnRemote, sizesGoWrong, deletions, (key: string) => self.trash(key), this.settings.password, this.settings.concurrency, - (ss: FileOrFolderMixedState[]) => { - new SizesConflictModal( - self.app, - self, - this.settings.skipSizeLargerThan ?? -1, - ss, - this.settings.password !== "" - ).open(); - }, + (i: number, totalCount: number, pathName: string, decision: string) => self.setCurrSyncMsg(i, totalCount, pathName, decision) ); @@ -496,52 +473,6 @@ export default class RemotelySavePlugin extends Plugin { this.syncStatus = "idle"; - this.registerEvent( - this.app.vault.on("delete", async (fileOrFolder) => { - await insertDeleteRecordByVault( - this.db, - fileOrFolder, - this.vaultRandomID - ); - }) - ); - - this.registerEvent( - this.app.vault.on("rename", async (fileOrFolder, oldPath) => { - await insertRenameRecordByVault( - this.db, - fileOrFolder, - oldPath, - this.vaultRandomID - ); - }) - ); - - 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") { @@ -814,9 +745,9 @@ export default class RemotelySavePlugin extends Plugin { // log.info("click", evt); // }); - if (!this.settings.agreeToUploadExtraMetadata) { - const syncAlgoV2Modal = new SyncAlgoV2Modal(this.app, this); - syncAlgoV2Modal.open(); + if (!this.settings.agreeToUseSyncV3) { + const syncAlgoV3Modal = new SyncAlgoV3Modal(this.app, this); + syncAlgoV3Modal.open(); } else { this.enableAutoSyncIfSet(); this.enableInitSyncIfSet(); @@ -829,9 +760,6 @@ export default class RemotelySavePlugin extends Plugin { this.vaultRandomID, this.manifest.version ); - if (compareVersion(REMOTELY_SAVE_VERSION_2024PREPARE, oldVersion) >= 0) { - new Notice(t("official_notice_2024_first_party"), 10 * 1000); - } } async onunload() { @@ -918,6 +846,10 @@ export default class RemotelySavePlugin extends Plugin { this.settings.s3.bypassCorsLocally = true; // deprecated as of 20240113 } + if (this.settings.agreeToUseSyncV3 === undefined) { + this.settings.agreeToUseSyncV3 = false; + } + await this.saveSettings(); } diff --git a/src/syncAlgoV3Notice.ts b/src/syncAlgoV3Notice.ts index c016762..34b6913 100644 --- a/src/syncAlgoV3Notice.ts +++ b/src/syncAlgoV3Notice.ts @@ -4,7 +4,7 @@ import type { TransItemType } from "./i18n"; import { log } from "./moreOnLog"; -export class SyncAlgoV2Modal extends Modal { +export class SyncAlgoV3Modal extends Modal { agree: boolean; readonly plugin: RemotelySavePlugin; constructor(app: App, plugin: RemotelySavePlugin) { @@ -19,11 +19,11 @@ export class SyncAlgoV2Modal extends Modal { }; contentEl.createEl("h2", { - text: t("syncalgov2_title"), + text: t("syncalgov3_title"), }); const ul = contentEl.createEl("ul"); - t("syncalgov2_texts") + t("syncalgov3_texts") .split("\n") .forEach((val) => { ul.createEl("li", { @@ -33,14 +33,14 @@ export class SyncAlgoV2Modal extends Modal { new Setting(contentEl) .addButton((button) => { - button.setButtonText(t("syncalgov2_button_agree")); + button.setButtonText(t("syncalgov3_button_agree")); button.onClick(async () => { this.agree = true; this.close(); }); }) .addButton((button) => { - button.setButtonText(t("syncalgov2_button_disagree")); + button.setButtonText(t("syncalgov3_button_disagree")); button.onClick(() => { this.close(); });