Ignore:
File:
1 edited

Legend:

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

    rd9ad6c5 r52fc278  
    4141    .tl-paste-go { background: var(--accent); color: var(--paper); }
    4242  </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). %>
    8144  <% if (typeof success !== 'undefined' && success) { %><div class="alert alert-success"><%= success %></div><% } %>
    8245  <% if (typeof error !== 'undefined' && error) { %><div class="alert alert-error"><%= error %></div><% } %>
     
    184147  .tl-act-block:hover { background: color-mix(in srgb, #d9534f 14%, transparent); border-color: color-mix(in srgb, #d9534f 50%, transparent); }
    185148</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">&rarr;</button><button type="button" class="fedi-remote-cancel" aria-label="x">&times;</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.