Changeset 7875a80 in Klonkt for src/views/partials/msg-item.ejs


Ignore:
Timestamp:
08/06/2026 01:56:08 AM (5 weeks ago)
Author:
Claude (agent) <aiclaude@…>
Branches:
main
Children:
0448e34
Parents:
04aca12
git-author:
Robin <roboburr@…> (08/06/2026 01:55:53 AM)
git-committer:
Claude (agent) <aiclaude@…> (08/06/2026 01:56:08 AM)
Message:

Berichten toont gesprekken: Berichten, Gesprekken en Verzonden vouwen samen

Berichten had zes chips, waarvan drie over hetzelfde gesprek gingen. Een
uitwisseling viel daardoor uit elkaar: wat jij stuurde stond onder Verzonden,
wat je terugkreeg onder Berichten of Gesprekken, en om een draad te volgen moest
je tussen chips heen en weer. Dat waren geen aparte pagina's maar client-side
filters over een enkele lijst, dus het probleem zat in het model, niet in de
weergave.

Antwoorden, mentions en je eigen verzonden berichten vouwen nu samen tot draden.
De sleutel: hangt het bericht aan een post van jou, dan is dat de draad --
ontvangen antwoorden kennen hun post via de join op posts, verzonden antwoorden
via ap_outbox.post_slug, en dat is dezelfde sleutel. Hangt het aan niets van jou
(een mention), dan loopt de draad per tegenpartij. De post wint van de persoon:
twee mensen onder dezelfde post voeren een gesprek, geen twee.

De context hoort bij de draad. Gaat het gesprek over een post, dan staat de link
ernaartoe in de kop, want zonder die context is een los antwoord in een lijst
niet te plaatsen. Binnen de draad leest het van oud naar nieuw, en jouw eigen
bijdragen staan aan de andere kant van de lijn zodat je de beurten ziet zonder
namen te lezen.

Likes, boosts, follows, reports en poll-uitslagen blijven losse regels: dat is
geen gesprek. De chips gaan van zes naar vier: Alles, Gesprekken, Activiteit,
Moderatie.

Twee dingen die daarbij moesten:

  • listOutbox selecteert post_slug (stond in de tabel, werd niet gelezen).
  • De filter kijkt naar ':scope > .msg-item', want de bubbels in een draad zijn geen zelfstandige regels meer; zoeken indexeert een draad op zijn hele tekst in plaats van op de eerste bubbel.

De titel van de post blijft leeg zolang hij onbekend is in plaats van terug te
vallen op de slug: het nieuwste bericht in een draad is vaak je eigen antwoord,
en dat kent alleen de slug -- zou die de titel worden, dan kon het ontvangen
antwoord eronder de echte titel niet meer invullen.

Getest tegen dev.klonkt.com: de groepering en de template gedraaid op de echte
database daar, en op een kopie ervan met een nagebouwd gesprek (twee ontvangen
antwoorden, jouw antwoord ertussen, plus een like). Dat levert een draad van
drie berichten op volgorde met de post als context, terwijl de like een losse
regel blijft. Suite 408/408.

Co-Authored-By: Claude Opus 5 <noreply@…>

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/views/partials/msg-item.ejs

    r04aca12 r7875a80  
     1<% if (n.type === 'thread') { %>
     2<%
     3           var _tseen = (typeof seen !== 'undefined' && seen) ? seen : 0;
     4           // Een draad is nieuw zodra EEN bericht erin nieuw is.
     5           var _tnew = !!_tseen && (n.messages || []).some(function (m) {
     6             return m.created_at && Date.parse(m.created_at) > _tseen;
     7           });
     8           var _tpeople = (n.people || []).map(function (p) { return p.name || p.handle || '?'; });
     9           // Alleen jij aan het woord: dan is de tegenpartij het adres waaraan
     10           // je schreef, niet een lege naam.
     11           var _tto = ((n.messages || []).find(function (m) { return m.to_handle; }) || {}).to_handle;
     12           var _tlabel = _tpeople.length ? _tpeople.join(', ') : (_tto || t('msg.you'));
     13      %>
     14        <li class="msg-item msg-thread<%= _tnew ? ' is-new' : '' %>" data-kind="conv" data-who="<%= (_tpeople.join(' ') + ' ' + (_tto || '')).toLowerCase() %>">
     15          <div class="msg-thread-head">
     16            <span class="msg-thread-who"><%= _tlabel %></span>
     17            <% if (n.count > 1) { %><span class="msg-thread-count"><%= n.count %></span><% } %>
     18            <% if (_tnew) { %><span class="msg-new" title="<%= t('msg.new') %>"></span><% } %>
     19            <%# De context bij de draad: waar gaat dit gesprek over? Zonder deze
     20                link is een antwoord in een lijst niet te plaatsen. %>
     21            <% if (n.post) { %>
     22              <a class="msg-thread-post" href="/<%= n.post.slug %>">
     23                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/></svg>
     24                <%= n.post.title || n.post.slug %>
     25              </a>
     26            <% } %>
     27          </div>
     28          <ul class="msg-thread-msgs">
     29            <% (n.messages || []).forEach(function (m) { %><%- include('msg-item', { n: m, seen: _tseen, inThread: true }) %><% }); %>
     30          </ul>
     31        </li>
     32<% } else { %>
    133<%
    234           var _seen = (typeof seen !== 'undefined' && seen) ? seen : 0;
     
    1345             : (_t === 'mention' || _priv0) ? 'msgs'
    1446             : 'conv';
     47           // Binnen een draad is dit geen zelfstandige regel: de chip filtert op
     48           // de draad, niet op de losse zinnen erin.
     49           var _sub = (typeof inThread !== 'undefined' && inThread);
    1550           var _init = String(_who || '?').replace(/^@/, '').charAt(0).toUpperCase();
    1651           var _priv = (n.visibility === 'followers' || n.visibility === 'direct');
    1752      %>
    18         <li class="msg-item msg-<%= _t %><%= _new ? ' is-new' : '' %>" data-kind="<%= _kind %>" data-who="<%= String(_who).toLowerCase() %>">
     53        <li class="<%= _sub ? 'msg-sub' : 'msg-item' %> msg-<%= _t %><%= _new ? ' is-new' : '' %>"<% if (!_sub) { %> data-kind="<%= _kind %>"<% } %> data-who="<%= String(_who).toLowerCase() %>">
    1954          <span class="msg-av<%= _t === 'sent' ? ' msg-av-sent' : '' %>" aria-hidden="true">
    2055            <% if (_t === 'sent') { %><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="22" y1="2" x2="11" y2="13"/><polygon points="22 2 15 22 11 13 2 9 22 2"/></svg>
     
    65100              <% } else { %><%= t('notif.replied') %><% } %>
    66101              <% if (_priv) { %><span class="msg-priv" title="<%= t('msg.private_hint') %>">🔒 <%= t('msg.private') %></span><% } %>
    67               <% if (n.post_slug) { %><a class="msg-post" href="/<%= n.post_slug %>"><%= n.post_title || n.post_slug %></a><% } %>
     102              <% if (n.post_slug && !_sub) { %><a class="msg-post" href="/<%= n.post_slug %>"><%= n.post_title || n.post_slug %></a><% } %>
    68103              <% if (_t === 'mention' && n.note_url) { %><a class="msg-post" href="<%= n.note_url %>" target="_blank" rel="nofollow noopener"><%= t('tl.view_original') %></a><% } %>
    69104              <% if (_t === 'sent' && n.in_reply_to) { %><a class="msg-post" href="<%= n.in_reply_to %>" target="_blank" rel="nofollow noopener"><%= t('tl.view_original') %></a><% } %>
     
    116151          </div>
    117152        </li>
     153<% } %>
Note: See TracChangeset for help on using the changeset viewer.