diff --git a/PLAN.md b/PLAN.md index cddcc65..5ae207e 100644 --- a/PLAN.md +++ b/PLAN.md @@ -284,3 +284,17 @@ Abgabe: **9. Dezember 2026, 03:00 MEZ**. Eingereicht wird in „Best Daily Game Aufnahmen werden vorher nach VP9/WebM umgewandelt. - Reddit selbst (Feed, Kommentar im Thread, Flair) nimmt der Besitzer mit seinem Konto auf (Reddit blockt Automatisierung); optional als `dist/trailer/input/feed.*` / `comment.*`. + +### 2026-11-13 – Realm im Vollbild (Bug vom Besitzer) + +- **Bug:** Am Handy öffnete „🎨 Realm“ das Fenster im Inline-Post (512 px hoch). Die Liste ist höher, „Done“ lag + außerhalb, und scrollen darf ein Inline-Post nicht (Devvit-Regel „Scrolling within inline webviews is prohibited“, + Scroll-Falle im Feed) → man saß fest. +- **Lösung:** eigener Einstiegspunkt `realm` (`public/realm.html`, `src/client/realm-page.ts`), geöffnet mit + `requestExpandedMode(ev, 'realm', {title: 'Your realm'})`; „Done“ ruft `exitExpandedMode`. Der Knopf klebt unten + (`position: sticky`), damit er auch bei langer Liste sichtbar bleibt. Der Startbildschirm lädt beim `focus`-Ereignis + (Rückkehr aus dem Vollbild, laut Doku der Ersatz für `addWebViewModeListener`) Tag und Aussehen neu – damit zeigt er + nach dem Spielen auch gleich das eigene Ergebnis. +- Credits-Fenster im Post geprüft: passt auch bei 320 px Breite (Knopf endet bei 413 von 512 px). +- Pixelify-Ligatur „fi“ (sieht aus wie „A“) jetzt für die ganze App aus (`font-variant-ligatures: none`). +- **Fallstrick:** `devvit.json` geändert → laufenden Playtest stoppen und neu starten. diff --git a/devvit.json b/devvit.json index a6e56ee..c895b15 100644 --- a/devvit.json +++ b/devvit.json @@ -10,6 +10,9 @@ }, "game": { "entry": "game.html" + }, + "realm": { + "entry": "realm.html" } } }, diff --git a/package.json b/package.json index de42295..44d87f9 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "type": "module", "scripts": { "build": "npm run build:client -- --metafile=dist/client.meta.json --minify && npm run build:server -- --metafile=dist/server.meta.json --minify", - "build:client": "esbuild --bundle --log-level=warning --sourcemap=linked --target=es2023 --format=esm --outdir=public --platform=browser --define:import.meta.env.MODE='\"reddit\"' --define:import.meta.env.BASE_URL='\"/\"' --define:__API_ORIGIN__='\"\"' --loader:.woff2=file --loader:.woff=file --asset-names=fonts/[name]-[hash] src/client/splash.ts src/client/game.ts", + "build:client": "esbuild --bundle --log-level=warning --sourcemap=linked --target=es2023 --format=esm --outdir=public --platform=browser --define:import.meta.env.MODE='\"reddit\"' --define:import.meta.env.BASE_URL='\"/\"' --define:__API_ORIGIN__='\"\"' --loader:.woff2=file --loader:.woff=file --asset-names=fonts/[name]-[hash] src/client/splash.ts src/client/game.ts src/client/realm-page.ts", "build:server": "esbuild --bundle --log-level=warning --sourcemap=linked --target=es2023 --format=cjs --outdir=dist/server --platform=node src/server/index.ts", "clean": "rm -rf dist/ public/*.js* public/*.css* public/fonts/", "format": "npm run lint -- --fix", diff --git a/public/realm.html b/public/realm.html new file mode 100644 index 0000000..1d70a46 --- /dev/null +++ b/public/realm.html @@ -0,0 +1,14 @@ + + + + + + Ninelands + + + + +
+ + + diff --git a/scripts/capture/trailer.mjs b/scripts/capture/trailer.mjs index a541ab8..49f64f0 100644 --- a/scripts/capture/trailer.mjs +++ b/scripts/capture/trailer.mjs @@ -349,17 +349,24 @@ async function scenes(page, o) { 'Streaks and stars unlock boards, peoples and banners.', ) await wait(900) - const s2 = frameOf('splash.html') - await tap(s2.locator('.realm-btn'), 300) - await wait(700) - await tap(s2.locator('.realm-item', {hasText: 'Winter'}).first(), 400) + // Realm öffnet im Vollbild (requestExpandedMode gibt es hier nicht → nur antippen, Bühne wechselt) + await tap(frameOf('splash.html').locator('.realm-btn'), 300, false) + await wait(300) + await stage('finger', null) + await stage('show', 'game', '/realm.html') + const r = frameOf('realm.html') + await r.waitForSelector('.realm-item') + await wait(600) + await tap(r.locator('.realm-item', {hasText: 'Winter'}).first(), 400) await wait(900) await stage('finger', null) await o.snap('05-realm') await wait(800) - await tap(s2.locator('.overlay button.primary', {hasText: 'Done'}), 300) + await tap(r.locator('.overlay button.primary', {hasText: 'Done'}), 300, false) + await wait(300) await stage('finger', null) - await wait(400) + await stage('show', 'post', '/splash.html') + await wait(700) await stage( 'caption', diff --git a/src/client/realm-page.ts b/src/client/realm-page.ts new file mode 100644 index 0000000..c085b19 --- /dev/null +++ b/src/client/realm-page.ts @@ -0,0 +1,35 @@ +// „🎨 Realm“ im Vollbild (Einstiegspunkt „realm“): Aussehen wählen, „Done“ führt zurück in den Post. +import './style.css' +import {exitExpandedMode} from '@devvit/web/client' +import {dailyMap} from '../shared/daily.ts' +import {fetchDay} from './api.ts' +import {byId, h} from './dom.ts' +import {applyLook, openRealm} from './realm.ts' + +const app = byId('app') + +async function main(): Promise { + app.replaceChildren(h('div.loading', 'Loading…')) + try { + const day = await fetchDay() + app.replaceChildren() + applyLook(day.look) + 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 => applyLook(look), + onClose: ev => exitExpandedMode(ev), + }) + } catch (err) { + app.replaceChildren( + h('div.error', `Could not load your realm. ${(err as Error).message}`), + ) + } +} + +void main() diff --git a/src/client/realm.ts b/src/client/realm.ts index 5a0bcf0..66a0b6d 100644 --- a/src/client/realm.ts +++ b/src/client/realm.ts @@ -75,6 +75,8 @@ export function openRealm(opts: { day: string loggedIn: boolean onChange: (look: Look) => void + /** Statt nur das Fenster zu schließen (Vollbild-Seite: zurück in den Post) */ + onClose?: (ev: MouseEvent) => void }): void { let look = opts.look const body = h('div.realm-rows') @@ -94,7 +96,9 @@ export function openRealm(opts: { h('div.row.end', close), ), ) - close.addEventListener('click', () => overlay.remove()) + close.addEventListener('click', ev => + opts.onClose ? opts.onClose(ev) : overlay.remove(), + ) const row = ( title: string, diff --git a/src/client/splash.ts b/src/client/splash.ts index 71dad5c..35350ad 100644 --- a/src/client/splash.ts +++ b/src/client/splash.ts @@ -9,7 +9,7 @@ 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 {applyLook} from './realm.ts' import {leaderTable} from './result.ts' import {lawName, starsLine} from './texts.ts' @@ -28,6 +28,12 @@ async function main(): Promise { } render(day) appReady() + // Zurück aus dem Vollbild (Spiel oder Realm): Ergebnis und Aussehen neu holen + addEventListener('focus', () => { + fetchDay() + .then(render) + .catch(() => {}) + }) } function render(day: GetDayRsp): void { @@ -38,21 +44,10 @@ function render(day: GetDayRsp): void { 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)) - }, - }), + // Im Vollbild: der Inline-Post ist nur 512 px hoch und darf nicht scrollen (Devvit-Regel) – sonst wäre + // „Done“ am Handy unerreichbar + realm.addEventListener('click', ev => + requestExpandedMode(ev, 'realm', {title: 'Your realm'}), ) const play = h('button.primary', day.mine ? 'Play again' : 'Play') diff --git a/src/client/style.css b/src/client/style.css index 0ca145e..1d1e480 100644 --- a/src/client/style.css +++ b/src/client/style.css @@ -43,6 +43,8 @@ body { body { background-color: var(--px-grass-dark); + /* Pixelify verbindet „fi“ sonst zu einem Zeichen, das wie „A“ aussieht */ + font-variant-ligatures: none; /* feines Schachbrett wie Grasnarbe */ background-image: conic-gradient( rgba(0, 0, 0, 0.08) 25%, @@ -219,6 +221,16 @@ button.icon { } /* ---------- Realm-Auswahl ---------- */ +/* „Done“ bleibt unten sichtbar, auch wenn die Liste scrollt (Vollbild am Handy) */ +.realm > .row.end { + position: sticky; + bottom: -1rem; + margin: 0 -1rem -1rem; + padding: 0.6rem 1rem; + background: var(--px-wood); + border-top: 2px solid var(--px-ink); +} + .realm h3 { margin: 0 0 0.25rem; font-family: var(--font-pixel);