source: Klonkt/src/views/pages/home.ejs@ 9da8027

main
Last change on this file since 9da8027 was 7cf8144, checked in by Bart <bart@…>, 3 weeks ago

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@…>

  • Property mode set to 100644
File size: 3.8 KB
Line 
1<%
2// Homepage — feed of posts.
3//
4// Renders BOTH a timeline view (.post-list, default) AND a grid view
5// (.feed-grid, square Instagram-style tiles). CSS toggles between the
6// two based on body[data-feed-view="timeline"|"grid"]. This mirrors the
7// v9 pattern in lib/template-content.php so the same view-switcher works.
8//
9// Pinned posts sort first inside the timeline list; they are not given a
10// separate "Pinned" header (v9 just lets order speak for itself + a ★ chip).
11
12const allPosts = [...pinnedPosts, ...posts];
13const _base = (typeof siteUrlBase !== 'undefined' && siteUrlBase) ? siteUrlBase : '';
14%>
15
16<%# View switcher used to be rendered here; moved to shell.ejs (above
17 #pcms-main) so it survives HTMX swaps and is visible on every
18 non-admin page. %>
19
20<%# FEP-7628 slice 3: this account moved. The signpost comes FIRST, before
21 any post: a visitor should not scroll a dead feed to find out we left.
22 typeof-guard because an old route may render this template for one
23 request right after a deploy (view cache fills on first hit). %>
24<% if (typeof movedTo !== 'undefined' && movedTo) { %>
25 <div class="container">
26 <aside class="moved-banner">
27 <p class="moved-banner-lead"><%= t('phome.moved_lead') %></p>
28 <a class="moved-banner-link" href="<%= movedTo %>" rel="me noopener"><%= movedToLabel || movedTo %></a>
29 <p class="moved-banner-hint"><%= t('phome.moved_hint') %></p>
30 </aside>
31 </div>
32<% } %>
33
34<!-- ========== TIMELINE ========== -->
35<div class="container feed-timeline">
36
37 <% if (allPosts.length === 0) { %>
38 <div class="empty">
39 <h1><%= t('phome.empty_title') %></h1>
40 <p><%= t('phome.empty_sub') %></p>
41 <% if (user && canMutate && permissions.canCreatePost(user, site)) { %>
42 <p style="margin-top:2rem">
43 <a class="btn" href="<%= _base %>/posts/new"
44 hx-get="<%= _base %>/posts/new?partial=1" hx-target="#pcms-main" hx-swap="innerHTML"
45 hx-push-url="<%= _base %>/posts/new" hx-indicator="#pcms-loading">
46 <%= t('phome.write_first') %> →
47 </a>
48 </p>
49 <% } %>
50 </div>
51 <% } else { %>
52 <ul class="post-list feed-timeline-list" id="post-list">
53 <% allPosts.forEach(function(post) { %>
54 <%- include('../partials/post-card', { post: post }) %>
55 <% }); %>
56 </ul>
57 <% } %>
58
59</div>
60
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
77<!-- ========== GRID (only visible when body[data-feed-view="grid"]) ========== -->
78<% if (allPosts.length > 0) { %>
79<section class="feed-grid container" aria-label="<%= t('phome.grid_view') %>">
80 <div class="grid-tiles" id="grid-tiles">
81 <% allPosts.forEach(function(post) { %>
82 <%- include('../partials/post-tile', { post: post }) %>
83 <% }); %>
84 </div>
85</section>
86<% } %>
87<% if (typeof hasMore !== 'undefined' && allPosts.length > 0) { %>
88<div class="container feed-more-wrap">
89 <%- include('../partials/load-more', { hasMore: hasMore, nextOffset: nextOffset, moreBase: moreBase, moreTarget: '#post-list', morePath: '/' }) %>
90</div>
91<% } %>
Note: See TracBrowser for help on using the repository browser.