This commit is contained in:
Chris Kruining 2025-05-18 18:12:42 +02:00
parent 873677ea04
commit d683b051b6
No known key found for this signature in database
GPG key ID: EB894A3560CCCAD2
17 changed files with 244 additions and 273 deletions

View file

@ -1,12 +1,10 @@
"use server";
import type { paths } from "./jellyfin.generated"; // generated by openapi-typescript
import createClient from "openapi-fetch";
import type { paths, components } from "./jellyfin.generated"; // generated by openapi-typescript
import { query } from "@solidjs/router";
import { Entry } from "../types";
// ===============================
'use server';
// ===============================
type ItemImageType = "Primary" | "Art" | "Backdrop" | "Banner" | "Logo" | "Thumb" | "Disc" | "Box" | "Screenshot" | "Menu" | "Chapter" | "BoxRear" | "Profile";
const baseUrl = process.env.JELLYFIN_BASE_URL;
@ -58,7 +56,71 @@ export const listUsers = query(async () => {
return data ?? [];
}, "jellyfin.listUsers");
export const listItems = query(async (userId: string): Promise<Entry[] | undefined> => {
const { data, error } = await client.GET("/Items", {
params: {
query: {
userId,
hasTmdbInfo: true,
recursive: true,
includeItemTypes: ["Movie", "Series"],
fields: [
"ProviderIds",
"Genres",
"DateLastMediaAdded",
"DateCreated",
"MediaSources",
],
},
},
});
if (data === undefined) {
return undefined;
}
return data.Items?.map(item => ({
id: item.Id!,
title: item.Name!,
thumbnail: new URL(`/Items/${item.Id!}/Images/Primary`, baseUrl), //await getItemImage(data.Id!, 'Primary'),
})) ?? [];
}, "jellyfin.listItems");
export const getRandomItem = query(async (userId: string): Promise<Entry | undefined> => getRandomItems(userId, 1).then(items => items?.at(0)), "jellyfin.listRandomItem");
export const getRandomItems = query(async (userId: string, limit: number = 10): Promise<Entry[]> => {
const { data, error } = await client.GET("/Items", {
params: {
query: {
userId,
hasTmdbInfo: true,
recursive: true,
limit,
sortBy: ["Random"],
includeItemTypes: ["Movie", "Series"],
imageTypes: ["Primary", "Backdrop", "Thumb"],
fields: [
"ProviderIds",
"Genres",
"DateLastMediaAdded",
"DateCreated",
"MediaSources",
],
},
},
});
return data?.Items?.map(item => ({
id: item.Id!,
title: item.Name!,
thumbnail: new URL(`/Items/${item.Id!}/Images/Primary`, baseUrl), //await getItemImage(data.Id!, 'Primary'),
image: new URL(`/Items/${item.Id!}/Images/Backdrop`, baseUrl), //await getItemImage(data.Id!, 'Primary'),
})) ?? [];
}, "jellyfin.listRandomItems");
export const getItem = query(async (userId: string, itemId: string): Promise<Entry | undefined> => {
console.log('baseUrl', baseUrl);
const { data, error } = await client.GET("/Items/{itemId}", {
params: {
path: {
@ -87,7 +149,10 @@ export const getItem = query(async (userId: string, itemId: string): Promise<Ent
return {
id: data.Id!,
title: data.Name!,
synopsis: data.Overview!,
thumbnail: new URL(`/Items/${itemId}/Images/Primary`, baseUrl), //await getItemImage(data.Id!, 'Primary'),
image: new URL(`/Items/${itemId}/Images/Backdrop`, baseUrl),
// ...data,
};
}, "jellyfin.getItem");
@ -142,32 +207,29 @@ export const queryItems = query(async () => {
}, 'jellyfin.queryItems');
export const getContinueWatching = query(
async (userId: string): Promise<Entry[]> => {
const { data, error } = await client.GET("/UserItems/Resume", {
params: {
query: {
userId,
mediaTypes: ["Video"],
// fields: ["ProviderIds", "Genres"],
// includeItemTypes: ["Series", "Movie"]
},
export const getContinueWatching = query(async (userId: string): Promise<Entry[]> => {
const { data, error } = await client.GET("/UserItems/Resume", {
params: {
query: {
userId,
mediaTypes: ["Video"],
// fields: ["ProviderIds", "Genres"],
// includeItemTypes: ["Series", "Movie"]
},
});
},
});
if (Array.isArray(data?.Items) !== true) {
return [];
}
if (Array.isArray(data?.Items) !== true) {
return [];
}
const uniqueIds = new Set<string>(data.Items.map(item => item.Type === 'Episode' ? item.SeriesId! : item.Id));
const results = await Promise.allSettled(uniqueIds.values().map(id => getItem(userId, id)).toArray());
const uniqueIds = new Set<string>(data.Items.map(item => item.Type === 'Episode' ? item.SeriesId! : item.Id!));
const results = await Promise.allSettled(uniqueIds.values().map(id => getItem(userId, id)).toArray());
assertNoErrors(results);
assertNoErrors(results);
return results.filter((result): result is PromiseFulfilledResult<Entry> => result.value !== undefined).map(({ value }) => value);
},
"jellyfin.continueWatching",
);
return results.filter((result): result is PromiseFulfilledResult<Entry> => result.value !== undefined).map(({ value }) => value);
}, "jellyfin.continueWatching");
function assertNoErrors<T>(results: PromiseSettledResult<T>[]): asserts results is PromiseFulfilledResult<T>[] {
if (results.some(({ status }) => status !== 'fulfilled')) {