// Startbildschirm im Post (Inline): Name, Nummer, Datum, Vorschau der Karte, eigene Werte, Spielen-Knopf. import './style.css' import './splash.css' import {requestExpandedMode} from '@devvit/web/client' import {renderMiniBoard} from '../engine/app/board/BoardView.ts' import type {WorldTrait} from '../engine/core/WorldRules.ts' import type {GetDayRsp} from '../shared/api.ts' import {dailyBoard, dailyMap, dayLabel} from '../shared/daily.ts' import {fetchDay} from './api.ts' import {byId, h} from './dom.ts' import {appReady} from './journeys.ts' import {applyLook, openRealm} from './realm.ts' import {leaderTable} from './result.ts' import {lawName, starsLine} from './texts.ts' const app = byId('app') async function main(): Promise { app.replaceChildren(h('div.loading', 'Loading…')) let day: GetDayRsp try { day = await fetchDay() } catch (err) { app.replaceChildren( h('div.error', `Could not load the map. ${(err as Error).message}`), ) return } render(day) appReady() } function render(day: GetDayRsp): void { const map = dailyMap(new Date(`${day.day}T00:00:00Z`)) applyLook(day.look) const mini = h('div.mini') renderMiniBoard(mini, dailyBoard(map)) const realm = h('button.icon.realm-btn', '🎨 Realm') realm.title = 'Customise your realm' realm.addEventListener('click', () => openRealm({ look: day.look, progress: { bestStreak: day.stats?.bestStreak ?? 0, totalStars: day.stats?.totalStars ?? 0, }, day: dailyMap(new Date()).day, loggedIn: day.loggedIn, onChange: look => { day.look = look applyLook(look) renderMiniBoard(mini, dailyBoard(map)) }, }), ) const play = h('button.primary', day.mine ? 'Play again' : 'Play') play.addEventListener('click', ev => requestExpandedMode(ev, 'game')) const info = h('button.icon.info', 'i') info.title = 'Credits' info.addEventListener('click', showCredits) const mine = day.mine const status = mine ? h( 'p.pixel.mine', h('span.stars', starsLine(mine.stars)), ` ${mine.gold} gold · #${mine.rank} of ${day.players}`, ) : h( 'p.goals-line', h('span.stars', '★'), ` ${day.goals.gold} gold `, h('span.stars', '★'), ` ${day.goals.lands} lands `, h('span.stars', '★'), ' both', ) const streak = day.stats?.streak ?? 0 app.replaceChildren( h( 'header.head', h('h1', 'Ninelands'), h( 'p.muted.sub', `#${day.number} · ${dayLabel(day.day)}${day.today ? '' : ' · past map'}`, ), realm, info, ), h( 'main.body', mini, h( 'div.side', h('p.law', 'Law: ', h('b', lawName(day.trait as WorldTrait))), status, play, streak > 0 ? h('p.pixel.streak', `🔥 ${streak}-day streak`) : null, h( 'div.top', h( 'p.pixel.top-title', day.players > 0 ? `Today's best · ${day.players} playing` : "Today's best", ), leaderTable(day.top.slice(0, 3), mine?.rank ?? 0), ), ), ), ) } function showCredits(): void { const close = h('button.primary', 'Close') const overlay = h( 'div.overlay', h( 'div.panel', h('h2', 'Credits'), h( 'p', 'Ninelands by StackTeam – a daily port of the strategy game Ninelands.', ), h( 'p', 'Music: "Dreamscape (part I)" by Vee Ray, CC BY-SA 4.0 (re-encoded).', ), h('p', 'Graphics: "Mini World Sprites" by Shade and octoshrimpy, CC0.'), h('p', 'Font: Pixelify Sans, SIL Open Font License 1.1.'), h('div.row.end', close), ), ) close.addEventListener('click', () => overlay.remove()) document.body.append(overlay) } void main()