mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-13 06:42:23 +00:00
Never let a share rewrite the Data Library entries remembered as on
Every restore wrote the selection it applied to browser storage, so opening a link that switched no library entry on stored every saved entry as off, and the next bare visit restored them off. Core layer state never writes a recipient's preferences from a share. The library now keeps what is remembered as on apart from what a share switches on for the session: a share's entries still join the library, but only a local restore and the viewer's own choices change what is remembered.
This commit is contained in:
1 parent
53f0a32a1b
commit
2d5db9f63d
2 files changed
+60
-7
No files matched your search
@@ -69,6 +69,10 @@ export function createDataLibrary({
|
||||
let availability = new Map();
|
||||
let serverPresent = false;
|
||||
let selection = { added: [], on: [] };
|
||||
// What this browser remembers as on. Like core layer state, a share
|
||||
// decides what is on for the session but never rewrites it: only the
|
||||
// viewer's explicit choices and a local restore do.
|
||||
let savedOn = [];
|
||||
let started = false;
|
||||
// Set once availability is known; a share navigated to before then waits.
|
||||
let loaded = false;
|
||||
@@ -89,7 +93,11 @@ export function createDataLibrary({
|
||||
|
||||
const persist = () => {
|
||||
selection = normalizeLibrarySelection(selection, switchable);
|
||||
writeStoredLibrarySelection(storage, selection);
|
||||
savedOn = savedOn.filter((id) => selection.added.includes(id));
|
||||
writeStoredLibrarySelection(storage, {
|
||||
added: selection.added,
|
||||
on: savedOn,
|
||||
});
|
||||
shareLink?.onLibraryStateChange?.();
|
||||
notify();
|
||||
};
|
||||
@@ -163,9 +171,16 @@ export function createDataLibrary({
|
||||
return;
|
||||
}
|
||||
const on = new Set(selection.on);
|
||||
if (change.enabled) on.add(id);
|
||||
else on.delete(id);
|
||||
const saved = new Set(savedOn);
|
||||
if (change.enabled) {
|
||||
on.add(id);
|
||||
saved.add(id);
|
||||
} else {
|
||||
on.delete(id);
|
||||
saved.delete(id);
|
||||
}
|
||||
selection = { ...selection, on: [...on] };
|
||||
savedOn = [...saved];
|
||||
persist();
|
||||
});
|
||||
|
||||
@@ -217,9 +232,10 @@ export function createDataLibrary({
|
||||
console.warn(`[Library] ${id} restore failed:`, error),
|
||||
);
|
||||
}
|
||||
writeStoredLibrarySelection(storage, selection);
|
||||
shareLink?.onLibraryStateChange?.();
|
||||
notify();
|
||||
// A share's entries join the library; only a local restore sets what
|
||||
// is remembered as on.
|
||||
if (origin !== 'share-restore') savedOn = selection.on;
|
||||
persist();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -262,6 +278,7 @@ export function createDataLibrary({
|
||||
availability = answer.availability;
|
||||
serverPresent = answer.server;
|
||||
const stored = readStoredLibrarySelection(storage, switchable);
|
||||
savedOn = stored.on;
|
||||
// A share opened in this tab while availability loaded wins over the
|
||||
// opening one.
|
||||
const linked = queuedShare ? idsForTokens(queuedShare) : openingShare();
|
||||
|
||||
@@ -201,12 +201,48 @@ test('a link decides what is on and adds its entries to the library', async (t)
|
||||
await manager.waitForLayerSettled?.('lib-sea-marks');
|
||||
assert.equal(manager.isEnabled('lib-sea-marks'), true);
|
||||
assert.equal(manager.isEnabled('lib-night-lights'), false);
|
||||
// The link's entry joins the library; what is remembered as on stays
|
||||
// the viewer's own.
|
||||
assert.deepEqual(JSON.parse(storage.store.get(LIBRARY_STORAGE_KEY)), {
|
||||
added: ['night-lights', 'sea-marks'],
|
||||
on: ['sea-marks'],
|
||||
on: ['night-lights'],
|
||||
});
|
||||
});
|
||||
|
||||
test('a share never rewrites what this browser remembers as on', async (t) => {
|
||||
const saved = JSON.stringify({
|
||||
added: ['night-lights', 'sea-marks'],
|
||||
on: ['night-lights'],
|
||||
});
|
||||
const storage = memoryStorage(saved);
|
||||
const manager = sealedManager(t);
|
||||
const shareLink = fakeShareLink([]);
|
||||
const library = createDataLibrary({
|
||||
entries,
|
||||
ledger,
|
||||
dataManager: manager,
|
||||
services: {},
|
||||
storage,
|
||||
shareLink,
|
||||
source: source({}),
|
||||
});
|
||||
await library.start();
|
||||
assert.equal(manager.isEnabled('lib-night-lights'), false);
|
||||
shareLink.listener(['01']);
|
||||
await manager.waitForLayerSettled?.('lib-sea-marks');
|
||||
assert.equal(manager.isEnabled('lib-sea-marks'), true);
|
||||
assert.deepEqual(JSON.parse(storage.store.get(LIBRARY_STORAGE_KEY)), {
|
||||
added: ['night-lights', 'sea-marks'],
|
||||
on: ['night-lights'],
|
||||
});
|
||||
// An explicit choice is remembered, and only that one.
|
||||
await manager.setEnabled('lib-sea-marks', false, { origin: 'user' });
|
||||
await manager.setEnabled('lib-night-lights', true, { origin: 'user' });
|
||||
await manager.setEnabled('lib-night-lights', false, { origin: 'user' });
|
||||
assert.deepEqual(JSON.parse(storage.store.get(LIBRARY_STORAGE_KEY)).on, []);
|
||||
library.destroy();
|
||||
});
|
||||
|
||||
/** A ShareLinkManager stand-in: the opening share and in-tab navigation. */
|
||||
function fakeShareLink(initialLibraryTokens) {
|
||||
const link = {
|
||||
|
||||
Reference in new issue
Block a user