Preserve legacy settings across same-profile upgrades

This commit is contained in:
vorotamoroz
2026-07-22 06:21:54 +00:00
parent c669f64933
commit aad0e56f09
22 changed files with 2258 additions and 167 deletions
+17 -25
View File
@@ -6,16 +6,10 @@ import {
DATABASE_COMPATIBILITY_VERSION_KEY,
evaluateCompatibilityPause,
legacyDatabaseCompatibilityVersionKey,
requiresFilenameCaseSensitivityDecision,
type CompatibilityPause,
} from "@/common/databaseCompatibility.ts";
export type CompatibilityReviewSummaryAction =
| "details"
| "resume"
| "use-case-sensitive"
| "keep-paused"
| false;
export type CompatibilityReviewSummaryAction = "details" | "resume" | "keep-paused" | false;
export type CompatibilityReviewDetailsAction = "back" | false;
// Explicit flag-file recovery runs at priorities 5, 10, and 20. Present the
@@ -68,11 +62,25 @@ export class CompatibilityReviewController {
if (this.disposed) return true;
const setting = this.core.services.setting;
const settings = setting.currentSettings();
const migrationState = setting.getSettingsMigrationState();
// An existing unconfigured Vault cannot replicate, so a database
// compatibility pause would only compete with onboarding and persist
// a misleading sync warning. Do not acknowledge the missing marker:
// activation on a later start must evaluate the same state again.
// Genuinely new Vaults still initialise their marker below.
if (settings.isConfigured !== true && migrationState?.isNewVault !== true) {
this.pause = undefined;
this.ui.clearReminder();
this._initialised = true;
return true;
}
const acknowledgedVersion = this.readAcknowledgedVersion();
const evaluation = evaluateCompatibilityPause({
acknowledgedVersion,
currentVersion: this.currentVersion,
migrationState: setting.getSettingsMigrationState(),
migrationState,
legacyReviewMessage: settings.versionUpFlash,
});
@@ -95,26 +103,16 @@ export class CompatibilityReviewController {
return true;
}
private async acknowledge(options: { useCaseSensitiveFilenames?: boolean } = {}): Promise<void> {
private async acknowledge(): Promise<void> {
if (!this.pause?.resumable) return;
const setting = this.core.services.setting;
const settings = setting.currentSettings();
const previousMessage = settings.versionUpFlash;
const hadFilenameCaseDecision = typeof settings.handleFilenameCaseSensitive === "boolean";
const previousFilenameCaseDecision = settings.handleFilenameCaseSensitive;
if (options.useCaseSensitiveFilenames) {
settings.handleFilenameCaseSensitive = true;
}
settings.versionUpFlash = "";
try {
await setting.saveSettingData();
} catch (error) {
settings.versionUpFlash = previousMessage || COMPATIBILITY_PAUSE_SETTING_MESSAGE;
if (hadFilenameCaseDecision) {
settings.handleFilenameCaseSensitive = previousFilenameCaseDecision;
} else {
delete (settings as Partial<typeof settings>).handleFilenameCaseSensitive;
}
throw error;
}
@@ -135,15 +133,9 @@ export class CompatibilityReviewController {
break;
}
if (action === "resume" && this.pause.resumable) {
if (requiresFilenameCaseSensitivityDecision(this.pause)) break;
await this.acknowledge();
return;
}
if (action === "use-case-sensitive" && this.pause.resumable) {
if (!requiresFilenameCaseSensitivityDecision(this.pause)) break;
await this.acknowledge({ useCaseSensitiveFilenames: true });
return;
}
break;
}
if (this.pause && !this.disposed) {