summaryrefslogtreecommitdiff
path: root/packages/frontend/src
diff options
context:
space:
mode:
authorsyuilo <4439005+syuilo@users.noreply.github.com>2025-05-31 16:33:03 +0900
committersyuilo <4439005+syuilo@users.noreply.github.com>2025-05-31 16:33:03 +0900
commitaa4c7a1313a9f3e31df6190d66e8665e8d736574 (patch)
tree948c17bfbe6a2203ee0823c9eef7786229101a6b /packages/frontend/src
parentenhance(frontend): make pref sync more smart (diff)
downloadmisskey-aa4c7a1313a9f3e31df6190d66e8665e8d736574.tar.gz
misskey-aa4c7a1313a9f3e31df6190d66e8665e8d736574.tar.bz2
misskey-aa4c7a1313a9f3e31df6190d66e8665e8d736574.zip
fix(frontend): アカウント依存かつ初期状態である設定値をサーバー同期しようとした際に正しくコンフリクト検出されない問題を修正
Diffstat (limited to 'packages/frontend/src')
-rw-r--r--packages/frontend/src/preferences/manager.ts64
1 files changed, 48 insertions, 16 deletions
diff --git a/packages/frontend/src/preferences/manager.ts b/packages/frontend/src/preferences/manager.ts
index ccb8ea0372..cede145e74 100644
--- a/packages/frontend/src/preferences/manager.ts
+++ b/packages/frontend/src/preferences/manager.ts
@@ -104,6 +104,8 @@ export function getInitialPrefValue<K extends keyof PREF>(k: K): ValueOf<K> {
}
}
+// TODO: PreferencesManagerForGuest のような非ログイン専用のクラスを分離すれば$iのnullチェックやaccountがnullであるスコープのレコード挿入などが不要になり綺麗になるかもしれない
+// NOTE: accountDependentな設定は初期状態であってもアカウントごとのスコープでレコードを作成しておかないと、サーバー同期する際に正しく動作しなくなる
export class PreferencesManager {
private storageProvider: StorageProvider;
public profile: PreferencesProfile;
@@ -139,11 +141,11 @@ export class PreferencesManager {
// TODO: 定期的にクラウドの値をフェッチ
}
- private isAccountDependentKey<K extends keyof PREF>(key: K): boolean {
+ private static isAccountDependentKey<K extends keyof PREF>(key: K): boolean {
return (PREF_DEF as PreferencesDefinition)[key].accountDependent === true;
}
- private isServerDependentKey<K extends keyof PREF>(key: K): boolean {
+ private static isServerDependentKey<K extends keyof PREF>(key: K): boolean {
return (PREF_DEF as PreferencesDefinition)[key].serverDependent === true;
}
@@ -166,7 +168,7 @@ export class PreferencesManager {
const record = this.getMatchedRecordOf(key);
- if (parseScope(record[0]).account == null && this.isAccountDependentKey(key)) {
+ if (parseScope(record[0]).account == null && PreferencesManager.isAccountDependentKey(key)) {
this.profile.preferences[key].push([makeScope({
server: host,
account: $i!.id,
@@ -175,7 +177,7 @@ export class PreferencesManager {
return;
}
- if (parseScope(record[0]).server == null && this.isServerDependentKey(key)) {
+ if (parseScope(record[0]).server == null && PreferencesManager.isServerDependentKey(key)) {
this.profile.preferences[key].push([makeScope({
server: host,
}), v, {}]);
@@ -276,7 +278,19 @@ export class PreferencesManager {
public static newProfile(): PreferencesProfile {
const data = {} as PreferencesProfile['preferences'];
for (const key in PREF_DEF) {
- data[key] = [[makeScope({}), getInitialPrefValue(key as keyof typeof PREF_DEF), {}]];
+ const v = getInitialPrefValue(key as keyof typeof PREF_DEF);
+ if (PreferencesManager.isAccountDependentKey(key as keyof typeof PREF_DEF)) {
+ data[key] = $i ? [[makeScope({}), v, {}], [makeScope({
+ server: host,
+ account: $i.id,
+ }), v, {}]] : [[makeScope({}), v, {}]];
+ } else if (PreferencesManager.isServerDependentKey(key as keyof typeof PREF_DEF)) {
+ data[key] = [[makeScope({
+ server: host,
+ }), v, {}]];
+ } else {
+ data[key] = [[makeScope({}), v, {}]];
+ }
}
return {
id: uuid(),
@@ -293,18 +307,36 @@ export class PreferencesManager {
for (const key in PREF_DEF) {
const records = profileLike.preferences[key];
if (records == null || records.length === 0) {
- data[key] = [[makeScope({}), getInitialPrefValue(key as keyof typeof PREF_DEF), {}]];
+ const v = getInitialPrefValue(key as keyof typeof PREF_DEF);
+ if (PreferencesManager.isAccountDependentKey(key as keyof typeof PREF_DEF)) {
+ data[key] = $i ? [[makeScope({}), v, {}], [makeScope({
+ server: host,
+ account: $i.id,
+ }), v, {}]] : [[makeScope({}), v, {}]];
+ } else if (PreferencesManager.isServerDependentKey(key as keyof typeof PREF_DEF)) {
+ data[key] = [[makeScope({
+ server: host,
+ }), v, {}]];
+ } else {
+ data[key] = [[makeScope({}), v, {}]];
+ }
continue;
} else {
- data[key] = records;
-
- // alpha段階ではmetaが無かったのでマイグレート
- // TODO: そのうち消す
- for (const record of data[key] as any[][]) {
- if (record.length === 2) {
- record.push({});
- }
+ if ($i && PreferencesManager.isAccountDependentKey(key as keyof typeof PREF_DEF) && !records.some(([scope]) => parseScope(scope).server === host && parseScope(scope).account === $i!.id)) {
+ data[key] = records.concat([[makeScope({
+ server: host,
+ account: $i.id,
+ }), getInitialPrefValue(key as keyof typeof PREF_DEF), {}]]);
+ continue;
+ }
+ if ($i && PreferencesManager.isServerDependentKey(key as keyof typeof PREF_DEF) && !records.some(([scope]) => parseScope(scope).server === host)) {
+ data[key] = records.concat([[makeScope({
+ server: host,
+ }), getInitialPrefValue(key as keyof typeof PREF_DEF), {}]]);
+ continue;
}
+
+ data[key] = records;
}
}
@@ -342,7 +374,7 @@ export class PreferencesManager {
public setAccountOverride<K extends keyof PREF>(key: K) {
if ($i == null) return;
- if (this.isAccountDependentKey(key)) throw new Error('already account-dependent');
+ if (PreferencesManager.isAccountDependentKey(key)) throw new Error('already account-dependent');
if (this.isAccountOverrided(key)) return;
const records = this.profile.preferences[key];
@@ -356,7 +388,7 @@ export class PreferencesManager {
public clearAccountOverride<K extends keyof PREF>(key: K) {
if ($i == null) return;
- if (this.isAccountDependentKey(key)) throw new Error('cannot clear override for this account-dependent property');
+ if (PreferencesManager.isAccountDependentKey(key)) throw new Error('cannot clear override for this account-dependent property');
const records = this.profile.preferences[key];