Wonders of Work Review hub

Open changes waiting for a look, and what shipped recently. Anyone can open a preview below and leave feedback on GitLab.

Open for review

MR !71 by Iftakhar Hasnayen Abir ·

Fix

only render events after relay acceptance

What this changes, and why

Every Nostr write operation fired handleEvent/onSuccess on the first relay OK frame without checking msg[2] (the success boolean), so a rejection was treated as an acceptance. Rejected events appeared in the UI and vanished after refresh. Also fixes a data-loss risk in updateStoryWithKindChange where the original story could be deleted even if the replacement was rejected by all relays.

Adds publishWithAck in nostr-create.js — waits for msg[2] === true before calling success callbacks, and shows a toast with the relay's reason on all-rejections or timeout. sendMessage now returns its dispatch count so the helper knows how many OK frames to expect.

Also fixes duplicate toasts: sendMessage gains a silent option so publishWithAck owns all user messaging on the publish path, preventing two toasts for the same failure. Error messages are Strapi-backed via window.wowMessages (falling back to hardcoded English).

What this affects
  • send-message.js — returns relay dispatch count (non-breaking; existing callers ignore the return value)
  • nostr-create.js — all write paths via create(): comments, reactions, RSVPs, stories, calendar events, profile, follows, bookmarks, file metadata, deletes
  • src/layouts/Layout.astro — exposes window.wowMessages from globals.texts on every page
  • src/utils/getGlobals.ts — adds 4 relay message keys to the Texts type (relayNoConnection, relayTimeout, relayPublishFailed, relayPublishRejected)
  • To override the fallback strings

How to try it

1. Log in and post a comment — it should appear and persist after refresh. 2. To test the failure path: post while disconnected from all relays — a toast should appear and nothing should render.

Updates · newest first

  • preview ↗ Merge branch 'main' into fix/relay-ok-ack-before-render by ih-abir ·
  • preview ↗ Merge branch 'main' into fix/relay-ok-ack-before-render by ih-abir ·
  • preview ↗ fix: localized relay connection messsage by ih-abir ·
  • no preview Merge branch 'main' into fix/relay-ok-ack-before-render by ih-abir ·
  • preview ↗ fix: only render events after relay acceptance by ih-abir ·

MR !78 by Iftakhar Hasnayen Abir ·

Other

Fix/ui text hardcoded to strapi

What this changes, and why

Moves hardcoded UI strings across the profile, story, and event flows into Strapi so all copy is editable per‑locale (en/nl) without code changes. Adds typed config loaders (getStoryUiConfig, getEventUiConfig), fixes the language switcher + ?d=/?key= preservation on preview pages, and removes three redundant profile pages now covered by profile-preview.

> Requires the matching Strapi single types/fields to be deployed, populated, and > published (separate MR).

What this affects
  • profile-preview.astro — edit-mode and follow.
  • Removes redundant profile.astro, profile-details.astro, profile-details-2.astro.

  • Story/event create-* and *-preview pages (form labels, alerts, menus, SEO).
  • Shared: Layout, Reactions, card-generator.js, Input/LocationSelector/
  • RoomSelector/TagSelector/LanguageSelector/MarkdownEditor2.

How to try it

On the preview link, in both en and nl: 1. Open create-story / create-event — labels, placeholders, buttons, and validation alerts should render from CMS; switch language and confirm it stays on the page. 2. Open a story / event preview — back button, action menu (Share/Copy/Delete), RSVP/location text, deleted/not-found states; language switch keeps ?d=. 3. Open /profile-preview?key=… — edit profile, follow, and the draft badge / reactions-comments block.

Updates · newest first

  • preview ↗ Merge branch 'main' into fix/ui-text-hardcoded-to-strapi by ih-abir ·
  • preview ↗ style: format getProfileUiConfig with prettier by ih-abir ·
  • no preview fix: hero text content alignment based on components used by ih-abir ·
  • no preview fix: remove redundant profile, profile details pages by ih-abir ·
  • no preview fix: replace profile, story, event all remaining hardcoded text to strapi by ih-abir ·

Recently shipped to production (main) wondersofwork.nl 🎉

  • Fix
    hero text content alignment based on components used
    What this changes, and why

    Image-less heroes now align based on what else is on the page:

    • hero + only rich text → center-left (centered column, text left)
    • hero + other sections, no rich text → centered
    • rich text + other sections, or a bare hero → left

    Previously these always rendered center-left, so a hero with a card grid (and no body text) looked misaligned.

    What this affects
    • getHeroAlign.ts — new shared rule used by both render paths.
    • PostDetailsLayout.astro — enrichers/agenda/stories/etc.
    • PageBuilder.astroall CMS pages with an image-less hero (incl. homepage/landing pages). Heroes with an image are untouched.

    No security-sensitive areas touched.

    How to try it

    On the preview link: 1. Open a content page whose hero has no image + a card grid + no body text → hero text should be centered. 2. Open a page with hero + rich text only → stays center-left. 3. Open a page with hero + rich text + other sections → everything left-aligned. 4. Sanity-check the homepage and a hero-with-image page look unchanged.

  • MR !77 by Jurjen de Vries ·
    CI
    rename typecheck to lint:types
    What this changes, and why

    Finishes the naming consistency: typecheck was the only job left outside the lint:/test: scheme. Type-checking is a static check, so it joins the lint family as lint:types. Now every job is lint:* (static checks) or test:* (tests) — one scheme, no exception.

    What this affects

    .gitlab-ci.yml (job name) and the CONTRIBUTING checks table. No application code, no behaviour change; still allow_failure (orange warning).

    How to try it

    This MR pipeline shows lint:types grouped with the other lint:* jobs.

  • MR !76 by Jurjen de Vries ·
    CI
    consistent job names (lint:/test: namespaces) + refresh checks table
    What this changes, and why

    Makes CI job names consistent and GitLab-idiomatic so the pipeline reads clearly for FOSS contributors. Colon namespaces group related jobs in the GitLab UI.

    • format -> lint:format
    • commitlint -> lint:commits
    • mr-description -> lint:mr
    • hardcoded-content -> lint:hardcoded
    • test -> test:redirects (was vague; now says what it runs and scales to test:unit etc)
    • typecheck stays (distinct category)

    Also refreshes the stale CONTRIBUTING What the build checks table: drops the removed build row, adds the missing jobs, and marks which are blocking vs advisory warnings.

    What this affects

    .gitlab-ci.yml job names and CONTRIBUTING.md. No application code, no behaviour change. Same checks run; only labels + docs change.

    How to try it

    This MR pipeline shows the new names; lint:* group together. The CONTRIBUTING table matches the jobs.

  • MR !75 by Jurjen de Vries ·
    CI
    orange passed-with-warnings via allow_failure
    What this changes, and why

    hardcoded-content showed a green check because the script exited 0. Now the script exits non-zero on findings and the job uses allow_failure: true, so findings show as an orange passed-with-warnings (like typecheck) without blocking the merge.

    What this affects

    scripts/check-hardcoded-content.mjs (exit code) and the hardcoded-content job in .gitlab-ci.yml. No application code. Once the existing copy is migrated to Strapi, drop allow_failure to make it a hard gate.

    How to try it

    This MR pipeline: hardcoded-content shows orange (warning), MR stays mergeable.

  • MR !74 by Jurjen de Vries ·
    CI
    orange passed-with-warnings via allow_failure
    What this changes, and why

    typecheck used pnpm check || echo, so it always exited 0 and showed a green check even with type errors. Switch to allow_failure: true + plain pnpm check, so a failing run shows as orange passed-with-warnings (visible) instead of green, while still not blocking the merge.

    What this affects

    .gitlab-ci.yml typecheck job only. Verifying the GitLab behavior: the job should go orange and the MR should stay mergeable.

    How to try it

    This MR pipeline: typecheck shows orange (warning), other jobs green, MR stays mergeable.

  • MR !73 by Jurjen de Vries ·
    CI
    warn on hardcoded translatable content
    What this changes, and why

    Adds a CI job + script (scripts/check-hardcoded-content.mjs, pnpm check:hardcoded) that flags hardcoded translatable copy in .astro components — visible text and user-facing attributes (aria-label, title, placeholder, alt) not bound to an expression. Such copy should come from Strapi so editors can edit/translate it. Currently ~137 findings.

    What this affects

    New scripts/check-hardcoded-content.mjs, one new package.json script, one new .gitlab-ci.yml job. No application code. Non-blocking: the script always exits 0 and only warns (like typecheck). Flip EXIT_ON_FINDINGS=true once the existing copy is migrated.

    How to try it

    pnpm check:hardcoded locally, or see the hardcoded-content job in this MR pipeline — it prints the count, a per-kind and per-file breakdown, and passes (warning only).

  • Fix
    align page text center-left
    What this changes, and why

    Removes forced text-center alignment from page content so all text reads left-aligned. Affected: Hero text block, RichText/Markdown body, table headers and cells, and figure captions.

    What this affects
    • Hero.astro, RichText.astro — text no longer centred
    • _base.scss — table th/td and figcaption lose text-center
    How to try it

    Open /en/cancellation-policy/ on the preview link and confirm all text is left-aligned.

  • MR !70 by Jurjen de Vries ·
    Fix
    restore Cyberdigma widget house-style override
    What this changes

    Restores is:inline on the Cyberdigma/MeetingSelect override <style> block in BookingForm.astro, so the Wonders of Work house-style colors apply to the booking widget again instead of the vendor default styling.

    How to try

    1. Open a space page with the booking form and run a search that opens the Cyberdigma booking overlay. 2. Confirm the widget shows the Wonders of Work house-style colors (primary brand color), not the default Cyberdigma blue. 3. Compare against current production / the broken build to see the regression.

    What this affects
    • Only src/components/BookingForm.astro — the inline override style block.
    • Root cause: merge 84d8404 (w3c-enhancements) flipped <style is:inline> to plain <style>. Astro scopes plain style blocks with a data-astro-cid attribute on selectors + rendered elements. The Cyberdigma widget DOM (.searchWidget, .c_lab-bw-widget, …) is injected at runtime by the third-party web component and never gets the scope attribute, so the scoped overrides stopped matching. is:inline keeps the CSS global/unscoped so it matches the runtime-injected widget again.
    • No JS or markup behavior change; styling only.
  • MR !69 by Jurjen de Vries ·
    Fix
    stop list from swallowing trailing paragraphs
    What this changes, and why

    Fixes two list-rendering bugs in the Nostr markdown renderer (public/scripts/render-markdown.js) seen on event previews:

    1. Text swallowed into the list. The renderer had no blank-line terminator, so every paragraph after a bullet list got pulled into the last <li> and indented. Now a blank line followed by a non-indented line ends the list, and continuation requires indentation to the item-content column (first.indent + 2). 2. Empty bullet markers. Some editors emit a list item as a bare marker plus a blank line, with the text as a separate non-indented paragraph (-\n\ntext). That left an empty bullet with the text dropped below it. An empty marker now adopts the following paragraph as its content. Blank-line termination only kicks in once an item already has content.

    Nested lists, multi-paragraph items, and same-paragraph lazy continuation still render correctly (covered by manual tests against the real event content).

    What this affects
    • Nostr markdown rendering on the event-preview and story-preview pages only. No security-sensitive areas (profile, key export, OpenBunker) touched.
    • Bumps the render-markdown.js import version query (?v=20260514?v=20260603) in both preview pages to bust the 4h public-script CDN/browser cache.
    How to try it

    Open these previews on the MR preview link:

    • /en/event-preview/?d=event:proeverij-leadership-embodiment-hoe-je-krachtig-n-ontspannen-kunt-zijn-in-uitdagende-situaties-door-belichaamd-persoonlijk-leiderschap-mpeb9k0uc6s2r3y6y504m2s — text after the bullet list ("Voor wie?" block) is left-aligned, not indented into the list.
    • /en/event-preview/?d=event:open-workshop-claude-code-mpf30obb1t1p2otx65725j — the "Wat leer je?" bullets show their text next to each arrow (not an empty arrow with the text dropped below).
  • MR !66 by Jurjen de Vries ·
    Fix
    align list markers with item text
    What this changes, and why

    Fixes a vertical gap between the list marker (arrow bullet / number) and the item text in .prose-text lists. Loose-list items render their content inside <p>. Because .prose-text lists are CSS grid containers, each <li> establishes its own block formatting context, so the paragraph's prose margin-top no longer collapses and pushes the text below the marker.

    Fix: zero margin-top on the first <p> and margin-bottom on the last <p> inside list items (.prose-text li > p).

    Spotted on the Nostr event preview (workshop event), but it affects every .prose-text surface.

    Also documents an existing implicit convention in AGENTS.md: merge request descriptions and test plans are written in English (the MR template already is).

    What this affects

    .prose-text li > p touches every .prose-text surface that renders a loose list (blank line between items, producing <li><p>…</p></li>):

    • Nostr event preview and story preview (render-markdown.js)
    • Strapi rich text via Markdown.astro: RichText, FAQs, Features, StepsGrid,
    • CardGrid, Spotlight, People, Categories, QuoteGrid, Newsletter, AudioPlayer, VideoGrid, ContactInfo

    • Hero.astro (inline marked)
    • Both bulleted (ul) and numbered (ol) lists

    Not affected: .arrow-list standalone (RichText "chapters" nav — different class), and tight lists (no <p> inside <li>, selector does not match). No security-sensitive areas touched.

    How to try it

    On the preview link, open content that contains a bulleted or numbered list with blank lines between items, and confirm the marker now lines up with the first line of text:

    • [x] Nostr event preview (the original bug) — arrow lists line up
    • [x] Nostr story preview
    • [x] Strapi RichText block: ul and ol lists
    • [x] Numbered list (ol): number circle aligns with text
    • [x] Strapi blocks with markdown that may contain lists: FAQs, Features,
    • StepsGrid, CardGrid, Spotlight, People, Categories, QuoteGrid, Newsletter, AudioPlayer, VideoGrid, ContactInfo, Hero

    • [x] Tight lists (no blank lines between items): unchanged
    • [x] Multi-paragraph list items: spacing between paragraphs preserved
    • (only first/last margin removed)

    Before you ask for review
    • [x] Branch named feat/…, fix/…, chore/…, docs/… or hotfix/…
    • [x] Commit messages follow Conventional Commits
    • [x] pnpm format has been run and the checks are green
    • [x] Tried it on the preview link
    • [x] Rebased on the latest main

See all merged changes on GitLab →