Changeset 952baf3 in Klonkt for src/views/partials/topnav.ejs


Ignore:
Timestamp:
08/07/2026 05:15:52 PM (5 weeks ago)
Author:
Robin <roboburr@…>
Branches:
main
Children:
ba76bf5
Parents:
f85b2c3 (diff), 0d5bd2c (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge GitHub-main (1.7.0) met de VPS-lijn

De twee mains waren een dag gedivergeerd en bevatten elk echt werk. GitHub had 66
commits die nooit langs prutfolio.git zijn gekomen, omdat een parallelle sessie
rechtstreeks naar GitHub pushte vanaf een kloon in /tmp op de VPS. De VPS had twee
commits die GitHub niet had. Geen van beide bevatte de ander, en stable had geen van
de twee.

Bewust een merge en geen rebase: dan blijft beide historie intact en wordt er niets
herschreven waar iemand anders al op voortbouwt.

Drie bestanden raakten beide kanten. Alle drie zijn nagekeken, want dat een merge
automatisch slaagt zegt niets over of hij inhoudelijk klopt:

src/services/ActivityPubService.js

  • de sleutelbinding staat nu boven de nieuwe asSlug-aanroep van 1.7.0, dus de controle komt nog steeds voor de handtekeningcontrole

scripts/klonkt-refresh-updater.sh

  • alleen de opzij-aanpak overleefde; systemctl mask staat nergens meer als code

deploy/MULTI-INSTANCE.md

  • spreekt zichzelf niet tegen: beschrijft opzij zetten, met de reden waarom mask weigert

remarks: het gat dat in de review naar boven kwam staat hiermee ook op de 1.7.0-lijn.
De andere bevindingen uit die review staan nog open en zijn niet in deze merge
opgelost; die horen als beads. Ook nog te doen: dezelfde sleutelbinding op stable
als 1.6.1, want daar is het gat nog open bij self-hosters.

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/views/partials/topnav.ejs

    rf85b2c3 r952baf3  
    176176
    177177<!-- Search overlay (shared by mobile bottom-tab + desktop top-nav) -->
    178 <div id="search-overlay" class="search-overlay" hidden data-suggest="<%= _siteUrlBase %>/search/suggest" data-action="<%= _siteUrlBase %>/search">
     178<%# De teksten staan op het element dat ze gebruikt, niet in het script: een
     179    module is een statisch bestand en kan geen vertaling interpoleren. %>
     180<div id="search-overlay" class="search-overlay" hidden data-suggest="<%= _siteUrlBase %>/search/suggest" data-action="<%= _siteUrlBase %>/search"
     181     data-i18n="<%= JSON.stringify({ posts: t('search.section_posts'), tracks: t('search.section_tracks'), events: t('search.section_events'), pages: t('search.section_pages'), all: t('search.suggest_all'), none: t('search.suggest_empty') }) %>">
    179182  <div class="container">
    180183    <form class="search-overlay-form" method="get" action="<%= _siteUrlBase %>/search">
     
    191194</div>
    192195
    193 <script>
    194 (function() {
    195   // Wired ONCE. This chrome (topnav) is re-inserted out-of-band during htmx navigation
    196   // → without this guard the script would stack EXTRA listeners on every navigation,
    197   // causing the theme toggle to fire 2× (or more) = no net change ("toggle stops working").
    198   // Everything below uses event delegation on body/document, so it also works for
    199   // buttons that appear after this run (OOB).
    200   if (window.__pcmsChromeWired) return;
    201   window.__pcmsChromeWired = true;
    202 
    203   function toggleTheme() {
    204     var cur = document.documentElement.getAttribute('data-theme') || 'dark';
    205     var next = cur === 'dark' ? 'light' : 'dark';
    206     document.documentElement.setAttribute('data-theme', next);
    207     try { localStorage.setItem('pcms-theme', next); } catch (e) {}
    208   }
    209   function overlay() { return document.getElementById('search-overlay'); }
    210   function openSearch() { var o = overlay(); if (o) { o.hidden = false; var i = o.querySelector('input'); if (i) i.focus(); } }
    211   function closeSearch() { var o = overlay(); if (o) { o.hidden = true; var b = document.getElementById('search-suggest'); if (b) b.innerHTML = ''; } }
    212 
    213   document.body.addEventListener('click', function(e) {
    214     if (e.target.closest('#theme-toggle, #theme-toggle-mobile, #theme-toggle-footer')) { toggleTheme(); return; }
    215     if (e.target.closest('#search-toggle')) { openSearch(); return; }
    216     if (e.target.closest('#search-close')) { closeSearch(); return; }
    217     // Close open dropdowns (user menu + language picker) on click outside.
    218     document.querySelectorAll('.user-menu[open], .lang-menu[open]').forEach(function(d) {
    219       if (!d.contains(e.target)) d.removeAttribute('open');
    220     });
    221   });
    222 
    223   document.addEventListener('keydown', function(e) {
    224     if (e.key === 'Escape') { var o = overlay(); if (o && !o.hidden) closeSearch(); }
    225   });
    226 
    227   // ── Live results while typing ───────────────────────────────────
    228   var _ST = {
    229     posts: '<%= t('search.section_posts') %>', tracks: '<%= t('search.section_tracks') %>',
    230     events: '<%= t('search.section_events') %>', pages: '<%= t('search.section_pages') %>',
    231     all: '<%= t('search.suggest_all') %>', none: '<%= t('search.suggest_empty') %>'
    232   };
    233   function esc(s) { return String(s == null ? '' : s).replace(/[&<>"]/g, function(c){ return {'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;'}[c]; }); }
    234   function renderSuggest(box, d, q, ov) {
    235     var html = '';
    236     function grp(title, items, fmt) {
    237       if (!items || !items.length) return;
    238       html += '<div class="ss-group"><div class="ss-title">' + esc(title) + '</div>' + items.map(fmt).join('') + '</div>';
    239     }
    240     grp(_ST.posts, d.posts, function(p){ return '<a class="ss-item" href="' + esc(p.url) + '">' + esc(p.title) + '</a>'; });
    241     grp(_ST.tracks, d.tracks, function(tk){ var sub = tk.artist ? ' <span class="ss-sub">' + esc(tk.artist) + '</span>' : ''; return tk.url ? '<a class="ss-item" href="' + esc(tk.url) + '">' + esc(tk.title) + sub + '</a>' : '<span class="ss-item ss-noclick">' + esc(tk.title) + sub + '</span>'; });
    242     grp(_ST.events, d.events, function(ev){ return '<a class="ss-item" href="' + esc(ev.url) + '">' + esc(ev.where || ev.when) + ' <span class="ss-sub">' + esc(ev.when) + '</span></a>'; });
    243     grp(_ST.pages, d.pages, function(pg){ return '<a class="ss-item" href="' + esc(pg.url) + '">' + esc(pg.label) + '</a>'; });
    244     var hasAny = (d.posts && d.posts.length) || (d.tracks && d.tracks.length) || (d.events && d.events.length) || (d.pages && d.pages.length);
    245     if (!hasAny) { box.innerHTML = '<div class="ss-empty">' + esc(_ST.none) + '</div>'; return; }
    246     var action = (ov && ov.getAttribute('data-action')) || '/search';
    247     html += '<a class="ss-all" href="' + esc(action) + '?q=' + encodeURIComponent(q) + '">' + esc(_ST.all) + '</a>';
    248     box.innerHTML = html;
    249   }
    250   var _sTimer;
    251   document.addEventListener('input', function(e) {
    252     var inp = e.target.closest && e.target.closest('#search-overlay input[name="q"]');
    253     if (!inp) return;
    254     var box = document.getElementById('search-suggest');
    255     if (!box) return;
    256     var q = inp.value.trim();
    257     clearTimeout(_sTimer);
    258     if (q.length < 2) { box.innerHTML = ''; return; }
    259     _sTimer = setTimeout(function() {
    260       var ov = document.getElementById('search-overlay');
    261       var url = (ov && ov.getAttribute('data-suggest')) || '/search/suggest';
    262       fetch(url + '?q=' + encodeURIComponent(q))
    263         .then(function(r){ return r.ok ? r.json() : null; })
    264         .then(function(d){ if (d) renderSuggest(box, d, q, ov); })
    265         .catch(function(){});
    266     }, 200);
    267   });
    268   // Click on a suggestion → close the overlay (the link/boost handles navigation).
    269   document.addEventListener('click', function(e) {
    270     if (e.target.closest && e.target.closest('#search-suggest a')) { var o = overlay(); if (o) o.hidden = true; }
    271   });
    272 })();
    273 </script>
     196<%# Het script van de topnav staat in assets/js/mod/chrome.js (shaer-bqr). %>
    274197
    275198<style>
Note: See TracChangeset for help on using the changeset viewer.