Changeset 7cf8144 in Klonkt for src/views


Ignore:
Timestamp:
08/18/2026 06:47:58 PM (3 weeks ago)
Author:
Bart <bart@…>
Branches:
main
Children:
9da8027
Parents:
2d2fd8c
git-author:
Bart <bart@…> (08/18/2026 05:28:31 AM)
git-committer:
Bart <bart@…> (08/18/2026 06:47:58 PM)
Message:

Lezen is een weergave van de feed, geen eigen plek

/read was een route met een eigen shell: eigen pagina, eigen chrome-gedrag, en
op een site zonder berichten een 404 -- een dode knop in de switcher. Nu is het
wat het altijd had moeten zijn: een derde waarde van body[data-feed-view], naast
timeline en grid. Dezelfde berichten, andere vorm.

De feed stuurt ze alledrie mee en CSS kiest, precies zoals timeline/grid dat al
deden. Het lijf loopt door PostAccessService, dus een gesloten poort levert ook
hier geen tekst op. "Meer laden" vult de leesstroom OOB mee aan, net als de
tegels.

DE LEGE STAAT zit in de :has(.feed-reader) op de verbergregel. Zonder berichten
rendert de leessectie niet, en dan blijft de tijdlijn staan -- want daar staat
"nog niets geschreven" met de knop om te beginnen. Zonder die voorwaarde was
Lezen op een verse site een wit scherm. Feeds zonder leessectie (cirkel,
archief) houden om dezelfde reden gewoon hun tijdlijn.

Wat weg kon, en dat is de winst:

  • de route, pages/read.ejs, en 'on-read' als page-class;
  • mod/read.js van 222 naar 51 regels. Het ophalen van buren, het corrigeren van de scrollpositie bij invoegen en het onderbreken van het snappen zijn niet opgelost maar OVERBODIG: de feed levert de berichten al. Wat blijft is de tik.
  • read.end en read.load_error: het script plaatst geen zinnen meer.

De balken schuiven niet meer weg. Dat was mooi op een eigen scherm, maar hier
zou het de switcher verbergen waarmee je net koos -- en dan kun je niet terug.

MOD_V naar 4, style.css naar v70.

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

Location:
src/views
Files:
1 deleted
5 edited

Legend:

Unmodified
Added
Removed
  • src/views/pages/home.ejs

    r2d2fd8c r7cf8144  
    5959</div>
    6060
     61<!-- ========== LEZEN (alleen zichtbaar bij body[data-feed-view="reader"]) ==========
     62     Hetzelfde stel berichten, maar heel: één per scherm, met de grenzen door
     63     CSS-snapping. Geen eigen route en geen eigen shell -- de balken blijven
     64     staan, want je bent nog gewoon op de feed en moet terug kunnen schakelen.
     65     Leeg? Dan valt de lege staat van de tijdlijn hierboven in beeld; deze
     66     sectie rendert dan niet. -->
     67<% if (typeof readerItems !== 'undefined' && readerItems && readerItems.length) { %>
     68<section class="feed-reader" aria-label="<%= t('switch.reader') %>">
     69  <div class="read-stream" id="read-stream" data-base="<%= _base %>">
     70    <% readerItems.forEach(function(it) { %>
     71      <%- include('../partials/read-article', { post: it.post, entry: it.entry }) %>
     72    <% }); %>
     73  </div>
     74</section>
     75<% } %>
     76
    6177<!-- ========== GRID (only visible when body[data-feed-view="grid"]) ========== -->
    6278<% if (allPosts.length > 0) { %>
  • src/views/partials/home-append.ejs

    r2d2fd8c r7cf8144  
    44    items instead of nesting under an extra box. %>
    55<div hx-swap-oob="beforeend:#grid-tiles" style="display:contents"><% posts.forEach(function(post){ %><%- include('post-tile', { post: post }) %><% }); %></div>
     6<%# Lezen: dezelfde berichten OOB achteraan de leesstroom, net als de tegels
     7    hierboven. Zonder dit zou "meer laden" in de leesweergave niets doen. %>
     8<% if (typeof readerItems !== 'undefined' && readerItems && readerItems.length) { %><div hx-swap-oob="beforeend:#read-stream" style="display:contents"><% readerItems.forEach(function(it){ %><%- include('read-article', { post: it.post, entry: it.entry }) %><% }); %></div><% } %>
    69<%- include('load-more', { hasMore: hasMore, nextOffset: nextOffset, moreBase: moreBase, moreTarget: '#post-list', morePath: (typeof morePath !== 'undefined' ? morePath : '/'), oob: true }) %>
  • src/views/partials/shared-styles.ejs

    r2d2fd8c r7cf8144  
    2727  padding: 0.15rem;
    2828}
    29 .view-switch-btn,
    30 .view-switch-link {
     29.view-switch-btn {
    3130  display: inline-flex; align-items: center; gap: 0.35rem;
    3231  padding: 0.35rem 0.85rem;
     
    3635  transition: background 120ms, color 120ms;
    3736}
    38 .view-switch-btn:hover,
    39 .view-switch-link:hover { color: var(--ink); }
    40 .view-switch-link { text-decoration: none; }
     37.view-switch-btn:hover { color: var(--ink); }
    4138/* Active = white (light background, dark text). Via aria-selected (element
    4239   attribute, set by syncAria + on htmx:afterSettle) → htmx-robust. On non-
    4340   feed pages syncAria sets aria-selected=false → both grey. */
    44 .view-switch-btn[aria-selected="true"],
    45 .view-switch-link[aria-selected="true"] { background: var(--ink); color: var(--paper); border-color: var(--ink); }
     41.view-switch-btn[aria-selected="true"] { background: var(--ink); color: var(--paper); border-color: var(--ink); }
    4642
    4743/* Agenda = its OWN pill (separate from Timeline/Grid, so the feed-toggle is never
  • src/views/partials/view-switcher.ejs

    r2d2fd8c r7cf8144  
    88  // Pagina's zonder actieve feed-weergave → niets in de pill is 'actief' (Solo/Cirkel
    99  // + Tijdlijn/Grid grijs). Alleen Agenda krijgt z'n eigen is-active op de agenda.
    10   var _neutral = ['on-shows','on-downloads','on-post','on-epk','on-linkbio','on-newsletter','on-archive','on-read']
     10  var _neutral = ['on-shows','on-downloads','on-post','on-epk','on-linkbio','on-newsletter','on-archive']
    1111                   .some(function(c){ return _bc.indexOf(c) >= 0; });
    12   var _onRead = _bc.indexOf('on-read') >= 0;
    13   var _sbR = (typeof siteUrlBase !== 'undefined' && siteUrlBase) ? siteUrlBase : '';
    1412%>
    1513<div class="view-switcher-wrap">
     
    4745        <span><%= t('switch.grid') %></span>
    4846      </button>
    49       <%# Lezen is GEEN in-place omschakeling maar een andere route (/read), dus
    50           een <a> en niet een <button>. En bewust NIET de klasse view-switch-btn:
    51           de gedelegeerde klik in shell.ejs pakt alles met die klasse op, zet
    52           body[data-feed-view] erop en springt op niet-feedpagina's terug naar
    53           home -- dat zou deze link opeten. Andere klasse, zelfde uiterlijk.
    54           aria-selected staat hier vast: syncAria() raakt alleen .view-switch-btn
    55           aan, dus de actieve staat op /read blijft staan na een htmx-navigatie. %>
    56       <a class="view-switch-link" href="<%= _sbR %>/read" role="tab"
    57          aria-selected="<%= _onRead ? 'true' : 'false' %>">
     47      <%# Lezen is een gewone derde weergave: dezelfde berichten, andere vorm.
     48          Dus een <button> met data-view, net als de andere twee -- dan doen de
     49          gedelegeerde klik, localStorage en syncAria in shell.ejs hun werk al. %>
     50      <button type="button" class="view-switch-btn" data-view="reader" role="tab"
     51              aria-selected="false">
    5852        <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"/><path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"/></svg>
    5953        <span><%= t('switch.reader') %></span>
    60       </a>
     54      </button>
    6155    </div>
    6256    <% if (!_neutral) { %>
  • src/views/shell.ejs

    r2d2fd8c r7cf8144  
    222222
    223223<!-- v9 stylesheet (full palette system) -->
    224 <link rel="stylesheet" href="/assets/css/style.css?v=68">
     224<link rel="stylesheet" href="/assets/css/style.css?v=70">
    225225<script>
    226226/* iOS safe-area, built by hand. env(safe-area-inset-top) resolves to 0 on this iOS in
     
    435435  // focusscherm óók via htmx z'n styling krijgt (geen chrome, geen tab, audio op 0).
    436436  // ALLES wat de server als page-class kan sturen moet hier staan: wat er niet in
    437   // staat wordt bij een htmx-navigatie stilletjes weggefilterd. 'on-read' ontbrak,
    438   // en dan kwam je via de Lezen-knop op een leesweergave waarvan ELKE regel
    439   // (.on-read ...) niet aansloeg: geen schermhoge berichten, geen snappen, geen
    440   // wegschuivende balken. Bij intikken van /read ging het wel goed, want dan
    441   // rendert de shell de class zelf -- vandaar dat het lang onzichtbaar bleef.
     437  // staat wordt bij een htmx-navigatie stilletjes weggefilterd.
    442438  var PAGE_CLASSES = ['on-home','on-post','on-special','on-archive','on-search','on-admin','on-auth',
    443439    'on-shows','on-downloads','on-download','on-epk','on-linkbio','on-newsletter',
    444     'on-tag','on-type','on-user','on-cirkel','on-hub','on-chat','on-read'];
     440    'on-tag','on-type','on-user','on-cirkel','on-hub','on-chat'];
    445441
    446442  document.body.addEventListener('pcmsNav', function(ev) {
     
    509505  // Eén nummer voor de hele map. Te vaak bumpen kost één download; te weinig
    510506  // bumpen kost een bugfix die nooit aankomt.
    511   var MOD_V = 3;
     507  var MOD_V = 4;
    512508
    513509  // name -> 1 (aan het laden) of de module-namespace (geladen). Een module
     
    554550  try {
    555551    var v = localStorage.getItem('pcms-feed-view');
    556     if (v === 'timeline' || v === 'grid') body.dataset.feedView = v;
     552    if (v === 'timeline' || v === 'grid' || v === 'reader') body.dataset.feedView = v;
    557553    var c = parseInt(localStorage.getItem('pcms-grid-cols'), 10);
    558554    if (c === 2 || c === 3 || c === 4) body.dataset.gridCols = String(c);
Note: See TracChangeset for help on using the changeset viewer.