diff --git a/src/lib/components/units/CharacterUnit.svelte b/src/lib/components/units/CharacterUnit.svelte index e0283e02..4bd3d492 100644 --- a/src/lib/components/units/CharacterUnit.svelte +++ b/src/lib/components/units/CharacterUnit.svelte @@ -5,13 +5,14 @@ import { getContext } from 'svelte' import Icon from '$lib/components/Icon.svelte' import ContextMenu from '$lib/components/ui/ContextMenu.svelte' - import { ContextMenu as ContextMenuBase } from 'bits-ui' + import { ContextMenu as ContextMenuBase, DropdownMenu as DropdownMenuBase } from 'bits-ui' import UncapIndicator from '$lib/components/uncap/UncapIndicator.svelte' import { getCharacterImageWithPose } from '$lib/utils/images' import { openDetailsSidebar } from '$lib/features/details/openDetailsSidebar.svelte' import { getJobPortraitUrl, Gender } from '$lib/utils/jobUtils' import perpetuityFilled from '$src/assets/icons/perpetuity/filled.svg' import perpetuityEmpty from '$src/assets/icons/perpetuity/empty.svg' + import * as m from '$lib/paraglide/messages' interface Props { item?: GridCharacter @@ -141,35 +142,42 @@
{#if item} - + {#snippet children()} {#key item?.id ?? position}
viewDetails()} > - {#if ctx?.canEdit()} - + {:else if item.perpetuity} Add Perpetuity Ring - - {:else if item.perpetuity} - Perpetuity Ring + {/if} {/if} - View Details + {m.context_view_details()} {#if ctx?.canEdit()} - Replace + {m.context_replace()} - Remove + {m.context_remove()} {/if} {/snippet} + + {#snippet dropdownMenu()} + + {m.context_view_details()} + + {#if ctx?.canEdit()} + + {m.context_replace()} + + + + {m.context_remove()} + + {/if} + {/snippet} {:else} {#key `empty-${position}`} @@ -213,8 +236,8 @@ class="image" class:placeholder={!isProtagonist || !job} class:protagonist={isProtagonist} - alt={isProtagonist && job ? job.name.en : ""} - src={isProtagonist ? imageUrl : "/images/placeholders/placeholder-weapon-grid.png"} + alt={isProtagonist && job ? job.name.en : ''} + src={isProtagonist ? imageUrl : '/images/placeholders/placeholder-weapon-grid.png'} /> {#if ctx?.canEdit()} @@ -318,6 +341,13 @@ .frame.character.cell { @include rep.aspect(rep.$char-cell-w, rep.$char-cell-h); + + &.protagonist { + background-image: url('/images/relief.png'), linear-gradient(to right, #000, #484440, #000); + background-size: cover; + background-position: center -20px; + background-repeat: no-repeat; + } } .image { diff --git a/src/lib/components/units/SummonUnit.svelte b/src/lib/components/units/SummonUnit.svelte index 25ece0c9..81f1158e 100644 --- a/src/lib/components/units/SummonUnit.svelte +++ b/src/lib/components/units/SummonUnit.svelte @@ -4,10 +4,11 @@ import { getContext } from 'svelte' import Icon from '$lib/components/Icon.svelte' import ContextMenu from '$lib/components/ui/ContextMenu.svelte' - import { ContextMenu as ContextMenuBase } from 'bits-ui' + import { ContextMenu as ContextMenuBase, DropdownMenu as DropdownMenuBase } from 'bits-ui' import UncapIndicator from '$lib/components/uncap/UncapIndicator.svelte' import { getSummonImage } from '$lib/features/database/detail/image' import { openDetailsSidebar } from '$lib/features/details/openDetailsSidebar.svelte' + import * as m from '$lib/paraglide/messages' interface Props { item?: GridSummon @@ -34,9 +35,10 @@ } // Use $derived to ensure consistent computation between server and client let imageUrl = $derived.by(() => { - // Check position first for main/friend summon determination - const isMain = position === -1 || position === 6 || item?.main || item?.friend - const variant = isMain ? 'main' : 'grid' + // Only position -1 (main) and position 6 (friend) use main-sized images + // All other positions (0-5) including subaura (4-5) use grid-sized images + const isMainSized = position === -1 || position === 6 || item?.main || item?.friend + const variant = isMainSized ? 'main' : 'grid' return getSummonImage(item?.summon?.granblueId, variant) }) @@ -74,7 +76,7 @@
{#if item} - + {#snippet children()} {#key item?.id ?? position}
- {#if ctx?.canEdit() && item?.id} -
- -
- {/if} {#if item?.main || position === -1} Main {/if} @@ -106,20 +103,35 @@ {/key} {/snippet} - {#snippet menu()} + {#snippet contextMenu()} - View Details + {m.context_view_details()} {#if ctx?.canEdit()} - Replace + {m.context_replace()} - Remove + {m.context_remove()} {/if} {/snippet} + + {#snippet dropdownMenu()} + + {m.context_view_details()} + + {#if ctx?.canEdit()} + + {m.context_replace()} + + + + {m.context_remove()} + + {/if} + {/snippet} {:else} {#key `empty-${position}`} @@ -263,26 +275,6 @@ color: $grey-50; } - .actions { - position: absolute; - top: 6px; - right: 6px; - display: flex; - gap: 6px; - z-index: 3; - } - - .remove { - background: rgba(0,0,0,.6); - color: white; - border: none; - border-radius: 12px; - width: 24px; - height: 24px; - line-height: 24px; - cursor: pointer; - } - .badge { position: absolute; left: 6px; diff --git a/src/lib/components/units/WeaponUnit.svelte b/src/lib/components/units/WeaponUnit.svelte index 6f89eac6..13bedb4d 100644 --- a/src/lib/components/units/WeaponUnit.svelte +++ b/src/lib/components/units/WeaponUnit.svelte @@ -4,11 +4,12 @@ import { getContext } from 'svelte' import Icon from '$lib/components/Icon.svelte' import ContextMenu from '$lib/components/ui/ContextMenu.svelte' - import { ContextMenu as ContextMenuBase } from 'bits-ui' + import { ContextMenu as ContextMenuBase, DropdownMenu as DropdownMenuBase } from 'bits-ui' import UncapIndicator from '$lib/components/uncap/UncapIndicator.svelte' import { getWeaponImage } from '$lib/features/database/detail/image' import { openDetailsSidebar } from '$lib/features/details/openDetailsSidebar.svelte' import { getAwakeningImage, getWeaponKeyImages, getAxSkillImages } from '$lib/utils/modifiers' + import * as m from '$lib/paraglide/messages' interface Props { item?: GridWeapon @@ -96,7 +97,7 @@
= 9}> {#if item} - + {#snippet children()} {#key item?.id ?? position}
- View Details + {m.context_view_details()} {#if ctx?.canEdit()} - Replace + {m.context_replace()} - Remove + {m.context_remove()} {/if} {/snippet} + + {#snippet dropdownMenu()} + + {m.context_view_details()} + + {#if ctx?.canEdit()} + + {m.context_replace()} + + + + {m.context_remove()} + + {/if} + {/snippet} {:else} {#key `empty-${position}`} @@ -218,6 +234,7 @@ @use '$src/themes/colors' as *; @use '$src/themes/typography' as *; @use '$src/themes/spacing' as *; + @use '$src/themes/layout' as *; @use '$src/themes/rep' as rep; .unit { @@ -265,13 +282,21 @@ justify-content: center; cursor: pointer; - &:hover { + &.editable:hover { opacity: 0.95; box-shadow: 0 2px 4px rgba(0,0,0,0.1); + transform: $scale-wide; + } + } + + .frame.weapon.main { + @include rep.aspect(rep.$weapon-main-w, rep.$weapon-main-h); + + &.editable:hover { + transform: $scale-tall; } } - .frame.weapon.main { @include rep.aspect(rep.$weapon-main-w, rep.$weapon-main-h); } .frame.weapon.cell { @include rep.aspect(rep.$weapon-cell-w, rep.$weapon-cell-h); } .image {