Changeset 1ecbf71 in Klonkt for src/routes


Ignore:
Timestamp:
06/26/2026 02:01:26 PM (2 months ago)
Author:
Robin Genis <roboburr@…>
Branches:
main
Children:
297c77d
Parents:
5e3be97
Message:

feat(tijdlijn): graphical redesign + inline embeds (others' media)

  • Redesigned timeline cards: rounded avatars with accent ring, cleaner meta, hover lift, image grid (Mastodon-style), nicer actions, empty state.
  • Render others' media: images (grid), video (<video>), audio (<audio>) — not just images.
  • Inline embeds: detect the first YouTube/Spotify/SoundCloud/Vimeo link in a remote post's content and render a direct iframe (CSP already allows these frame-srcs).
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/routes/posts.js

    r5e3be97 r1ecbf71  
    580580
    581581// ==================== FEDIVERSE CLIENT: home timeline + following ====================
     582// Build a direct embed iframe for the first embeddable link (YouTube/Spotify/
     583// SoundCloud/Vimeo) in a remote post's content, so others' media plays inline.
     584function timelineEmbedHtml(html) {
     585  if (!html) return null;
     586  const re = /href=["']([^"']+)["']/gi; let m; const seen = new Set();
     587  while ((m = re.exec(html))) {
     588    const u = m[1]; if (seen.has(u)) continue; seen.add(u);
     589    let p; try { p = AudioEmbedService.detectProvider(u); } catch { p = null; }
     590    if (!p) continue;
     591    if (p.provider === 'youtube') return `<iframe class="tl-embed-frame" src="https://www.youtube-nocookie.com/embed/${p.id}" title="YouTube" loading="lazy" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>`;
     592    if (p.provider === 'spotify') return `<iframe class="tl-embed-frame tl-embed-spotify" src="https://open.spotify.com/embed/${p.type}/${p.id}" title="Spotify" loading="lazy" frameborder="0" allow="encrypted-media"></iframe>`;
     593    if (p.provider === 'soundcloud') return `<iframe class="tl-embed-frame tl-embed-sc" src="https://w.soundcloud.com/player/?url=${encodeURIComponent(p.url)}&color=%23ff5500&visual=false" title="SoundCloud" loading="lazy" frameborder="0" allow="autoplay" scrolling="no"></iframe>`;
     594    if (p.provider === 'vimeo') return `<iframe class="tl-embed-frame" src="https://player.vimeo.com/video/${p.id}" title="Vimeo" loading="lazy" frameborder="0" allow="autoplay; fullscreen; picture-in-picture" allowfullscreen></iframe>`;
     595  }
     596  return null;
     597}
     598
    582599router.get('/tijdlijn', requireSiteManager, (req, res) => {
    583600  const site = res.locals.site;
    584   const timeline = site ? ActivityPubService.getTimeline(site.slug, 60) : [];
     601  const timeline = (site ? ActivityPubService.getTimeline(site.slug, 60) : [])
     602    .map((p) => ({ ...p, embedHtml: timelineEmbedHtml(p.content) }));
    585603  renderPage(req, res, 'pages/timeline', {
    586604    pageTitle: 'Tijdlijn', bodyClass: 'on-special',
Note: See TracChangeset for help on using the changeset viewer.