extract CharacterTags component, use in unit and search
This commit is contained in:
parent
d0fc56d00c
commit
321e7585b8
5 changed files with 89 additions and 53 deletions
|
|
@ -3,9 +3,7 @@
|
|||
<script lang="ts">
|
||||
import type { Cell } from 'wx-svelte-grid'
|
||||
import type { Character } from '$lib/types/api/entities'
|
||||
import type { CharacterSeriesRef } from '$lib/types/api/characterSeries'
|
||||
import CharacterTag from '$lib/components/tags/CharacterTag.svelte'
|
||||
import { CHARACTER_SEASON_NAMES, CHARACTER_SERIES_NAMES } from '$lib/types/enums'
|
||||
import CharacterTags from '$lib/components/tags/CharacterTags.svelte'
|
||||
|
||||
const { row }: Cell = $props()
|
||||
|
||||
|
|
@ -19,52 +17,11 @@
|
|||
if (typeof nameObj === 'string') return nameObj
|
||||
return nameObj.en || nameObj.ja || '—'
|
||||
})
|
||||
|
||||
// Get season text for comparison
|
||||
const seasonText = $derived.by(() => {
|
||||
if (character.season === undefined || character.season === null || character.season <= 0) {
|
||||
return null
|
||||
}
|
||||
return CHARACTER_SEASON_NAMES[character.season] ?? null
|
||||
})
|
||||
|
||||
// Get first series text for comparison
|
||||
const seriesText = $derived.by(() => {
|
||||
if (!character.series || !Array.isArray(character.series) || character.series.length === 0) {
|
||||
return null
|
||||
}
|
||||
const seriesValue = character.series[0] as number | CharacterSeriesRef
|
||||
if (typeof seriesValue === 'object' && seriesValue !== null && 'name' in seriesValue) {
|
||||
return seriesValue.name.en
|
||||
}
|
||||
if (typeof seriesValue === 'number') {
|
||||
return CHARACTER_SERIES_NAMES[seriesValue] ?? null
|
||||
}
|
||||
return null
|
||||
})
|
||||
|
||||
// Special case: Yukata is more specific than Summer, so hide Summer if Yukata is present
|
||||
const isYukataWithSummer = $derived(seriesText === 'Yukata' && seasonText === 'Summer')
|
||||
|
||||
// Check if character has season (seasonal variant), but hide if Yukata+Summer
|
||||
const hasSeason = $derived(seasonText !== null && !isYukataWithSummer)
|
||||
|
||||
// Check if character has series with different text than season
|
||||
const hasDistinctSeries = $derived(seriesText !== null && seriesText !== seasonText)
|
||||
</script>
|
||||
|
||||
<div class="name-cell">
|
||||
<span class="name">{displayName}</span>
|
||||
{#if hasSeason || hasDistinctSeries}
|
||||
<div class="tags">
|
||||
{#if hasSeason}
|
||||
<CharacterTag {character} type="season" />
|
||||
{/if}
|
||||
{#if hasDistinctSeries}
|
||||
<CharacterTag {character} type="series" />
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
<CharacterTags {character} />
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
|
|
@ -81,10 +38,4 @@
|
|||
.name {
|
||||
font-weight: $medium;
|
||||
}
|
||||
|
||||
.tags {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: $unit-half;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
import { collectionQueries } from '$lib/api/queries/collection.queries'
|
||||
import Button from '../ui/Button.svelte'
|
||||
import Icon from '../Icon.svelte'
|
||||
import CharacterTags from '$lib/components/tags/CharacterTags.svelte'
|
||||
import { IsInViewport } from 'runed'
|
||||
import { getCharacterImage, getWeaponImage, getSummonImage } from '$lib/features/database/detail/image'
|
||||
import type { AddItemResult, SearchMode } from '$lib/types/api/search'
|
||||
|
|
@ -447,6 +448,9 @@
|
|||
loading="lazy"
|
||||
/>
|
||||
<span class="result-name">{getItemName(item)}</span>
|
||||
{#if type === 'character'}
|
||||
<CharacterTags character={item} />
|
||||
{/if}
|
||||
{#if item.collectionId}
|
||||
<Icon name="bookmark" size={14} class="collection-indicator" />
|
||||
{:else if owned}
|
||||
|
|
|
|||
77
src/lib/components/tags/CharacterTags.svelte
Normal file
77
src/lib/components/tags/CharacterTags.svelte
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
<svelte:options runes={true} />
|
||||
|
||||
<script lang="ts">
|
||||
import type { CharacterSeriesRef } from '$lib/types/api/characterSeries'
|
||||
import CharacterTag from './CharacterTag.svelte'
|
||||
import { CHARACTER_SEASON_NAMES, CHARACTER_SERIES_NAMES } from '$lib/types/enums'
|
||||
|
||||
/** Minimal character data needed for tag display */
|
||||
interface CharacterForTags {
|
||||
element?: number | null
|
||||
season?: number | null
|
||||
series?: (number | CharacterSeriesRef)[] | null
|
||||
seriesNames?: string[] | null
|
||||
}
|
||||
|
||||
interface Props {
|
||||
character: CharacterForTags
|
||||
}
|
||||
|
||||
let { character }: Props = $props()
|
||||
|
||||
// Get season text for comparison
|
||||
const seasonText = $derived.by(() => {
|
||||
if (character.season === undefined || character.season === null || character.season <= 0) {
|
||||
return null
|
||||
}
|
||||
return CHARACTER_SEASON_NAMES[character.season] ?? null
|
||||
})
|
||||
|
||||
// Get first series text for comparison
|
||||
const seriesText = $derived.by(() => {
|
||||
if (!character.series || !Array.isArray(character.series) || character.series.length === 0) {
|
||||
return null
|
||||
}
|
||||
const seriesValue = character.series[0] as number | CharacterSeriesRef
|
||||
if (typeof seriesValue === 'object' && seriesValue !== null && 'name' in seriesValue) {
|
||||
return seriesValue.name.en
|
||||
}
|
||||
if (typeof seriesValue === 'number') {
|
||||
return CHARACTER_SERIES_NAMES[seriesValue] ?? null
|
||||
}
|
||||
return null
|
||||
})
|
||||
|
||||
// Special case: Yukata is more specific than Summer, so hide Summer if Yukata is present
|
||||
const isYukataWithSummer = $derived(seriesText === 'Yukata' && seasonText === 'Summer')
|
||||
|
||||
// Check if character has season (seasonal variant), but hide if Yukata+Summer
|
||||
const hasSeason = $derived(seasonText !== null && !isYukataWithSummer)
|
||||
|
||||
// Check if character has series with different text than season
|
||||
const hasDistinctSeries = $derived(seriesText !== null && seriesText !== seasonText)
|
||||
|
||||
// Whether any tags should be shown
|
||||
const hasTags = $derived(hasSeason || hasDistinctSeries)
|
||||
</script>
|
||||
|
||||
{#if hasTags}
|
||||
<div class="tags">
|
||||
{#if hasSeason}
|
||||
<CharacterTag {character} type="season" />
|
||||
{/if}
|
||||
{#if hasDistinctSeries}
|
||||
<CharacterTag {character} type="series" />
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<style lang="scss">
|
||||
@use '$src/themes/spacing' as *;
|
||||
|
||||
.tags {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: $unit-half;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -6,6 +6,7 @@
|
|||
import UnitMenuContainer from '$lib/components/ui/menu/UnitMenuContainer.svelte'
|
||||
import MenuItems from '$lib/components/ui/menu/MenuItems.svelte'
|
||||
import UncapIndicator from '$lib/components/uncap/UncapIndicator.svelte'
|
||||
import CharacterTags from '$lib/components/tags/CharacterTags.svelte'
|
||||
import { getCharacterImageWithPose } from '$lib/utils/images'
|
||||
import { openDetailsSidebar } from '$lib/features/details/openDetailsSidebar.svelte'
|
||||
import { sidebar } from '$lib/stores/sidebar.svelte'
|
||||
|
|
@ -326,6 +327,9 @@
|
|||
<Icon name="gem" size={12} class="artifact-indicator" />
|
||||
{/if}
|
||||
</div>
|
||||
{#if item?.character}
|
||||
<CharacterTags character={item.character} />
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@
|
|||
buildKamigameUrl
|
||||
} from '$lib/utils/external-links'
|
||||
import Button from '$lib/components/ui/Button.svelte'
|
||||
import CharacterTag from '$lib/components/tags/CharacterTag.svelte'
|
||||
import CharacterTags from '$lib/components/tags/CharacterTags.svelte'
|
||||
|
||||
// Types
|
||||
import type { PageData } from './$types'
|
||||
|
|
@ -325,7 +325,7 @@
|
|||
class="related-image"
|
||||
/>
|
||||
<span class="related-name">{related.name.en}</span>
|
||||
<CharacterTag character={related} type="element" />
|
||||
<CharacterTags character={related} />
|
||||
</a>
|
||||
{/each}
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Reference in a new issue