From a06b9eefaa550b2fa67ad661384d431cc842bfc2 Mon Sep 17 00:00:00 2001
From: syuilo <4439005+syuilo@users.noreply.github.com>
Date: Wed, 12 Mar 2025 21:05:39 +0900
Subject: [PATCH] enhance(frontend): suppress needless confirmation when turn
 on pref sync

---
 packages/frontend/src/preferences/manager.ts |  3 +-
 packages/frontend/src/utility/deep-equal.ts  | 29 ++++++++++++++++++++
 2 files changed, 31 insertions(+), 1 deletion(-)
 create mode 100644 packages/frontend/src/utility/deep-equal.ts

diff --git a/packages/frontend/src/preferences/manager.ts b/packages/frontend/src/preferences/manager.ts
index 9866227d93..3f3eba6389 100644
--- a/packages/frontend/src/preferences/manager.ts
+++ b/packages/frontend/src/preferences/manager.ts
@@ -13,6 +13,7 @@ import { $i } from '@/account.js';
 import { copyToClipboard } from '@/utility/copy-to-clipboard.js';
 import { i18n } from '@/i18n.js';
 import * as os from '@/os.js';
+import { deepEqual } from '@/utility/deep-equal.js';
 
 // NOTE: 明示的な設定値のひとつとして null もあり得るため、設定が存在しないかどうかを判定する目的で null で比較したり ?? を使ってはいけない
 
@@ -340,7 +341,7 @@ export class ProfileManager {
 		const record = this.getMatchedRecordOf(key);
 
 		const existing = await this.storageProvider.cloudGet({ key, cond: record[0] });
-		if (existing != null) {
+		if (existing != null && !deepEqual(existing.value, record[1])) {
 			const { canceled, result } = await os.select({
 				title: i18n.ts.preferenceSyncConflictTitle,
 				text: i18n.ts.preferenceSyncConflictText,
diff --git a/packages/frontend/src/utility/deep-equal.ts b/packages/frontend/src/utility/deep-equal.ts
new file mode 100644
index 0000000000..c64d82c6cc
--- /dev/null
+++ b/packages/frontend/src/utility/deep-equal.ts
@@ -0,0 +1,29 @@
+/*
+ * SPDX-FileCopyrightText: syuilo and misskey-project
+ * SPDX-License-Identifier: AGPL-3.0-only
+ */
+
+export function deepEqual(a: any, b: any): boolean {
+	if (a === b) return true;
+
+	if (a === null) return b === null;
+
+	if (Array.isArray(a) && Array.isArray(b)) {
+		if (a.length !== b.length) return false;
+		for (let i = 0; i < a.length; i++) {
+			if (!deepEqual(a[i], b[i])) return false;
+		}
+		return true;
+	} else if (((typeof a) === 'object') && ((typeof b) === 'object')) {
+		const aks = Object.keys(a);
+		const bks = Object.keys(b);
+		if (aks.length !== bks.length) return false;
+		for (let i = 0; i < aks.length; i++) {
+			const k = aks[i];
+			if (!deepEqual(a[k], b[k])) return false;
+		}
+		return true;
+	}
+
+	return false;
+}