Files
idle-xboct/packages/web/src/App.svelte
T
2026-09-05 15:27:53 +05:00

126 lines
2.7 KiB
Svelte
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script lang="ts">
import { onMount } from 'svelte';
import { mountWorld, type WorldHandle } from '@idle/render';
import { connectWorld, type ConnectHandlers, type NetStatus } from './net';
const STATUS_TEXT: Record<NetStatus, string> = {
connecting: 'подключение…',
online: 'онлайн',
reconnecting: 'переподключение…',
};
let host = $state<HTMLDivElement | undefined>(undefined);
let status = $state<NetStatus>('connecting');
onMount(() => {
let world: WorldHandle | undefined;
let disposeNet: (() => void) | undefined;
if (host) {
void mountWorld(host, { background: 0x1d232d }).then((w) => {
world = w;
const handlers: ConnectHandlers = {
onStatus: (s) => {
status = s;
},
onSnapshot: (snap) => world?.applySnapshot(snap.avatars),
};
disposeNet = connectWorld(handlers);
});
}
return () => {
disposeNet?.();
world?.destroy();
};
});
</script>
<div class="root">
<header>
<span class="title">Idle XBOCT</span>
<span class="badge" data-status={status}>{STATUS_TEXT[status]}</span>
</header>
<div class="main">
<div class="world" bind:this={host}></div>
<aside>
<section>
<h2>Инвентарь</h2>
<p class="muted">свой инвентарь по нику — с M2</p>
</section>
<section>
<h2>Рецепты</h2>
<p class="muted">дерево рецептов — с M2</p>
</section>
<section>
<h2>Лидерборды</h2>
<p class="muted">топ зрителей — с M5</p>
</section>
<section>
<h2>Костёр</h2>
<p class="muted">общий прогресс — с M4</p>
</section>
</aside>
</div>
</div>
<style>
.root {
display: flex;
flex-direction: column;
height: 100%;
}
header {
display: flex;
align-items: center;
gap: 12px;
padding: 10px 16px;
border-bottom: 1px solid #2a3242;
}
.title {
font-weight: 700;
letter-spacing: 0.04em;
}
.badge {
margin-left: auto;
font: 12px/1.4 monospace;
color: #9fb0c3;
background: #232b38;
padding: 2px 8px;
border-radius: 8px;
}
.badge[data-status='online'] {
color: #7ee2a8;
}
.main {
display: flex;
flex: 1;
min-height: 0;
}
.world {
flex: 1;
min-width: 0;
}
aside {
width: 300px;
border-left: 1px solid #2a3242;
padding: 12px 16px;
overflow: auto;
}
section {
margin-bottom: 18px;
}
h2 {
font-size: 14px;
margin: 0 0 4px;
color: #b7c4d4;
}
.muted {
font-size: 12px;
color: #6d7d90;
margin: 0;
}
</style>