diff --git a/muxplex/frontend/app.js b/muxplex/frontend/app.js index 61d0efc..ae44883 100644 --- a/muxplex/frontend/app.js +++ b/muxplex/frontend/app.js @@ -1233,6 +1233,40 @@ function applyDisplaySettings(ds) { } } +/** + * Load grid view mode preference based on viewPreferenceScope in display settings. + * When scope is 'local' (default), reads gridViewMode from display settings (localStorage). + * When scope is 'server', reads grid_view_mode from _serverSettings. + * Returns 'flat' as default. + * @returns {string} + */ +function loadGridViewMode() { + var ds = loadDisplaySettings(); + var scope = ds.viewPreferenceScope || 'local'; + if (scope === 'server') { + return (_serverSettings && _serverSettings.grid_view_mode) || 'flat'; + } + return ds.gridViewMode || 'flat'; +} + +/** + * Save grid view mode preference to the appropriate scope and update _gridViewMode. + * When scope is 'local', saves gridViewMode to display settings (localStorage). + * When scope is 'server', patches the server setting via patchServerSetting. + * @param {string} mode - The grid view mode to save. + */ +function saveGridViewMode(mode) { + var ds = loadDisplaySettings(); + var scope = ds.viewPreferenceScope || 'local'; + if (scope === 'server') { + patchServerSetting('grid_view_mode', mode); + } else { + ds.gridViewMode = mode; + saveDisplaySettings(ds); + } + _gridViewMode = mode; +} + /** * Handle a change event on any Display settings control. * Reads current values from form elements, saves via saveDisplaySettings, @@ -1913,6 +1947,7 @@ function _setActiveFilterDevice(device) { document.addEventListener('DOMContentLoaded', () => { initDeviceId(); applyDisplaySettings(loadDisplaySettings()); + _gridViewMode = loadGridViewMode(); document.addEventListener('keydown', trackInteraction); document.addEventListener('click', trackInteraction); document.addEventListener('touchstart', trackInteraction); @@ -1981,6 +2016,8 @@ if (typeof module !== 'undefined' && module.exports) { loadDisplaySettings, saveDisplaySettings, applyDisplaySettings, + loadGridViewMode, + saveGridViewMode, onDisplaySettingChange, openSettings, closeSettings, diff --git a/muxplex/frontend/tests/test_app.mjs b/muxplex/frontend/tests/test_app.mjs index ba770ba..9c19d8f 100644 --- a/muxplex/frontend/tests/test_app.mjs +++ b/muxplex/frontend/tests/test_app.mjs @@ -2608,4 +2608,62 @@ test('renderFilterBar and _setActiveFilterDevice are exported', () => { assert.strictEqual(typeof app._setActiveFilterDevice, 'function', '_setActiveFilterDevice should be exported'); }); +// --- loadGridViewMode / saveGridViewMode (task-13) --- + +test('loadGridViewMode returns flat by default', () => { + // Clear display settings and server settings so everything is at defaults + _localStorageStore = {}; + app._setServerSettings(null); + + const mode = app.loadGridViewMode(); + assert.strictEqual(mode, 'flat', 'loadGridViewMode should return flat when no preference is set'); +}); + +test('loadGridViewMode reads from localStorage when scope is local', () => { + // Set display settings with viewPreferenceScope 'local' and gridViewMode 'grouped' + _localStorageStore = {}; + _localStorageStore['muxplex.display'] = JSON.stringify({ viewPreferenceScope: 'local', gridViewMode: 'grouped' }); + app._setServerSettings(null); + + const mode = app.loadGridViewMode(); + assert.strictEqual(mode, 'grouped', 'loadGridViewMode should return gridViewMode from localStorage when scope is local'); + + // Cleanup + _localStorageStore = {}; +}); + +test('loadGridViewMode reads from serverSettings when scope is server', () => { + // Set display settings with viewPreferenceScope 'server', server has grid_view_mode 'filtered' + _localStorageStore = {}; + _localStorageStore['muxplex.display'] = JSON.stringify({ viewPreferenceScope: 'server' }); + app._setServerSettings({ grid_view_mode: 'filtered' }); + + const mode = app.loadGridViewMode(); + assert.strictEqual(mode, 'filtered', 'loadGridViewMode should return grid_view_mode from serverSettings when scope is server'); + + // Cleanup + _localStorageStore = {}; + app._setServerSettings(null); +}); + +test('saveGridViewMode stores to localStorage when scope is local', () => { + // Set scope to local (default) + _localStorageStore = {}; + _localStorageStore['muxplex.display'] = JSON.stringify({ viewPreferenceScope: 'local' }); + app._setServerSettings(null); + + app.saveGridViewMode('grouped'); + + // Verify _gridViewMode was updated + assert.strictEqual(app._getGridViewMode(), 'grouped', '_gridViewMode should be set to grouped'); + + // Verify it was saved to localStorage display settings + const saved = JSON.parse(_localStorageStore['muxplex.display'] || '{}'); + assert.strictEqual(saved.gridViewMode, 'grouped', 'gridViewMode should be saved to localStorage display settings'); + + // Cleanup + _localStorageStore = {}; + app._setGridViewMode('flat'); +}); +