feat: keep list rows plain instead of tinting them by tag by default

This commit is contained in:
Linus Rath
2026-10-31 01:32:29 +01:00
parent 99aff47d6e
commit ced40c7e5c
2 changed files with 65 additions and 4 deletions
@@ -0,0 +1,46 @@
import { beforeEach, describe, it, expect } from 'vitest';
import { useSettingsStore, migrateSettings } from '../settings-store';
// List rows are plain by default; tinting them by the first tag color was
// the default before.
const migrate = (state: Record<string, unknown>, version: number) =>
migrateSettings(state, version) as unknown as Record<string, unknown>;
describe('tint list rows by tag default', () => {
beforeEach(() => {
useSettingsStore.getState().resetToDefaults();
});
it('keeps rows plain on a fresh install', () => {
expect(useSettingsStore.getState().tintListRowsByTag).toBe(false);
});
it('turns off a tint the user never switched on', () => {
expect(migrate({ tintListRowsByTag: true, explicitSettings: [] }, 10).tintListRowsByTag).toBe(false);
});
it('keeps a tint the user switched on', () => {
const out = migrate({ tintListRowsByTag: true, explicitSettings: ['tintListRowsByTag'] }, 10);
expect(out.tintListRowsByTag).toBe(true);
});
it('does not take the tint from before explicitSettings existed as chosen', () => {
const out = migrate({ tintListRowsByTag: true }, 7);
expect(out.tintListRowsByTag).toBe(false);
expect(out.explicitSettings).not.toContain('tintListRowsByTag');
});
it('turns the tint off in a server copy or export from an older build', () => {
const store = useSettingsStore.getState();
expect(store.importSettings(JSON.stringify({ tintListRowsByTag: true, explicitSettings: [] }))).toBe(true);
expect(useSettingsStore.getState().tintListRowsByTag).toBe(false);
expect(store.importSettings(JSON.stringify({ tintListRowsByTag: true }))).toBe(true);
expect(useSettingsStore.getState().tintListRowsByTag).toBe(false);
expect(useSettingsStore.getState().explicitSettings).not.toContain('tintListRowsByTag');
expect(store.importSettings(JSON.stringify({ tintListRowsByTag: true, explicitSettings: ['tintListRowsByTag'] }))).toBe(true);
expect(useSettingsStore.getState().tintListRowsByTag).toBe(true);
});
});
+19 -4
View File
@@ -984,7 +984,7 @@ const DEFAULT_SETTINGS = {
// Sidebar
colorfulSidebarIcons: true,
tintListRowsByTag: true,
tintListRowsByTag: false,
tintListRowsByAccount: false,
showAccountDot: true,
showFolderTotalCount: true,
@@ -1496,6 +1496,7 @@ export const useSettingsStore = create<SettingsState>()(
}
migrateAnimationsSetting(settings);
migrateNotificationSoundDefault(settings);
migrateTintListRowsDefault(settings);
// Apply settings, noting which keys were taken over for the
// onSettingsImport hook.
@@ -1897,7 +1898,7 @@ export const useSettingsStore = create<SettingsState>()(
},
{
name: 'settings-storage',
version: 10,
version: 11,
migrate: migrateSettings,
onRehydrateStorage: () => {
return (state) => {
@@ -1995,9 +1996,11 @@ export function migrateSettings(persisted: unknown, version: number): SettingsSt
if (version < 6 || !isPlainRecord(state.preferredIdentityIds)) {
state.preferredIdentityIds = {};
}
// Before the v8 step: a beep from before explicitSettings existed was
// the default then, and must not be taken as chosen below.
// Before the v8 step: a beep or a tinted list from before
// explicitSettings existed was the default then, and must not be
// taken as chosen below.
migrateNotificationSoundDefault(state);
migrateTintListRowsDefault(state);
// v8: admin policy defaults (#1248) skip settings the user chose.
// Earlier builds did not record that, so a setting that differs from
// the build default is taken as chosen.
@@ -2036,6 +2039,18 @@ export function migrateNotificationSoundDefault(state: Record<string, unknown>):
if (!chosen) state.notificationSoundChoice = 'involved';
}
/**
* v11: list rows no longer take their first tag's color by default. A tint
* the user never switched on was only the old default and goes; one they
* switched on stays. Imports and server copies from older builds still
* carry the tint and go through this too.
*/
export function migrateTintListRowsDefault(state: Record<string, unknown>): void {
if (state.tintListRowsByTag !== true) return;
const chosen = Array.isArray(state.explicitSettings) && state.explicitSettings.includes('tintListRowsByTag');
if (!chosen) state.tintListRowsByTag = false;
}
// Helper functions to apply settings to DOM
/** The settings applyAccessibilityTo() writes onto <html>. */