diff --git a/userscript/manga-bookmark.user.js b/userscript/manga-bookmark.user.js index d2933c8..bec8d4a 100644 --- a/userscript/manga-bookmark.user.js +++ b/userscript/manga-bookmark.user.js @@ -29,6 +29,10 @@ // with its own prefix, so the two never share a cache, a queue or a panel. const STORE_PREFIX = "bmgr:manga:"; + // Which library this script's rows belong to. The novel script is a separate + // install that declares "novel"; the backend keeps whichever it is told. + const LIBRARY = "manga"; + // Safe in Bromite's isolated world: the page's own JS cannot read these. const CACHE_KEY = STORE_PREFIX + "cache"; @@ -518,7 +522,9 @@ } function setList(list) { - state.list = Array.isArray(list) ? list : []; + // GET /bookmarks answers with every library; this panel owns one of them, + // and the cache must not hold rows it can never show. + state.list = (Array.isArray(list) ? list : []).filter((b) => kindOf(b) === LIBRARY); reindex(); saveCache(state.list); } @@ -543,6 +549,12 @@ return b.status || "reading"; } + // A list cached by an older version has no kind field, and a row the server + // defaulted has "manga" — both mean the same thing here. + function kindOf(b) { + return b.kind || "manga"; + } + // ============================================================ // Retry queue // @@ -827,6 +839,7 @@ const bm = { key: key, site: p.site, + kind: LIBRARY, series_id: p.seriesId, title: p.title || (existing && existing.title) || p.seriesId, series_url: p.seriesUrl || (existing && existing.series_url) || "", @@ -849,6 +862,7 @@ const bm = Object.assign({}, existing, { key: key, site: p.site, + kind: LIBRARY, series_id: p.seriesId, title: existing.title || p.title || p.seriesId, series_url: existing.series_url || p.seriesUrl || "", @@ -1799,7 +1813,7 @@ // Exposes pure logic only — see userscript/test/logic.test.js. // ============================================================ if (typeof window === "undefined" && typeof module === "object" && module.exports) { - module.exports = { stripBuildHash, comixSeriesId, asura, demonic, comix, kagane, anchorsFromHTML, statusOf }; + module.exports = { stripBuildHash, comixSeriesId, asura, demonic, comix, kagane, anchorsFromHTML, statusOf, kindOf }; } // ============================================================ diff --git a/userscript/test/logic.test.js b/userscript/test/logic.test.js index f6b96c3..73230d0 100644 --- a/userscript/test/logic.test.js +++ b/userscript/test/logic.test.js @@ -60,6 +60,7 @@ const { kagane, anchorsFromHTML, statusOf, + kindOf, } = require("../manga-bookmark.user.js"); // detect() reads only these four properties off location. @@ -377,3 +378,17 @@ test("statusOf defaults a missing status to reading", () => { assert.equal(statusOf({ status: "archived" }), "archived"); assert.equal(statusOf({ status: "finished" }), "finished"); }); + +// ============================================================ +// kindOf — a row written before the kind column existed has none, and every +// one of those is manga. +// ============================================================ + +test("kindOf defaults a missing kind to manga", () => { + assert.equal(kindOf({}), "manga"); + assert.equal(kindOf({ kind: "" }), "manga"); +}); + +test("kindOf passes through an explicit kind", () => { + assert.equal(kindOf({ kind: "novel" }), "novel"); +});