feat: setup project
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
<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>
|
||||
Reference in New Issue
Block a user