mirror of
https://github.com/moku-project/Moku.git
synced 2026-06-13 09:19:56 -05:00
Chore: Restructure Repository for SvelteKit
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
import type { Chapter } from "@types";
|
||||
|
||||
export type ChapterSortMode = "source" | "chapterNumber" | "uploadDate";
|
||||
export type ChapterSortDir = "asc" | "desc";
|
||||
|
||||
export interface ChapterDisplayPrefs {
|
||||
sortMode?: ChapterSortMode;
|
||||
sortDir?: ChapterSortDir;
|
||||
preferredScanlator?: string;
|
||||
scanlatorFilter?: string[];
|
||||
scanlatorBlacklist?: string[];
|
||||
scanlatorForce?: boolean;
|
||||
}
|
||||
|
||||
function sortByMode(a: Chapter, b: Chapter, mode: ChapterSortMode): number {
|
||||
if (mode === "chapterNumber") return a.chapterNumber - b.chapterNumber;
|
||||
if (mode === "uploadDate") return Number(a.uploadDate ?? 0) - Number(b.uploadDate ?? 0);
|
||||
return a.sourceOrder - b.sourceOrder;
|
||||
}
|
||||
|
||||
export function buildChapterList(chapters: Chapter[], prefs: ChapterDisplayPrefs = {}): Chapter[] {
|
||||
const {
|
||||
sortMode = "source",
|
||||
sortDir = "asc",
|
||||
preferredScanlator = "",
|
||||
scanlatorFilter = [],
|
||||
scanlatorBlacklist = [],
|
||||
scanlatorForce = false,
|
||||
} = prefs;
|
||||
|
||||
let base = [...chapters];
|
||||
|
||||
if (scanlatorBlacklist.length > 0) {
|
||||
base = base.filter(c => !scanlatorBlacklist.includes(c.scanlator ?? ""));
|
||||
}
|
||||
|
||||
base.sort((a, b) => sortByMode(a, b, sortMode));
|
||||
|
||||
if (preferredScanlator) {
|
||||
const pref: Chapter[] = [], rest: Chapter[] = [];
|
||||
for (const c of base) (c.scanlator === preferredScanlator ? pref : rest).push(c);
|
||||
base = [...pref, ...rest];
|
||||
}
|
||||
|
||||
if (scanlatorFilter.length > 0) {
|
||||
const seen = new Map<number, Chapter>();
|
||||
for (const ch of base) {
|
||||
const existing = seen.get(ch.chapterNumber);
|
||||
if (!existing) {
|
||||
if (!scanlatorForce || scanlatorFilter.includes(ch.scanlator ?? "")) {
|
||||
seen.set(ch.chapterNumber, ch);
|
||||
}
|
||||
} else {
|
||||
const np = scanlatorFilter.indexOf(ch.scanlator ?? "");
|
||||
const op = scanlatorFilter.indexOf(existing.scanlator ?? "");
|
||||
if (np !== -1 && (op === -1 || np < op)) seen.set(ch.chapterNumber, ch);
|
||||
}
|
||||
}
|
||||
base = [...seen.values()].sort((a, b) => sortByMode(a, b, sortMode));
|
||||
}
|
||||
|
||||
return sortDir === "desc" ? base.reverse() : base;
|
||||
}
|
||||
|
||||
export function chaptersAscending(chapters: Chapter[]): Chapter[] {
|
||||
return [...chapters].sort((a, b) => a.sourceOrder - b.sourceOrder);
|
||||
}
|
||||
|
||||
export function buildReaderChapterList(
|
||||
chapters: Chapter[],
|
||||
prefs: Pick<ChapterDisplayPrefs, "preferredScanlator" | "scanlatorFilter"> | undefined,
|
||||
): Chapter[] {
|
||||
return buildChapterList(chapters, {
|
||||
sortMode: "source",
|
||||
sortDir: "asc",
|
||||
preferredScanlator: prefs?.preferredScanlator,
|
||||
scanlatorFilter: prefs?.scanlatorFilter,
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import { store, updateSettings } from "@store/state.svelte";
|
||||
import { DEFAULT_MANGA_PREFS } from "@store/state.svelte";
|
||||
import type { MangaPrefs } from "@store/state.svelte";
|
||||
|
||||
export function getPref<K extends keyof MangaPrefs>(mangaId: number, key: K): MangaPrefs[K] {
|
||||
const prefs = store.settings.mangaPrefs?.[mangaId] ?? {};
|
||||
return (prefs[key] ?? DEFAULT_MANGA_PREFS[key]) as MangaPrefs[K];
|
||||
}
|
||||
|
||||
export function setPref<K extends keyof MangaPrefs>(mangaId: number, key: K, value: MangaPrefs[K]) {
|
||||
updateSettings({
|
||||
mangaPrefs: {
|
||||
...store.settings.mangaPrefs,
|
||||
[mangaId]: { ...(store.settings.mangaPrefs?.[mangaId] ?? {}), [key]: value },
|
||||
},
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user