mirror of
https://github.com/moku-project/Moku.git
synced 2026-06-13 09:19:56 -05:00
Fix: Caching Logic & Settings Warning for Auth
This commit is contained in:
@@ -37,13 +37,13 @@
|
|||||||
const pageCache = new Map<number, string[]>();
|
const pageCache = new Map<number, string[]>();
|
||||||
const inflight = new Map<number, Promise<string[]>>();
|
const inflight = new Map<number, Promise<string[]>>();
|
||||||
|
|
||||||
const isAuth = () => (appStore.settings.serverAuthMode ?? "NONE") === "BASIC_AUTH";
|
const useBlob = $derived((appStore.settings.serverAuthMode ?? "NONE") === "BASIC_AUTH");
|
||||||
|
|
||||||
function resolveUrl(url: string, priority = 0): Promise<string> {
|
function resolveUrl(url: string, priority = 0): Promise<string> {
|
||||||
return isAuth() ? getBlobUrl(url, priority) : Promise.resolve(url);
|
return useBlob ? getBlobUrl(url, priority) : Promise.resolve(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
function fetchPages(chapterId: number, signal?: AbortSignal): Promise<string[]> {
|
function fetchPages(chapterId: number, signal?: AbortSignal, priorityPage = 0): Promise<string[]> {
|
||||||
const cached = pageCache.get(chapterId);
|
const cached = pageCache.get(chapterId);
|
||||||
if (cached) return Promise.resolve(cached);
|
if (cached) return Promise.resolve(cached);
|
||||||
if (signal?.aborted) return Promise.reject(new DOMException("Aborted", "AbortError"));
|
if (signal?.aborted) return Promise.reject(new DOMException("Aborted", "AbortError"));
|
||||||
@@ -52,7 +52,10 @@
|
|||||||
const p = gql<{ fetchChapterPages: { pages: string[] } }>(FETCH_CHAPTER_PAGES, { chapterId })
|
const p = gql<{ fetchChapterPages: { pages: string[] } }>(FETCH_CHAPTER_PAGES, { chapterId })
|
||||||
.then(d => {
|
.then(d => {
|
||||||
const urls = d.fetchChapterPages.pages.map(p => plainThumbUrl(p));
|
const urls = d.fetchChapterPages.pages.map(p => plainThumbUrl(p));
|
||||||
if (isAuth()) preloadBlobUrls(urls, urls.length);
|
if (useBlob) {
|
||||||
|
if (urls[priorityPage]) getBlobUrl(urls[priorityPage], urls.length + 999);
|
||||||
|
preloadBlobUrls(urls.filter((_, i) => i !== priorityPage), urls.length);
|
||||||
|
}
|
||||||
pageCache.set(chapterId, urls);
|
pageCache.set(chapterId, urls);
|
||||||
return urls;
|
return urls;
|
||||||
})
|
})
|
||||||
@@ -286,12 +289,13 @@
|
|||||||
|
|
||||||
store.pageNumber = 1;
|
store.pageNumber = 1;
|
||||||
try {
|
try {
|
||||||
const urls = await fetchPages(id, ctrl.signal);
|
const urls = await fetchPages(id, ctrl.signal, resumeTo > 1 ? resumeTo - 1 : 0);
|
||||||
if (ctrl.signal.aborted) return;
|
if (ctrl.signal.aborted) return;
|
||||||
store.pageUrls = urls;
|
store.pageUrls = urls;
|
||||||
if (resumeTo > 1) store.pageNumber = Math.min(resumeTo, urls.length || resumeTo);
|
if (resumeTo > 1) store.pageNumber = Math.min(resumeTo, urls.length || resumeTo);
|
||||||
pageReady = true;
|
pageReady = true;
|
||||||
loading = false;
|
loading = false;
|
||||||
|
if (adjacent.next) fetchPages(adjacent.next.id).catch(() => {});
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
if (ctrl.signal.aborted) return;
|
if (ctrl.signal.aborted) return;
|
||||||
error = e instanceof Error ? e.message : String(e);
|
error = e instanceof Error ? e.message : String(e);
|
||||||
@@ -480,7 +484,7 @@
|
|||||||
const ahead = store.settings.preloadPages ?? 3;
|
const ahead = store.settings.preloadPages ?? 3;
|
||||||
const current = store.pageUrls[store.pageNumber - 1];
|
const current = store.pageUrls[store.pageNumber - 1];
|
||||||
if (!current) return;
|
if (!current) return;
|
||||||
if (isAuth()) {
|
if (useBlob) {
|
||||||
getBlobUrl(current, 999);
|
getBlobUrl(current, 999);
|
||||||
const upcoming = Array.from({ length: ahead }, (_, i) => store.pageUrls[store.pageNumber + i]).filter(Boolean) as string[];
|
const upcoming = Array.from({ length: ahead }, (_, i) => store.pageUrls[store.pageNumber + i]).filter(Boolean) as string[];
|
||||||
const behind = store.pageUrls[store.pageNumber - 2];
|
const behind = store.pageUrls[store.pageNumber - 2];
|
||||||
|
|||||||
@@ -1759,6 +1759,13 @@
|
|||||||
|
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
{#if store.settings.serverAuthMode === "BASIC_AUTH"}
|
||||||
|
<div class="step-row">
|
||||||
|
<div class="toggle-info"></div>
|
||||||
|
<p class="auth-perf-note">Images are proxied through Tauri when Basic Auth is active, which reduces loading speed.</p>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
<div class="step-row">
|
<div class="step-row">
|
||||||
<div class="toggle-info"></div>
|
<div class="toggle-info"></div>
|
||||||
<div class="sec-btn-row">
|
<div class="sec-btn-row">
|
||||||
@@ -2455,6 +2462,7 @@
|
|||||||
.sec-eye-btn { position: absolute; right: 8px; top: 50%; transform: translateY(-50%); display: flex; align-items: center; justify-content: center; padding: 0; border: none; background: none; color: var(--text-faint); cursor: pointer; transition: color var(--t-base); }
|
.sec-eye-btn { position: absolute; right: 8px; top: 50%; transform: translateY(-50%); display: flex; align-items: center; justify-content: center; padding: 0; border: none; background: none; color: var(--text-faint); cursor: pointer; transition: color var(--t-base); }
|
||||||
.sec-eye-btn:hover { color: var(--text-muted); }
|
.sec-eye-btn:hover { color: var(--text-muted); }
|
||||||
.sec-btn-row { display: flex; align-items: center; gap: var(--sp-2); flex-shrink: 0; }
|
.sec-btn-row { display: flex; align-items: center; gap: var(--sp-2); flex-shrink: 0; }
|
||||||
|
.auth-perf-note { font-size: var(--text-xs); color: var(--text-faint); max-width: 260px; line-height: var(--leading-snug); }
|
||||||
.sec-action-btn { font-family: var(--font-ui); font-size: var(--text-xs); letter-spacing: var(--tracking-wide); padding: 5px 14px; border-radius: var(--radius-md); border: 1px solid var(--border-dim); background: none; color: var(--text-muted); cursor: pointer; flex-shrink: 0; transition: color var(--t-base), border-color var(--t-base), background var(--t-base); }
|
.sec-action-btn { font-family: var(--font-ui); font-size: var(--text-xs); letter-spacing: var(--tracking-wide); padding: 5px 14px; border-radius: var(--radius-md); border: 1px solid var(--border-dim); background: none; color: var(--text-muted); cursor: pointer; flex-shrink: 0; transition: color var(--t-base), border-color var(--t-base), background var(--t-base); }
|
||||||
.sec-action-btn:hover:not(:disabled) { color: var(--text-secondary); border-color: var(--border-strong); }
|
.sec-action-btn:hover:not(:disabled) { color: var(--text-secondary); border-color: var(--border-strong); }
|
||||||
.sec-action-btn:disabled { opacity: 0.35; cursor: default; }
|
.sec-action-btn:disabled { opacity: 0.35; cursor: default; }
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { store } from "../store/state.svelte";
|
|||||||
const cache = new Map<string, string>();
|
const cache = new Map<string, string>();
|
||||||
const inflight = new Map<string, Promise<string>>();
|
const inflight = new Map<string, Promise<string>>();
|
||||||
|
|
||||||
const MAX_CONCURRENT = 6;
|
const MAX_CONCURRENT = 14;
|
||||||
let active = 0;
|
let active = 0;
|
||||||
|
|
||||||
interface QueueEntry {
|
interface QueueEntry {
|
||||||
|
|||||||
Reference in New Issue
Block a user