refactor rep components to accept flexible props

This commit is contained in:
Justin Edmund 2025-09-16 20:09:20 -07:00
parent fed7b5ae50
commit acf49c718c
3 changed files with 70 additions and 49 deletions

View file

@ -1,35 +1,36 @@
<script lang="ts"> <script lang="ts">
import type { Party, GridWeapon, GridCharacter } from '$lib/types/api/party' import type { Party, GridWeapon, GridCharacter } from '$lib/types/api/party'
export let party: Party import { getElementClass } from '$lib/types/enums'
const characters = party.characters || [] interface Props {
const grid = Array.from({ length: 3 }, (_, i) => party?: Party
characters.find((c: GridCharacter) => c?.position === i) characters?: GridCharacter[]
) jobId?: string
element?: number
function protagonistClass(): string { gender?: number
const main: GridWeapon | undefined = (party.weapons || []).find(
(w: GridWeapon) => w?.mainhand || w?.position === -1
)
const el = main?.element ?? main?.weapon?.element
switch (el) {
case 1:
return 'wind'
case 2:
return 'fire'
case 3:
return 'water'
case 4:
return 'earth'
case 5:
return 'dark'
case 6:
return 'light'
default:
return ''
}
} }
let { party, characters: directCharacters, jobId, element, gender }: Props = $props()
// Use direct characters if provided, otherwise get from party
const characters = $derived(directCharacters || party?.characters || [])
const grid = $derived(Array.from({ length: 3 }, (_, i) =>
characters.find((c: GridCharacter) => c?.position === i)
))
const protagonistClass = $derived(
// If element is directly provided, use it
element ? getElementClass(element) :
// Otherwise try to get from party's mainhand weapon
party ? (() => {
const main: GridWeapon | undefined = (party.weapons || []).find(
(w: GridWeapon) => w?.mainhand || w?.position === -1
)
const el = main?.element ?? main?.weapon?.element
return getElementClass(el) || ''
})() : ''
)
function characterImageUrl(c?: GridCharacter): string { function characterImageUrl(c?: GridCharacter): string {
const id = c?.character?.granblueId const id = c?.character?.granblueId
if (!id) return '' if (!id) return ''
@ -39,7 +40,7 @@
if (trans > 0) suffix = '04' if (trans > 0) suffix = '04'
else if (uncap >= 5) suffix = '03' else if (uncap >= 5) suffix = '03'
else if (uncap > 2) suffix = '02' else if (uncap > 2) suffix = '02'
if (String(id) === '3030182000') { if (String(id) === '3030182000' && party) {
const main: GridWeapon | undefined = (party.weapons || []).find( const main: GridWeapon | undefined = (party.weapons || []).find(
(w: GridWeapon) => w?.mainhand || w?.position === -1 (w: GridWeapon) => w?.mainhand || w?.position === -1
) )
@ -52,7 +53,7 @@
<div class="rep"> <div class="rep">
<ul class="characters"> <ul class="characters">
<li class={`protagonist ${protagonistClass()}`} class:empty={!protagonistClass()}></li> <li class={`protagonist ${protagonistClass}`} class:empty={!protagonistClass}></li>
{#each grid as c, i} {#each grid as c, i}
<li class="character" class:empty={!c}> <li class="character" class:empty={!c}>
{#if c}<img {#if c}<img

View file

@ -1,22 +1,26 @@
<script lang="ts"> <script lang="ts">
import type { Party, GridSummon } from '$lib/types/api/party' import type { Party, GridSummon } from '$lib/types/api/party'
export let party: Party interface Props {
export let extendedView = false party?: Party
summons?: GridSummon[]
extendedView?: boolean
}
const summons = party.summons || [] let { party, summons: directSummons, extendedView = false }: Props = $props()
const main: GridSummon | undefined = summons.find(
(s: GridSummon) => s?.main || s?.position === -1 // Use direct summons if provided, otherwise get from party
const summons = $derived(directSummons || party?.summons || [])
const main = $derived(summons.find((s: GridSummon) => s?.main || s?.position === -1))
const friend = $derived(
extendedView ? summons.find((s: GridSummon) => s?.friend || s?.position === -2) : undefined
) )
const friend: GridSummon | undefined = extendedView
? summons.find((s: GridSummon) => s?.friend || s?.position === -2)
: undefined
// In standard view: show positions 0-3 (4 summons) // In standard view: show positions 0-3 (4 summons)
// In extended view: show positions 0-5 (6 summons including subauras) // In extended view: show positions 0-5 (6 summons including subauras)
const gridLength = extendedView ? 6 : 4 const gridLength = $derived(extendedView ? 6 : 4)
const grid = Array.from({ length: gridLength }, (_, i) => const grid = $derived(
summons.find((s: GridSummon) => s?.position === i) Array.from({ length: gridLength }, (_, i) => summons.find((s: GridSummon) => s?.position === i))
) )
function summonImageUrl(s?: GridSummon, isMain = false): string { function summonImageUrl(s?: GridSummon, isMain = false): string {
@ -64,12 +68,21 @@
width: 100%; width: 100%;
height: 100%; height: 100%;
display: grid; display: grid;
gap: calc($unit-half + 1px); gap: $unit-half;
// Standard view layout: main summon | 4 grid summons
grid-template-columns: 0.96fr 2.2fr;
grid-template-rows: 1fr;
// Extended view layout: main summon | 6 grid summons | friend summon // Extended view layout: main summon | 6 grid summons | friend summon
&.extended { &.extended {
gap: calc($unit-half + 1px);
grid-template-columns: auto 1fr auto; grid-template-columns: auto 1fr auto;
.mainSummon {
min-width: 69px;
}
.mainSummon, .mainSummon,
.friendSummon { .friendSummon {
@include rep.aspect(56, 97); @include rep.aspect(56, 97);
@ -111,6 +124,8 @@
.mainSummon { .mainSummon {
@include rep.aspect(56, 97); @include rep.aspect(56, 97);
display: grid; display: grid;
max-width: 70px;
height: auto;
} }
.summons { .summons {
@ -118,6 +133,7 @@
margin: 0; margin: 0;
padding: 0; padding: 0;
list-style: none; list-style: none;
align-content: center; // Center the grid vertically
} }
.summon { .summon {

View file

@ -1,14 +1,18 @@
<script lang="ts"> <script lang="ts">
import type { Party, GridWeapon } from '$lib/types/api/party' import type { Party, GridWeapon } from '$lib/types/api/party'
export let party: Party interface Props {
party?: Party
weapons?: GridWeapon[]
}
const weapons = party.weapons || [] let { party, weapons: directWeapons }: Props = $props()
const mainhand: GridWeapon | undefined = weapons.find(
(w: GridWeapon) => w?.mainhand || w?.position === -1 // Use direct weapons if provided, otherwise get from party
) const weapons = $derived(directWeapons || party?.weapons || [])
const grid = Array.from({ length: 9 }, (_, i) => const mainhand = $derived(weapons.find((w: GridWeapon) => w?.mainhand || w?.position === -1))
weapons.find((w: GridWeapon) => w?.position === i) const grid = $derived(
Array.from({ length: 9 }, (_, i) => weapons.find((w: GridWeapon) => w?.position === i))
) )
function weaponImageUrl(w?: GridWeapon, isMain = false): string { function weaponImageUrl(w?: GridWeapon, isMain = false): string {
@ -79,7 +83,7 @@
.weapons { .weapons {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: $unit-half; gap: $unit;
height: 100%; height: 100%;
.weapon-row { .weapon-row {