Skip to content

Commit 030ad44

Browse files
authored
feat: allow user to decide wheher recently viewed files should be automatically loaded
1 parent 0559e8b commit 030ad44

7 files changed

Lines changed: 155 additions & 97 deletions

File tree

index.html

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -481,6 +481,17 @@ <h3>Settings & Preferences</h3>
481481
</label>
482482
</div>
483483

484+
<div class="pref-item">
485+
<div class="pref-info">
486+
<span class="pref-title">Remember active files</span>
487+
<span class="pref-desc">Remember recently viewed files.</span>
488+
</div>
489+
<label class="switch">
490+
<input type="checkbox" id="pref-remember-files" checked />
491+
<span class="slider-round"></span>
492+
</label>
493+
</div>
494+
484495
<div class="pref-item">
485496
<div class="pref-info">
486497
<span class="pref-title">Show Area Fills</span>

src/entry.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { PaletteManager } from './palettemanager.js';
1313
import { xyAnalysis } from './xyanalysis.js';
1414
import { Histogram } from './histogram.js';
1515
import { mathChannels } from './mathchannels.js';
16+
import { projectManager } from './projectmanager.js';
1617

1718
window.onload = async function () {
1819
await dataProcessor.loadConfiguration();
@@ -29,6 +30,7 @@ window.onload = async function () {
2930
PaletteManager.init();
3031
xyAnalysis.init();
3132
Histogram.init();
33+
projectManager.init();
3234

3335
const fileInput = DOM.get('fileInput');
3436
if (fileInput) {

src/preferences.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export const Preferences = {
1919
'pref-show-area-fills': 'showAreaFills',
2020
'pref-smooth-lines': 'smoothLines',
2121
'pref-load-map': 'loadMap',
22+
'pref-remember-files': 'rememberFiles',
2223
},
2324

2425
defaultPrefs: {
@@ -29,6 +30,7 @@ export const Preferences = {
2930
showAreaFills: true,
3031
smoothLines: false,
3132
loadMap: false,
33+
rememberFiles: true,
3234
},
3335

3436
get prefs() {

src/projectmanager.js

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,22 @@ import { AppState, EVENTS } from './config.js';
22
import { mathChannels } from './mathchannels.js';
33
import { messenger } from './bus.js';
44
import { dbManager } from './dbmanager.js';
5+
import { Preferences } from './preferences.js';
56

67
class ProjectManager {
78
#currentProject;
89
#isReplaying;
910
#libraryContainer;
1011

1112
constructor() {
12-
this.#currentProject =
13-
this.#loadFromStorage() || this.#createEmptyProject();
1413
this.#isReplaying = false;
1514
this.#libraryContainer = null;
15+
this.#currentProject = this.#createEmptyProject();
16+
}
17+
18+
init() {
19+
this.#currentProject =
20+
this.#loadFromStorage() || this.#createEmptyProject();
1621

1722
dbManager.init().then(async () => {
1823
await this.#hydrateActiveFiles();
@@ -185,6 +190,8 @@ class ProjectManager {
185190

186191
messenger.emit('ui:set-loading', { message: 'Restoring Session...' });
187192

193+
let actuallyLoaded = false;
194+
188195
for (const res of activeResources) {
189196
if (res.dbId && !AppState.files.some((f) => f.dbId === res.dbId)) {
190197
const signals = await dbManager.getFileSignals(res.dbId);
@@ -202,13 +209,26 @@ class ProjectManager {
202209
size: meta.size,
203210
metadata: meta.metadata,
204211
});
212+
actuallyLoaded = true;
213+
} else {
214+
res.isActive = false;
205215
}
206216
}
207217
}
208218

209-
if (AppState.files.length > 0) {
219+
if (actuallyLoaded) {
210220
messenger.emit('dataprocessor:batch-load-completed', {});
221+
222+
requestAnimationFrame(() => {
223+
this.replayHistory();
224+
});
225+
} else {
226+
messenger.emit('dataprocessor:batch-load-completed', {});
227+
messenger.emit('ui:updateDataLoadedState', { status: false });
211228
}
229+
messenger.emit('dataprocessor:batch-load-completed', {});
230+
231+
this.#saveToStorage();
212232
}
213233

214234
registerFile(file) {
@@ -284,8 +304,23 @@ class ProjectManager {
284304
}
285305

286306
#loadFromStorage() {
287-
const data = localStorage.getItem('current_project');
288-
return data ? JSON.parse(data) : null;
307+
if (Preferences.prefs.rememberFiles) {
308+
const data = localStorage.getItem('current_project');
309+
return data ? JSON.parse(data) : null;
310+
} else {
311+
const data = localStorage.getItem('current_project');
312+
if (data) {
313+
const project = JSON.parse(data);
314+
315+
if (project && project.resources) {
316+
project.resources.forEach((resource) => {
317+
resource.isActive = false;
318+
});
319+
}
320+
321+
return project;
322+
}
323+
}
289324
}
290325

291326
#saveToStorage() {

src/ui.js

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,9 @@ export const UI = {
3939
UI.setLoading(true, event.message);
4040
});
4141

42-
messenger.on('dataprocessor:batch-load-completed', (event) => {
42+
messenger.on('dataprocessor:batch-load-completed', () => {
4343
UI.renderSignalList();
4444

45-
// 1. Reveal the container first
4645
UI.updateDataLoadedState(true);
4746
UI.setLoading(false);
4847

@@ -51,7 +50,6 @@ export const UI = {
5150
fileInfo.innerText = `${AppState.files.length} logs loaded`;
5251
}
5352

54-
// 2. Wait for DOM reflow before rendering chart.
5553
if (AppState.files.length > 0) {
5654
requestAnimationFrame(() => {
5755
ChartManager.render();

tests/preferences.test.js

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,23 @@
11
import { jest, describe, test, expect, beforeEach } from '@jest/globals';
22

3-
import { Preferences } from '../src/preferences.js';
4-
import { UI } from '../src/ui.js';
3+
await jest.unstable_mockModule('../src/ui.js', () => ({
4+
UI: {
5+
setTheme: jest.fn(),
6+
},
7+
}));
58

6-
UI.setTheme = jest.fn();
9+
const { Preferences } = await import('../src/preferences.js');
10+
const { UI } = await import('../src/ui.js');
711

812
describe('Preferences Module', () => {
913
beforeEach(() => {
10-
// 2. Set up the DOM structure expected by Preferences
1114
document.body.innerHTML = `
1215
<div class="preferences-list">
1316
<input type="checkbox" id="pref-persistence" />
1417
<input type="checkbox" id="pref-performance" />
1518
<input type="checkbox" id="pref-theme-dark" />
1619
<input type="checkbox" id="pref-custom-palette" />
20+
<input type="checkbox" id="pref-remember-files" />
1721
</div>
1822
`;
1923
localStorage.clear();
@@ -41,7 +45,6 @@ describe('Preferences Module', () => {
4145
});
4246

4347
test('init sets theme and attaches listeners', () => {
44-
// 1. Setup localStorage so loadPreferences() sees the dark theme as active
4548
localStorage.setItem(
4649
Preferences.PREFS_KEY,
4750
JSON.stringify({
@@ -52,15 +55,11 @@ describe('Preferences Module', () => {
5255

5356
const themeToggle = document.getElementById('pref-theme-dark');
5457

55-
// 2. Run init
5658
Preferences.init();
5759

58-
// Now it should be checked because loadPreferences() set it
5960
expect(themeToggle.checked).toBe(true);
60-
// And UI.setTheme should be called with 'dark'
6161
expect(UI.setTheme).toHaveBeenCalledWith('dark');
6262

63-
// 3. Test the toggle listener
6463
themeToggle.checked = false;
6564
themeToggle.dispatchEvent(new Event('change'));
6665

0 commit comments

Comments
 (0)