refactor(fend): character-level operations on the left, global operations on the right
This commit is contained in:
parent
ef0c982d98
commit
b7fe539cf0
4 changed files with 77 additions and 59 deletions
|
|
@ -1,36 +1,78 @@
|
|||
<script lang="ts">
|
||||
import { Sun, Moon } from 'lucide-svelte';
|
||||
import { Sun, Moon, Share2, Check, Trash2 } from 'lucide-svelte';
|
||||
import { theme } from '$lib/theme.svelte';
|
||||
import { roster } from '$lib/state.svelte';
|
||||
import { presets } from '$lib/presets';
|
||||
import { encodeCharacterURL } from '$lib/sharing';
|
||||
import { slugify } from '$lib/utils/slugify';
|
||||
import CharacterSwitcher from './CharacterSwitcher.svelte';
|
||||
import Modal from './Modal.svelte';
|
||||
|
||||
let shared = $state(false);
|
||||
let confirmDelete = $state(false);
|
||||
|
||||
async function createCharacter() {
|
||||
await roster.create(presets[0]);
|
||||
}
|
||||
|
||||
async function share() {
|
||||
const char = roster.active;
|
||||
if (!char) return;
|
||||
const encoded = encodeCharacterURL(char);
|
||||
const url = `${window.location.origin}${window.location.pathname}#${encoded}`;
|
||||
await navigator.clipboard.writeText(url);
|
||||
shared = true;
|
||||
setTimeout(() => { shared = false; }, 2000);
|
||||
}
|
||||
|
||||
function displayName(): string {
|
||||
const char = roster.active;
|
||||
if (!char) return '';
|
||||
const name = char.data[slugify('Name')];
|
||||
return (name as string) || 'Unnamed Character';
|
||||
}
|
||||
|
||||
async function doDelete() {
|
||||
if (roster.active) {
|
||||
await roster.remove(roster.active.id);
|
||||
}
|
||||
confirmDelete = false;
|
||||
}
|
||||
</script>
|
||||
|
||||
<header class="flex items-center gap-3 px-4 py-3 border-b shrink-0" style="border-color: var(--border); background: var(--bg-card);">
|
||||
<header class="flex items-center gap-2 px-4 py-3 border-b shrink-0" style="border-color: var(--border); background: var(--bg-card);">
|
||||
<h1 class="font-bold whitespace-nowrap">Aurora Records</h1>
|
||||
|
||||
{#if roster.characters.length > 0}
|
||||
<CharacterSwitcher />
|
||||
|
||||
<button onclick={share} class="flex items-center justify-center w-[30px] h-[30px] rounded border hover:opacity-80" style="border-color: var(--border);" title="Share character">
|
||||
{#if shared}
|
||||
<Check size={14} />
|
||||
{:else}
|
||||
<Share2 size={14} />
|
||||
{/if}
|
||||
</button>
|
||||
|
||||
<button onclick={() => { confirmDelete = true; }} class="flex items-center justify-center w-[30px] h-[30px] rounded border hover:opacity-80" style="border-color: var(--border);" title="Delete character">
|
||||
<Trash2 size={14} />
|
||||
</button>
|
||||
{/if}
|
||||
|
||||
<div class="ml-auto flex items-center gap-3">
|
||||
<div class="ml-auto flex items-center gap-2">
|
||||
<span class="text-sm" style="color: var(--text-muted);">
|
||||
{#if roster.saveStatus === 'saving'}Saving...{:else if roster.saveStatus === 'saved'}Saved{/if}
|
||||
</span>
|
||||
|
||||
<button
|
||||
onclick={createCharacter}
|
||||
class="px-3 py-1 rounded text-sm border hover:opacity-80"
|
||||
class="px-3 h-[30px] rounded text-sm border hover:opacity-80"
|
||||
style="border-color: var(--border);"
|
||||
>
|
||||
New Character
|
||||
</button>
|
||||
|
||||
<button onclick={() => theme.toggle()} class="p-1 rounded hover:opacity-80" title="Toggle theme">
|
||||
<button onclick={() => theme.toggle()} class="flex items-center justify-center w-[30px] h-[30px] rounded hover:opacity-80" title="Toggle theme">
|
||||
{#if theme.dark}
|
||||
<Sun size={18} />
|
||||
{:else}
|
||||
|
|
@ -39,3 +81,18 @@
|
|||
</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
{#if confirmDelete && roster.active}
|
||||
<Modal onClose={() => { confirmDelete = false; }}>
|
||||
<h2 class="font-semibold mb-2">Delete Character</h2>
|
||||
<p class="text-sm mb-4">Delete <strong>{displayName()}</strong>? This can't be undone.</p>
|
||||
<div class="flex gap-2 justify-end">
|
||||
<button onclick={() => { confirmDelete = false; }} class="px-3 py-1 rounded text-sm border hover:opacity-80" style="border-color: var(--border);">
|
||||
Cancel
|
||||
</button>
|
||||
<button onclick={doDelete} class="px-3 py-1 rounded text-sm border hover:opacity-80" style="border-color: var(--border); color: #dc2626;">
|
||||
Delete
|
||||
</button>
|
||||
</div>
|
||||
</Modal>
|
||||
{/if}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue