Reader: stale reading sessions never move "Continue" back
A reader tab left open on one device (or restored by the browser) used to save its old chapter as the newest position as soon as it was shown again. Progress saves now carry the tab id and the newest progress time the tab knows (`seen`); the server refuses a save when another tab or device saved a newer position since. The reader then asks: jump to the newest position, or keep reading here (which makes this chapter the head again). It checks on open, when the tab becomes visible, and on every save. Reader links carry `at` and the reader keeps it in the address bar, so reloads and restored tabs still know what they had seen. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
03767d5704
commit
618992ec14
9 files changed
+228
-24
No files matched your search
+16
-1
@@ -39,6 +39,20 @@ const store = {
|
||||
get(k) { try { return localStorage.getItem('mc.' + k); } catch (e) { return null; } },
|
||||
set(k, v) { try { localStorage.setItem('mc.' + k, v); } catch (e) { /* private mode */ } },
|
||||
};
|
||||
// One id per browser tab (it survives navigation and reloads in that tab): progress saves carry it, so
|
||||
// a reader can tell its own saves from those of another tab or device.
|
||||
const tabId = (() => {
|
||||
let id = null;
|
||||
return () => {
|
||||
if (id) return id;
|
||||
try { id = sessionStorage.getItem('mc.tab'); } catch (e) { /* storage blocked */ }
|
||||
if (!/^[a-zA-Z0-9_-]{8,40}$/.test(id || '')) {
|
||||
id = Array.from(crypto.getRandomValues(new Uint8Array(12)), b => b.toString(16).padStart(2, '0')).join('');
|
||||
try { sessionStorage.setItem('mc.tab', id); } catch (e) { /* this page keeps it in memory */ }
|
||||
}
|
||||
return id;
|
||||
};
|
||||
})();
|
||||
|
||||
function ago(t) {
|
||||
const s = (Date.now() - t) / 1000;
|
||||
@@ -60,7 +74,8 @@ function readingDuration(ms, compact = false) {
|
||||
}
|
||||
|
||||
const qsa = obj => { const p = new URLSearchParams(); for (const k in obj) if (obj[k] != null && obj[k] !== '') p.set(k, obj[k]); return p.toString(); };
|
||||
const readUrl = (m, c, v) => 'read.html?' + qsa({ m, c, v });
|
||||
// `at`: the manga's latest progress time the linking page knew, so the reader can tell it opened from a stale page.
|
||||
const readUrl = (m, c, v, at) => 'read.html?' + qsa({ m, c, v, at: at || null });
|
||||
const mangaUrl = m => 'manga.html?' + qsa({ m });
|
||||
const libraryUrlForTags = tags => {
|
||||
const p = new URLSearchParams();
|
||||
|
||||
Reference in new issue
Block a user