optimize sync status bar
This commit is contained in:
parent
57493f57cf
commit
35f5355c8e
@ -1417,6 +1417,7 @@ export const doActualSync = async (
|
||||
db: InternalDBs,
|
||||
profiler: Profiler | undefined,
|
||||
conflictAction: ConflictActionType,
|
||||
triggerSource: SyncTriggerSourceType,
|
||||
callbackSyncProcess?: any
|
||||
) => {
|
||||
profiler?.addIndent();
|
||||
@ -1524,13 +1525,16 @@ export const doActualSync = async (
|
||||
// );
|
||||
|
||||
await callbackSyncProcess?.(
|
||||
triggerSource,
|
||||
realCounter,
|
||||
realTotalCount,
|
||||
key,
|
||||
val.decision
|
||||
);
|
||||
|
||||
realCounter += 1;
|
||||
if (val.change === undefined || val.change) {
|
||||
realCounter += 1;
|
||||
}
|
||||
|
||||
await dispatchOperationToActualV3(
|
||||
key,
|
||||
@ -1743,6 +1747,7 @@ export async function syncer(
|
||||
db,
|
||||
profiler,
|
||||
settings.conflictAction ?? "keep_newer",
|
||||
triggerSource,
|
||||
callbackSyncProcess
|
||||
);
|
||||
profiler?.insert(`finish step${step} (actual sync)`);
|
||||
|
||||
@ -45,20 +45,26 @@
|
||||
|
||||
"command_exportlogsindb": "export logs saved in db",
|
||||
|
||||
"statusbar_time_years": "Synced {{time}} years ago",
|
||||
"statusbar_time_months": "Synced {{time}} months ago",
|
||||
"statusbar_time_weeks": "Synced {{time}} weeks ago",
|
||||
"statusbar_time_days": "Synced {{time}} days ago",
|
||||
"statusbar_time_hours": "Synced {{time}} hours ago",
|
||||
"statusbar_time_minutes": "Synced {{time}} minutes ago",
|
||||
"statusbar_time_lessminute": "Synced last minute ago",
|
||||
"statusbar_lastsync": "Synced {{time}} ago",
|
||||
"statusbar_sync_source_manual": "Manual: ",
|
||||
"statusbar_sync_source_dry": "Dry: ",
|
||||
"statusbar_sync_source_auto": "Auto: ",
|
||||
"statusbar_sync_source_auto_once_init": "Auto (init): ",
|
||||
"statusbar_sync_source_auto_sync_on_save": "Auto (save): ",
|
||||
"statusbar_sync_status_prefix_success": "Successfully synced ",
|
||||
"statusbar_sync_status_prefix_failed": "Failed to sync ",
|
||||
"statusbar_time_years": "{{time}} years ago",
|
||||
"statusbar_time_months": "{{time}} months ago",
|
||||
"statusbar_time_weeks": "{{time}} weeks ago",
|
||||
"statusbar_time_days": "{{time}} days ago",
|
||||
"statusbar_time_hours": "{{time}} hours ago",
|
||||
"statusbar_time_minutes": "{{time}} minutes ago",
|
||||
"statusbar_time_lessminute": "last minute ago",
|
||||
"statusbar_time_now": "just now",
|
||||
"statusbar_syncing": "Syncing...",
|
||||
"statusbar_failed": "Last sync failed",
|
||||
"statusbar_now": "Synced just now",
|
||||
"statusbar_lastsync_label": "Last successful Sync on {{date}}",
|
||||
"statusbar_lastsync_label": "on {{date}}",
|
||||
"statusbar_lastsync_never": "Never Synced",
|
||||
"statusbar_lastsync_never_label": "Never Synced before",
|
||||
|
||||
"modal_password_title": "Hold on and PLEASE READ ON...",
|
||||
"modal_password_shortdesc": "If the field is not empty, files would be encrypted locally before being uploaded.\nIf the field is empty, then files would be uploaded without encryption.",
|
||||
"modal_password_attn1": "Attention 1/5: The vault name is NOT encrypted. The plugin creates a folder with the vault name on some remote services.",
|
||||
|
||||
@ -45,20 +45,26 @@
|
||||
"command_exportsyncplans_all": "导出同步计划(所有)(export sync plans (all))",
|
||||
"command_exportlogsindb": "从数据库导出终端日志(export logs saved in db)",
|
||||
|
||||
"statusbar_time_years": "{{time}} 年前同步",
|
||||
"statusbar_time_months": "{{time}} 月前同步",
|
||||
"statusbar_time_weeks": "{{time}} 周前同步",
|
||||
"statusbar_time_days": "{{time}} 天前同步",
|
||||
"statusbar_time_hours": "{{time}} 小时前同步",
|
||||
"statusbar_time_minutes": "{{time}} 分钟前同步",
|
||||
"statusbar_time_lessminute": "一分钟之内同步",
|
||||
"statusbar_lastsync": "上一次同步于:{{time}}",
|
||||
"statusbar_sync_source_manual": "手动:",
|
||||
"statusbar_sync_source_dry": "空跑:",
|
||||
"statusbar_sync_source_auto": "自动:",
|
||||
"statusbar_sync_source_auto_once_init": "启动时自动:",
|
||||
"statusbar_sync_source_auto_sync_on_save": "保存时自动:",
|
||||
"statusbar_sync_status_prefix_success": "同步成功:",
|
||||
"statusbar_sync_status_prefix_failed": "同步失败:",
|
||||
"statusbar_time_years": "{{time}} 年前",
|
||||
"statusbar_time_months": "{{time}} 月前",
|
||||
"statusbar_time_weeks": "{{time}} 周前",
|
||||
"statusbar_time_days": "{{time}} 天前",
|
||||
"statusbar_time_hours": "{{time}} 小时前",
|
||||
"statusbar_time_minutes": "{{time}} 分钟前",
|
||||
"statusbar_time_lessminute": "一分钟之内",
|
||||
"statusbar_time_now": "刚刚",
|
||||
"statusbar_syncing": "正在同步",
|
||||
"statusbar_failed": "上次同步失败了",
|
||||
"statusbar_now": "刚同步完",
|
||||
"statusbar_lastsync_label": "上一次同步于:{{date}}",
|
||||
"statusbar_lastsync_label": "日期:{{date}}",
|
||||
"statusbar_lastsync_never": "没触发过同步",
|
||||
"statusbar_lastsync_never_label": "没触发过同步",
|
||||
|
||||
"modal_password_title": "稍等一下,请阅读下文:",
|
||||
"modal_password_shortdesc": "如果密码不是空的,那么文件会在上传之前,在本地先用此密码加密。\n如果密码是空的,那么文件会被非加密地上传。",
|
||||
"modal_password_attn1": "注意 1/5:库(Vault)名字是不会加密的!本插件会在一些远程存储里创建一个和库名字有着同名的文件夹。",
|
||||
|
||||
@ -44,20 +44,26 @@
|
||||
"command_exportsyncplans_all": "匯出同步計劃(所有)(export sync plans (all))",
|
||||
"command_exportlogsindb": "從資料庫匯出終端日誌(export logs saved in db)",
|
||||
|
||||
"statusbar_time_years": "{{time}} 年前同步",
|
||||
"statusbar_time_months": "{{time}} 月前同步",
|
||||
"statusbar_time_weeks": "{{time}} 周前同步",
|
||||
"statusbar_time_days": "{{time}} 天前同步",
|
||||
"statusbar_time_hours": "{{time}} 小時前同步",
|
||||
"statusbar_time_minutes": "{{time}} 分鐘前同步",
|
||||
"statusbar_time_lessminute": "一分鐘之內同步",
|
||||
"statusbar_lastsync": "上一次同步於:{{time}}",
|
||||
"statusbar_sync_source_manual": "手動:",
|
||||
"statusbar_sync_source_dry": "空跑:",
|
||||
"statusbar_sync_source_auto": "自動:",
|
||||
"statusbar_sync_source_auto_once_init": "啟動時自動:",
|
||||
"statusbar_sync_source_auto_sync_on_save": "儲存時自動:",
|
||||
"statusbar_sync_status_prefix_success": "同步成功:",
|
||||
"statusbar_sync_status_prefix_failed": "同步失敗:",
|
||||
"statusbar_time_years": "{{time}} 年前",
|
||||
"statusbar_time_months": "{{time}} 月前",
|
||||
"statusbar_time_weeks": "{{time}} 周前",
|
||||
"statusbar_time_days": "{{time}} 天前",
|
||||
"statusbar_time_hours": "{{time}} 小時前",
|
||||
"statusbar_time_minutes": "{{time}} 分鐘前",
|
||||
"statusbar_time_lessminute": "一分鐘之內",
|
||||
"statusbar_time_now": "剛剛",
|
||||
"statusbar_syncing": "正在同步",
|
||||
"statusbar_failed": "上次同步失敗了",
|
||||
"statusbar_now": "剛同步完",
|
||||
"statusbar_lastsync_label": "上一次同步於:{{date}}",
|
||||
"statusbar_lastsync_label": "日期:{{date}}",
|
||||
"statusbar_lastsync_never": "沒觸發過同步",
|
||||
"statusbar_lastsync_never_label": "沒觸發過同步",
|
||||
|
||||
"modal_password_title": "稍等一下,請閱讀下文:",
|
||||
"modal_password_shortdesc": "如果密碼不是空的,那麼檔案會在上傳之前,在本地先用此密碼加密。\n如果密碼是空的,那麼檔案會被非加密地上傳。",
|
||||
"modal_password_attn1": "注意 1/5:儲存庫(Vault)名字是不會加密的!本外掛會在一些遠端儲存裡建立一個和庫名字有著同名的資料夾。",
|
||||
|
||||
@ -519,7 +519,27 @@ export const getLastSuccessSyncTimeByVault = async (
|
||||
) => {
|
||||
return (await db.simpleKVForMiscTbl.getItem(
|
||||
`${vaultRandomID}-lastSuccessSyncMillis`
|
||||
)) as number;
|
||||
)) as number | null | undefined;
|
||||
};
|
||||
|
||||
export const upsertLastFailedSyncTimeByVault = async (
|
||||
db: InternalDBs,
|
||||
vaultRandomID: string,
|
||||
millis: number
|
||||
) => {
|
||||
await db.simpleKVForMiscTbl.setItem(
|
||||
`${vaultRandomID}-lastFailedSyncMillis`,
|
||||
millis
|
||||
);
|
||||
};
|
||||
|
||||
export const getLastFailedSyncTimeByVault = async (
|
||||
db: InternalDBs,
|
||||
vaultRandomID: string
|
||||
) => {
|
||||
return (await db.simpleKVForMiscTbl.getItem(
|
||||
`${vaultRandomID}-lastFailedSyncMillis`
|
||||
)) as number | null | undefined;
|
||||
};
|
||||
|
||||
export const upsertPluginVersionByVault = async (
|
||||
|
||||
129
src/main.ts
129
src/main.ts
@ -92,8 +92,10 @@ import {
|
||||
type InternalDBs,
|
||||
clearAllLoggerOutputRecords,
|
||||
clearExpiredSyncPlanRecords,
|
||||
getLastFailedSyncTimeByVault,
|
||||
getLastSuccessSyncTimeByVault,
|
||||
prepareDBs,
|
||||
upsertLastFailedSyncTimeByVault,
|
||||
upsertLastSuccessSyncTimeByVault,
|
||||
upsertPluginVersionByVault,
|
||||
} from "./localdb";
|
||||
@ -176,6 +178,29 @@ const getIconSvg = () => {
|
||||
return res;
|
||||
};
|
||||
|
||||
const getStatusBarShortMsgFromSyncSource = (
|
||||
t: (x: TransItemType, vars?: any) => string,
|
||||
s: SyncTriggerSourceType | undefined
|
||||
) => {
|
||||
if (s === undefined) {
|
||||
return "";
|
||||
}
|
||||
switch (s) {
|
||||
case "manual":
|
||||
return t("statusbar_sync_source_manual");
|
||||
case "dry":
|
||||
return t("statusbar_sync_source_dry");
|
||||
case "auto":
|
||||
return t("statusbar_sync_source_auto");
|
||||
case "auto_once_init":
|
||||
return t("statusbar_sync_source_auto_once_init");
|
||||
case "auto_sync_on_save":
|
||||
return t("statusbar_sync_source_auto_sync_on_save");
|
||||
default:
|
||||
throw Error(`no translate for ${s}`);
|
||||
}
|
||||
};
|
||||
|
||||
export default class RemotelySavePlugin extends Plugin {
|
||||
settings!: RemotelySavePluginSettings;
|
||||
db!: InternalDBs;
|
||||
@ -393,17 +418,15 @@ export default class RemotelySavePlugin extends Plugin {
|
||||
) => {
|
||||
if (step === 1) {
|
||||
// change status to "syncing..." on statusbar
|
||||
this.updateLastSuccessSyncMsg(-1);
|
||||
this.updateLastSyncMsg(s, -1, -1);
|
||||
} else if (step === 8 && everythingOk) {
|
||||
const lastSuccessSyncMillis = Date.now();
|
||||
await upsertLastSuccessSyncTimeByVault(
|
||||
this.db,
|
||||
this.vaultRandomID,
|
||||
lastSuccessSyncMillis
|
||||
);
|
||||
this.updateLastSuccessSyncMsg(lastSuccessSyncMillis);
|
||||
const ts = Date.now();
|
||||
await upsertLastSuccessSyncTimeByVault(this.db, this.vaultRandomID, ts);
|
||||
this.updateLastSyncMsg(s, ts, null);
|
||||
} else if (!everythingOk) {
|
||||
this.updateLastSuccessSyncMsg(-2); // magic number
|
||||
const ts = Date.now();
|
||||
await upsertLastFailedSyncTimeByVault(this.db, this.vaultRandomID, ts);
|
||||
this.updateLastSyncMsg(s, null, ts); // magic number
|
||||
}
|
||||
};
|
||||
|
||||
@ -412,12 +435,15 @@ export default class RemotelySavePlugin extends Plugin {
|
||||
};
|
||||
|
||||
const callbackSyncProcess = async (
|
||||
s: SyncTriggerSourceType,
|
||||
realCounter: number,
|
||||
realTotalCount: number,
|
||||
pathName: string,
|
||||
decision: string
|
||||
) => {
|
||||
this.setCurrSyncMsg(
|
||||
t,
|
||||
s,
|
||||
realCounter,
|
||||
realTotalCount,
|
||||
pathName,
|
||||
@ -1060,15 +1086,21 @@ export default class RemotelySavePlugin extends Plugin {
|
||||
this.statusBarElement = statusBarItem.createEl("span");
|
||||
this.statusBarElement.setAttribute("data-tooltip-position", "top");
|
||||
|
||||
this.updateLastSuccessSyncMsg(
|
||||
await getLastSuccessSyncTimeByVault(this.db, this.vaultRandomID)
|
||||
this.updateLastSyncMsg(
|
||||
undefined,
|
||||
await getLastSuccessSyncTimeByVault(this.db, this.vaultRandomID),
|
||||
await getLastFailedSyncTimeByVault(this.db, this.vaultRandomID)
|
||||
);
|
||||
// update statusbar text every 30 seconds
|
||||
this.registerInterval(
|
||||
window.setInterval(async () => {
|
||||
this.updateLastSuccessSyncMsg(
|
||||
await getLastSuccessSyncTimeByVault(this.db, this.vaultRandomID)
|
||||
);
|
||||
if (!this.isSyncing) {
|
||||
this.updateLastSyncMsg(
|
||||
undefined,
|
||||
await getLastSuccessSyncTimeByVault(this.db, this.vaultRandomID),
|
||||
await getLastFailedSyncTimeByVault(this.db, this.vaultRandomID)
|
||||
);
|
||||
}
|
||||
}, 1000 * 30)
|
||||
);
|
||||
}
|
||||
@ -1618,7 +1650,8 @@ export default class RemotelySavePlugin extends Plugin {
|
||||
|
||||
if (
|
||||
caller === "SYNC" ||
|
||||
(caller === "FILE_CHANGES" && lastModified > lastSuccessSyncMillis)
|
||||
(caller === "FILE_CHANGES" &&
|
||||
lastModified > (lastSuccessSyncMillis ?? 1))
|
||||
) {
|
||||
console.debug(
|
||||
`so lastModified > lastSuccessSyncMillis or it's called while syncing before`
|
||||
@ -1734,17 +1767,34 @@ export default class RemotelySavePlugin extends Plugin {
|
||||
}
|
||||
|
||||
setCurrSyncMsg(
|
||||
t: (x: TransItemType, vars?: any) => string,
|
||||
s: SyncTriggerSourceType,
|
||||
i: number,
|
||||
totalCount: number,
|
||||
pathName: string,
|
||||
decision: string,
|
||||
triggerSource: SyncTriggerSourceType
|
||||
) {
|
||||
const msg = `syncing progress=${i}/${totalCount},decision=${decision},path=${pathName},source=${triggerSource}`;
|
||||
this.currSyncMsg = msg;
|
||||
const L = `${totalCount}`.length;
|
||||
const iStr = `${i}`.padStart(L, "0");
|
||||
const prefix = getStatusBarShortMsgFromSyncSource(t, s);
|
||||
const shortMsg = prefix + `Syncing ${iStr}/${totalCount}`;
|
||||
const longMsg =
|
||||
prefix +
|
||||
`Syncing progress=${iStr}/${totalCount},decision=${decision},path=${pathName},source=${triggerSource}`;
|
||||
this.currSyncMsg = longMsg;
|
||||
|
||||
if (this.statusBarElement !== undefined) {
|
||||
this.statusBarElement.setText(shortMsg);
|
||||
this.statusBarElement.setAttribute("aria-label", longMsg);
|
||||
}
|
||||
}
|
||||
|
||||
updateLastSuccessSyncMsg(lastSuccessSyncMillis?: number) {
|
||||
updateLastSyncMsg(
|
||||
s: SyncTriggerSourceType | undefined,
|
||||
lastSuccessSyncMillis: number | null | undefined,
|
||||
lastFailedSyncMillis: number | null | undefined
|
||||
) {
|
||||
if (this.statusBarElement === undefined) return;
|
||||
|
||||
const t = (x: TransItemType, vars?: any) => {
|
||||
@ -1754,18 +1804,27 @@ export default class RemotelySavePlugin extends Plugin {
|
||||
let lastSyncMsg = t("statusbar_lastsync_never");
|
||||
let lastSyncLabelMsg = t("statusbar_lastsync_never_label");
|
||||
|
||||
if (lastSuccessSyncMillis !== undefined && lastSuccessSyncMillis === -1) {
|
||||
lastSyncMsg = t("statusbar_syncing");
|
||||
}
|
||||
const inputTs = Math.max(
|
||||
lastSuccessSyncMillis ?? -999,
|
||||
lastFailedSyncMillis ?? -999
|
||||
);
|
||||
const isSuccess =
|
||||
(lastSuccessSyncMillis ?? -999) >= (lastFailedSyncMillis ?? -999);
|
||||
|
||||
if (lastSuccessSyncMillis !== undefined && lastSuccessSyncMillis === -2) {
|
||||
lastSyncMsg = t("statusbar_failed");
|
||||
lastSyncLabelMsg = t("statusbar_failed");
|
||||
}
|
||||
|
||||
if (lastSuccessSyncMillis !== undefined && lastSuccessSyncMillis > 0) {
|
||||
const deltaTime = Date.now() - lastSuccessSyncMillis;
|
||||
if (lastSuccessSyncMillis === -1) {
|
||||
// magic number
|
||||
// otherwise how can we know we are syncing??
|
||||
lastSyncMsg =
|
||||
getStatusBarShortMsgFromSyncSource(t, s!) + t("statusbar_syncing");
|
||||
} else if (inputTs > 0) {
|
||||
let prefix = "";
|
||||
if (isSuccess) {
|
||||
prefix = t("statusbar_sync_status_prefix_success");
|
||||
} else {
|
||||
prefix = t("statusbar_sync_status_prefix_failed");
|
||||
}
|
||||
|
||||
const deltaTime = Date.now() - inputTs;
|
||||
// create human readable time
|
||||
const years = Math.floor(deltaTime / 31556952000);
|
||||
const months = Math.floor(deltaTime / 2629746000);
|
||||
@ -1774,9 +1833,7 @@ export default class RemotelySavePlugin extends Plugin {
|
||||
const hours = Math.floor(deltaTime / 3600000);
|
||||
const minutes = Math.floor(deltaTime / 60000);
|
||||
const seconds = Math.floor(deltaTime / 1000);
|
||||
|
||||
let timeText = "";
|
||||
|
||||
if (years > 0) {
|
||||
timeText = t("statusbar_time_years", { time: years });
|
||||
} else if (months > 0) {
|
||||
@ -1792,10 +1849,9 @@ export default class RemotelySavePlugin extends Plugin {
|
||||
} else if (seconds > 30) {
|
||||
timeText = t("statusbar_time_lessminute");
|
||||
} else {
|
||||
timeText = t("statusbar_now");
|
||||
timeText = t("statusbar_time_now");
|
||||
}
|
||||
|
||||
const dateText = new Date(lastSuccessSyncMillis).toLocaleTimeString(
|
||||
const dateText = new Date(inputTs).toLocaleTimeString(
|
||||
navigator.language,
|
||||
{
|
||||
weekday: "long",
|
||||
@ -1805,8 +1861,11 @@ export default class RemotelySavePlugin extends Plugin {
|
||||
}
|
||||
);
|
||||
|
||||
lastSyncMsg = timeText;
|
||||
lastSyncLabelMsg = t("statusbar_lastsync_label", { date: dateText });
|
||||
lastSyncMsg = prefix + timeText;
|
||||
lastSyncLabelMsg =
|
||||
prefix + t("statusbar_lastsync_label", { date: dateText });
|
||||
} else {
|
||||
// TODO: no idea what happened.
|
||||
}
|
||||
|
||||
this.statusBarElement.setText(lastSyncMsg);
|
||||
|
||||
@ -55,6 +55,7 @@ import {
|
||||
clearAllPrevSyncRecordByVault,
|
||||
clearAllSyncPlanRecords,
|
||||
destroyDBs,
|
||||
upsertLastFailedSyncTimeByVault,
|
||||
upsertLastSuccessSyncTimeByVault,
|
||||
} from "./localdb";
|
||||
import type RemotelySavePlugin from "./main"; // unavoidable
|
||||
@ -2134,7 +2135,12 @@ export class RemotelySaveSettingTab extends PluginSettingTab {
|
||||
this.plugin.vaultRandomID,
|
||||
-1
|
||||
);
|
||||
this.plugin.updateLastSuccessSyncMsg(-1);
|
||||
await upsertLastFailedSyncTimeByVault(
|
||||
this.plugin.db,
|
||||
this.plugin.vaultRandomID,
|
||||
-1
|
||||
);
|
||||
this.plugin.updateLastSyncMsg(undefined, null, null);
|
||||
new Notice(t("settings_resetstatusbar_notice"));
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
Reference in New Issue
Block a user