Changeset 7d01696 in Klonkt for src/services
- Timestamp:
- 07/30/2026 07:56:33 AM (6 weeks ago)
- Branches:
- main
- Children:
- 9ed940e
- Parents:
- 97bcf7e
- File:
-
- 1 edited
-
src/services/ActivityPubService.js (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/services/ActivityPubService.js
r97bcf7e r7d01696 17 17 */ 18 18 import crypto from 'crypto'; 19 import fs from 'fs'; 20 import path from 'path'; 19 21 import dns from 'dns'; 20 22 import net from 'net'; … … 380 382 try { 381 383 for (const a of JSON.parse(post.c2s_attachments || '[]')) { 382 if (a && a.url) urls.push({ url: abs(a.url), name: a.name || '', mt: a.mediaType });384 if (a && a.url) urls.push({ url: abs(a.url), name: a.name || '', mt: a.mediaType, poster: a.poster ? abs(a.poster) : null }); 383 385 } 384 386 } catch { /* malformed never blocks the Note */ } … … 480 482 const a = { type: ty, mediaType: mt, url: x.url }; 481 483 if (x.name) a.name = String(x.name).slice(0, 1500); // alt text / description (AS2 `name`) 484 if (x.poster) a.icon = { type: 'Image', url: x.poster }; // the video's still (shaer-zowq) 482 485 return a; }); 483 486 for (const a of openAudio) attachment.push(a); // fedi_open tracks → native Audio players … … 2379 2382 && /^(image|audio|video)\//.test(String(a.mediaType || ''))) 2380 2383 .slice(0, 4) 2381 .map((a) => ({ url: a.url, mediaType: String(a.mediaType), name: String(a.name || '').slice(0, 120) })); 2384 .map((a) => { 2385 const entry = { url: a.url, mediaType: String(a.mediaType), name: String(a.name || '').slice(0, 120) }; 2386 // A video's poster frame, when the upload leg made one (shaer-zowq): 2387 // rides along so the tag, the federated attachment and the apps all 2388 // show a still instead of a black box. 2389 if (entry.mediaType.startsWith('video/')) { 2390 try { 2391 const mediaRoot = path.resolve(process.env.MEDIA_PATH || './storage/media'); 2392 const rel = entry.url.replace(/^\/media\//, ''); 2393 if (fs.existsSync(path.join(mediaRoot, rel + '.poster.jpg'))) entry.poster = entry.url + '.poster.jpg'; 2394 } catch { /* no poster is fine */ } 2395 } 2396 return entry; 2397 }); 2382 2398 if (!html.trim() && !media.length) return { status: 400, error: 'empty_note' }; 2383 2399 // The web reads the post's content, so the media goes IN it (we build these … … 2389 2405 if (a.mediaType.startsWith('image/')) return `<p><img src="${a.url}" alt="${esc(a.name)}"></p>`; 2390 2406 if (a.mediaType.startsWith('audio/')) return `<p><audio controls preload="metadata" src="${a.url}"></audio></p>`; 2391 return `<p><video controls playsinline preload="metadata" src="${a.url}"></video></p>`; 2407 const poster = a.poster ? ` poster="${a.poster}"` : ''; 2408 return `<p><video controls playsinline preload="metadata"${poster} src="${a.url}"></video></p>`; 2392 2409 }).join(''); 2393 2410 const postId = crypto.randomUUID(); … … 2818 2835 const rows = (Array.isArray(list) ? list : []) 2819 2836 .filter((m) => m && m.url) 2820 .map((m) => ({ type: 'Document', mediaType: m.type || undefined, url: m.url })); 2837 .map((m) => { 2838 const a = { type: 'Document', mediaType: m.type || undefined, url: m.url }; 2839 if (m.poster) a.icon = { type: 'Image', url: m.poster }; // the video's still (shaer-zowq) 2840 return a; 2841 }); 2821 2842 return rows.length ? rows : undefined; 2822 2843 } catch { return undefined; } … … 3027 3048 } 3028 3049 function mediaFromNote(note) { 3029 const atts = (Array.isArray(note.attachment) ? note.attachment : []).map((a) => ({ url: safeUrl(a && a.url), type: (a && a.mediaType) || '' })).filter((m) => m.url); 3050 const atts = (Array.isArray(note.attachment) ? note.attachment : []).map((a) => { 3051 const m = { url: safeUrl(a && a.url), type: (a && a.mediaType) || '' }; 3052 // A federated video may carry its poster as an AS2 icon (shaer-zowq). 3053 const iconUrl = a && a.icon && safeUrl(typeof a.icon === 'string' ? a.icon : a.icon.url); 3054 if (iconUrl && /^video\//i.test(m.type)) m.poster = iconUrl; 3055 return m; 3056 }).filter((m) => m.url); 3030 3057 if (!atts.some((m) => !m.type || /image/i.test(m.type)) && note.image) { 3031 3058 const im = Array.isArray(note.image) ? note.image[0] : note.image;
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)