diff --git a/src/lib/api/adapters/raid.adapter.ts b/src/lib/api/adapters/raid.adapter.ts index 85b31271..9e3d581f 100644 --- a/src/lib/api/adapters/raid.adapter.ts +++ b/src/lib/api/adapters/raid.adapter.ts @@ -109,12 +109,12 @@ export class RaidAdapter extends BaseAdapter { * Downloads a single image for a raid (synchronous) * Requires editor role (>= 7) * @param slug - Raid slug - * @param size - Image size variant ('icon' or 'thumbnail') + * @param size - Image size variant ('icon', 'thumbnail', 'lobby', or 'background') * @param force - Force re-download even if image exists */ async downloadRaidImage( slug: string, - size: 'icon' | 'thumbnail', + size: 'icon' | 'thumbnail' | 'lobby' | 'background', force?: boolean, options?: RequestOptions ): Promise<{ success: boolean; error?: string }> { @@ -131,7 +131,7 @@ export class RaidAdapter extends BaseAdapter { */ async downloadRaidImages( slug: string, - downloadOptions?: { force?: boolean; size?: 'all' | 'icon' | 'thumbnail' }, + downloadOptions?: { force?: boolean; size?: 'all' | 'icon' | 'thumbnail' | 'lobby' | 'background' }, requestOptions?: RequestOptions ): Promise<{ status: string; raidId: string; message: string }> { return this.request(`/raids/${slug}/download_images`, { diff --git a/src/lib/types/api/entities.ts b/src/lib/types/api/entities.ts index 56cc16c5..a4f87b01 100644 --- a/src/lib/types/api/entities.ts +++ b/src/lib/types/api/entities.ts @@ -222,6 +222,7 @@ export interface Raid { element: number enemy_id?: number summon_id?: number + quest_id?: number group?: RaidGroup } diff --git a/src/lib/types/api/raid.ts b/src/lib/types/api/raid.ts index 3cdd159b..a0208e17 100644 --- a/src/lib/types/api/raid.ts +++ b/src/lib/types/api/raid.ts @@ -18,6 +18,7 @@ export interface RaidFull { element: number enemy_id?: number summon_id?: number + quest_id?: number group?: RaidGroupFlat } @@ -49,6 +50,7 @@ export interface CreateRaidInput { group_id: string enemy_id?: number summon_id?: number + quest_id?: number } export interface UpdateRaidInput { @@ -60,6 +62,7 @@ export interface UpdateRaidInput { group_id?: string enemy_id?: number summon_id?: number + quest_id?: number } // Input types for creating/updating raid groups diff --git a/src/routes/(app)/database/raids/[slug]/+page.svelte b/src/routes/(app)/database/raids/[slug]/+page.svelte index de244cd1..17080455 100644 --- a/src/routes/(app)/database/raids/[slug]/+page.svelte +++ b/src/routes/(app)/database/raids/[slug]/+page.svelte @@ -18,6 +18,8 @@ // CDN base URLs for raid images const ICON_BASE_URL = 'https://prd-game-a-granbluefantasy.akamaized.net/assets_en/img/sp/assets/enemy/m' const THUMBNAIL_BASE_URL = 'https://prd-game-a1-granbluefantasy.akamaized.net/assets_en/img/sp/assets/summon/qm' + const LOBBY_BASE_URL = 'https://prd-game-a1-granbluefantasy.akamaized.net/assets_en/img/sp/quest/assets/lobby' + const BACKGROUND_BASE_URL = 'https://prd-game-a-granbluefantasy.akamaized.net/assets_en/img/sp/quest/assets/treasureraid' function displayName(input: any): string { if (!input) return '—' @@ -85,6 +87,16 @@ return `${THUMBNAIL_BASE_URL}/${summonId}_high.png` } + // Get lobby image URL (quest_id with "1" appended) + function getLobbyUrl(questId: number): string { + return `${LOBBY_BASE_URL}/${questId}1.png` + } + + // Get background image URL + function getBackgroundUrl(questId: number): string { + return `${BACKGROUND_BASE_URL}/${questId}/raid_image_new.png` + } + // Get header image - prefer thumbnail, fallback to icon const headerImage = $derived.by(() => { if (raid?.summon_id) return getThumbnailUrl(raid.summon_id) @@ -97,6 +109,10 @@ const sizes: string[] = [] if (raid?.enemy_id) sizes.push('icon') if (raid?.summon_id) sizes.push('thumbnail') + if (raid?.quest_id) { + sizes.push('lobby') + sizes.push('background') + } return sizes }) @@ -124,17 +140,33 @@ }) } + // Lobby and background images from quest + if (raid.quest_id) { + images.push({ + url: getLobbyUrl(raid.quest_id), + label: 'Lobby', + variant: 'lobby' + }) + images.push({ + url: getBackgroundUrl(raid.quest_id), + label: 'Background', + variant: 'background' + }) + } + return images }) // Image download handlers + type RaidImageSize = 'icon' | 'thumbnail' | 'lobby' | 'background' + async function handleDownloadImage( size: string, _transformation: string | undefined, force: boolean ) { if (!raidSlug) return - await raidAdapter.downloadRaidImage(raidSlug, size as 'icon' | 'thumbnail', force) + await raidAdapter.downloadRaidImage(raidSlug, size as RaidImageSize, force) } async function handleDownloadAllImages(force: boolean) { @@ -144,7 +176,7 @@ async function handleDownloadSize(size: string) { if (!raidSlug) return - await raidAdapter.downloadRaidImage(raidSlug, size as 'icon' | 'thumbnail', false) + await raidAdapter.downloadRaidImage(raidSlug, size as RaidImageSize, false) } @@ -188,6 +220,7 @@ + {#if raid.element !== undefined && raid.element !== null} diff --git a/src/routes/(app)/database/raids/[slug]/edit/+page.svelte b/src/routes/(app)/database/raids/[slug]/edit/+page.svelte index c1df54a9..30ab6798 100644 --- a/src/routes/(app)/database/raids/[slug]/edit/+page.svelte +++ b/src/routes/(app)/database/raids/[slug]/edit/+page.svelte @@ -59,7 +59,8 @@ element: 0, group_id: '', enemy_id: undefined as number | undefined, - summon_id: undefined as number | undefined + summon_id: undefined as number | undefined, + quest_id: undefined as number | undefined }) // Sync edit data when raid changes @@ -73,7 +74,8 @@ element: raid.element ?? 0, group_id: raid.group?.id || '', enemy_id: raid.enemy_id, - summon_id: raid.summon_id + summon_id: raid.summon_id, + quest_id: raid.quest_id } } }) @@ -118,7 +120,8 @@ element: editData.element, group_id: editData.group_id, enemy_id: editData.enemy_id, - summon_id: editData.summon_id + summon_id: editData.summon_id, + quest_id: editData.quest_id }) // Invalidate queries @@ -201,6 +204,12 @@ editable={true} type="number" /> + +