fix mal querying

This commit is contained in:
2026-02-05 20:05:50 -08:00
parent a558bee991
commit 1e788203f2
3 changed files with 13 additions and 11 deletions

View File

@@ -54,7 +54,7 @@ export const MalAnimeListEntry = z
score: z.number().int().min(0).max(10), score: z.number().int().min(0).max(10),
num_episodes_watched: z.number().int().min(0), num_episodes_watched: z.number().int().min(0),
is_rewatching: z.boolean(), is_rewatching: z.boolean(),
updated_at: z.iso.datetime(), updated_at: z.iso.datetime({ offset: true }),
start_date: z.iso.date().optional(), start_date: z.iso.date().optional(),
finish_date: z.iso.date().optional(), finish_date: z.iso.date().optional(),
}) })

View File

@@ -26,7 +26,9 @@ export const GET: RequestHandler = async ({ params, request, fetch, url }) => {
`${UPSTREAM_ORIGIN}/users/${encodeURIComponent(username)}/animelist`, `${UPSTREAM_ORIGIN}/users/${encodeURIComponent(username)}/animelist`,
); );
upstreamUrl.search = url.search; const upstreamSearch = new URLSearchParams(url.search);
upstreamSearch.set("fields", "list_status");
upstreamUrl.search = upstreamSearch.toString();
const ifNoneMatch = pickForwardHeader(request, "if-none-match"); const ifNoneMatch = pickForwardHeader(request, "if-none-match");
const ifModifiedSince = pickForwardHeader(request, "if-modified-since"); const ifModifiedSince = pickForwardHeader(request, "if-modified-since");

View File

@@ -14,7 +14,7 @@
} from "$lib/types/mal"; } from "$lib/types/mal";
const ListSearchSchema = MalAnimeListQuerySchema.extend({ const ListSearchSchema = MalAnimeListQuerySchema.extend({
mal: z.string(), mal: z.string().default(""),
}).strict(); }).strict();
type PageStatus = "idle" | "loading" | "ready" | "error"; type PageStatus = "idle" | "loading" | "ready" | "error";
@@ -31,7 +31,7 @@
let isLoadingDb = $state(false); let isLoadingDb = $state(false);
// Keep MAL calls snappy if you later add more query params; for now it's mostly future-proofing. // Keep MAL calls snappy if you later add more query params; for now it's mostly future-proofing.
const debouncedMalUser = new Debounced(() => params.mal, 250); const debouncedMalUser = new Debounced(() => params.mal ?? "", 1000);
type MalListResponse = z.infer<typeof MalAnimeListResponseSchema>; type MalListResponse = z.infer<typeof MalAnimeListResponseSchema>;
type MalEntry = MalListResponse["data"][number]; type MalEntry = MalListResponse["data"][number];
@@ -79,8 +79,8 @@
return MalAnimeListResponseSchema.parse(json); return MalAnimeListResponseSchema.parse(json);
} }
async function loadAllFor(username: string) { async function loadAllFor(username: string | undefined) {
const u = username.trim(); const u = (username ?? "").trim();
if (!u) { if (!u) {
malResponse = null; malResponse = null;
malEntries = []; malEntries = [];
@@ -109,7 +109,7 @@
const { db } = getClientDb(); const { db } = getClientDb();
const malIds = (malResponse?.data ?? []).map((e) => e.node.id); const malIds = (malResponse?.data ?? []).map((e) => e.node.id);
songRows = await querySongsForMalAnimeIds(db, malIds); songRows = await getSongsForMalAnimeIds(db, malIds);
} finally { } finally {
isLoadingDb = false; isLoadingDb = false;
} }
@@ -178,7 +178,7 @@
id="mal-user" id="mal-user"
class="rounded border px-3 py-2 text-sm" class="rounded border px-3 py-2 text-sm"
placeholder="e.g. CaZzzer" placeholder="e.g. CaZzzer"
value={params.mal} value={params.mal ?? ""}
oninput={(e) => oninput={(e) =>
(params.mal = (e.currentTarget as HTMLInputElement).value)} (params.mal = (e.currentTarget as HTMLInputElement).value)}
autocomplete="off" autocomplete="off"
@@ -186,7 +186,7 @@
/> />
<div class="text-sm text-muted-foreground"> <div class="text-sm text-muted-foreground">
{#if !params.mal.trim()} {#if !(params.mal ?? "").trim()}
Waiting for username… Waiting for username…
{:else} {:else}
{#if isLoadingMal} {#if isLoadingMal}
@@ -217,13 +217,13 @@
{/if} {/if}
</div> </div>
{#if params.mal.trim() && !isLoadingMal && malEntries.length === 0} {#if (params.mal ?? "").trim() && !isLoadingMal && malEntries.length === 0}
<p class="mt-4 text-sm text-muted-foreground"> <p class="mt-4 text-sm text-muted-foreground">
No anime returned from MAL (did you set a restrictive status/sort?). No anime returned from MAL (did you set a restrictive status/sort?).
</p> </p>
{/if} {/if}
{#if params.mal.trim() && !isLoadingDb && malEntries.length > 0 && songRows.length === 0} {#if (params.mal ?? "").trim() && !isLoadingDb && malEntries.length > 0 && songRows.length === 0}
<p class="mt-4 text-sm text-muted-foreground"> <p class="mt-4 text-sm text-muted-foreground">
No songs matched in the local database. This likely means none of the MAL No songs matched in the local database. This likely means none of the MAL
anime IDs exist in the snapshot DB. anime IDs exist in the snapshot DB.