add quest_id support and lobby/background images for raids
- add quest_id to types and forms - add lobby and background images to detail page - update adapter for new image sizes
This commit is contained in:
parent
96db589dea
commit
b2559f5f39
6 changed files with 64 additions and 10 deletions
|
|
@ -109,12 +109,12 @@ export class RaidAdapter extends BaseAdapter {
|
||||||
* Downloads a single image for a raid (synchronous)
|
* Downloads a single image for a raid (synchronous)
|
||||||
* Requires editor role (>= 7)
|
* Requires editor role (>= 7)
|
||||||
* @param slug - Raid slug
|
* @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
|
* @param force - Force re-download even if image exists
|
||||||
*/
|
*/
|
||||||
async downloadRaidImage(
|
async downloadRaidImage(
|
||||||
slug: string,
|
slug: string,
|
||||||
size: 'icon' | 'thumbnail',
|
size: 'icon' | 'thumbnail' | 'lobby' | 'background',
|
||||||
force?: boolean,
|
force?: boolean,
|
||||||
options?: RequestOptions
|
options?: RequestOptions
|
||||||
): Promise<{ success: boolean; error?: string }> {
|
): Promise<{ success: boolean; error?: string }> {
|
||||||
|
|
@ -131,7 +131,7 @@ export class RaidAdapter extends BaseAdapter {
|
||||||
*/
|
*/
|
||||||
async downloadRaidImages(
|
async downloadRaidImages(
|
||||||
slug: string,
|
slug: string,
|
||||||
downloadOptions?: { force?: boolean; size?: 'all' | 'icon' | 'thumbnail' },
|
downloadOptions?: { force?: boolean; size?: 'all' | 'icon' | 'thumbnail' | 'lobby' | 'background' },
|
||||||
requestOptions?: RequestOptions
|
requestOptions?: RequestOptions
|
||||||
): Promise<{ status: string; raidId: string; message: string }> {
|
): Promise<{ status: string; raidId: string; message: string }> {
|
||||||
return this.request(`/raids/${slug}/download_images`, {
|
return this.request(`/raids/${slug}/download_images`, {
|
||||||
|
|
|
||||||
|
|
@ -222,6 +222,7 @@ export interface Raid {
|
||||||
element: number
|
element: number
|
||||||
enemy_id?: number
|
enemy_id?: number
|
||||||
summon_id?: number
|
summon_id?: number
|
||||||
|
quest_id?: number
|
||||||
group?: RaidGroup
|
group?: RaidGroup
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ export interface RaidFull {
|
||||||
element: number
|
element: number
|
||||||
enemy_id?: number
|
enemy_id?: number
|
||||||
summon_id?: number
|
summon_id?: number
|
||||||
|
quest_id?: number
|
||||||
group?: RaidGroupFlat
|
group?: RaidGroupFlat
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -49,6 +50,7 @@ export interface CreateRaidInput {
|
||||||
group_id: string
|
group_id: string
|
||||||
enemy_id?: number
|
enemy_id?: number
|
||||||
summon_id?: number
|
summon_id?: number
|
||||||
|
quest_id?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface UpdateRaidInput {
|
export interface UpdateRaidInput {
|
||||||
|
|
@ -60,6 +62,7 @@ export interface UpdateRaidInput {
|
||||||
group_id?: string
|
group_id?: string
|
||||||
enemy_id?: number
|
enemy_id?: number
|
||||||
summon_id?: number
|
summon_id?: number
|
||||||
|
quest_id?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
// Input types for creating/updating raid groups
|
// Input types for creating/updating raid groups
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,8 @@
|
||||||
// CDN base URLs for raid images
|
// 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 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 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 {
|
function displayName(input: any): string {
|
||||||
if (!input) return '—'
|
if (!input) return '—'
|
||||||
|
|
@ -85,6 +87,16 @@
|
||||||
return `${THUMBNAIL_BASE_URL}/${summonId}_high.png`
|
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
|
// Get header image - prefer thumbnail, fallback to icon
|
||||||
const headerImage = $derived.by(() => {
|
const headerImage = $derived.by(() => {
|
||||||
if (raid?.summon_id) return getThumbnailUrl(raid.summon_id)
|
if (raid?.summon_id) return getThumbnailUrl(raid.summon_id)
|
||||||
|
|
@ -97,6 +109,10 @@
|
||||||
const sizes: string[] = []
|
const sizes: string[] = []
|
||||||
if (raid?.enemy_id) sizes.push('icon')
|
if (raid?.enemy_id) sizes.push('icon')
|
||||||
if (raid?.summon_id) sizes.push('thumbnail')
|
if (raid?.summon_id) sizes.push('thumbnail')
|
||||||
|
if (raid?.quest_id) {
|
||||||
|
sizes.push('lobby')
|
||||||
|
sizes.push('background')
|
||||||
|
}
|
||||||
return sizes
|
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
|
return images
|
||||||
})
|
})
|
||||||
|
|
||||||
// Image download handlers
|
// Image download handlers
|
||||||
|
type RaidImageSize = 'icon' | 'thumbnail' | 'lobby' | 'background'
|
||||||
|
|
||||||
async function handleDownloadImage(
|
async function handleDownloadImage(
|
||||||
size: string,
|
size: string,
|
||||||
_transformation: string | undefined,
|
_transformation: string | undefined,
|
||||||
force: boolean
|
force: boolean
|
||||||
) {
|
) {
|
||||||
if (!raidSlug) return
|
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) {
|
async function handleDownloadAllImages(force: boolean) {
|
||||||
|
|
@ -144,7 +176,7 @@
|
||||||
|
|
||||||
async function handleDownloadSize(size: string) {
|
async function handleDownloadSize(size: string) {
|
||||||
if (!raidSlug) return
|
if (!raidSlug) return
|
||||||
await raidAdapter.downloadRaidImage(raidSlug, size as 'icon' | 'thumbnail', false)
|
await raidAdapter.downloadRaidImage(raidSlug, size as RaidImageSize, false)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
@ -188,6 +220,7 @@
|
||||||
<DetailItem label="Level" value={raid.level?.toString() ?? '-'} />
|
<DetailItem label="Level" value={raid.level?.toString() ?? '-'} />
|
||||||
<DetailItem label="Enemy ID" value={raid.enemy_id?.toString() ?? '-'} />
|
<DetailItem label="Enemy ID" value={raid.enemy_id?.toString() ?? '-'} />
|
||||||
<DetailItem label="Summon ID" value={raid.summon_id?.toString() ?? '-'} />
|
<DetailItem label="Summon ID" value={raid.summon_id?.toString() ?? '-'} />
|
||||||
|
<DetailItem label="Quest ID" value={raid.quest_id?.toString() ?? '-'} />
|
||||||
<DetailItem label="Element">
|
<DetailItem label="Element">
|
||||||
{#if raid.element !== undefined && raid.element !== null}
|
{#if raid.element !== undefined && raid.element !== null}
|
||||||
<ElementBadge element={raid.element} />
|
<ElementBadge element={raid.element} />
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,8 @@
|
||||||
element: 0,
|
element: 0,
|
||||||
group_id: '',
|
group_id: '',
|
||||||
enemy_id: undefined as number | undefined,
|
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
|
// Sync edit data when raid changes
|
||||||
|
|
@ -73,7 +74,8 @@
|
||||||
element: raid.element ?? 0,
|
element: raid.element ?? 0,
|
||||||
group_id: raid.group?.id || '',
|
group_id: raid.group?.id || '',
|
||||||
enemy_id: raid.enemy_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,
|
element: editData.element,
|
||||||
group_id: editData.group_id,
|
group_id: editData.group_id,
|
||||||
enemy_id: editData.enemy_id,
|
enemy_id: editData.enemy_id,
|
||||||
summon_id: editData.summon_id
|
summon_id: editData.summon_id,
|
||||||
|
quest_id: editData.quest_id
|
||||||
})
|
})
|
||||||
|
|
||||||
// Invalidate queries
|
// Invalidate queries
|
||||||
|
|
@ -201,6 +204,12 @@
|
||||||
editable={true}
|
editable={true}
|
||||||
type="number"
|
type="number"
|
||||||
/>
|
/>
|
||||||
|
<DetailItem
|
||||||
|
label="Quest ID"
|
||||||
|
bind:value={editData.quest_id}
|
||||||
|
editable={true}
|
||||||
|
type="number"
|
||||||
|
/>
|
||||||
<DetailItem
|
<DetailItem
|
||||||
label="Element"
|
label="Element"
|
||||||
bind:value={editData.element}
|
bind:value={editData.element}
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,8 @@
|
||||||
element: 0,
|
element: 0,
|
||||||
group_id: '',
|
group_id: '',
|
||||||
enemy_id: undefined as number | undefined,
|
enemy_id: undefined as number | undefined,
|
||||||
summon_id: undefined as number | undefined
|
summon_id: undefined as number | undefined,
|
||||||
|
quest_id: undefined as number | undefined
|
||||||
})
|
})
|
||||||
|
|
||||||
// Element options
|
// Element options
|
||||||
|
|
@ -89,7 +90,8 @@
|
||||||
element: editData.element,
|
element: editData.element,
|
||||||
group_id: editData.group_id,
|
group_id: editData.group_id,
|
||||||
enemy_id: editData.enemy_id,
|
enemy_id: editData.enemy_id,
|
||||||
summon_id: editData.summon_id
|
summon_id: editData.summon_id,
|
||||||
|
quest_id: editData.quest_id
|
||||||
})
|
})
|
||||||
|
|
||||||
// Invalidate queries
|
// Invalidate queries
|
||||||
|
|
@ -167,6 +169,12 @@
|
||||||
editable={true}
|
editable={true}
|
||||||
type="number"
|
type="number"
|
||||||
/>
|
/>
|
||||||
|
<DetailItem
|
||||||
|
label="Quest ID"
|
||||||
|
bind:value={editData.quest_id}
|
||||||
|
editable={true}
|
||||||
|
type="number"
|
||||||
|
/>
|
||||||
<DetailItem
|
<DetailItem
|
||||||
label="Element"
|
label="Element"
|
||||||
bind:value={editData.element}
|
bind:value={editData.element}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue