Changeset 2086ea2 in Klonkt for src/views


Ignore:
Timestamp:
08/12/2026 09:16:09 PM (3 months ago)
Author:
Robin <roboburr@…>
Children:
39dab6b
Parents:
5412cbb
Message:

Ward-PWA: de composer met media

Schrijven met foto, geluid of video, in de browser.

DEZELFDE POORT ALS DE APP, en dat is de kern. De composer bouwt precies
de AS2 Create die Shaer over C2S stuurt en geeft die aan
ingestOutboxActivity: die doet de compose-poort (par. 5), de
attachment-validatie en de zichtbaarheid. GEEN eigen posting-pad, want
dan zou de web-ward een sluiproute om de guardians heen zijn. Een test
bewaakt precies dat: een gated ward wordt ook via de browser
tegengehouden.

Media gaan eerst apart naar /ward/api/upload, in DEZELFDE bak als de
app (reply-media), zodat een foto van een app-ward en een browser-ward
niet van twee plekken federeert. De server maakt de rest af zoals altijd:
posterframe voor video, waveform voor audio. De post draagt daarna alleen
de url, dus de payload blijft klein.

Sessie-geauthenticeerd, niet met een bearer: /ward draait op je eigen
ingelogde Klonkt, dus de browser heeft geen token nodig zoals de app.

New file: (geen)
Changed files:
src/routes/ward.js

  • /api/upload: sessie-geauthenticeerd, zelfde filters/map als C2S
  • /api/post: bouwt de AS2 Create, door ingestOutboxActivity

src/views/pages/ward.ejs

  • schrijfknop, composer-dialoog met tekst, media en zichtbaarheid

src/assets/js/ward.js

  • upload-per-bestand, media-chips, plaatsen; opruiming van een dubbel geraakte doc-comment

src/assets/css/ward.css

  • composer, media-chips, tools

src/services/i18n.js

  • twaalf sleutels in nl, en, de

test/ward-pwa.test.js

  • de gate geldt ook in de browser; een vrij account plaatst met media; leeg wordt geweigerd; een vreemde kan niet uploaden

remarks: 903 tests groen. Opnemen van audio/video in de browser zelf
(MediaRecorder) is nog niet gebouwd; nu kies je een bestand. Bead volgt.

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

File:
1 edited

Legend:

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

    r5412cbb r2086ea2  
    3030
    3131    <section id="feed">
    32       <h2><%= state.strings.feed %></h2>
     32      <div class="feed-head">
     33        <h2><%= state.strings.feed %></h2>
     34        <button id="compose-open" type="button" class="primary"><%= state.strings.write %></button>
     35      </div>
    3336      <div class="cards" id="card-list"></div>
    3437      <p class="empty" id="feed-empty" hidden><%= state.strings.feedEmpty %></p>
    … …  
    5154    </section>
    5255  </main>
     56
     57  <!-- De composer: schrijven met foto, geluid of video. De posttypes
     58       dicteren hoe de widget eruitziet (Robins wens), maar de kern is een
     59       tekstvak plus tot vier media; de server maakt de rest af (poster,
     60       waveform) zoals bij de app. -->
     61  <dialog id="compose-dialog">
     62    <div class="compose-head">
     63      <button id="compose-cancel" type="button" aria-label="<%= state.strings.cancel %>">✕</button>
     64      <select id="compose-vis" aria-label="<%= state.strings.visibility %>">
     65        <option value="friends"><%= state.strings.visFriends %></option>
     66        <option value="public"><%= state.strings.visPublic %></option>
     67      </select>
     68      <button id="compose-send" type="button" class="primary"><%= state.strings.post %></button>
     69    </div>
     70    <textarea id="compose-text" rows="4" maxlength="5000" placeholder="<%= state.strings.writeHere %>"></textarea>
     71    <div id="compose-media" class="compose-media"></div>
     72    <div class="compose-tools">
     73      <label class="tool" title="<%= state.strings.addPhoto %>">
     74        📷<input type="file" accept="image/*" hidden data-kind="image">
     75      </label>
     76      <label class="tool" title="<%= state.strings.addAudio %>">
     77        🎤<input type="file" accept="audio/*" hidden data-kind="audio">
     78      </label>
     79      <label class="tool" title="<%= state.strings.addVideo %>">
     80        🎬<input type="file" accept="video/*" hidden data-kind="video">
     81      </label>
     82      <span id="compose-status" class="hint"></span>
     83    </div>
     84  </dialog>
    5385
    5486  <!-- De reddingsboei zweeft boven de pagina en is sleepbaar, net als in
Note: See TracChangeset for help on using the changeset viewer.