source: Klonkt/src/views/partials/fedi-interact-styles.ejs@ 3ceaef6

main
Last change on this file since 3ceaef6 was 3ceaef6, checked in by Robin <roboburr@…>, 6 hours ago

Zoeken op een adres: het object erachter, met de knoppen erbij

Plak je een link naar een fediverse-post of -profiel in de zoekbalk, dan is dat
geen zoekterm maar een aanwijzing. Klonkt haalt hem op en zet hem bovenaan de
resultaten, met dezelfde knoppen als /authorize_interaction: antwoorden,
waarderen, boosten, stemmen, volgen en melden.

De weg erheen was vooral opruimen. De render en de formulieren stonden als 200
regels in authorize-interaction.ejs, en er een tweede kopie van maken voor de
zoekpagina zou een tweede plek zijn waar een poort, een sanitizer of een knop
vergeten kan worden. Ze staan nu in partials/remote-object.ejs en
partials/remote-actor.ejs, met de opmaak in een derde. De pagina die ze had
gebruikt ze nu ook, dus er is één render en de formulieren posten in beide
gevallen naar /authorize_interaction/..., waar het werk en de rechtencontrole
al zaten.

DRIE DINGEN DIE VASTLIGGEN, en elk om een eigen reden:

Het schema is verplicht. "soundfabrics.nl" is een geldige zoekterm -- iemand
zoekt naar de naam -- en een kale domeinnaam als adres opvatten maakt van elke
zoekopdracht met een punt erin een netwerkverzoek. Met ​https:// ervoor is er
geen twijfel over de bedoeling.

Ophalen mag alleen een beheerder van de site laten doen. Dat is dezelfde grens
als /authorize_interaction, en met opzet: ophalen is een uitgaand verzoek dat
deze server namens de bezoeker doet. Zonder die grens is de zoekbalk een
haalservice waarmee een vreemde deze server laat aankloppen op adressen naar
keuze. Een bezoeker die toch een link plakt krijgt de gewone zoekresultaten en
een zin die zegt waarom er verder niets staat.

De ophaling gaat ONDERTEKEND als de site. Een post die alleen voor volgers
zichtbaar is weigert een anonieme GET, en dan lijkt een bestaande post te
ontbreken -- dezelfde val als bij het antwoorden op een post van een vriend.

Bijgekomen zonder dat erom gevraagd is, en het is het vermelden waard: het
profiel toont nu zijn avatar. Die hadden we al in handen (actor_icon uit
resolveRemoteActor) en hij stond op geen van beide schermen.

Getoetst: de herkenning zelf, dat een zoekterm GEEN verzoek wordt, dat de post
met zijn vier formulieren binnenkomt, dat een profiel de volgknop geeft, dat
een bezoeker niets laat ophalen, en dat /authorize_interaction na de verhuizing
nog steeds hetzelfde toont -- die pagina had zelf geen enkele toets, dus dat
was de bodem die er onder moest. Tegenproef per zaak.

Nog open: een @naam@server in de zoekbalk (webfinger kan het al, dus klein
werk) en een hint in de live-suggesties terwijl je plakt.

shaer-utpi

  • Property mode set to 100644
File size: 10.0 KB
Line 
1<%#
2 De opmaak van de fediverse-interactieschermen. Staat apart zodat de pagina en
3 de zoekresultaten dezelfde render krijgen zonder de regels twee keer op te
4 schrijven (een tweede kopie loopt gegarandeerd uit de pas).
5%>
6<style>
7 .auth-interact { max-width: 640px; margin: 1rem auto; padding: 0 1rem; }
8 .auth-interact-title { margin: 0 0 1rem; }
9 .auth-interact-meta { color: var(--ink-soft, #888); margin: 0 0 .75rem; }
10 .auth-interact-preview {
11 margin: 0 0 1rem; padding: .75rem 1rem; border-left: 3px solid var(--accent, #888);
12 background: color-mix(in srgb, var(--ink, #000) 4%, transparent); border-radius: 0 12px 12px 0;
13 color: var(--ink, inherit);
14 }
15 .auth-interact-form { display: flex; flex-direction: column; gap: .75rem; }
16 .auth-interact-form textarea, .auth-interact-form input[type=url] {
17 width: 100%; box-sizing: border-box; padding: .6rem .8rem; font: inherit; resize: vertical;
18 border-radius: 12px; border: 1px solid color-mix(in srgb, var(--ink, #000) 18%, transparent);
19 background: var(--paper, #fff); color: var(--ink, #000);
20 }
21 .auth-interact-actions { display: flex; gap: .5rem; align-items: center; }
22 .auth-interact-note { color: var(--ink-soft, #999); font-size: .85rem; margin-top: 1rem; }
23 .auth-interact-where { margin: .25rem 0 .85rem; padding: .6rem .8rem; font-size: .85rem; line-height: 1.5; border-radius: 10px; background: color-mix(in srgb, var(--accent, #888) 12%, transparent); color: var(--ink, inherit); }
24 .auth-interact-content { line-height: 1.55; }
25 .auth-interact-content p { margin: .35rem 0; }
26 .auth-interact-content p:first-child { margin-top: 0; }
27 .auth-interact-img { max-width: 100%; height: auto; border-radius: 10px; margin: .5rem 0 0; display: block; }
28 .auth-interact-orig { margin: .75rem 0 0; font-size: .85rem; }
29 .auth-interact-orig a { color: var(--accent, #06c); }
30 .auth-view-src { display: inline-flex; align-items: center; gap: .5rem; margin: 0 0 1.1rem; padding: .6rem 1rem;
31 border: 1px solid color-mix(in srgb, var(--accent, #888) 45%, transparent); border-radius: 12px;
32 background: color-mix(in srgb, var(--accent, #888) 10%, transparent); color: var(--accent, #06c);
33 text-decoration: none; font-weight: 600; font-size: .92rem; transition: background .15s, border-color .15s; }
34 .auth-view-src:hover { background: color-mix(in srgb, var(--accent, #888) 18%, transparent); border-color: var(--accent, #888); }
35 .auth-interact-react { display: flex; gap: .6rem; flex-wrap: wrap; margin: 0 0 .25rem; }
36 .auth-interact-react form { margin: 0; }
37 .fedi-bigact { display: inline-flex; align-items: center; gap: .5rem; padding: .55rem 1.1rem; border-radius: 999px;
38 border: 1px solid color-mix(in srgb, var(--ink, #000) 14%, transparent);
39 background: color-mix(in srgb, var(--ink, #000) 4%, transparent);
40 color: var(--ink, inherit); font: inherit; font-weight: 600; font-size: .92rem; cursor: pointer; white-space: nowrap;
41 transition: background .12s, border-color .12s; }
42 .fedi-bigact svg { width: 17px; height: 17px; flex: 0 0 17px; }
43 .fedi-bigact-like svg { color: #e8b04b; }
44 .fedi-bigact-like:hover, .fedi-bigact-like.is-on { background: color-mix(in srgb, #e8b04b 16%, transparent); border-color: color-mix(in srgb, #e8b04b 55%, transparent); }
45 .fedi-bigact-boost svg { color: #2fa85a; }
46 .fedi-bigact-boost:hover, .fedi-bigact-boost.is-on { background: color-mix(in srgb, #2fa85a 16%, transparent); border-color: color-mix(in srgb, #2fa85a 55%, transparent); }
47 .fedi-manage { list-style: none; padding: 0; margin: 1.25rem 0 1rem; display: flex; flex-direction: column; gap: .7rem; }
48 .fedi-manage-item { padding: .9rem 1rem; border-radius: 14px; background: color-mix(in srgb, var(--ink, #000) 3.5%, transparent); border: 1px solid color-mix(in srgb, var(--ink, #000) 9%, transparent); transition: border-color .15s ease, box-shadow .15s ease; }
49 .fedi-manage-item:hover { border-color: color-mix(in srgb, var(--accent, #888) 28%, transparent); box-shadow: 0 2px 12px color-mix(in srgb, var(--ink, #000) 6%, transparent); }
50 .fedi-manage-head { display: flex; align-items: center; gap: .5rem; margin: 0 0 .5rem; }
51 .fedi-manage-icon { flex: 0 0 26px; width: 26px; height: 26px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center;
52 background: color-mix(in srgb, var(--accent, #888) 16%, transparent); color: var(--accent, #06c); }
53 .fedi-manage-icon svg { width: 14px; height: 14px; }
54 .fedi-manage-to { font-weight: 600; color: var(--ink, inherit); font-size: .9rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
55 .fedi-manage-time { color: var(--ink-soft, #999); font-size: .76rem; margin-left: auto; flex: 0 0 auto; white-space: nowrap; }
56 .fedi-manage-content { line-height: 1.55; overflow-wrap: anywhere; padding-left: calc(26px + .5rem); }
57 .fedi-manage-content p { margin: .15rem 0; }
58 .fedi-manage-content p:first-child { margin-top: 0; }
59 .fedi-manage-content p:last-child { margin-bottom: 0; }
60 .fedi-manage-foot { display: flex; align-items: center; justify-content: flex-start; flex-wrap: wrap; gap: .5rem; margin-top: .65rem; }
61 .fedi-goto-btn { display: inline-flex; align-items: center; gap: .35rem; border: 1px solid color-mix(in srgb, var(--accent, #888) 45%, transparent); background: color-mix(in srgb, var(--accent, #888) 12%, transparent); color: var(--accent, #06c); border-radius: 999px; padding: .3rem .8rem; font-size: .82rem; text-decoration: none; transition: background .15s ease; }
62 .fedi-goto-btn:hover { background: color-mix(in srgb, var(--accent, #888) 22%, transparent); }
63 .fedi-del-btn { display: inline-flex; align-items: center; gap: .35rem; border: 1px solid color-mix(in srgb, #d9534f 45%, transparent); background: color-mix(in srgb, #d9534f 12%, transparent); color: #e06b66; border-radius: 999px; padding: .3rem .8rem; font: inherit; font-size: .82rem; cursor: pointer; transition: background .15s ease; }
64 .fedi-del-btn:hover { background: color-mix(in srgb, #d9534f 24%, transparent); }
65 .fedi-bm { margin: 0 0 1.5rem; padding: 1rem; border-radius: 14px;
66 border: 1px dashed color-mix(in srgb, var(--accent, #888) 45%, transparent);
67 background: color-mix(in srgb, var(--accent, #888) 7%, transparent); }
68 .fedi-bm-btn { display: inline-flex; align-items: center; gap: .45rem; padding: .5rem 1rem; border-radius: 999px;
69 background: var(--accent, #06c); color: #fff; font: inherit; font-weight: 600; font-size: .9rem; text-decoration: none;
70 cursor: grab; user-select: none; box-shadow: 0 2px 8px color-mix(in srgb, var(--accent, #000) 30%, transparent); }
71 .fedi-bm-btn:active { cursor: grabbing; }
72 .fedi-bm-btn.nudge { animation: fedi-bm-nudge .6s ease; }
73 @keyframes fedi-bm-nudge { 0%,100% { transform: translateX(0); } 25% { transform: translateX(-4px); } 75% { transform: translateX(4px); } }
74 .fedi-bm-help { color: var(--ink-soft, #888); font-size: .82rem; line-height: 1.5; margin: .6rem 0 0; }
75 .fedi-edit-btn { display: inline-flex; align-items: center; gap: .35rem; border: 1px solid color-mix(in srgb, var(--ink, #888) 28%, transparent);
76 background: color-mix(in srgb, var(--ink, #888) 8%, transparent); color: var(--ink-soft, #aaa); border-radius: 999px; padding: .3rem .8rem;
77 font: inherit; font-size: .82rem; cursor: pointer; transition: background .15s ease, color .15s ease; }
78 .fedi-edit-btn:hover { background: color-mix(in srgb, var(--ink, #888) 16%, transparent); }
79 .fedi-edit-btn.is-open { color: var(--accent); border-color: color-mix(in srgb, var(--accent) 45%, transparent); background: color-mix(in srgb, var(--accent) 10%, transparent); }
80 .fedi-del-form { margin-left: auto; }
81 .fedi-edit-form { display: none; margin: .55rem 0 0; }
82 .fedi-edit-form.is-open { display: block; }
83 .fedi-edit-ta { width: 100%; box-sizing: border-box; min-height: 70px; resize: vertical; padding: .55rem .7rem;
84 border: 1.5px solid var(--rule, #333); border-radius: 10px; background: var(--paper-2, #14141a); color: var(--ink, #eee); font: inherit; font-size: .9rem; }
85 .fedi-edit-ta:focus { outline: none; border-color: var(--accent); }
86 .fedi-edit-actions { display: flex; justify-content: flex-end; margin-top: .5rem; }
87 .fedi-edit-save { padding: .4rem 1rem; border: 0; border-radius: 999px; background: var(--accent); color: var(--paper, #fff);
88 font: inherit; font-weight: 600; font-size: .82rem; cursor: pointer; }
89 /* Poll ballot / results on the interact page */
90 .auth-poll { display: flex; flex-direction: column; gap: 8px; margin: 0 0 1rem; }
91 .auth-poll-choice { display: flex; align-items: center; gap: 10px; padding: 10px 12px; border-radius: 10px; cursor: pointer;
92 border: 1px solid color-mix(in srgb, var(--ink, #000) 14%, transparent); }
93 .auth-poll-choice:hover { border-color: var(--accent); }
94 .auth-poll-choice input { accent-color: var(--accent); }
95 .auth-poll-res { position: relative; padding: 9px 12px; border-radius: 10px; overflow: hidden; display: flex; align-items: center; gap: 8px;
96 background: color-mix(in srgb, var(--ink, #000) 6%, transparent); }
97 .auth-poll-fill { position: absolute; inset: 0 auto 0 0; background: color-mix(in srgb, var(--accent) 22%, transparent); z-index: 0; }
98 .auth-poll-name { position: relative; z-index: 1; flex: 1; font-size: .95rem; }
99 .auth-poll-pct { position: relative; z-index: 1; font-variant-numeric: tabular-nums; font-weight: 500; }
100 .auth-poll-foot { font-size: .82rem; color: var(--ink-soft, #888); margin: .1rem 0 0; }
101 .auth-report { margin: .6rem 0 0; }
102 .auth-report summary { cursor: pointer; font-size: .85rem; color: var(--ink-soft, #888); }
103 .auth-report summary:hover, .auth-report[open] summary { color: #c0392b; }
104 .auth-report[open] summary { margin-bottom: .5rem; }
105 .auth-report-note { font-size: .82rem; color: var(--ink-muted, #999); margin: 0 0 .5rem; }
106 /* Het gezicht van een profiel dat we net hebben opgehaald. */
107 .remote-actor { display: flex; align-items: center; gap: .75rem; }
108 .remote-actor .auth-interact-meta { margin: 0; }
109 .remote-actor-icon { width: 48px; height: 48px; border-radius: 50%; object-fit: cover; flex: 0 0 48px;
110 background: color-mix(in srgb, var(--ink, #000) 8%, transparent); }
111</style>
Note: See TracBrowser for help on using the repository browser.