Started working on adding mobile buzzers, a lot of rewriting
This commit is contained in:
153
src/lib/components/editor/EditorHeader.svelte
Normal file
153
src/lib/components/editor/EditorHeader.svelte
Normal file
@@ -0,0 +1,153 @@
|
||||
<script lang="ts">
|
||||
import { editorStore } from "$lib/stores/editor.svelte";
|
||||
import { KvButton } from "$lib/components/kuldvillak/ui";
|
||||
import * as m from "$lib/paraglide/messages";
|
||||
|
||||
interface Props {
|
||||
gameName: string;
|
||||
onStart: () => void;
|
||||
onReset: () => void;
|
||||
onSettings?: () => void;
|
||||
onImportSuccess?: () => void;
|
||||
onImportError?: (error: string) => void;
|
||||
}
|
||||
|
||||
let {
|
||||
gameName = $bindable(),
|
||||
onStart,
|
||||
onReset,
|
||||
onSettings,
|
||||
onImportSuccess,
|
||||
onImportError,
|
||||
}: Props = $props();
|
||||
|
||||
let fileInput: HTMLInputElement;
|
||||
|
||||
function handleExport() {
|
||||
const { blob, filename } = editorStore.exportGame();
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement("a");
|
||||
a.href = url;
|
||||
a.download = filename;
|
||||
a.click();
|
||||
URL.revokeObjectURL(url);
|
||||
}
|
||||
|
||||
function handleImport(event: Event) {
|
||||
const file = (event.target as HTMLInputElement).files?.[0];
|
||||
if (!file) return;
|
||||
|
||||
const reader = new FileReader();
|
||||
reader.onload = (e) => {
|
||||
try {
|
||||
const data = JSON.parse(e.target?.result as string);
|
||||
const result = editorStore.importGame(data);
|
||||
if (result === true) {
|
||||
gameName = editorStore.gameName;
|
||||
onImportSuccess?.();
|
||||
} else {
|
||||
onImportError?.(result);
|
||||
}
|
||||
} catch {
|
||||
onImportError?.(m.kv_toast_invalid_file());
|
||||
}
|
||||
};
|
||||
reader.readAsText(file);
|
||||
(event.target as HTMLInputElement).value = "";
|
||||
}
|
||||
|
||||
// SVG Icons
|
||||
const BackIcon = `<path d="M29.5334 40L13.5334 24L29.5334 8L33.2668 11.7333L21.0001 24L33.2668 36.2667L29.5334 40Z"/>`;
|
||||
const LoadIcon = `<path d="M5.41634 33.3332C4.49967 33.3332 3.71495 33.0068 3.06217 32.354C2.4094 31.7012 2.08301 30.9165 2.08301 29.9998V9.99984C2.08301 9.08317 2.4094 8.29845 3.06217 7.64567C3.71495 6.99289 4.49967 6.6665 5.41634 6.6665H15.4163L18.7497 9.99984H32.083C32.9997 9.99984 33.7844 10.3262 34.4372 10.979C35.09 11.6318 35.4163 12.4165 35.4163 13.3332H17.3747L14.0413 9.99984H5.41634V29.9998L9.41634 16.6665H37.9163L33.6247 30.9582C33.4025 31.6804 32.9927 32.2568 32.3955 32.6873C31.7983 33.1179 31.1386 33.3332 30.4163 33.3332H5.41634ZM8.91634 29.9998H30.4163L33.4163 19.9998H11.9163L8.91634 29.9998Z"/>`;
|
||||
const SaveIcon = `<path d="M35 11.6667V31.6667C35 32.5833 34.6736 33.3681 34.0208 34.0208C33.3681 34.6736 32.5833 35 31.6667 35H8.33333C7.41667 35 6.63194 34.6736 5.97917 34.0208C5.32639 33.3681 5 32.5833 5 31.6667V8.33333C5 7.41667 5.32639 6.63194 5.97917 5.97917C6.63194 5.32639 7.41667 5 8.33333 5H28.3333L35 11.6667ZM31.6667 13.0833L26.9167 8.33333H8.33333V31.6667H31.6667V13.0833ZM20 30C21.3889 30 22.5694 29.5139 23.5417 28.5417C24.5139 27.5694 25 26.3889 25 25C25 23.6111 24.5139 22.4306 23.5417 21.4583C22.5694 20.4861 21.3889 20 20 20C18.6111 20 17.4306 20.4861 16.4583 21.4583C15.4861 22.4306 15 23.6111 15 25C15 26.3889 15.4861 27.5694 16.4583 28.5417C17.4306 29.5139 18.6111 30 20 30ZM10 16.6667H25V10H10V16.6667Z"/>`;
|
||||
const ResetIcon = `<path d="M20.0837 33.3332C16.3614 33.3332 13.1948 32.0415 10.5837 29.4582C7.97255 26.8748 6.66699 23.7221 6.66699 19.9998V19.7082L4.00033 22.3748L1.66699 20.0415L8.33366 13.3748L15.0003 20.0415L12.667 22.3748L10.0003 19.7082V19.9998C10.0003 22.7776 10.9795 25.1387 12.9378 27.0832C14.8962 29.0276 17.2781 29.9998 20.0837 29.9998C20.8059 29.9998 21.5142 29.9165 22.2087 29.7498C22.9031 29.5832 23.5837 29.3332 24.2503 28.9998L26.7503 31.4998C25.6948 32.111 24.6114 32.5693 23.5003 32.8748C22.3892 33.1804 21.2503 33.3332 20.0837 33.3332ZM31.667 26.6248L25.0003 19.9582L27.3337 17.6248L30.0003 20.2915V19.9998C30.0003 17.2221 29.0212 14.8609 27.0628 12.9165C25.1045 10.9721 22.7225 9.99984 19.917 9.99984C19.1948 9.99984 18.4864 10.0832 17.792 10.2498C17.0975 10.4165 16.417 10.6665 15.7503 10.9998L13.2503 8.49984C14.3059 7.88873 15.3892 7.43039 16.5003 7.12484C17.6114 6.81928 18.7503 6.6665 19.917 6.6665C23.6392 6.6665 26.8059 7.95817 29.417 10.5415C32.0281 13.1248 33.3337 16.2776 33.3337 19.9998V20.2915L36.0003 17.6248L38.3337 19.9582L31.667 26.6248Z"/>`;
|
||||
const SettingsIcon = `<path d="M12.125 27.5L11.5 23.34Q10.91 23.09 10.25 22.72Q9.59 22.34 9.09 21.94L5.19 23.63L2.5 18.88L5.91 16.28Q5.84 15.97 5.83 15.61Q5.81 15.25 5.81 15Q5.81 14.75 5.83 14.39Q5.84 14.03 5.91 13.72L2.5 11.13L5.19 6.38L9.09 8.06Q9.59 7.66 10.25 7.28Q10.91 6.91 11.5 6.66L12.125 2.5H17.875L18.5 6.66Q19.09 6.91 19.75 7.28Q20.41 7.66 20.91 8.06L24.81 6.38L27.5 11.13L24.09 13.72Q24.16 14.03 24.17 14.39Q24.19 14.75 24.19 15Q24.19 15.25 24.17 15.61Q24.16 15.97 24.09 16.28L27.5 18.88L24.81 23.63L20.91 21.94Q20.41 22.34 19.75 22.72Q19.09 23.09 18.5 23.34L17.875 27.5ZM15 19.06Q16.69 19.06 17.88 17.88Q19.06 16.69 19.06 15Q19.06 13.31 17.88 12.13Q16.69 10.94 15 10.94Q13.31 10.94 12.13 12.13Q10.94 13.31 10.94 15Q10.94 16.69 12.13 17.88Q13.31 19.06 15 19.06Z"/>`;
|
||||
</script>
|
||||
|
||||
<header
|
||||
class="bg-kv-blue flex flex-wrap items-center gap-4 lg:gap-8 p-2 md:p-4"
|
||||
>
|
||||
<!-- Back + Game Name -->
|
||||
<div class="flex items-center gap-4 flex-1">
|
||||
<a
|
||||
href="/kuldvillak"
|
||||
class="block w-12 h-12 hover:opacity-80 transition-opacity text-kv-yellow"
|
||||
aria-label={m.kv_edit_back()}
|
||||
>
|
||||
<svg viewBox="0 0 48 48" fill="currentColor" class="w-full h-full">
|
||||
{@html BackIcon}
|
||||
</svg>
|
||||
</a>
|
||||
<div class="flex-1 px-4 py-4 bg-kv-black/50">
|
||||
<input
|
||||
type="text"
|
||||
bind:value={gameName}
|
||||
placeholder={m.kv_edit_game_name()}
|
||||
class="w-full bg-transparent border-none outline-none font-kv-body text-2xl text-kv-white uppercase kv-shadow-text placeholder:text-kv-white/50"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Action Buttons -->
|
||||
<div class="flex items-center gap-8">
|
||||
<KvButton
|
||||
variant="icon"
|
||||
size="icon"
|
||||
onclick={() => fileInput.click()}
|
||||
ariaLabel={m.kv_edit_load()}
|
||||
>
|
||||
<svg viewBox="0 0 40 40" fill="currentColor" class="w-full h-full">
|
||||
{@html LoadIcon}
|
||||
</svg>
|
||||
</KvButton>
|
||||
<KvButton
|
||||
variant="icon"
|
||||
size="icon"
|
||||
onclick={handleExport}
|
||||
ariaLabel={m.kv_edit_save()}
|
||||
>
|
||||
<svg viewBox="0 0 40 40" fill="currentColor" class="w-full h-full">
|
||||
{@html SaveIcon}
|
||||
</svg>
|
||||
</KvButton>
|
||||
<KvButton
|
||||
variant="icon"
|
||||
size="icon"
|
||||
onclick={onReset}
|
||||
ariaLabel={m.kv_edit_reset()}
|
||||
>
|
||||
<svg viewBox="0 0 40 40" fill="currentColor" class="w-full h-full">
|
||||
{@html ResetIcon}
|
||||
</svg>
|
||||
</KvButton>
|
||||
{#if onSettings}
|
||||
<KvButton
|
||||
variant="icon"
|
||||
size="icon"
|
||||
onclick={onSettings}
|
||||
ariaLabel={m.kv_settings()}
|
||||
class="w-8 h-8"
|
||||
>
|
||||
<svg
|
||||
viewBox="0 0 30 30"
|
||||
fill="currentColor"
|
||||
class="w-full h-full"
|
||||
>
|
||||
{@html SettingsIcon}
|
||||
</svg>
|
||||
</KvButton>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<input
|
||||
type="file"
|
||||
accept=".json"
|
||||
class="hidden"
|
||||
bind:this={fileInput}
|
||||
onchange={handleImport}
|
||||
/>
|
||||
|
||||
<KvButton variant="secondary" onclick={onStart}>
|
||||
▶ {m.kv_edit_start()}
|
||||
</KvButton>
|
||||
</header>
|
||||
Reference in New Issue
Block a user