<% if (n.type === 'thread') { %> <% var _tseen = (typeof seen !== 'undefined' && seen) ? seen : 0; // Een draad is nieuw zodra EEN bericht erin nieuw is. var _tnew = !!_tseen && (n.messages || []).some(function (m) { return m.created_at && Date.parse(m.created_at) > _tseen; }); var _tpeople = (n.people || []).map(function (p) { return p.name || p.handle || '?'; }); // Alleen jij aan het woord: dan is de tegenpartij het adres waaraan // je schreef, niet een lege naam. var _tto = ((n.messages || []).find(function (m) { return m.to_handle; }) || {}).to_handle; var _tlabel = _tpeople.length ? _tpeople.join(', ') : (_tto || t('msg.you')); // Zwaaide er iemand in dit gesprek? Dan hoort dat in de KOP // (Robins aanwijzing, 25-8). Ingeklapt zijn de bubbels weg, en juist // een zwaai is het bericht dat om een antwoord vraagt zonder iets te // zeggen -- die mag niet achter een dichtgeklapt gesprek verdwijnen. // Alleen een ONTVANGEN zwaai: je eigen zwaai staat er als 'sent' en // is geen uitnodiging aan jezelf. var _twave = (n.messages || []).some(function (m) { return m.type === 'mention' && m.wave; }); %>
  • <%# Tegenpartij en aantal in EEN uitsparing: het is een label bij het gesprek, geen kop erboven. Zo houdt de inhoud de ruimte. Deze uitsparing is ook de knop die het gesprek in- en uitklapt (Barts aanwijzing): tikken op de tegenpartij is waar je van nature naar wijst als je "dit gesprek" bedoelt. Een BUTTON en geen span met een klikhandler, want dan werkt hij ook met het toetsenbord en leest een schermlezer de stand voor. Zonder JavaScript doet hij niets, en dan staat het gesprek gewoon open -- dat is ook de stand waar we mee beginnen. %> <%# Blijft staan als het gesprek dicht is, net als het aantal in de uitsparing hierboven -- daar is hij juist het meest waard. %> <% if (_twave) { %>👋<% } %> <% if (_tnew) { %><% } %> <%# De context bij de draad: waar gaat dit gesprek over? Zonder deze link is een antwoord in een lijst niet te plaatsen. %> <% if (n.post) { %> <%= n.post.title || n.post.slug %> <% } %>
    <%# Antwoorden vanuit de draad zelf, BOVEN de berichten (Robins besluit, 25-8). Sinds het nieuwste bovenaan staat, is de bovenkant waar het gesprek nu is: antwoorden hoort bij het laatste bericht, en dat staat er direct onder. Onderaan zou de knop bij het OUDSTE bericht komen te staan, en dat is precies waar je niet op antwoordt. Nog steeds ingeklapt, want een open editor onder elk gesprek maakt de lijst onleesbaar -- juist het probleem dat deze weergave moest oplossen. De route kiest het pad: een draad aan een post krijgt een reply, een draad aan een persoon een direct bericht. %> <%# shaer-r4c: precies de tak die de server ook kiest. /messages/reply gaat naar deliverReply als er een interaction+post is (dat is een ANTWOORD en valt onder de poort), en anders naar deliverDirectNote (dat is een bericht, andere poort). Alleen de eerste verbergen. %> <% var _rt = n.replyTo || {}; var _thread = _rt.interactionId && _rt.postSlug; %> <% var _kan = canMutate && ((_thread && locals.mayReply !== false) || (!_thread && _rt.actorUri)); %> <% if (_kan) { %> <%# Heette msg-thread-foot toen hij onderaan stond. Een naam die zegt waar iets staat is een leugen zodra het verhuist, dus nu zegt hij wat het IS. %>
    <%= t('fedi.reply') %>
    <%- include('../partials/reply-editor', { action: (typeof siteUrlBase !== 'undefined' ? siteUrlBase : '') + '/messages/reply', hiddenFields: [ { name: 'interaction_id', value: _rt.interactionId || '' }, { name: 'post_slug', value: _rt.postSlug || '' }, { name: 'to', value: _rt.actorUri || '' }, ], placeholder: t('fedi.reply_ph'), submitLabel: t('fedi.reply'), rows: 2, }) %>
    <%# De zwaai blijft een eigen knop: het is geen antwoord maar een seintje (FEP-633c), en die twee horen niet op een hoop. %> <% if (_rt.actorUri) { %>
    <% } %>
    <% } %> <%# NIEUWSTE BOVENAAN binnen een gesprek (Robins besluit, 25-8). De LIJST van gesprekken en de meldingen blijven staan zoals ze stonden; alleen binnen een draad leest het van nieuw naar oud, dus wat er net bij kwam staat er meteen en niet onderaan een lange draad. Op een KOPIE, want groupConversations sorteert `messages` oplopend en de rest van deze pagina rekent daarop -- `_tnew` en `_tto` hierboven lezen dezelfde array. Een reverse() zonder slice() draait het origineel om en dat werkt door naar alles wat er daarna nog naar kijkt. In de MARKUP en niet met column-reverse: die draait alleen het beeld om, terwijl een schermlezer en het toetsenbord de oude volgorde houden. %>
  • <% } else { %> <% var _seen = (typeof seen !== 'undefined' && seen) ? seen : 0; var _t = n.type === 'announce' ? 'boost' : n.type; // reply|mention|report|like|boost|follow|sent var _new = _seen && n.created_at ? (Date.parse(n.created_at) > _seen) : false; var _who = n.name || n.handle || ''; var _priv0 = (n.visibility === 'followers' || n.visibility === 'direct'); // Emmers: Activiteit = likes/boosts/follows/polls, Moderatie = // reports, en al het overige is gesprek. De oude emmers 'msgs' en // 'sent' bestaan niet meer sinds Berichten, Gesprekken en Verzonden // samenvielen -- en dat is geen cosmetische hernoeming: een // gespreksregel die om wat voor reden dan ook geen draad werd (geen // post, geen herkenbare tegenpartij) hield anders een data-kind // waarvoor geen chip meer bestond, en was daarmee onder ELKE chip // behalve Alles onzichtbaar. var _kind = (_t === 'like' || _t === 'boost' || _t === 'follow' || _t === 'poll_done') ? 'act' : _t === 'report' ? 'mod' : 'conv'; // Binnen een draad is dit geen zelfstandige regel: de chip filtert op // de draad, niet op de losse zinnen erin. var _sub = (typeof inThread !== 'undefined' && inThread); var _init = String(_who || '?').replace(/^@/, '').charAt(0).toUpperCase(); var _priv = (n.visibility === 'followers' || n.visibility === 'direct'); %>
  • data-kind="<%= _kind %>"<% } %> data-who="<%= String(_who).toLowerCase() %>">
    <% if (_t === 'sent') { %> <%= t('msg.you') %> <% if (n.to_handle && !_sub) { %>→ <%= n.to_handle %><% } %> <% } else { %> <%- emojiName(_who, n.actor_emoji_json) %> <% /* De naam blijft: binnen een draad moet je zien WIE wat zei. De handle erachter niet -- die staat in de kop. */ %> <% if (n.handle && n.name && !_sub) { %><%= n.handle %><% } %> <% } %> <% if (_new) { %><% } %> <% /* When the post was written, like de Krant and de Guardian PWA show it. created_at (when it reached us) stays the sort key and drives the "new since your last visit" dot above. */ %> <% if (n.published || n.created_at) { %><%= formatDateTime(n.published || n.created_at) %><% } %>
    <% var _hasWhat = !_sub || _priv || (_t === 'mention' && (n.help_request || n.wave || n.note_url)) || (_t === 'sent' && n.in_reply_to); %> <% if (_hasWhat) { %>
    <% if (n.count && n.count > 1) { %> <%= t('msg.and_more', { n: n.count - 1 }) %> <%= _t === 'like' ? t('msg.liked_many') : t('msg.boosted_many') %> <% } else if (_t === 'follow') { %><%= t('notif.followed') %> <% } else if (_t === 'like') { %><%= t('notif.liked') %> <% } else if (_t === 'boost') { %><%= t('notif.boosted') %> <% } else if (_t === 'report') { %><%= t('notif.reported') %> <% } else if (_t === 'mention' && n.help_request) { %>🛟 <%= t('msg.help_request') %> <% } else if (_t === 'mention' && n.wave) { %>👋 <%= t('msg.waved_at_you') %> <% } else if (_sub) { %><%# binnen een draad zegt de kop al dat dit een gesprek is %> <% } else if (_t === 'mention') { %><%= t('notif.mentioned') %> <% } else if (_t === 'sent') { %><%= t('msg.sent_reply') %> <% } else if (_t === 'poll_done') { %><%= t('msg.poll_done') %> <% } else { %><%= t('notif.replied') %><% } %> <% if (_priv) { %>🔒 <%= t('msg.private') %><% } %> <% if (n.post_slug && !_sub) { %><%= n.post_title || n.post_slug %><% } %> <% if (_t === 'mention' && n.note_url) { %><%= t('tl.view_original') %><% } %> <% if (_t === 'sent' && n.in_reply_to) { %><%= t('tl.view_original') %><% } %>
    <% } %> <% if (_t === 'report' && n.content) { %>
    <%= n.content %>
    <% } else if ((_t === 'reply' || _t === 'mention' || _t === 'sent') && n.content) { %>
    <%- include('../partials/note-body', { nb: n }) %>
    <% if (_t === 'mention' && n.wave && n.actorUri && canMutate) { %>
    <% } %> <% } else if (_t === 'poll_done' && n.poll) { %>
    <% n.poll.options.forEach(function (o) { %>
    <%= o.name %><%= o.pct %>%
    <% }); %>
    <%= t('msg.poll_total', { n: n.poll.voters }) %>
    <% } %> <% if (_t === 'sent' && n.outboxId) { %>
    <%= t('fedi.edit') %>
    <%- include('../partials/reply-editor', { action: '/fediverse/' + n.outboxId + '/edit', placeholder: t('fedi.reply_ph'), submitLabel: t('fedi.save_edit'), rows: 2, initialHtml: n.content, initialText: n.editable, defaultLang: n.language, noAttach: true, }) %>
    <% } %>
  • <% } %>