From f3805952762fcaa9ce07bde6d4b4af35222fffea Mon Sep 17 00:00:00 2001 From: mattsigal Date: Sat, 25 Jul 2026 11:45:00 -0700 Subject: [PATCH 1/3] =?UTF-8?q?=EF=BB=BFfix(sync):=20prevent=20home=20row?= =?UTF-8?q?=20toggles=20re-enabling=20loop=20during=20profile=20sync?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix feedback loop where omitted server built-in sections were re-created as enabled: true by _appendDisabledBuiltinSections due to reading default true boolean preferences. - Append missing built-in home sections as enabled: false in _appendDisabledBuiltinSections and explicitly update their toggle preferences. - Add missing sinceYouWatched1..5 mappings to _rowEnabledPreference. --- lib/data/services/plugin_sync_service.dart | 37 ++++++++++------------ 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/lib/data/services/plugin_sync_service.dart b/lib/data/services/plugin_sync_service.dart index 1dbc284d9..ee46e2cfc 100644 --- a/lib/data/services/plugin_sync_service.dart +++ b/lib/data/services/plugin_sync_service.dart @@ -1315,29 +1315,14 @@ class PluginSyncService extends ChangeNotifier { if (type == prefs.HomeSectionType.none || present.contains(type)) { continue; } - - var isEnabled = false; - if (type == prefs.HomeSectionType.rewatch) { - isEnabled = _prefs.get(UserPreferences.displayRewatchRow); - } else if (type == prefs.HomeSectionType.sinceYouWatched1 || - type == prefs.HomeSectionType.sinceYouWatched2 || - type == prefs.HomeSectionType.sinceYouWatched3 || - type == prefs.HomeSectionType.sinceYouWatched4 || - type == prefs.HomeSectionType.sinceYouWatched5) { - final localPref = switch (type) { - prefs.HomeSectionType.sinceYouWatched1 => UserPreferences.sinceYouWatched1Enabled, - prefs.HomeSectionType.sinceYouWatched2 => UserPreferences.sinceYouWatched2Enabled, - prefs.HomeSectionType.sinceYouWatched3 => UserPreferences.sinceYouWatched3Enabled, - prefs.HomeSectionType.sinceYouWatched4 => UserPreferences.sinceYouWatched4Enabled, - prefs.HomeSectionType.sinceYouWatched5 => UserPreferences.sinceYouWatched5Enabled, - _ => throw StateError('Invalid type'), - }; - isEnabled = _prefs.get(localPref); - } - + sections.add( - HomeSectionConfig(type: type, enabled: isEnabled, order: order++), + HomeSectionConfig(type: type, enabled: false, order: order++), ); + final toggle = _rowEnabledPreference(type); + if (toggle != null) { + _prefs.set(toggle, false); + } } return order; } @@ -1715,6 +1700,16 @@ class PluginSyncService extends ChangeNotifier { prefs.HomeSectionType.sonarrCalendar => UserPreferences.enableSonarrCalendar, prefs.HomeSectionType.rewatch => UserPreferences.displayRewatchRow, + prefs.HomeSectionType.sinceYouWatched1 => + UserPreferences.sinceYouWatched1Enabled, + prefs.HomeSectionType.sinceYouWatched2 => + UserPreferences.sinceYouWatched2Enabled, + prefs.HomeSectionType.sinceYouWatched3 => + UserPreferences.sinceYouWatched3Enabled, + prefs.HomeSectionType.sinceYouWatched4 => + UserPreferences.sinceYouWatched4Enabled, + prefs.HomeSectionType.sinceYouWatched5 => + UserPreferences.sinceYouWatched5Enabled, _ => null, }; } From 360c9eb769363f34b0114b24345562c23f3edafc Mon Sep 17 00:00:00 2001 From: mattsigal Date: Sun, 26 Jul 2026 07:27:11 -0700 Subject: [PATCH 2/3] Extend safety sync behaviour to currently unprotected External Lists as well --- lib/data/services/plugin_sync_service.dart | 13 +++++++++++++ lib/preference/seerr_preferences.dart | 6 ++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/lib/data/services/plugin_sync_service.dart b/lib/data/services/plugin_sync_service.dart index ee46e2cfc..53cc9fece 100644 --- a/lib/data/services/plugin_sync_service.dart +++ b/lib/data/services/plugin_sync_service.dart @@ -1126,6 +1126,7 @@ class PluginSyncService extends ChangeNotifier { } _appendDisabledBuiltinSections(sections, order); await _prefs.setHomeSectionsConfig(sections); + _syncSeerrHomeRowsWithSections(sections); appliedHomeSections = true; } } @@ -1302,6 +1303,7 @@ class PluginSyncService extends ChangeNotifier { } await _prefs.setHomeSectionsConfig(sections); + _syncSeerrHomeRowsWithSections(sections); } /// Appends a disabled entry for every built-in HomeSectionType not already in @@ -1327,6 +1329,17 @@ class PluginSyncService extends ChangeNotifier { return order; } + void _syncSeerrHomeRowsWithSections(List sections) { + final currentHomeRows = _seerrPrefs.homeRowsConfig; + final updated = currentHomeRows.map((row) { + final idx = sections.indexWhere((s) => s.type == row.type.homeSectionType); + return idx >= 0 + ? row.copyWith(enabled: sections[idx].enabled) + : row.copyWith(enabled: false); + }).toList(); + _seerrPrefs.setHomeRowsConfig(updated); + } + /// Applies one table-driven field from an incoming profile. void _applySyncedField(Map data, SyncedField field) { switch (field.codec) { diff --git a/lib/preference/seerr_preferences.dart b/lib/preference/seerr_preferences.dart index e2c621f36..ddca13e77 100644 --- a/lib/preference/seerr_preferences.dart +++ b/lib/preference/seerr_preferences.dart @@ -134,7 +134,9 @@ class SeerrPreferences { final sections = HomeSectionConfig.fromJsonString(sectionsJson); return SeerrRowConfig.defaults().map((row) { final idx = sections.indexWhere((s) => s.type == row.type.homeSectionType); - return idx >= 0 ? row.copyWith(enabled: sections[idx].enabled) : row; + return idx >= 0 + ? row.copyWith(enabled: sections[idx].enabled) + : row.copyWith(enabled: false); }).toList(); } @@ -143,7 +145,7 @@ class SeerrPreferences { if (seerrType == null || !enabled) return false; final config = homeRowsConfig.firstWhere( (c) => c.type == seerrType, - orElse: () => SeerrRowConfig(type: seerrType, enabled: true, order: 0), + orElse: () => SeerrRowConfig(type: seerrType, enabled: false, order: 0), ); return config.enabled; } From 9b2db01cae9fb3fd960518689043b269567e998a Mon Sep 17 00:00:00 2001 From: RadicalMuffinMan <103554043+RadicalMuffinMan@users.noreply.github.com> Date: Wed, 29 Jul 2026 10:28:39 -0400 Subject: [PATCH 3/3] stop home rows re-enabling on every profile sync --- lib/data/services/plugin_sync_service.dart | 41 +++++++++++++--------- lib/preference/home_section_config.dart | 33 +++++++++++++++++ lib/preference/seerr_preferences.dart | 4 +-- 3 files changed, 59 insertions(+), 19 deletions(-) diff --git a/lib/data/services/plugin_sync_service.dart b/lib/data/services/plugin_sync_service.dart index 53cc9fece..5c24279d4 100644 --- a/lib/data/services/plugin_sync_service.dart +++ b/lib/data/services/plugin_sync_service.dart @@ -1126,7 +1126,7 @@ class PluginSyncService extends ChangeNotifier { } _appendDisabledBuiltinSections(sections, order); await _prefs.setHomeSectionsConfig(sections); - _syncSeerrHomeRowsWithSections(sections); + await _syncSeerrHomeRowsWithSections(sections); appliedHomeSections = true; } } @@ -1202,6 +1202,7 @@ class PluginSyncService extends ChangeNotifier { sections.add(entry.copyWith(order: order++)); } await _prefs.setHomeSectionsConfig(sections); + await _syncSeerrHomeRowsWithSections(sections); } } } @@ -1303,11 +1304,16 @@ class PluginSyncService extends ChangeNotifier { } await _prefs.setHomeSectionsConfig(sections); - _syncSeerrHomeRowsWithSections(sections); + await _syncSeerrHomeRowsWithSections(sections); } /// Appends a disabled entry for every built-in HomeSectionType not already in /// [sections] so the settings UI shows every toggle. Returns the next order. + /// + /// A section the profile doesn't mention carries no opinion, so it lands + /// disabled rather than being re-derived from a toggle preference that + /// defaults to on. The preferences stay untouched because the profile's own + /// synced fields already set them, and writing false would push that back. int _appendDisabledBuiltinSections( List sections, int order, @@ -1317,27 +1323,30 @@ class PluginSyncService extends ChangeNotifier { if (type == prefs.HomeSectionType.none || present.contains(type)) { continue; } - sections.add( HomeSectionConfig(type: type, enabled: false, order: order++), ); - final toggle = _rowEnabledPreference(type); - if (toggle != null) { - _prefs.set(toggle, false); - } } return order; } - void _syncSeerrHomeRowsWithSections(List sections) { - final currentHomeRows = _seerrPrefs.homeRowsConfig; - final updated = currentHomeRows.map((row) { - final idx = sections.indexWhere((s) => s.type == row.type.homeSectionType); - return idx >= 0 - ? row.copyWith(enabled: sections[idx].enabled) - : row.copyWith(enabled: false); - }).toList(); - _seerrPrefs.setHomeRowsConfig(updated); + /// Seerr home rows keep their own copy of the enabled state that the settings + /// screens write alongside the section layout, so mirror it here too. Without + /// this the home view gates Seerr rows on stale values after a sync. + Future _syncSeerrHomeRowsWithSections( + List sections, + ) async { + final enabledByType = { + for (final section in sections) section.type: section.enabled, + }; + final updated = _seerrPrefs.homeRowsConfig + .map( + (row) => row.copyWith( + enabled: enabledByType[row.type.homeSectionType] ?? false, + ), + ) + .toList(); + await _seerrPrefs.setHomeRowsConfig(updated); } /// Applies one table-driven field from an incoming profile. diff --git a/lib/preference/home_section_config.dart b/lib/preference/home_section_config.dart index 297df672f..df6f86812 100644 --- a/lib/preference/home_section_config.dart +++ b/lib/preference/home_section_config.dart @@ -326,6 +326,39 @@ class HomeSectionConfig { enabled: false, order: 39, ), + // These carry a toggle preference too, but they still need a section entry. + // Without one there was nowhere for turning the row off to persist, so the + // next sync kept bringing it back. + HomeSectionConfig( + type: HomeSectionType.sinceYouWatched1, + enabled: false, + order: 40, + ), + HomeSectionConfig( + type: HomeSectionType.sinceYouWatched2, + enabled: false, + order: 41, + ), + HomeSectionConfig( + type: HomeSectionType.sinceYouWatched3, + enabled: false, + order: 42, + ), + HomeSectionConfig( + type: HomeSectionType.sinceYouWatched4, + enabled: false, + order: 43, + ), + HomeSectionConfig( + type: HomeSectionType.sinceYouWatched5, + enabled: false, + order: 44, + ), + HomeSectionConfig( + type: HomeSectionType.rewatch, + enabled: false, + order: 45, + ), ]; static bool isSupportedJson(Map json) { diff --git a/lib/preference/seerr_preferences.dart b/lib/preference/seerr_preferences.dart index ddca13e77..5e41b4ad4 100644 --- a/lib/preference/seerr_preferences.dart +++ b/lib/preference/seerr_preferences.dart @@ -134,9 +134,7 @@ class SeerrPreferences { final sections = HomeSectionConfig.fromJsonString(sectionsJson); return SeerrRowConfig.defaults().map((row) { final idx = sections.indexWhere((s) => s.type == row.type.homeSectionType); - return idx >= 0 - ? row.copyWith(enabled: sections[idx].enabled) - : row.copyWith(enabled: false); + return idx >= 0 ? row.copyWith(enabled: sections[idx].enabled) : row; }).toList(); }