summaryrefslogtreecommitdiff
path: root/packages/frontend/src/preferences/manager.ts
diff options
context:
space:
mode:
authorsyuilo <4439005+syuilo@users.noreply.github.com>2025-05-31 14:15:40 +0900
committersyuilo <4439005+syuilo@users.noreply.github.com>2025-05-31 14:15:40 +0900
commit743995e4695af1ade073172f87fc91f1c9b37ba8 (patch)
tree121e0208eda42498b6b5f3565b11a47bcdcfb1db /packages/frontend/src/preferences/manager.ts
parentenhance(frontend): 設定の同期をオンにするときに競合したと... (diff)
downloadmisskey-743995e4695af1ade073172f87fc91f1c9b37ba8.tar.gz
misskey-743995e4695af1ade073172f87fc91f1c9b37ba8.tar.bz2
misskey-743995e4695af1ade073172f87fc91f1c9b37ba8.zip
enhance(frontend): make pref sync more smart
Diffstat (limited to 'packages/frontend/src/preferences/manager.ts')
-rw-r--r--packages/frontend/src/preferences/manager.ts50
1 files changed, 38 insertions, 12 deletions
diff --git a/packages/frontend/src/preferences/manager.ts b/packages/frontend/src/preferences/manager.ts
index 016e1ad85b..ccb8ea0372 100644
--- a/packages/frontend/src/preferences/manager.ts
+++ b/packages/frontend/src/preferences/manager.ts
@@ -377,14 +377,12 @@ export class PreferencesManager {
public async enableSync<K extends keyof PREF>(key: K): Promise<{ enabled: boolean; } | null> {
if (this.isSyncEnabled(key)) return Promise.resolve(null);
- const record = this.getMatchedRecordOf(key);
-
- const existing = await this.storageProvider.cloudGet({ key, scope: record[0] });
- if (existing != null && !deepEqual(existing.value, record[1])) {
+ // undefined ... cancel
+ async function resolveConflict(local: ValueOf<K>, remote: ValueOf<K>): Promise<ValueOf<K> | undefined> {
const merge = (PREF_DEF as PreferencesDefinition)[key].mergeStrategy;
let mergedValue: ValueOf<K> | undefined = undefined; // null と区別したいため
try {
- if (merge != null) mergedValue = merge(record[1], existing.value);
+ if (merge != null) mergedValue = merge(local, remote);
} catch (err) {
// nop
}
@@ -406,23 +404,51 @@ export class PreferencesManager {
}],
default: mergedValue !== undefined ? 'merge' : 'remote',
});
- if (canceled || choice == null) return { enabled: false };
+ if (canceled || choice == null) return undefined;
if (choice === 'remote') {
- this.commit(key, existing.value);
+ return remote;
} else if (choice === 'local') {
- // nop
+ return local;
} else if (choice === 'merge') {
- this.commit(key, mergedValue!);
+ return mergedValue!;
}
}
+ const record = this.getMatchedRecordOf(key);
+
+ let newValue = record[1];
+
+ const existing = await this.storageProvider.cloudGet({ key, scope: record[0] });
+ if (existing != null && !deepEqual(record[1], existing.value)) {
+ const resolvedValue = await resolveConflict(record[1], existing.value);
+ if (resolvedValue === undefined) return { enabled: false }; // canceled
+ newValue = resolvedValue;
+ }
+
+ this.commit(key, newValue);
+
+ const done = os.waiting();
+
+ try {
+ await this.storageProvider.cloudSet({ key, scope: record[0], value: newValue });
+ } catch (err) {
+ done();
+
+ os.alert({
+ type: 'error',
+ title: i18n.ts.somethingHappened,
+ text: err,
+ });
+
+ return { enabled: false };
+ }
+
+ done({ success: true });
+
record[2].sync = true;
this.save();
- // awaitの必要性は無い
- this.storageProvider.cloudSet({ key, scope: record[0], value: this.s[key] });
-
return { enabled: true };
}