mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-09-10 02:25:56 +00:00
Always apply the server full-width mode after auth (#1130)
Back-port v5 fix 6c3a2cd70 to v6. Adds layoutStore.applyServerMode, which
applies the server's canonical fullWidthMode authoritatively (even when a
local preference exists), and the post-auth path now calls it with the
already-fetched system settings instead of loadFromServer() — which made a
redundant API call and short-circuited on any stale localStorage entry, so
a user's server-side full-width setting was not honored after login/reload.
Exports createLayoutStore and adds a regression test.
This commit is contained in:
@@ -279,7 +279,10 @@ export const useAppRuntimeState = () => {
|
||||
updateSystemSettingsFromResponse(systemSettings);
|
||||
applyServerThemeIfAllowed(systemSettings.theme);
|
||||
setHasLoadedServerTheme(true);
|
||||
layoutStore.loadFromServer();
|
||||
// Apply the server's canonical full-width mode using the settings we just
|
||||
// fetched, so it is honored after auth even if a stale localStorage
|
||||
// preference exists (#1130) — loadFromServer() would short-circuit on it.
|
||||
layoutStore.applyServerMode(systemSettings.fullWidthMode);
|
||||
} catch (error) {
|
||||
logger.error('Failed to load system settings from server', error);
|
||||
markSystemSettingsLoadedWithDefaults();
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
vi.mock('@/api/settings', () => ({
|
||||
SettingsAPI: { getSystemSettings: vi.fn() },
|
||||
}));
|
||||
|
||||
vi.mock('@/utils/logger', () => ({
|
||||
logger: { debug: vi.fn(), info: vi.fn(), warn: vi.fn(), error: vi.fn() },
|
||||
}));
|
||||
|
||||
import { createLayoutStore } from '@/utils/layout';
|
||||
import { STORAGE_KEYS } from '@/utils/localStorage';
|
||||
|
||||
describe('layout store applyServerMode (#1130)', () => {
|
||||
beforeEach(() => {
|
||||
localStorage.clear();
|
||||
});
|
||||
|
||||
it('applies the server full-width value even when a stale local preference exists', () => {
|
||||
// Stale local preference that loadFromServer() would otherwise honor.
|
||||
localStorage.setItem(STORAGE_KEYS.FULL_WIDTH_MODE, 'default');
|
||||
|
||||
const store = createLayoutStore();
|
||||
expect(store.isFullWidth()).toBe(false);
|
||||
|
||||
store.applyServerMode(true);
|
||||
|
||||
expect(store.isFullWidth()).toBe(true);
|
||||
expect(localStorage.getItem(STORAGE_KEYS.FULL_WIDTH_MODE)).toBe('full-width');
|
||||
});
|
||||
|
||||
it('applies a server default that overrides a local full-width preference', () => {
|
||||
localStorage.setItem(STORAGE_KEYS.FULL_WIDTH_MODE, 'full-width');
|
||||
|
||||
const store = createLayoutStore();
|
||||
expect(store.isFullWidth()).toBe(true);
|
||||
|
||||
store.applyServerMode(false);
|
||||
|
||||
expect(store.isFullWidth()).toBe(false);
|
||||
});
|
||||
|
||||
it('leaves the current mode unchanged when the server value is undefined', () => {
|
||||
localStorage.setItem(STORAGE_KEYS.FULL_WIDTH_MODE, 'full-width');
|
||||
|
||||
const store = createLayoutStore();
|
||||
store.applyServerMode(undefined);
|
||||
|
||||
expect(store.isFullWidth()).toBe(true);
|
||||
});
|
||||
});
|
||||
@@ -12,7 +12,7 @@ export type LayoutMode = 'default' | 'full-width';
|
||||
* Creates a reactive store for layout mode preference
|
||||
* Syncs with both localStorage (for immediate access) and server (for persistence across updates)
|
||||
*/
|
||||
function createLayoutStore() {
|
||||
export function createLayoutStore() {
|
||||
const stored = localStorage.getItem(STORAGE_KEYS.FULL_WIDTH_MODE);
|
||||
const initialMode: LayoutMode = stored === 'full-width' ? 'full-width' : 'default';
|
||||
|
||||
@@ -38,6 +38,22 @@ function createLayoutStore() {
|
||||
|
||||
const isFullWidth = () => mode() === 'full-width';
|
||||
|
||||
/**
|
||||
* Apply the server's canonical full-width preference (called after auth with
|
||||
* the already-fetched system settings). Unlike loadFromServer this is
|
||||
* authoritative: it applies the server value even when a local preference
|
||||
* exists, so the server setting is honored after login/reload (#1130).
|
||||
*/
|
||||
const applyServerMode = (serverFullWidthMode: boolean | undefined) => {
|
||||
if (serverFullWidthMode !== undefined) {
|
||||
const serverMode: LayoutMode = serverFullWidthMode ? 'full-width' : 'default';
|
||||
localStorage.setItem(STORAGE_KEYS.FULL_WIDTH_MODE, serverMode);
|
||||
setModeInternal(serverMode);
|
||||
logger.debug('Applied full-width mode from server', { mode: serverMode });
|
||||
}
|
||||
setHasLoadedFromServer(true);
|
||||
};
|
||||
|
||||
/**
|
||||
* Load full-width preference from server (called after auth)
|
||||
* Only uses server preference if no local preference exists
|
||||
@@ -50,13 +66,7 @@ function createLayoutStore() {
|
||||
|
||||
try {
|
||||
const settings = await SettingsAPI.getSystemSettings();
|
||||
if (settings.fullWidthMode !== undefined) {
|
||||
const serverMode: LayoutMode = settings.fullWidthMode ? 'full-width' : 'default';
|
||||
localStorage.setItem(STORAGE_KEYS.FULL_WIDTH_MODE, serverMode);
|
||||
setModeInternal(serverMode);
|
||||
logger.debug('Loaded full-width mode from server', { mode: serverMode });
|
||||
}
|
||||
setHasLoadedFromServer(true);
|
||||
applyServerMode(settings.fullWidthMode);
|
||||
} catch (error) {
|
||||
logger.warn('Failed to load full-width mode from server', error);
|
||||
}
|
||||
@@ -67,6 +77,7 @@ function createLayoutStore() {
|
||||
setMode,
|
||||
toggle,
|
||||
isFullWidth,
|
||||
applyServerMode,
|
||||
loadFromServer,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user