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">
import type { Party, GridWeapon, GridCharacter } from '$lib/types/api/party'
export let party: Party
import { getElementClass } from '$lib/types/enums'
const characters = party.characters || []
const grid = Array.from({ length: 3 }, (_, i) =>
characters.find((c: GridCharacter) => c?.position === i)
)
function protagonistClass(): string {
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 ''
}
interface Props {
party?: Party
characters?: GridCharacter[]
jobId?: string
element?: number
gender?: number
}
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 {
const id = c?.character?.granblueId
if (!id) return ''
@ -39,7 +40,7 @@
if (trans > 0) suffix = '04'
else if (uncap >= 5) suffix = '03'
else if (uncap > 2) suffix = '02'
if (String(id) === '3030182000') {
if (String(id) === '3030182000' && party) {
const main: GridWeapon | undefined = (party.weapons || []).find(
(w: GridWeapon) => w?.mainhand || w?.position === -1
)
@ -52,7 +53,7 @@
<div class="rep">
<ul class="characters">
<li class={`protagonist ${protagonistClass()}`} class:empty={!protagonistClass()}></li>
<li class={`protagonist ${protagonistClass}`} class:empty={!protagonistClass}></li>
{#each grid as c, i}
<li class="character" class:empty={!c}>
{#if c}<img

View file

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

View file

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