Changeset 6dd26e5 in Klonkt for test/c2s-compose.test.js


Ignore:
Timestamp:
07/30/2026 11:48:53 AM (6 weeks ago)
Author:
Robin <roboburr@…>
Branches:
main
Children:
1f640ff
Parents:
67f7150
Message:

De audio-tegel opgevrolijkt: golfvorm als thumbnail en een echte titel

Een audiopost uit Shaer was op Klonkt een kale gradient met (untitled)
(Robins schermafdruk, 30-7). Twee dingen tegelijk gefixt.

De thumbnail: de upload-leg tekent bij audio nu een golfvorm met de
gebundelde ffmpeg (showwavespic, wit op transparant) naar
<naam>.poster.png, precies zoals video zijn stilstaand beeld krijgt. Die
golfvorm rijdt mee als data-poster op de audio-tag (voor de tegels), in
c2s_attachments en als AS2-icon op het gefedereerde Audio-attachment. De
tegel toont hem OVER de eigen hue-gradient, dus elke audiopost houdt
zijn kleur en krijgt zijn vorm.

De titel: C2S-posts hebben geen titel, dus elke Shaer-post toonde
(untitled). Tegels en kaarten leiden de titel nu af: eerst de eigen
woorden van de post (afgekapt op 64), anders een vriendelijk typelabel
(muzieknoot audio, pijl video), en pas als er echt niets is (untitled).
Een tegel die zijn beeld al toont forceert geen label meer.

Changed files:
src/routes/activitypub.js

  • uploadMedia: audio/* -> showwavespic-golfvorm naar .poster.png (best-effort, zelfde patroon als de videoposter)

src/services/ActivityPubService.js

  • c2sCreatePost: posterExt per type (video .jpg, audio .png); de audio-tag krijgt data-poster

src/views/partials/post-tile.ejs

  • audio-detectie + golfvorm over de gradient; titelcascade (titel -> tekst -> typelabel)

src/views/partials/post-card.ejs

  • zelfde spiegel: golfvorm als cover met eigen accent-gradient, zelfde titelcascade

src/assets/css/style.css

  • .grid-tile-wave: contain, padding, transparant op de gradient

test/c2s-compose.test.js

  • audio-golfvormketen: data-poster op de tag, poster in de store, icon op het gefedereerde attachment

remarks: bestaande audioposts kregen hun upload voor deze code en hebben
dus nog geen golfvorm-bestand; die tonen nu wel het muzieknoot-label. Een
verse audiopost laat het hele effect zien. ffmpeg-commando en beide
templates hier lokaal gesmoke-test (RGBA-png, render ok), 345 tests
groen.

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • test/c2s-compose.test.js

    r67f7150 r6dd26e5  
    102102});
    103103
     104test("an audio note's waveform rides the tag, the store and the federated attachment", async () => {
     105  // Same courtesy as the video poster (Robins vraag, 30-7: de kale
     106  // audio-tegel): the upload leg draws <name>.poster.png (showwavespic).
     107  // From there it must reach the data-poster on the folded tag (the tiles
     108  // read it), the stored entry, and the AS2 icon on the federated Audio.
     109  const os = await import('os');
     110  const fsm = await import('fs');
     111  const pathm = await import('path');
     112  const root = fsm.mkdtempSync(pathm.join(os.tmpdir(), 'klonkt-media-'));
     113  fsm.mkdirSync(pathm.join(root, 'reply-media'), { recursive: true });
     114  fsm.writeFileSync(pathm.join(root, 'reply-media', 'lied.m4a.poster.png'), 'x');
     115  const prev = process.env.MEDIA_PATH;
     116  process.env.MEDIA_PATH = root;
     117  try {
     118    const r = await AP.ingestOutboxActivity(site, user, {
     119      type: 'Create',
     120      object: {
     121        type: 'Note', content: '',
     122        to: ['https://test.example/ap/users/kid/followers'],
     123        attachment: [{ type: 'Audio', url: '/media/reply-media/lied.m4a', mediaType: 'audio/mp4' }],
     124      },
     125    });
     126    assert.equal(r.status, 201);
     127    const post = db.prepare('SELECT * FROM posts WHERE id = ?').get(r.id);
     128    assert.match(post.content, /data-poster="\/media\/reply-media\/lied\.m4a\.poster\.png"/, 'the tag carries the waveform for the tiles');
     129    const note = AP.buildNote('https://test.example', site, post);
     130    const aud = (note.attachment || []).find((a) => a.url.endsWith('lied.m4a'));
     131    assert.ok(aud && aud.type === 'Audio');
     132    assert.equal(aud.icon && aud.icon.url, 'https://test.example/media/reply-media/lied.m4a.poster.png',
     133      'the waveform federates as the attachment icon');
     134  } finally {
     135    if (prev === undefined) delete process.env.MEDIA_PATH; else process.env.MEDIA_PATH = prev;
     136  }
     137});
     138
    104139test('a video without a poster simply has none: no guessed icon', async () => {
    105140  const r = await AP.ingestOutboxActivity(site, user, {
Note: See TracChangeset for help on using the changeset viewer.