Changeset 52fc278 in Klonkt
- Timestamp:
- 08/07/2026 01:38:51 PM (5 weeks ago)
- Branches:
- main
- Children:
- 156baa3
- Parents:
- 54ee51c
- git-author:
- Robin <roboburr@…> (08/07/2026 01:16:27 PM)
- git-committer:
- roboburr <roboburr@…> (08/07/2026 01:38:51 PM)
- Location:
- src
- Files:
-
- 2 added
- 4 edited
-
assets/js/mod/download.js (added)
-
assets/js/mod/news.js (added)
-
routes/download.js (modified) (1 diff)
-
routes/posts.js (modified) (1 diff)
-
views/pages/download.ejs (modified) (2 diffs)
-
views/pages/news.ejs (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/routes/download.js
r54ee51c r52fc278 85 85 const fan = req.session && req.session.user; 86 86 renderPage(req, res, 'pages/download', { 87 pageJs: 'download', 87 88 pageTitle: track.title + ' — download', 88 89 bodyClass: 'on-download', -
src/routes/posts.js
r54ee51c r52fc278 1194 1194 } 1195 1195 renderPage(req, res, 'pages/news', { 1196 pageJs: 'news', 1196 1197 pageTitle: 'News', bodyClass: 'on-special', 1197 1198 timeline, hasMore, nextOffset: offset + FEED_PAGE, moreBase, -
src/views/pages/download.ejs
r54ee51c r52fc278 26 26 <p class="dl-sub"><%= _ready_sub %></p> 27 27 <p><a class="dl-go" href="<%= fileUrl %>"><%= _manual %></a></p> 28 <script> 29 // Auto-start de download (zelfde-origin attachment-link). 30 setTimeout(function(){ try { window.location.href = <%- JSON.stringify(fileUrl) %>; } catch(e){} }, 600); 31 </script> 28 <%# Het script staat in assets/js/mod/download.js; de servergegevens gaan via partials/page-data.ejs (shaer-bqr). %> 32 29 <% } else { %> 33 30 <h1 class="dl-h1"><%= _download_btn %> <%= tr.title %></h1> … … 57 54 .dl-go { padding: 12px 20px; border-radius: 10px; border: none; background: var(--accent,#6b8f71); color: #fff; font-weight: 600; font-size: 15px; cursor: pointer; text-decoration: none; display: inline-block; } 58 55 </style> 56 <%- include('../partials/page-data', { pageData: { fileUrl: fileUrl } }) %> -
src/views/pages/news.ejs
r54ee51c r52fc278 41 41 .tl-paste-go { background: var(--accent); color: var(--paper); } 42 42 </style> 43 <script> 44 (function () { 45 if (window.__tlPasteWired) return; window.__tlPasteWired = true; 46 function modal() { return document.getElementById('tl-paste'); } 47 function openM() { 48 var m = modal(); if (!m) return; 49 var inp = m.querySelector('.tl-paste-input'); 50 m.classList.add('is-open'); 51 if (inp) { 52 inp.value = ''; inp.focus(); 53 if (navigator.clipboard && navigator.clipboard.readText) { 54 navigator.clipboard.readText().then(function (t) { 55 t = (t || '').trim(); 56 if (/^https?:\/\//i.test(t) && !inp.value) { inp.value = t; inp.select(); } 57 }).catch(function () {}); 58 } 59 } 60 } 61 function closeM() { var m = modal(); if (m) m.classList.remove('is-open'); } 62 function go() { 63 var m = modal(); if (!m) return; 64 var inp = m.querySelector('.tl-paste-input'), v = (inp ? inp.value : '').trim(); 65 if (!/^https?:\/\//i.test(v)) { if (inp) inp.focus(); return; } 66 location.href = '/authorize_interaction?uri=' + encodeURIComponent(v); 67 } 68 document.addEventListener('click', function (e) { 69 if (e.target.closest && e.target.closest('#tl-paste-btn')) { e.preventDefault(); openM(); return; } 70 if (e.target.closest && e.target.closest('.tl-paste-go')) { e.preventDefault(); go(); return; } 71 if (e.target.closest && (e.target.closest('.tl-paste-cancel') || e.target.closest('.tl-paste-x'))) { e.preventDefault(); closeM(); return; } 72 var op = document.querySelector('.tl-paste.is-open'); if (op && e.target === op) closeM(); 73 }); 74 document.addEventListener('keydown', function (e) { 75 var m = document.querySelector('.tl-paste.is-open'); if (!m) return; 76 if (e.key === 'Escape') closeM(); 77 else if (e.key === 'Enter' && e.target.closest && e.target.closest('.tl-paste')) { e.preventDefault(); go(); } 78 }); 79 })(); 80 </script> 43 <%# Het script staat in assets/js/mod/news.js; de servergegevens gaan via partials/page-data.ejs (shaer-bqr). %> 81 44 <% if (typeof success !== 'undefined' && success) { %><div class="alert alert-success"><%= success %></div><% } %> 82 45 <% if (typeof error !== 'undefined' && error) { %><div class="alert alert-error"><%= error %></div><% } %> … … 184 147 .tl-act-block:hover { background: color-mix(in srgb, #d9534f 14%, transparent); border-color: color-mix(in srgb, #d9534f 50%, transparent); } 185 148 </style> 186 187 <script> 188 (function(){ 189 if (window.__fediRemoteWired) return; window.__fediRemoteWired = true; 190 var current = null, currentBtn = null; 191 function close(){ if (current) { current.remove(); current = null; currentBtn = null; } } 192 function go(raw, uri){ var d=(raw||'').trim().replace(/^@?[^@\s]*@/,'').replace(/^https?:\/\//i,'').replace(/\/.*$/,'').trim(); if(d){ try{ localStorage.setItem('pcmsFediServer', d); }catch(e){} location.href='https://'+d+'/authorize_interaction?uri='+encodeURIComponent(uri||''); } } 193 function place(f, b){ var r=b.getBoundingClientRect(); f.style.top=(r.bottom+window.scrollY+6)+'px'; f.style.left=Math.max(8, Math.min(r.left+window.scrollX, window.scrollX+window.innerWidth-340))+'px'; } 194 document.addEventListener('click', function(e){ 195 if (e.target.closest && e.target.closest('.fedi-remote-cancel')) { close(); return; } 196 if (current && e.target.closest && e.target.closest('.fedi-remote-form')) return; 197 var b = e.target.closest && e.target.closest('.fedi-remote-reply-btn'); 198 if (b) { 199 e.preventDefault(); 200 if (currentBtn === b) { close(); return; } 201 close(); 202 var f = document.createElement('form'); f.className='fedi-remote-form'; f.dataset.uri = b.getAttribute('data-fedi-uri')||''; 203 f.innerHTML = '<input type="text" autocomplete="off" spellcheck="false"><button type="submit" class="btn btn-primary fedi-remote-go" aria-label="ok">→</button><button type="button" class="fedi-remote-cancel" aria-label="x">×</button>'; 204 var _inp = f.querySelector('input'); _inp.placeholder = b.getAttribute('data-fedi-ph') || 'mastodon.social'; 205 try{ var _sv = localStorage.getItem('pcmsFediServer'); if(_sv) _inp.value = _sv; }catch(e){} 206 document.body.appendChild(f); place(f, b); current=f; currentBtn=b; _inp.focus(); _inp.select(); 207 return; 208 } 209 if (current) close(); 210 }); 211 document.addEventListener('submit', function(e){ var f=e.target.closest && e.target.closest('.fedi-remote-form'); if(!f) return; e.preventDefault(); go(f.querySelector('input').value, f.dataset.uri); }); 212 document.addEventListener('keydown', function(e){ if (e.key === 'Escape') close(); }); 213 window.addEventListener('scroll', close, true); 214 })(); 215 216 /* Short feed videos (gif/cover loops like an animated cover) autoplay + loop muted like a GIF; 217 longer real videos keep their controls. Decided on the actual duration once metadata loads. */ 218 (function(){ 219 document.querySelectorAll('.tl-media-video').forEach(function(v){ 220 if (v.dataset.gifWired) return; v.dataset.gifWired = '1'; 221 var decide = function(){ 222 if (v.duration && v.duration <= 30) { 223 v.removeAttribute('controls'); v.loop = true; v.muted = true; v.play().catch(function(){}); 224 } 225 }; 226 if (v.readyState >= 1) decide(); else v.addEventListener('loadedmetadata', decide, { once: true }); 227 }); 228 })(); 229 230 /* Like/Boost toggle in place — POST via fetch, flip the button, stay on the page (no reload, no banner). */ 231 (function(){ 232 if (window.__newsReactWired) return; window.__newsReactWired = true; 233 document.addEventListener('submit', function(e){ 234 var f = e.target.closest && e.target.closest('.tl-react-form'); 235 if (!f) return; 236 e.preventDefault(); 237 var btn = f.querySelector('button'); if (!btn || btn.disabled) return; 238 btn.disabled = true; 239 var body = new URLSearchParams(); 240 new FormData(f).forEach(function(v, k){ body.append(k, v); }); 241 fetch(f.action, { method: 'POST', body: body, headers: { 'X-Requested-With': 'fetch' }, credentials: 'same-origin' }) 242 .then(function(r){ return r.ok ? r.json() : null; }) 243 .then(function(j){ if (j) btn.classList.toggle('is-on', !!j.on); }) 244 .catch(function(){}) 245 .then(function(){ btn.disabled = false; }); 246 }); 247 })(); 248 </script> 249 250 <script> 251 // Collapse long post bodies to a max height with a "read more" toggle — only when the content 252 // actually overflows. Runs on every /news render (full load + htmx swap); a per-element flag 253 // prevents double-wiring. 254 (function(){ 255 var RM = '<%= t("tl.read_more") %>', SL = '<%= t("tl.show_less") %>'; 256 document.querySelectorAll('.tl-content:not(.nsfw-media):not([data-rm])').forEach(function(c){ 257 c.setAttribute('data-rm', '1'); 258 if (c.scrollHeight > 360) { 259 c.classList.add('tl-clamp'); 260 var b = document.createElement('button'); 261 b.type = 'button'; b.className = 'tl-readmore'; b.textContent = RM; 262 b.addEventListener('click', function(){ 263 b.textContent = c.classList.toggle('tl-clamp') ? RM : SL; 264 }); 265 c.insertAdjacentElement('afterend', b); 266 } 267 }); 268 })(); 269 </script> 149 <%- include('../partials/page-data', { pageData: { readMore: t('tl.read_more'), showLess: t('tl.show_less') } }) %>
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)