| 1 | <%
|
|---|
| 2 | /* The body of a post, rendered the same way wherever a post shows up: de
|
|---|
| 3 | Krant, Berichten and the Guardian PWA. Takes `nb` with the column names an
|
|---|
| 4 | ap_timeline row uses (content, emoji_json, media_json, quote_json,
|
|---|
| 5 | embed_json, nsfw, cw); ap_mentions and ap_interactions carry the same names
|
|---|
| 6 | so a mention or a reply can be handed straight to it.
|
|---|
| 7 |
|
|---|
| 8 | Krant-only trimmings (the boost byline, polls, the audio player iframe, the
|
|---|
| 9 | action bar) stay in tl-item: they are about the feed, not about the post. */
|
|---|
| 10 | // De catch vangt KAPOTTE json; hij vangt niet geldige json van het verkeerde
|
|---|
| 11 | // TYPE. Drie posts van een remote server droegen media_json = "[]", dus een
|
|---|
| 12 | // string met daarin [], en JSON.parse geeft dan netjes een string terug. Een
|
|---|
| 13 | // string heeft geen .filter, en daarmee lag de hele Krant plat: één vreemde
|
|---|
| 14 | // note nam de pagina mee. Wat er binnenkomt is niet van ons, dus de vorm moet
|
|---|
| 15 | // hier afgedwongen worden en niet aangenomen.
|
|---|
| 16 | var _m = []; try { _m = JSON.parse(nb.media_json || '[]'); } catch (e) { _m = []; }
|
|---|
| 17 | if (!Array.isArray(_m)) _m = [];
|
|---|
| 18 | var _imgs = _m.filter(function (m) { return m && m.url && (!m.type || /^image\//.test(m.type)); });
|
|---|
| 19 | var _vids = _m.filter(function (m) { return m && m.url && m.type && /^video\//.test(m.type); });
|
|---|
| 20 | var _auds = _m.filter(function (m) { return m && m.url && m.type && /^audio\//.test(m.type); });
|
|---|
| 21 | var _hasVisual = _imgs.length || _vids.length || _auds.length;
|
|---|
| 22 | var _nsfwVisual = !!nb.nsfw && _hasVisual;
|
|---|
| 23 | var _nsfwText = !!nb.nsfw && !_hasVisual;
|
|---|
| 24 | // One card for both: a fediverse quote and an external link preview look
|
|---|
| 25 | // identical; only where they came from differs. An embed carries a title and
|
|---|
| 26 | // a thumbnail, never an iframe.
|
|---|
| 27 | var _quote = noteQuote(nb.quote_json);
|
|---|
| 28 | if (!_quote) {
|
|---|
| 29 | var _emb = noteQuote(nb.embed_json);
|
|---|
| 30 | // The title comes from a third-party oEmbed provider, so it is escaped
|
|---|
| 31 | // here: the quote card renders `content` as HTML (fine for AP content,
|
|---|
| 32 | // which we sanitise on the way in, but not for this).
|
|---|
| 33 | if (_emb) _quote = { url: _emb.url, author: _emb.author || (_emb.provider ? { name: _emb.provider } : null),
|
|---|
| 34 | content: _emb.title ? ('<p>' + emojiName(_emb.title, null) + '</p>') : '', media: _emb.media || [] };
|
|---|
| 35 | }
|
|---|
| 36 | var _noAudio = !!nb.suppressAudio; // the Klonkt player iframe already covers these tracks
|
|---|
| 37 | %>
|
|---|
| 38 | <% if (_nsfwText) { %>
|
|---|
| 39 | <div class="tl-content nsfw-media"><span class="nsfw-veil"><%- include('../partials/nsfw-veil', { cw: nb.cw }) %></span><%- emojiHtml(nb.content, nb.emoji_json) %></div>
|
|---|
| 40 | <% } else { %>
|
|---|
| 41 | <div class="tl-content"><%- emojiHtml(nb.content, nb.emoji_json) %></div>
|
|---|
| 42 | <% } %>
|
|---|
| 43 | <% if (_quote) { %><%- include('../partials/quote-card', { q: _quote }) %><% } %>
|
|---|
| 44 | <% if (_nsfwVisual) { %><div class="nsfw-media"><% } %>
|
|---|
| 45 | <% if (_imgs.length) { %>
|
|---|
| 46 | <div class="tl-media">
|
|---|
| 47 | <% _imgs.forEach(function (m) { %>
|
|---|
| 48 | <a class="tl-media-img" href="<%= m.url %>" target="_blank" rel="noopener"><img src="<%= thumb(m.url, 1280) %>" alt="" loading="lazy" decoding="async"></a>
|
|---|
| 49 | <% }); %>
|
|---|
| 50 | </div>
|
|---|
| 51 | <% } %>
|
|---|
| 52 | <% _vids.forEach(function (m) { %><video class="tl-media-video" src="<%= m.url %>" poster="<%= thumb(m.url, 1280) %>" controls preload="metadata" playsinline></video><% }); %>
|
|---|
| 53 | <% if (!_noAudio) { _auds.forEach(function (m) { %><audio class="tl-media-audio" src="<%= m.url %>" controls preload="none"></audio><% }); } %>
|
|---|
| 54 | <% if (_nsfwVisual) { %><div class="nsfw-veil"><%- include('../partials/nsfw-veil', { cw: nb.cw }) %></div></div><% } %>
|
|---|