source: Klonkt/src/views/pages/admin-migrate.ejs@ bfadc15

main
Last change on this file since bfadc15 was bfadc15, checked in by Robin <roboburr@…>, 4 weeks ago

De teksten op de migrate-pagina in mensentaal

Robin: er zijn miljoenen Klonkt-gebruikers, dus het moet gebruiksvriendelijk
worden gemaakt. Ik had die opmerking eerst gelezen als een schaalwaarschuwing
en zat prestaties te repareren. Dat leverde wel een echte fout op (7e474f7),
maar het was zijn vraag niet.

Wat er stond was voor mij geschreven, niet voor wie verhuist:

claimen, alias, actor-adres, instantie, AP-ids, fediverse,
"een bericht met dezelfde webadres-naam maar een ander id"

Achttien teksten herschreven in nl/en/de. "Je oude account claimen" werd "je
vorige account koppelen". De overschrijf-waarschuwing gaat niet meer over
unieke sleutels maar over wat je kwijtraakt. De foutmelding bij een ontbrekende
koppeling verwijst nu naar stap 1 op het scherm in plaats van naar een begrip.

DE VOORBEELDEN TONEN HANDLES. Er stond https://oude-klonkt.nl/ap/users/jij als
placeholder. Niemand kent zijn eigen actor-URL; mensen kennen
@robo@….

EN HET VELD GEEFT TERUG WAT JE GAF. Je typte een handle, wij slaan de actor-URL
op omdat het protocol daarop draait, en dan kreeg je een adres terug dat je
nooit had ingetypt. Nu tonen we de handle, en alleen als er echt een uit te
halen valt: een verkeerde handle is erger dan een lelijke URL. Opslaan leest
beide vormen, dus daar verandert niets.

Changed files:
src/services/i18n.js

  • 19 teksten herschreven in drie talen, jargon eruit

src/views/pages/admin-migrate.ejs

  • placeholders tonen @handle in plaats van een actor-URL

src/routes/admin-migrate.js

  • aliasTekst() toont handles, met de URL als terugval

test/migrate-page.test.js

  • een jargonwacht over 23 sleutels maal drie talen
  • de handle-heenweg en -terugweg
  • de stap-5-test toetst nu op BETEKENIS; hij brak omdat het woord "alias" verdween, en dat was precies de bedoeling

remarks: de indeling blijft zoals hij was (Robins keuze). Het grotere idee, een
vraag bovenaan of je hier binnenkomt of weggaat en dan alleen die helft tonen,
is niet gedaan. Suite 1016 groen.

-robo
Co-Authored-By: Claude Opus 4.8 <noreply@…>

  • Property mode set to 100644
File size: 18.6 KB
Line 
1<div class="container mig-wrap">
2 <h1><%= t('mig.title') %></h1>
3 <p class="mig-lead"><%= t('mig.lead') %></p>
4
5 <% if (typeof success !== 'undefined' && success) { %><div class="alert alert-success"><%= success %></div><% } %>
6 <% if (typeof error !== 'undefined' && error) { %><div class="alert alert-error"><%= error %></div><% } %>
7
8 <%# ── Het stappenplan ────────────────────────────────────────── %>
9 <%# Bestaat omdat de VOLGORDE niet vanzelfsprekend is en een fout erin je
10 halverwege vastzet. Twee dingen die niemand raadt:
11 - de ophaalknop werkt PAS nadat de verhuizing is aangekondigd; de bron
12 geeft niets af aan een instantie die niet in zijn movedTo staat;
13 - met een zip kan het juist andersom, want een zip vraagt niemand iets.
14 En stap 5 staat erbij omdat hij bestaat, niet omdat er een knop voor is. %>
15 <section class="mig-card mig-plan">
16 <h2><%= t('mig.plan_title') %></h2>
17 <p class="form-hint"><%= t('mig.plan_hint') %></p>
18 <%# "hier" hangt af van WELKE kant je bekijkt. Deze pagina draait op allebei
19 de instanties, en een vaste tekst is dus op de helft van de schermen
20 onzin. Heeft deze site een moved_to, dan is dit de vertrekkende kant. %>
21 <%# Stap 1, 3 en 4 horen op de NIEUWE kant; stap 2 en 5 op de oude. Vanaf
22 welke instantie je kijkt bepaalt dus welk van de twee "hier" is. %>
23 <% var _hier = stap.isOud ? t('mig.plan_new') : t('mig.plan_here');
24 var _daar = stap.isOud ? t('mig.plan_here') : t('mig.plan_old'); %>
25 <% if (stap.isOud) { %>
26 <p class="form-hint mig-warn"><%= t('mig.plan_from_old') %></p>
27 <% } %>
28 <ol class="mig-steps">
29 <li class="<%= stap.geclaimd ? 'is-done' : '' %>">
30 <strong><%= t('mig.plan_1') %></strong>
31 <span class="mig-waar"><%= _hier %></span>
32 <em><%= t('mig.plan_1_why') %></em>
33 </li>
34 <li class="<%= stap.aangekondigd ? 'is-done' : '' %>">
35 <strong><%= t('mig.plan_2') %></strong>
36 <span class="mig-waar"><%= _daar %></span>
37 <em><%= t('mig.plan_2_why') %></em>
38 </li>
39 <li class="<%= stap.opgehaald ? 'is-done' : '' %>">
40 <strong><%= t('mig.plan_3') %></strong>
41 <span class="mig-waar"><%= _hier %></span>
42 <em><%= t('mig.plan_3_why') %></em>
43 </li>
44 <li>
45 <strong><%= t('mig.plan_4') %></strong>
46 <span class="mig-waar"><%= _hier %></span>
47 </li>
48 <li class="mig-step-later">
49 <strong><%= t('mig.plan_5') %></strong>
50 <span class="mig-waar"><%= _daar %></span>
51 <em><%= t('mig.plan_5_why') %></em>
52 </li>
53 </ol>
54 </section>
55
56 <%# ── Je oude account claimen (FEP-7628 alsoKnownAs) ─────────── %>
57 <%# Bewust als EERSTE: zonder deze claim weigert de oude instantie de Move
58 met no_backreference, en kan de ophaalknop hieronder ook niets. Dit stond
59 op de site-bewerkpagina tussen de kleuren; daar zoekt niemand het als hij
60 aan het verhuizen is. %>
61 <section class="mig-card">
62 <h2><%= t('mig.alias_title') %></h2>
63 <p class="form-hint"><%= t('mig.alias_hint') %></p>
64 <form method="post" action="/admin/migrate/aliases">
65 <label for="mig-alias"><%= t('mig.alias_label') %></label>
66 <textarea id="mig-alias" name="ap_aliases" rows="3" class="mig-input"
67 placeholder="@jij@mastodon.social&#10;@jij@oude-klonkt.nl"><%= aliassen || '' %></textarea>
68 <p class="form-hint"><%= t('mig.alias_note') %></p>
69 <button type="submit" class="btn"><%= t('mig.alias_btn') %></button>
70 </form>
71 </section>
72
73 <%# ── Exporteren ─────────────────────────────────────────────── %>
74 <section class="mig-card">
75 <h2><%= t('mig.export_title') %></h2>
76 <p class="form-hint"><%= t('mig.export_hint') %></p>
77
78 <% if (telling) { %>
79 <ul class="mig-counts">
80 <li><strong><%= telling.posts %></strong> <%= t('mig.c_posts') %></li>
81 <li><strong><%= telling.replies %></strong> <%= t('mig.c_replies') %></li>
82 <li><strong><%= telling.media %></strong> <%= t('mig.c_media') %></li>
83 <%# Muziek APART tellen, niet onder "media". Dit ontbrak, en juist daardoor
84 kon een export van 140 nummers er als 4,5 MB uitzien zonder dat iemand
85 het merkte: de teller zei "39 mediabestanden" en zweeg over de rest. %>
86 <% if (telling.tracks) { %>
87 <%# Wat er ECHT meegaat, niet hoeveel rijen er in de database staan.
88 "8 nummers" met daaronder "van 3 ontbreekt het bestand" telt niet
89 op; 5 plus die waarschuwing wel. %>
90 <li><strong><%= telling.tracks - (telling.audioMissing || 0) %></strong> <%= t('mig.c_tracks') %></li>
91 <% } %>
92 <% if (telling.playlists) { %>
93 <li><strong><%= telling.playlists %></strong> <%= t('mig.c_playlists') %></li>
94 <% } %>
95 <% if (typeof telling.following === 'number') { %>
96 <li><strong><%= telling.following %></strong> <%= t('mig.c_following') %></li>
97 <% } %>
98 <li><strong><%= mb(telling.bytes) %></strong> <%= t('mig.c_size') %></li>
99 </ul>
100
101 <% if (telling.ontbrekend) { %>
102 <%# Niets stils: media die op schijf ontbreekt wordt geteld en gemeld, want
103 een archief dat stilzwijgend minder bevat is erger dan een waarschuwing. %>
104 <p class="alert alert-error"><%= t('mig.missing', { n: telling.ontbrekend }) %></p>
105 <% } %>
106
107 <% if (telling.audioMissing) { %>
108 <%# Een eigen zin voor muziek. "N mediaverwijzingen" zei niets over de
109 vraag die er toe doet: gaat mijn bibliotheek mee. %>
110 <p class="alert alert-error"><%= t('mig.audio_missing', { n: telling.audioMissing }) %></p>
111 <% } %>
112
113
114 <% if (telling.groot) { %>
115 <p class="alert alert-error"><%= t('mig.too_big') %></p>
116 <% } else { %>
117 <p><a class="btn btn-primary" href="/admin/migrate/export"><%= t('mig.export_btn') %></a></p>
118 <% } %>
119 <% } else { %>
120 <p class="form-hint"><%= t('mig.export_none') %></p>
121 <% } %>
122 </section>
123
124 <%# ── Rechtstreeks ophalen (FEP-1580) ────────────────────────── %>
125 <section class="mig-card">
126 <h2><%= t('mig.pull_title') %></h2>
127 <p class="form-hint"><%= t('mig.pull_hint') %></p>
128
129 <% if (haalVerslag) { %>
130 <div class="mig-report<%= haalVerslag.error ? '' : ' is-done' %>">
131 <% if (haalVerslag.error) { %>
132 <h3><%= t('mig.pull_failed') %></h3>
133 <%# Elke weigering krijgt een eigen zin. "Er ging iets mis" laat je
134 raden welke van de twee kanten van de afspraak ontbreekt, en dat
135 is precies wat je moet weten om het op te lossen. %>
136 <p><%= t('mig.e_' + haalVerslag.error) !== 'mig.e_' + haalVerslag.error
137 ? t('mig.e_' + haalVerslag.error) : (haalVerslag.melding || haalVerslag.error) %></p>
138 <% if (haalVerslag.error === 'not_moved_here' && haalVerslag.movedTo) { %>
139 <p class="form-hint"><%= t('mig.e_points_at') %> <code><%= haalVerslag.movedTo %></code></p>
140 <% } %>
141 <% } else { %>
142 <h3><%= t('mig.pull_done') %></h3>
143 <ul class="mig-counts">
144 <li><strong><%= haalVerslag.posts %></strong> <%= t('mig.r_imported') %></li>
145 <% if (haalVerslag.overgeslagen) { %><li><strong><%= haalVerslag.overgeslagen %></strong> <%= t('mig.r_skipped') %></li><% } %>
146 <% if (haalVerslag.media) { %><li><strong><%= haalVerslag.media %></strong> <%= t('mig.r_media') %></li><% } %>
147 <% if (haalVerslag.blocks) { %><li><strong><%= haalVerslag.blocks %></strong> <%= t('mig.r_blocks') %></li><% } %>
148 <% if (haalVerslag.tracksBinnen) { %><li><strong><%= haalVerslag.tracksBinnen %></strong> <%= t('mig.c_tracks') %></li><% } %>
149 <%# Aangevuld telt apart van nieuw. Een tweede ronde die "0 erbij"
150 meldt terwijl hij drie nummers compleet maakte, leest als niets
151 gedaan. %>
152 <% if (haalVerslag.tracksBijgewerkt) { %><li><strong><%= haalVerslag.tracksBijgewerkt %></strong> <%= t('mig.r_tracks_updated') %></li><% } %>
153 <% if (haalVerslag.postsBijgewerkt) { %><li><strong><%= haalVerslag.postsBijgewerkt %></strong> <%= t('mig.r_posts_updated') %></li><% } %>
154 <% if (haalVerslag.linksBijgetrokken) { %><li><strong><%= haalVerslag.linksBijgetrokken %></strong> <%= t('mig.r_links_fixed') %></li><% } %>
155 <% if (haalVerslag.playlistsBinnen) { %><li><strong><%= haalVerslag.playlistsBinnen %></strong> <%= t('mig.c_playlists') %></li><% } %>
156 </ul>
157 <% if (haalVerslag.tracksMislukt) { %>
158 <p class="alert alert-error"><%= t('mig.r_tracks_missing', { n: haalVerslag.tracksMislukt }) %></p>
159 <% } %>
160 <% } %>
161 <% if (haalVerslag.waarschuwingen && haalVerslag.waarschuwingen.length) { %>
162 <ul class="mig-warnlist">
163 <% haalVerslag.waarschuwingen.slice(0, 6).forEach(function (w) { %><li><%= w %></li><% }); %>
164 </ul>
165 <% } %>
166 </div>
167 <% } %>
168
169 <form method="post" action="/admin/migrate/pull">
170 <label for="mig-bron"><%= t('mig.pull_source') %></label>
171 <input type="url" id="mig-bron" name="bron" value="<%= bron || '' %>"
172 placeholder="@jij@oude-klonkt.nl" class="mig-input">
173 <p class="form-hint"><%= t('mig.pull_source_hint') %></p>
174 <button type="submit" class="btn"><%= t('mig.pull_btn') %></button>
175 </form>
176
177 <% if (mig && (mig.total || mig.moves)) { %>
178 <p class="form-hint mig-state">
179 <%= t('mig.state', { n: mig.total }) %>
180 <%= mig.complete ? t('mig.state_done') : t('mig.state_busy') %>
181 </p>
182 <% } %>
183 </section>
184
185 <%# ── Importeren ─────────────────────────────────────────────── %>
186 <section class="mig-card">
187 <h2><%= t('mig.import_title') %></h2>
188 <p class="form-hint"><%= t('mig.import_hint') %></p>
189
190 <% if (verslag) { %>
191 <div class="mig-report<%= verslag.echt ? ' is-done' : '' %>">
192 <h3><%= verslag.echt ? t('mig.r_done') : t('mig.r_dry') %></h3>
193 <p class="form-hint"><%= verslag.bestand %> &middot; <%= mb(verslag.bytes) %></p>
194 <ul class="mig-counts">
195 <li><strong><%= verslag.posts %></strong> <%= verslag.echt ? t('mig.r_imported') : t('mig.r_would') %></li>
196 <li><strong><%= verslag.overgeslagen %></strong> <%= t('mig.r_skipped') %></li>
197 <% if (verslag.overschreven) { %><li><strong><%= verslag.overschreven %></strong> <%= t('mig.r_overwritten') %></li><% } %>
198 <% if (verslag.mediaMissing) { %><li><strong><%= verslag.mediaMissing %></strong> <%= t('mig.r_media_missing') %></li><% } %>
199 <% if (verslag.media) { %><li><strong><%= verslag.media %></strong> <%= t('mig.r_media') %></li><% } %>
200 <%# Ook hier: muziek apart. Zonder deze twee regels zie je aan de
201 ontvangende kant net zo min of je bibliotheek is aangekomen. %>
202 <% if (verslag.tracks) { %><li><strong><%= verslag.tracks %></strong> <%= t('mig.c_tracks') %></li><% } %>
203 <% if (verslag.playlists) { %><li><strong><%= verslag.playlists %></strong> <%= t('mig.c_playlists') %></li><% } %>
204 <% if (verslag.linksBijgetrokken) { %><li><strong><%= verslag.linksBijgetrokken %></strong> <%= t('mig.r_links_fixed') %></li><% } %>
205 </ul>
206 <% if (verslag.tracksMissing) { %>
207 <p class="alert alert-error"><%= t('mig.r_tracks_missing', { n: verslag.tracksMissing }) %></p>
208 <% } %>
209 <% if (verslag.waarschuwingen && verslag.waarschuwingen.length) { %>
210 <ul class="mig-warnlist">
211 <% verslag.waarschuwingen.slice(0, 6).forEach(function (w) { %><li><%= w %></li><% }); %>
212 </ul>
213 <% } %>
214 <% if (verslag.idsBehouden === false) { %>
215 <%# Dit is de belangrijkste regel van het hele verslag: komt het archief
216 van een ANDER adres, dan krijgen de posts nieuwe id's en zijn het
217 nieuwe objecten voor de fediverse. %>
218 <p class="alert alert-error"><%= t('mig.r_new_ids') %></p>
219 <% } %>
220
221 <% if (!verslag.echt && verslag.posts > 0) { %>
222 <form method="post" action="/admin/migrate/import" enctype="multipart/form-data" class="mig-confirm">
223 <p class="form-hint"><%= t('mig.r_confirm_hint') %></p>
224 <label for="mig-file2"><%= t('mig.file_label') %></label>
225 <input type="file" id="mig-file2" name="archief" accept=".zip,application/zip" required>
226 <input type="hidden" name="echt" value="1">
227 <% if (verslag.overschrijf) { %><input type="hidden" name="overschrijf" value="1"><% } %>
228 <button type="submit" class="btn btn-primary"><%= t('mig.r_confirm_btn') %></button>
229 </form>
230 <% } %>
231 </div>
232 <% } %>
233
234 <form method="post" action="/admin/migrate/import" enctype="multipart/form-data">
235 <label for="mig-file"><%= t('mig.file_label') %></label>
236 <input type="file" id="mig-file" name="archief" accept=".zip,application/zip" required>
237
238 <label class="mig-check">
239 <input type="checkbox" name="overschrijf" value="1">
240 <%= t('mig.overwrite_label') %>
241 </label>
242 <p class="form-hint mig-warn"><%= t('mig.overwrite_hint') %></p>
243
244 <button type="submit" class="btn"><%= t('mig.check_btn') %></button>
245 <p class="form-hint"><%= t('mig.check_hint') %></p>
246 </form>
247 </section>
248
249 <%# ── De verhuizing aankondigen (FEP-7628 Move) ──────────────── %>
250 <%# ONDERAAN, en met een rode knop. Dit is de enige knop op deze pagina die
251 de fediverse in gaat en niet terug te draaien is: je volgers verhuizen
252 mee en dit account gaat op slot. Alles hierboven kun je overdoen. %>
253 <section class="mig-card mig-card-danger">
254 <h2><%= t('mig.move_title') %></h2>
255 <p class="form-hint"><%= t('mig.move_hint') %></p>
256 <% if (movedTo) { %>
257 <p class="alert alert-error"><%= t('mig.move_done') %> <code><%= movedTo %></code></p>
258 <% } else { %>
259 <form method="post" action="/admin/sites/<%= site.slug %>/move"
260 onsubmit="return confirm('<%= t('mig.move_confirm') %>');">
261 <input type="hidden" name="next" value="/admin/migrate">
262 <label for="mig-move"><%= t('mig.move_label') %></label>
263 <input type="text" id="mig-move" name="move_target" class="mig-input"
264 placeholder="@nieuw@andere-server.nl" required>
265 <p class="form-hint mig-warn"><%= t('mig.move_warn') %></p>
266 <button type="submit" class="btn btn-danger"><%= t('mig.move_btn') %></button>
267 </form>
268 <% } %>
269 </section>
270
271 <%# ── Wie je volgt ────────────────────────────────────────────── %>
272 <%# Stond op Connect, in een <details> zonder een greintje opmaak: labels als
273 losse tekst naast hun invoerveld, een textarea van vijf regels breed. Hier
274 krijgt hij de kaartopmaak van deze pagina, en hij hoort hier ook: je
275 volglijst meenemen is een migratie-optie. %>
276 <section class="mig-card">
277 <h2><%= t('mig.follows_title') %></h2>
278 <p class="form-hint"><%= t('tl.move_hint') %></p>
279 <p><a class="btn" href="/news/following.csv" download>&#11015; <%= t('tl.move_export') %></a></p>
280
281 <form method="post" action="/news/following/import" enctype="multipart/form-data">
282 <input type="hidden" name="next" value="/admin/migrate">
283 <label for="mig-volg-bestand"><%= t('tl.move_import_file') %></label>
284 <input type="file" id="mig-volg-bestand" name="csvfile" accept=".csv,text/csv,text/plain">
285
286 <label for="mig-volg-csv"><%= t('tl.move_import_lbl') %></label>
287 <textarea id="mig-volg-csv" name="csv" rows="5" spellcheck="false" class="mig-input"
288 placeholder="Account address,Show boosts,Notify on new posts,Languages,Featured"></textarea>
289 <p class="form-hint"><%= t('mig.follows_note') %></p>
290
291 <button type="submit" class="btn btn-primary"><%= t('tl.move_import') %></button>
292 </form>
293 </section>
294</div>
295
296<style>
297 .mig-wrap { max-width: 46rem; }
298 .mig-lead { color: var(--sub); margin-bottom: 1.5rem; }
299 .mig-card { border: 1px solid var(--rule); border-radius: 12px; padding: 1.25rem 1.4rem; margin-bottom: 1.25rem; }
300 .mig-card h2 { margin: 0 0 .35rem; font-size: 1.1rem; }
301 .mig-counts { list-style: none; padding: 0; margin: .9rem 0; display: flex; flex-wrap: wrap; gap: .4rem 1.4rem; }
302 .mig-counts li { color: var(--sub); font-size: .94rem; }
303 .mig-counts strong { color: var(--ink); font-size: 1.05rem; }
304 .mig-card label { display: block; margin: .9rem 0 .35rem; font-weight: 600; font-size: .92rem; }
305 .mig-card input[type="file"] { display: block; margin-bottom: .6rem; }
306 .mig-check { display: flex; align-items: center; gap: .5rem; font-weight: 400 !important; }
307 .mig-input { width: 100%; max-width: 34rem; padding: .5rem .6rem; border: 1px solid var(--rule);
308 border-radius: 8px; background: transparent; color: var(--ink); font-size: .95rem; }
309 .mig-state { margin-top: .9rem; }
310 .mig-report code { word-break: break-all; font-size: .88rem; }
311 .mig-warn { color: var(--accent); }
312 .mig-plan { background: color-mix(in srgb, var(--ink, #000) 3%, transparent); }
313 .mig-steps { margin: 1rem 0 0; padding-left: 1.4rem; display: flex; flex-direction: column; gap: .7rem; }
314 .mig-steps li { color: var(--ink); }
315 .mig-steps li em { display: block; color: var(--sub); font-style: normal; font-size: .9rem; margin-top: .15rem; }
316 .mig-steps li.is-done > strong { text-decoration: line-through; opacity: .6; }
317 .mig-steps li.is-done::marker { content: '✓ '; }
318 .mig-steps li.mig-step-later { opacity: .8; }
319 .mig-waar { font-size: .8rem; padding: .05rem .4rem; border: 1px solid var(--rule); border-radius: 999px;
320 color: var(--sub); margin-left: .4rem; white-space: nowrap; }
321 .mig-card-danger { border-color: color-mix(in srgb, var(--accent, #c33) 45%, var(--rule)); }
322 textarea.mig-input { font-family: inherit; resize: vertical; }
323 .mig-report { border-left: 3px solid var(--accent); padding: .8rem 1rem; margin-bottom: 1.2rem;
324 background: color-mix(in srgb, var(--ink, #000) 4%, transparent); border-radius: 0 8px 8px 0; }
325 .mig-report.is-done { border-left-color: #3fa843; }
326 .mig-report h3 { margin: 0 0 .3rem; font-size: 1rem; }
327 .mig-warnlist { margin: .5rem 0; padding-left: 1.2rem; color: var(--accent); font-size: .9rem; }
328 .mig-confirm { margin-top: .9rem; padding-top: .9rem; border-top: 1px solid var(--rule); }
329</style>
Note: See TracBrowser for help on using the repository browser.