Changeset 6dd26e5 in Klonkt for src/views/partials/post-tile.ejs


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
  • src/views/partials/post-tile.ejs

    r67f7150 r6dd26e5  
    1111// content instead, like the Cirkel card: first <video> (with its poster) or
    1212// first <img>.
    13 let _cVideo = null, _cPoster = null, _cImg = null;
     13let _cVideo = null, _cPoster = null, _cImg = null, _cAudio = false, _cWave = null;
    1414if (!_hasCover && post.content) {
    1515  const vm = String(post.content).match(/<video[^>]*\ssrc="([^"]+)"[^>]*>/i);
    1616  if (vm) { _cVideo = vm[1]; const pm = vm[0].match(/poster="([^"]+)"/i); if (pm) _cPoster = pm[1]; }
    17   else { const im = String(post.content).match(/<img[^>]*\ssrc="([^"]+)"/i); if (im) _cImg = im[1]; }
     17  else {
     18    const im = String(post.content).match(/<img[^>]*\ssrc="([^"]+)"/i);
     19    if (im) _cImg = im[1];
     20    else {
     21      // An audio post (Robins vraag, 30-7): the waveform the upload leg drew
     22      // (data-poster) goes OVER the gradient, so the tile keeps its own hue.
     23      const am = String(post.content).match(/<audio[^>]*>/i);
     24      if (am) { _cAudio = true; const wm = am[0].match(/data-poster="([^"]+)"/i); if (wm) _cWave = wm[1]; }
     25    }
     26  }
    1827}
    19 const _showCover = _hasCover || !!_cVideo || !!_cImg;
     28const _showCover = _hasCover || !!_cVideo || !!_cImg;   // the wave keeps the gradient
     29// A C2S post has no title: fall back to the post's own words, and for a
     30// media-only post to a friendly type label instead of "(untitled)". A tile
     31// that already shows its picture needs no forced label at all.
     32let _title = post.title || '';
     33if (!_title && post.content) {
     34  const _txt = String(post.content).replace(/<[^>]*>/g, ' ').replace(/&[a-zA-Z#0-9]+;/g, ' ').replace(/\s+/g, ' ').trim();
     35  if (_txt) _title = _txt.length > 64 ? _txt.slice(0, 63).replace(/\s+\S*$/, '') + '…' : _txt;
     36}
     37if (!_title) _title = _cAudio ? '♪ audio' : (_cVideo || _cImg) ? '' : '(untitled)';
    2038const _typeLabel = (post.type && post.type !== 'post') ? post.type : '';
    2139const _src = post.source_name || '';   // bron-site (cirkel-feed: van welke site komt deze post)
     
    3048   <% if (_ext) { %>target="_blank" rel="noopener"<% } else { %>hx-get="<%= _href %>?partial=1" hx-target="#pcms-main" hx-swap="innerHTML" hx-push-url="<%= _href %>" hx-indicator="#pcms-loading"<% } %>>
    3149
    32   <% if (post.cover_image_url) { %><img class="grid-tile-img" src="<%= thumb(post.cover_image_url, 480) %>" alt="" loading="lazy" decoding="async"<% if (post.cover_video_url) { %> data-ios-mp4="<%= post.cover_video_url %>"<% } %>><% } else if (post.cover_video_url) { %><video class="grid-tile-img" src="<%= post.cover_video_url %>" poster="<%= thumb(post.cover_video_url, 480) %>" autoplay loop muted playsinline></video><% } else if (_cVideo) { %><video class="grid-tile-img" src="<%= _cVideo %>"<% if (_cPoster) { %> poster="<%= _cPoster %>"<% } %> autoplay loop muted playsinline preload="metadata"></video><% } else if (_cImg) { %><img class="grid-tile-img" src="<%= _cImg %>" alt="" loading="lazy" decoding="async"><% } %>
     50  <% if (post.cover_image_url) { %><img class="grid-tile-img" src="<%= thumb(post.cover_image_url, 480) %>" alt="" loading="lazy" decoding="async"<% if (post.cover_video_url) { %> data-ios-mp4="<%= post.cover_video_url %>"<% } %>><% } else if (post.cover_video_url) { %><video class="grid-tile-img" src="<%= post.cover_video_url %>" poster="<%= thumb(post.cover_video_url, 480) %>" autoplay loop muted playsinline></video><% } else if (_cVideo) { %><video class="grid-tile-img" src="<%= _cVideo %>"<% if (_cPoster) { %> poster="<%= _cPoster %>"<% } %> autoplay loop muted playsinline preload="metadata"></video><% } else if (_cImg) { %><img class="grid-tile-img" src="<%= _cImg %>" alt="" loading="lazy" decoding="async"><% } else if (_cWave) { %><img class="grid-tile-img grid-tile-wave" src="<%= _cWave %>" alt="" loading="lazy" decoding="async"><% } %>
    3351
    3452  <% if (_typeLabel) { %>
     
    4361  <% if (_hasCover) { %>
    4462    <div class="grid-tile-overlay">
    45       <strong><%= post.title || '(untitled)' %></strong>
     63      <strong><%= _title %></strong>
    4664      <% if (_src) { %><span class="grid-tile-overlay-src">van <%= _src %></span><% } %>
    4765    </div>
    4866  <% } else { %>
    49     <span class="grid-tile-title"><%= post.title || '(untitled)' %></span>
     67    <span class="grid-tile-title"><%= _title %></span>
    5068    <% if (_src) { %><span class="grid-tile-gradient-src">van <%= _src %></span><% } %>
    5169  <% } %>
Note: See TracChangeset for help on using the changeset viewer.