// @ts-check /* Imports */ /** @typedef {import("@libs/filterInputs").Filters} Filters */ /** @typedef {import("@typings/types").PluginList} PluginList */ /** @typedef {import("@typings/plugin").Plugin.PluginItem} PluginItem */ /** @typedef {import("@typings/plugin").Plugin.ChapterItem} ChapterItem */ /** @typedef {import("@typings/plugin").Plugin.NovelItem} NovelItem */ /** @typedef {import("@typings/plugin").Plugin.SourceNovel} SourceNovel */ /** @typedef {import("@libs/filterInputs").FilterTypes} FilterTypes */ /** @typedef {import("@libs/filterInputs").FilterTypes.CheckboxGroup} CheckboxGroup */ /** * @template {FilterTypes} T * @typedef {import("@libs/filterInputs").ValueOfFilter} ValueOfFilter */ /** * @template {Filters} T * @typedef {import("@libs/filterInputs").FilterToValues} FilterToValues */ /** @typedef {{backgroundColor:string, textColor:string}} Theme */ /** @typedef {Theme[]} Themes */ /** @typedef {import("./accordion").AccordionBox} AccordionBox */ /// // #region DOM Queries const nav = $("nav"); /** @type {JQuery} */ const headerChanger = $("#headerChanger"); /** @type {JQuery} */ const popularNovels = $("#popularNovels"); /** @type {JQuery} */ const popularNovels_page_select = $("#popularNovels .page-select"); /** @type {JQuery} */ const popularNovels_fetch_btn = $("#popularNovels .fetch-btn"); /** @type {JQuery} */ const popularNovels_spinner = $("#popularNovels .spinner-border"); /** @type {JQuery} */ const popularNovels_novel_list = $("#popularNovels .novel-list"); /** @type {JQuery} */ const searchNovels = $("#searchNovels"); /** @type {JQuery} */ const seacrhNovels_novel_list = $("#searchNovels .novel-list"); /** @type {JQuery} */ const searchNovels_page_select = $("#searchNovels .page-select"); /** @type {JQuery} */ const searchNovels_fetch_btn = $("#searchNovels .fetch-btn"); /** @type {JQuery} */ const searchNovels_searchbar = $("#searchNovels .searchbar input"); /** @type {JQuery} */ const parseNovelAndChapters = $("#parseNovelAndChapters"); /** @type {JQuery} */ const parseChapter = $("#parseChapter"); /** @type {JQuery} */ const fetchImage = $("#fetchImage"); /** @type {JQuery}*/ const plugin_language_selection = $("#language"); /** @type {JQuery} */ const plugin_search = $("#plugin"); /** @type {JQuery} */ const plugin_search_results = $("#search-results"); /** @type {JQuery} */ const clear_plugin_search = $("#clear-search"); /** @type {JQuery} */ const previewSwitch = $("#raw-preview-switch"); /** @type {JQuery} */ const chapterViewer = $("#chapter-viewer"); /** @type {JQuery} */ const filtersModal = $("#filtersModal .modal-body"); /** @type {JQuery} */ const latestSwitch = $("#latest-switch"); // #endregion // #region pagination class NovelListPagination { constructor( /** @type {boolean} */ sL, /** @type {JQuery} */ sE, /** @type {JQuery} */ fC, /** @type {JQuery} */ nL ) { /** @type {Record} */ this.pageStore = {}; this._showlatest = sL; this.lastFetchedPage = 0; this.currentPage = 0; this.canFetchMore = true; this.selectElement = sE; this.fetchContainer = fC; this.resetStoreOnFetch = true; this.novelList = nL; } get showLatest() { return this._showlatest; } set showLatest(val) { this._showlatest = val; this.reset(); } get fetchBtn() { return this.fetchContainer.children("button")[0]; } get numSelect() { return this.selectElement.children("select")[0]; } lockFetch(cause = 0) { this.canFetchMore = false; this.fetchBtn.disabled = true; if (cause === 1) this.fetchBtn.innerText = "no more to fetch"; if (cause === 2) this.fetchBtn.innerText = "fetching"; if (cause === 3) this.fetchBtn.innerText = "error"; } unlockFetch() { this.canFetchMore = true; this.fetchBtn.disabled = false; this.fetchBtn.innerText = "fetch"; } async fetchNovels( /** @type {(page:number, latest: boolean)=>Promise} */ fn ) { this.error = undefined; if (this.resetStoreOnFetch) { this.resetStoreOnFetch = false; this.pageStore = {}; } try { this.lockFetch(2); const lfp = ++this.lastFetchedPage; console.log("fetching ", lfp, "page"); const novels = await fn(lfp, this.showLatest); if (novels.length === 0) { this.lastFetchedPage--; this.lockFetch(1); if (this.lastFetchedPage === 0) { this.error = "No novels found!"; this.render(); } return false; } this.loadNovels(lfp, novels); this.unlockFetch(); return true; } catch (e) { this.lastFetchedPage--; this.lockFetch(3); this.error = `${e}`; this.render(); return false; } } showNextPage() { console.log("lf", this.lastFetchedPage, "cp", this.currentPage); if (this.lastFetchedPage > this.currentPage) { this.currentPage = this.lastFetchedPage; this.render(); } this.numSelect.value = `${this.currentPage}`; } arePagesTheSame( /** @type {NovelItem[]} */ p1, /** @type {NovelItem[]} */ p2 ) { if (p1.length !== p2.length) return false; let i = 0; for (const novel of p1) { if (novel.url !== p2[i].url) return false; i++; } return true; } loadNovels(/** @type {number} */ page, /** @type {NovelItem[]} */ list) { this.pageStore[page] = list; if (page - 1 > 0 && this.pageStore[page - 1]) { if ( this.arePagesTheSame( this.pageStore[page], this.pageStore[page - 1] ) ) { if (this.numSelect.nextElementSibling) this.numSelect.nextElementSibling.innerHTML = "Pages are the same! It's possible that pagination is not implemented in the source!"; } } } reset() { this.hideSelectBox(); this.currentPage = 0; this.lastFetchedPage = 0; this.resetStoreOnFetch = true; this.error = undefined; if (this.numSelect.nextElementSibling) { this.numSelect.nextElementSibling.innerHTML = ""; } this.unlockFetch(); } setupSelectBox() { this.selectElement[0].style.display = "inline"; this.numSelect.innerHTML = ""; for (let i = 1; i <= this.lastFetchedPage; i++) { const option = $("