Changeset 79bba6e in Klonkt for src/views/pages
- Timestamp:
- 06/17/2026 12:29:16 AM (3 months ago)
- Branches:
- main
- Children:
- cbd1761
- Parents:
- 44cf44d
- Location:
- src/views/pages
- Files:
-
- 2 edited
-
hub-home.ejs (modified) (1 diff)
-
prutter-conversation.ejs (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/views/pages/hub-home.ejs
r44cf44d r79bba6e 1 1 <div class="hub<%= hub.heroImage ? ' hub--img' : '' %>"> 2 2 3 <%# ── Minimale nav (alleen auth) — over de hero, geen brand/switcher ── %> 4 <nav class="hub-nav"> 5 <div class="hub-nav-inner container"> 6 <% if (user) { %> 7 <% if (typeof canSeeBeheer !== 'undefined' && canSeeBeheer) { %> 8 <a class="hub-nav-link" href="/admin" 9 hx-get="/admin?partial=1" hx-target="#pcms-main" hx-swap="innerHTML" 10 hx-push-url="/admin" hx-indicator="#pcms-loading">Beheer</a> 11 <% } %> 12 <a class="hub-nav-link" href="/account" 13 hx-get="/account?partial=1" hx-target="#pcms-main" hx-swap="innerHTML" 14 hx-push-url="/account" hx-indicator="#pcms-loading"><%= user.username %></a> 15 <a class="hub-nav-link" href="/auth/logout">Uitloggen</a> 16 <% } else { %> 17 <a class="hub-nav-link" href="/auth/login">Inloggen</a> 18 <% } %> 19 </div> 20 </nav> 21 22 <%# ── HERO (label) — de pagina begint hier, geen header erboven ────── %> 3 <%# ── HERO (label) — de mini topnav-balk staat erboven (chrome.ejs); 4 de hero zelf is de "grote" header van de hub-home ──────────────── %> 23 5 <header class="hub-hero<%= hub.heroImage ? ' has-img' : '' %>"<% if (hub.heroImage) { %> style="--hero-img:url('<%= hub.heroImage %>'); --hero-ov:<%= ((hub.heroOverlay == null ? 45 : hub.heroOverlay)/100).toFixed(2) %>"<% } %>> 24 6 <div class="hub-hero-inner container"> -
src/views/pages/prutter-conversation.ejs
r44cf44d r79bba6e 1 <div class=" containerprutter-conv-page" data-conversation-id="<%= conversation.id %>" data-me="<%= user.id %>">1 <div class="prutter-conv-page" data-conversation-id="<%= conversation.id %>" data-me="<%= user.id %>"> 2 2 <header class="prutter-conv-header"> 3 < p class="prutter-back"><a href="<%= siteUrlBase %>/prutter">← Inbox</a></p>4 <div class="prutter-conv-headline">5 <div class="prutter-conv-avatar prutter-conv-avatar--lg">6 <% if (other && other.avatar_url) { %>7 <img src="<%= other.avatar_url %>" alt="">8 < % } else { %>9 <span><%= (other && other.username || '?').charAt(0).toUpperCase() %></span>10 < % } %>11 < /div>12 <div>13 <h1><%= other ? other.username : 'Unknown' %></h1>14 <% if (other) { %>15 <p class="prutter-conv-sub"><a href="/users/<%= encodeURIComponent(other.username) %>">View profile</a></p>16 < % } %>17 < /div>3 <a class="prutter-back" href="<%= siteUrlBase %>/prutter" aria-label="Terug naar inbox" title="Inbox"> 4 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><line x1="19" y1="12" x2="5" y2="12"/><polyline points="12 19 5 12 12 5"/></svg> 5 </a> 6 <div class="prutter-conv-avatar"> 7 <% if (other && other.avatar_url) { %> 8 <img src="<%= other.avatar_url %>" alt=""> 9 <% } else { %> 10 <span><%= (other && other.username || '?').charAt(0).toUpperCase() %></span> 11 <% } %> 12 </div> 13 <div class="prutter-conv-id"> 14 <span class="prutter-conv-name"><%= other ? other.username : 'Onbekend' %></span> 15 <% if (other) { %> 16 <a class="prutter-conv-sub" href="/users/<%= encodeURIComponent(other.username) %>">Bekijk profiel</a> 17 <% } %> 18 18 </div> 19 19 </header> … … 35 35 hx-swap="beforeend" 36 36 hx-on::after-request="this.querySelector('textarea').value=''; window.__prutterScroll && window.__prutterScroll();"> 37 <textarea name="content" rows=" 2" maxlength="2000" placeholder="Type a message…" required></textarea>38 <button type="submit" class="btn btn-primary">S end</button>37 <textarea name="content" rows="1" maxlength="2000" placeholder="Bericht…" required></textarea> 38 <button type="submit" class="btn btn-primary">Stuur</button> 39 39 </form> 40 40 </div> … … 87 87 88 88 <style> 89 .prutter-conv-page { max-width: 720px; margin: 2rem auto; padding: 0 1rem; display: flex; flex-direction: column; gap: 1rem; } 90 .prutter-back { margin: 0; } 91 .prutter-back a { color: var(--accent); text-decoration: none; } 92 93 .prutter-conv-headline { 94 display: flex; align-items: center; gap: 0.85rem; 95 padding-bottom: 1rem; border-bottom: 1px solid var(--rule); 96 } 97 .prutter-conv-headline h1 { 98 font-family: var(--font-display, serif); 99 font-size: 1.5rem; margin: 0; 100 } 101 .prutter-conv-sub { margin: 0; font-size: 0.85rem; color: var(--ink-muted, var(--ink-soft)); } 102 .prutter-conv-sub a { color: var(--accent); } 103 104 .prutter-conv-avatar--lg { width: 56px; height: 56px; } 105 .prutter-conv-avatar--lg span { font-size: 1.2rem; } 106 89 /* ── Full-height chat-layout (mobile-first) ────────────────────────────── 90 De pagina is FIXED gepind tussen de topnav (desktop) en de onderste balken 91 (bottom-tab + audiospeler), zodat ALLEEN de thread scrollt — niet de hele 92 pagina. De offsets volgen de body-classes has-bottom-tab/has-audio-player, 93 dus de composer valt nooit achter een balk. */ 94 .prutter-conv-page { 95 position: fixed; 96 left: 0; right: 0; 97 top: 0; /* mobiel: masthead is verborgen → vanaf de top */ 98 bottom: 0; 99 max-width: 760px; margin: 0 auto; 100 display: flex; flex-direction: column; 101 padding: 0.5rem 0.75rem; 102 z-index: 1; 103 } 104 /* Desktop: de sticky masthead staat erboven → begin eronder. */ 105 @media (min-width: 768px) { 106 .prutter-conv-page { top: 64px; padding: 0.75rem 1rem; } 107 } 108 /* Onderste vrije ruimte = de balken die de viewport-bodem overlappen. */ 109 @media (max-width: 767px) { 110 body.has-bottom-tab .prutter-conv-page { bottom: calc(56px + env(safe-area-inset-bottom, 0)); } 111 } 112 body.has-audio-player .prutter-conv-page { bottom: calc(76px + env(safe-area-inset-bottom, 0)); } 113 @media (max-width: 767px) { 114 body.has-bottom-tab.has-audio-player .prutter-conv-page { bottom: calc(56px + 76px + env(safe-area-inset-bottom, 0)); } 115 } 116 117 /* Compacte chat-kop: terug-pijl + avatar + naam op één regel. */ 118 .prutter-conv-header { 119 flex: 0 0 auto; 120 display: flex; align-items: center; gap: 0.65rem; 121 padding-bottom: 0.6rem; margin-bottom: 0.5rem; 122 border-bottom: 1px solid var(--rule); 123 } 124 .prutter-back { 125 flex: 0 0 auto; 126 display: inline-flex; align-items: center; justify-content: center; 127 width: 40px; height: 40px; border-radius: 8px; 128 color: var(--ink); text-decoration: none; 129 } 130 .prutter-back:hover { color: var(--accent); background: var(--paper-2); } 131 .prutter-back svg { width: 20px; height: 20px; } 132 .prutter-conv-avatar { 133 flex: 0 0 auto; 134 width: 40px; height: 40px; border-radius: 50%; 135 overflow: hidden; background: var(--paper-2); 136 display: inline-flex; align-items: center; justify-content: center; 137 color: var(--accent); font-weight: 700; 138 } 139 .prutter-conv-avatar img { width: 100%; height: 100%; object-fit: cover; } 140 .prutter-conv-id { display: flex; flex-direction: column; min-width: 0; line-height: 1.2; } 141 .prutter-conv-name { 142 font-family: var(--font-display, serif); font-size: 1.15rem; color: var(--ink); 143 white-space: nowrap; overflow: hidden; text-overflow: ellipsis; 144 } 145 .prutter-conv-sub { font-size: 0.78rem; color: var(--ink-muted, var(--ink-soft)); text-decoration: none; } 146 .prutter-conv-sub:hover { color: var(--accent); } 147 148 /* De ENIGE scroller. min-height:0 is cruciaal in een flex-kolom, anders 149 groeit de lijst i.p.v. te scrollen. */ 107 150 .prutter-thread { 108 list-style: none; padding: 0; margin: 0; 109 display: flex; flex-direction: column; gap: 0.5rem; 110 background: var(--paper-2); 111 border: 1px solid var(--rule); 112 border-radius: 8px; 113 padding: 1rem; 114 height: 60vh; 115 overflow-y: auto; 116 } 117 118 .prutter-msg { display: flex; flex-direction: column; max-width: 80%; } 151 flex: 1 1 auto; min-height: 0; 152 list-style: none; margin: 0; 153 display: flex; flex-direction: column; gap: 0.4rem; 154 padding: 0.25rem 0.1rem 0.5rem; 155 overflow-y: auto; overscroll-behavior: contain; 156 -webkit-overflow-scrolling: touch; 157 } 158 159 .prutter-msg { display: flex; flex-direction: column; max-width: 82%; } 119 160 .prutter-msg-bubble { 120 161 padding: 0.55rem 0.85rem; … … 148 189 149 190 .prutter-composer { 191 flex: 0 0 auto; 150 192 display: flex; gap: 0.5rem; align-items: flex-end; 151 padding-bottom: env(safe-area-inset-bottom, 0); 193 padding-top: 0.6rem; margin-top: 0.25rem; 194 border-top: 1px solid var(--rule); 152 195 } 153 196 .prutter-composer textarea { 154 197 flex: 1; 155 padding: 0.6 rem 0.85rem;198 padding: 0.65rem 0.85rem; 156 199 border: 1px solid var(--rule); 157 border-radius: 8px;200 border-radius: 12px; 158 201 background: var(--paper); 159 202 color: var(--ink); 160 203 font-family: inherit; 161 font-size: 0.95rem; 162 resize: vertical; 163 min-height: 44px; 164 } 204 font-size: 1rem; /* ≥16px → iOS zoomt niet in bij focus */ 205 line-height: 1.35; 206 resize: none; 207 min-height: 44px; max-height: 40vh; 208 } 209 .prutter-composer .btn { flex: 0 0 auto; min-height: 44px; } 165 210 </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)