- Timestamp:
- 06/27/2026 10:45:01 AM (2 months ago)
- Branches:
- main
- Children:
- ce16d8a
- Parents:
- 7eddb3b
- File:
-
- 1 edited
-
src/views/partials/profile-header.ejs (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/views/partials/profile-header.ejs
r7eddb3b rf1ce47a 144 144 </div> 145 145 <% } %> 146 <% if (_showFollow) { %> 147 <%# Follow-via-fediverse modal — replaces the native prompt() (which looked ugly). %> 148 <div class="pf-follow"> 149 <div class="pf-follow-card" role="dialog" aria-label="<%= t('fedi.follow_heading') %>"> 150 <button type="button" class="pf-follow-cancel pf-follow-x" aria-label="Sluiten">×</button> 151 <h3 class="pf-follow-title"><%= t('fedi.follow_heading') %></h3> 152 <p class="pf-follow-sub"><%= t('fedi.remote_prompt') %></p> 153 <input type="text" class="pf-follow-input" inputmode="url" autocomplete="off" autocapitalize="none" spellcheck="false" 154 placeholder="<%= t('fedi.remote_ph') %>" list="pf-follow-servers"> 155 <datalist id="pf-follow-servers"><option value="mastodon.social"></option><option value="mastodon.online"></option><option value="mas.to"></option><option value="fosstodon.org"></option><option value="hachyderm.io"></option></datalist> 156 <div class="pf-follow-actions"> 157 <button type="button" class="pf-follow-cancel"><%= t('fedi.cancel') %></button> 158 <button type="button" class="pf-follow-go"><%= t('fedi.follow_btn') %></button> 159 </div> 160 </div> 161 </div> 162 <% } %> 146 163 <script> 147 164 (function () { 148 165 if (window.__pcmsFediFollowWired) return; 149 166 window.__pcmsFediFollowWired = true; 167 function modal() { return document.querySelector('.pf-follow'); } 168 function closeM() { var m = modal(); if (m) m.classList.remove('is-open'); } 169 function go() { 170 var m = modal(); if (!m) return; 171 var inp = m.querySelector('.pf-follow-input'), raw = inp ? inp.value : ''; 172 // Strip a full @user@host handle (and any scheme/path) down to the server host. 173 var server = String(raw || '').trim().replace(/^@?[^@\s]*@/, '').replace(/^https?:\/\//i, '').replace(/\/.*$/, '').trim(); 174 if (!server) { if (inp) inp.focus(); return; } 175 try { localStorage.setItem('pcmsFediServer', server); } catch (e) {} 176 var actor = location.origin + '/ap/users/' + encodeURIComponent(m.getAttribute('data-actor-slug') || ''); 177 location.href = 'https://' + server + '/authorize_interaction?uri=' + encodeURIComponent(actor); 178 } 150 179 document.addEventListener('click', function (e) { 151 180 var b = e.target.closest && e.target.closest('.profile-fedi-link'); 152 if (!b) return; 153 var raw = window.prompt(<%- JSON.stringify(t('fedi.remote_prompt')) %>, ''); 154 if (!raw) return; 155 // Strip a full @user@host handle (and any scheme/path) down to the server host. 156 var server = raw.trim().replace(/^@?[^@\s]*@/, '').replace(/^https?:\/\//i, '').replace(/\/.*$/, '').trim(); 157 if (!server) return; 158 var actor = location.origin + '/ap/users/' + encodeURIComponent(b.getAttribute('data-fedi-actor-slug') || ''); 159 location.href = 'https://' + server + '/authorize_interaction?uri=' + encodeURIComponent(actor); 181 if (b) { e.preventDefault(); 182 var m = modal(); if (!m) return; 183 m.setAttribute('data-actor-slug', b.getAttribute('data-fedi-actor-slug') || ''); 184 var inp = m.querySelector('.pf-follow-input'); 185 try { if (inp && !inp.value) inp.value = localStorage.getItem('pcmsFediServer') || ''; } catch (e2) {} 186 m.classList.add('is-open'); 187 setTimeout(function () { if (inp) inp.focus(); }, 30); 188 return; 189 } 190 if (e.target.closest && e.target.closest('.pf-follow-go')) { e.preventDefault(); go(); return; } 191 if (e.target.closest && e.target.closest('.pf-follow-cancel')) { e.preventDefault(); closeM(); return; } 192 var open = document.querySelector('.pf-follow.is-open'); 193 if (open && e.target === open) closeM(); /* click on backdrop */ 194 }); 195 document.addEventListener('keydown', function (e) { 196 var m = document.querySelector('.pf-follow.is-open'); if (!m) return; 197 if (e.key === 'Escape') { closeM(); } 198 else if (e.key === 'Enter' && e.target.closest && e.target.closest('.pf-follow')) { e.preventDefault(); go(); } 160 199 }); 161 200 })(); … … 384 423 .pf-summary-follow:hover { background: var(--accent); color: var(--paper); } 385 424 .pf-summary-follow-ico { width: 18px; height: 18px; flex: 0 0 auto; } 425 .pf-follow { position: fixed; inset: 0; z-index: 2147483601; display: none; align-items: center; justify-content: center; padding: 1rem; background: rgba(0,0,0,.55); } 426 .pf-follow.is-open { display: flex; } 427 .pf-follow-card { position: relative; width: 100%; max-width: 380px; text-align: left; 428 background: var(--paper); color: var(--ink); border: 1px solid var(--rule); border-radius: 16px; 429 padding: 1.5rem 1.4rem 1.3rem; box-shadow: 0 18px 50px rgba(0,0,0,.4); } 430 .pf-follow-x { position: absolute; top: .55rem; right: .65rem; width: 2rem; height: 2rem; border: 0; border-radius: 999px; 431 background: transparent; color: var(--ink-soft); font-size: 1.4rem; line-height: 1; cursor: pointer; } 432 .pf-follow-title { margin: 0 0 .35rem; font-size: 1.15rem; } 433 .pf-follow-sub { margin: 0 0 .8rem; color: var(--ink-soft); font-size: .86rem; line-height: 1.45; } 434 .pf-follow-input { width: 100%; box-sizing: border-box; padding: .6rem .8rem; border: 1.5px solid var(--rule); 435 border-radius: 10px; background: var(--paper-2); color: var(--ink); font: inherit; font-size: .95rem; } 436 .pf-follow-input:focus { outline: none; border-color: var(--accent); } 437 .pf-follow-actions { display: flex; justify-content: flex-end; gap: .6rem; margin-top: 1rem; } 438 .pf-follow-actions button { padding: .5rem 1.1rem; border-radius: 999px; font: inherit; font-weight: 600; font-size: .88rem; cursor: pointer; border: 0; } 439 .pf-follow-actions .pf-follow-cancel { background: transparent; border: 1.5px solid var(--rule); color: var(--ink); } 440 .pf-follow-actions .pf-follow-go { background: var(--accent); color: var(--paper); } 441 .pf-follow-actions .pf-follow-go:hover { filter: brightness(1.06); } 386 442 </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)