Changeset 084b046 in Klonkt for src/routes


Ignore:
Timestamp:
08/12/2026 08:04:38 PM (3 months ago)
Author:
Robin <roboburr@…>
Children:
5218863
Parents:
a5a6249
Message:

De Ward PWA: de avatarhemel achter de kaarten

Plak 3. Robins correctie: niet de hemel IN PLAATS VAN de kaarten, maar
allebei, met de hemel er altijd achter. Zelfde beweging als in Shaer: de
kaarten vallen weg en wat eronder lag was er al.

MODEL EN RENDERER APART, en die naad is het punt. orbitPlacement en
nearestFace zijn pure wiskunde en bestaan nu drie keer (Swift, Kotlin,
hier). Drie keer kans op drift, en drift zie je niet aan een screenshot:
je ziet het als gezichten ergens anders hangen dan in de app. Daarom in
een eigen module, met dezelfde eigenschappen bewaakt als AvatarSkyTest.kt.

CANVAS, GEEN ENGINE, en dat is een afweging en geen luiheid. De rem is
niet het aantal sprites maar het aantal texturen: alle avatars gaan een
keer in een atlas, daarna is elk gezicht een drawImage uit datzelfde
plaatje. Dat haalt duizenden. Wil het ooit meer, dan vervangt een
WebGL-variant alleen SkyRenderer en merkt de rest er niets van. De echte
schaaloplossing is trouwens niet sneller tekenen maar clusteren; dat
staat als bead voor later.

New file:
src/assets/js/ward-sky.js

  • orbitPlacement + nearestFace, letterlijke port
  • SkyRenderer: atlas, ademhaling, pan, zoom, tik

test/ward-sky.test.js

  • vers dichterbij dan oud, deterministisch, geen overlap, mikken kiest de dichtstbijzijnde en schaalt mee met de zoom

Changed files:
src/routes/ward.js

  • /api/conversations: per tegenpartij het jongste bericht
  • /sky.js als eigen asset

src/views/pages/ward.ejs

  • canvas achter alles, wisselknop, app.js als module

src/assets/js/ward.js

  • de wissel: kaarten of hemel, hemel draait altijd

src/assets/css/ward.css

  • hemel op z-index 0, kaarten erboven

src/services/i18n.js

  • drie sleutels in nl, en, de

remarks: 895 tests groen. Een tik op een gezicht wijst naar /ward/thread,
en die route bestaat nog niet; dat is de volgende plak.

-robo
Co-Authored-By: Claude Opus 4.8 <noreply@…>

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/routes/ward.js

    ra5a6249 r084b046  
    9898      helpSent: i18nT(L, 'ward.help_sent'),
    9999      cancel: i18nT(L, 'ward.cancel'),
     100      toSky: i18nT(L, 'ward.to_sky'),
     101      toCards: i18nT(L, 'ward.to_cards'),
     102      skyEmpty: i18nT(L, 'ward.sky_empty'),
    100103    },
    101104  };
    … …  
    217220});
    218221
     222/**
     223 * De gesprekken voor de hemel: iedereen met wie dit kind persoonlijk berichten
     224 * heeft gewisseld, met hoe lang geleden dat voor het laatst was.
     225 *
     226 * De hemel toont GESPREKKEN, geen posts. Directe berichten leven in
     227 * ap_mentions en niet in de tijdlijn, precies omdat een bericht aan genoemde
     228 * mensen geen post is. Per tegenpartij houden we het jongste bericht: dat is
     229 * wat de afstand tot het midden bepaalt.
     230 */
     231router.get('/api/conversations', requireAuth, (req, res) => {
     232  const site = siteForUser(req);
     233  if (!site) return res.status(404).json({ error: 'no_site' });
     234  const now = Date.now();
     235  const byUri = new Map();
     236  for (const m of AP.getDirectMessages(site.slug, 200)) {
     237    if (!m.actor_uri) continue;
     238    const when = Date.parse(m.published || m.created_at || '') || now;
     239    const seen = byUri.get(m.actor_uri);
     240    if (!seen || when > seen.when) {
     241      byUri.set(m.actor_uri, {
     242        uri: m.actor_uri,
     243        name: m.actor_name || m.actor_handle || m.actor_uri,
     244        handle: m.actor_handle || m.actor_uri,
     245        icon: m.actor_icon || null,
     246        when,
     247      });
     248    }
     249  }
     250  const items = [...byUri.values()]
     251    .sort((a, b) => b.when - a.when)
     252    .map((c) => ({ ...c, ageMs: Math.max(0, now - c.when) }));
     253  res.json({ items });
     254});
     255
    219256function pwaAsset(rel, type) {
    220257  return (req, res) => {
    … …  
    225262}
    226263router.get('/app.js', pwaAsset('js/ward.js', 'application/javascript'));
     264// De hemel is een eigen module, zodat model en renderer los staan van de rest.
     265router.get('/sky.js', pwaAsset('js/ward-sky.js', 'application/javascript'));
    227266router.get('/app.css', pwaAsset('css/ward.css', 'text/css'));
    228267
Note: See TracChangeset for help on using the changeset viewer.