source: Klonkt/src/views/pages/authorize-interaction.ejs@ ffa53cc

main
Last change on this file since ffa53cc was 7d932ce, checked in by Robin Genis <roboburr@…>, 3 months ago

feat(activitypub): nested threading + delete your own replies

Inbox now stores replies-to-comments nested (findThreadTarget resolves the post
via the parent comment); getInteractions builds a thread tree shown on the post
(fedi-node partial). deliverReply also cc's the post author's inbox so their
Klonkt threads it. Owners can delete their outbound replies (Delete+Tombstone)
inline + via /fediverse manage list. Schema: ap_interactions.parent_uri.

Co-Authored-By: Claude <noreply@…>

  • Property mode set to 100644
File size: 4.7 KB
RevLine 
[3d7312a]1<div class="auth-interact">
[7d932ce]2 <% if (typeof manage !== 'undefined' && manage) { %>
3 <h1 class="auth-interact-title"><%= t('fedi.manage_title') %></h1>
4 <% if (!manage.length) { %><p class="auth-interact-note"><%= t('fedi.manage_empty') %></p><% } %>
5 <ol class="comments-list">
6 <% manage.forEach(function(m){ %>
7 <li class="comment">
8 <div class="comment-body">
9 <div class="comment-content"><%- m.content %></div>
10 <div class="comment-actions">
11 <% if (m.to_handle) { %><span class="fedi-handle">→ <%= m.to_handle %></span><% } %>
12 <form method="post" action="/fediverse/<%= m.id %>/delete" onsubmit="return confirm('<%= t('fedi.delete_confirm') %>')">
13 <button type="submit" class="comment-delete-btn"><%= t('comments.delete') %></button>
14 </form>
15 </div>
16 </div>
17 </li>
18 <% }); %>
19 </ol>
20 <% } else if (typeof sent !== 'undefined' && sent) { %>
[41a7637]21 <h1 class="auth-interact-title"><%= t('fedi.remote_sent_title') %></h1>
22 <p class="auth-interact-note"><%= t('fedi.remote_sent') %></p>
23 <p class="auth-interact-actions">
24 <% if (uri) { %><a class="btn" href="<%= uri %>" target="_blank" rel="nofollow noopener"><%= t('fedi.remote_view_original') %></a><% } %>
25 <a class="btn btn-primary" href="/"><%= t('fedi.remote_back') %></a>
26 </p>
27 <% } else { %>
[3d7312a]28 <h1 class="auth-interact-title"><%= t('fedi.remote_title') %></h1>
29
30 <% if (!target) { %>
31 <p class="auth-interact-note"><%= t('fedi.remote_notfound') %></p>
32 <form method="get" action="/authorize_interaction" class="auth-interact-form">
33 <input type="url" name="uri" placeholder="https://…/een-post" value="<%= uri || '' %>" required>
34 <button type="submit" class="btn btn-primary"><%= t('fedi.remote_load') %></button>
35 </form>
36 <% } else { %>
37 <p class="auth-interact-meta">
38 <%= t('fedi.remote_replying_to') %>
39 <a href="<%= target.actor_url %>" rel="nofollow noopener" target="_blank"><strong><%= target.actor_name %></strong></a>
40 <span class="fedi-handle"><%= target.actor_handle %></span>
41 </p>
[2826bb97]42 <blockquote class="auth-interact-preview">
43 <% if (target.content) { %><div class="auth-interact-content"><%- target.content %></div>
44 <% } else if (target.preview) { %><%= target.preview %><% } %>
45 <% (target.images || []).forEach(function(im){ %>
46 <img class="auth-interact-img" src="<%= im %>" alt="" loading="lazy">
47 <% }); %>
48 <% if (target.url || uri) { %>
49 <p class="auth-interact-orig"><a href="<%= target.url || uri %>" target="_blank" rel="nofollow noopener"><%= t('fedi.remote_view_original') %></a></p>
50 <% } %>
51 </blockquote>
[3d7312a]52 <form method="post" action="/authorize_interaction" class="auth-interact-form">
53 <input type="hidden" name="uri" value="<%= uri %>">
54 <textarea name="text" rows="4" required placeholder="<%= t('fedi.reply_ph') %>"></textarea>
55 <div class="auth-interact-actions">
56 <button type="submit" class="btn btn-primary"><%= t('fedi.send') %></button>
57 <a href="<%= uri %>" class="btn"><%= t('comments.cancel') %></a>
58 </div>
59 </form>
60 <p class="auth-interact-note"><%= t('fedi.remote_as', { site: siteTitle }) %></p>
61 <% } %>
[41a7637]62 <% } %>
[3d7312a]63</div>
64
65<style>
66 .auth-interact { max-width: 580px; margin: 2rem auto; padding: 0 1rem; }
67 .auth-interact-title { margin: 0 0 1rem; }
68 .auth-interact-meta { color: var(--ink-soft, #888); margin: 0 0 .75rem; }
69 .auth-interact-preview {
70 margin: 0 0 1rem; padding: .75rem 1rem; border-left: 3px solid var(--accent, #888);
71 background: color-mix(in srgb, var(--ink, #000) 4%, transparent); border-radius: 0 12px 12px 0;
72 color: var(--ink, inherit);
73 }
74 .auth-interact-form { display: flex; flex-direction: column; gap: .75rem; }
75 .auth-interact-form textarea, .auth-interact-form input[type=url] {
76 width: 100%; box-sizing: border-box; padding: .6rem .8rem; font: inherit; resize: vertical;
77 border-radius: 12px; border: 1px solid color-mix(in srgb, var(--ink, #000) 18%, transparent);
78 background: var(--paper, #fff); color: var(--ink, #000);
79 }
80 .auth-interact-actions { display: flex; gap: .5rem; align-items: center; }
81 .auth-interact-note { color: var(--ink-soft, #999); font-size: .85rem; margin-top: 1rem; }
[2826bb97]82 .auth-interact-content { line-height: 1.55; }
83 .auth-interact-content p { margin: .35rem 0; }
84 .auth-interact-content p:first-child { margin-top: 0; }
85 .auth-interact-img { max-width: 100%; height: auto; border-radius: 10px; margin: .5rem 0 0; display: block; }
86 .auth-interact-orig { margin: .75rem 0 0; font-size: .85rem; }
87 .auth-interact-orig a { color: var(--accent, #06c); }
[3d7312a]88</style>
Note: See TracBrowser for help on using the repository browser.