Changeset e64a49b in Klonkt
- Timestamp:
- 08/07/2026 12:24:02 PM (5 weeks ago)
- Branches:
- main
- Children:
- 0db68bd
- Parents:
- 20ae7b0
- git-author:
- Robin <roboburr@…> (08/07/2026 12:24:00 PM)
- git-committer:
- roboburr <roboburr@…> (08/07/2026 12:24:02 PM)
- Location:
- src
- Files:
-
- 1 added
- 3 edited
-
assets/js/mod/messages.js (added)
-
middleware/render.js (modified) (1 diff)
-
routes/posts.js (modified) (1 diff)
-
views/pages/messages.ejs (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
src/middleware/render.js
r20ae7b0 re64a49b 249 249 appVersion: APP_VERSION, 250 250 bodyClass: data.bodyClass || 'on-home', 251 // Welke module(s) deze pagina nodig heeft (shaer-bqr). De shell zet ze op 252 // body[data-js]; de bootstrap daar importeert ze uit /assets/js/mod/. 253 // Alleen kleine letters, cijfers, streepjes en spaties -- de naam wordt een 254 // pad. 255 pageJs: /^[a-z0-9 -]*$/.test(String(data.pageJs || '')) ? (data.pageJs || '') : '', 251 256 socialDescr: data.socialDescr || '', 252 257 socialImage: data.socialImage || '', -
src/routes/posts.js
r20ae7b0 re64a49b 936 936 : []).filter((o) => o['shaer:ward'] === gMe && o['shaer:needsMyAccept']); 937 937 renderPage(req, res, 'pages/messages', { 938 pageTitleKey: 'msg.title', bodyClass: 'on-special', items, seenAt,938 pageTitleKey: 'msg.title', bodyClass: 'on-special', pageJs: 'messages', items, seenAt, 939 939 hasMore, nextOffset: offset + FEED_PAGE, moreBase, guardianOffers, 940 940 success: req.query.success || null, error: req.query.error || null, -
src/views/pages/messages.ejs
r20ae7b0 re64a49b 60 60 </div> 61 61 62 <script> 63 (function () { 64 if (window.__msgWired) return; window.__msgWired = true; 65 66 // Filtering: kind chip AND free-text search, combined in JS (search over the 67 // sender and the rendered message text). Empty search + "all" = show all. 68 var list = document.querySelector('.msg-list'); 69 var noMatch = document.querySelector('.msg-nomatch'); 70 var q = document.getElementById('msg-q'); 71 var kind = 'all'; 72 var items = []; 73 function indexItem(li) { 74 // Een draad indexeren op zijn eerste bubbel zou de rest onvindbaar maken, 75 // dus daar nemen we de hele tekst; losse regels blijven gericht geindexeerd. 76 if (li.classList.contains('msg-thread')) { 77 li._search = ((li.getAttribute('data-who') || '') + ' ' + li.textContent).toLowerCase(); 78 return; 79 } 80 // Index once: sender + message body + linked post title + poll text. 81 var body = li.querySelector('.msg-content'); 82 var post = li.querySelector('.msg-post'); 83 var poll = li.querySelector('.msg-poll'); 84 li._search = ((li.getAttribute('data-who') || '') + ' ' + 85 (body ? body.textContent : '') + ' ' + (post ? post.textContent : '') + ' ' + 86 (poll ? poll.textContent : '')).toLowerCase(); 87 } 88 // Re-collect + index; called on load and after each "Load more" append so new 89 // items join the filter/search (and inherit the active chip via apply()). 90 function reindex() { 91 items = list ? Array.prototype.slice.call(list.querySelectorAll(':scope > .msg-item')) : []; 92 items.forEach(function (li) { if (!li._search) indexItem(li); }); 93 } 94 reindex(); 95 function apply() { 96 if (!list) return; 97 var term = (q && q.value || '').trim().toLowerCase(); 98 var shown = 0; 99 items.forEach(function (li) { 100 var ok = (kind === 'all' || li.getAttribute('data-kind') === kind) && 101 (!term || li._search.indexOf(term) !== -1); 102 li.style.display = ok ? '' : 'none'; 103 // Een treffer die in een dichtgeklapt gesprek zit, laat anders alleen de 104 // naam zien: je zoekt iets, het staat er, en je ziet het niet. Zolang er 105 // gezocht wordt gaat zo'n gesprek open; daarna keert hij terug naar de 106 // stand die de lezer zelf koos. 107 if (li.classList.contains('msg-thread')) { 108 li.classList.toggle('is-search-open', !!term && ok); 109 } 110 if (ok) shown++; 111 }); 112 if (noMatch) noMatch.hidden = shown !== 0; 113 } 114 // In- en uitklappen door op de tegenpartij te tikken (Barts aanwijzing). 115 // Gedelegeerd, zodat draden die via "meer laden" binnenkomen het vanzelf ook 116 // doen. De stand leeft alleen in deze pagina: standaard uitgeklapt, en na een 117 // herlading weer. Dat is bewust -- een gesprek dat je gisteren dichtklapte 118 // stilhouden is niet hetzelfde als het opruimen van je scherm van nu. 119 document.addEventListener('click', function (e) { 120 var who = e.target.closest('.msg-thread-who'); if (!who) return; 121 var li = who.closest('.msg-thread'); if (!li) return; 122 var dicht = li.classList.toggle('is-collapsed'); 123 who.setAttribute('aria-expanded', dicht ? 'false' : 'true'); 124 }); 125 document.addEventListener('click', function (e) { 126 var chip = e.target.closest('.msg-chip'); if (!chip) return; 127 kind = chip.getAttribute('data-show'); 128 document.querySelectorAll('.msg-chip').forEach(function (c) { c.classList.toggle('is-on', c === chip); }); 129 apply(); 130 }); 131 if (q) q.addEventListener('input', apply); 132 // After a "Load more" append (htmx), index the new rows and re-apply the filter. 133 document.body.addEventListener('htmx:afterSettle', function (e) { 134 if (e.target && e.target.id === 'msg-list') { reindex(); apply(); } 135 }); 136 137 var a = document.getElementById('fedi-bm-btn'); 138 if (a) { 139 a.setAttribute('href', "javascript:void(window.open('" + location.origin + "/authorize_interaction?uri='+encodeURIComponent(window.location.href)))"); 140 a.addEventListener('click', function (e) { e.preventDefault(); a.classList.add('nudge'); setTimeout(function(){ a.classList.remove('nudge'); }, 600); }); 141 } 142 })(); 143 </script> 62 <%# Filteren, zoeken en het in-/uitklappen zitten in assets/js/mod/messages.js. 63 Inline script hier wordt door de CSP geweigerd zodra je deze pagina via een 64 link BINNEN de site opent -- zie shaer-0i6. De shell laadt de module op 65 body[data-js]; deze pagina vraagt erom met pageJs (routes/posts.js). %> 144 66 145 67 <style>
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)