Commit graph

120 commits

Author SHA1 Message Date
0b952f429a radio: move to a nav tab next to Friends (new nav_item slot), drop the grey bg 2026-07-07 15:07:38 +00:00
cd92bfc972 radio: footer trigger becomes a now-playing pill (station name + bars) 2026-07-07 14:41:36 +00:00
0c41b33fd3 radio: themed floating player card with equalizer + station list 2026-07-07 14:37:26 +00:00
84679568d5 plugins: add a sandboxed footer web-radio player (third/orbit-radio.js) 2026-07-07 14:17:05 +00:00
120806886c sandbox: add explicit "none" permission for zero-grant plugins 2026-07-07 14:03:17 +00:00
7bf51bdff8 plugins: consolidate under third/, run the clock fully sandboxed 2026-07-07 13:42:33 +00:00
6059ae321b auth: SASL SCRAM-SHA-256 for typed-password login, with PLAIN fallback 2026-07-07 04:05:53 +00:00
54dd2c3dc0 config: enable passkey sign-in on the tchatou deployment 2026-07-07 03:26:30 +00:00
efb73dfef3 sw: network-first for unhashed /app/ resources (plugins, icons); cache-first only for hashed /app/assets/ (was pinning stale plugins) 2026-07-07 01:08:41 +00:00
6f67e56ed4 fix invalid font shorthand (…/lh inherit) in clock/invite/games plugins 2026-07-07 01:02:29 +00:00
cb6c9ecf21 persistent session resume: reopen the tab straight back into your channels (opt-in; members re-auth via a fresh cookie-minted ticket, guests reconnect, no stored secret) 2026-07-06 23:44:52 +00:00
fa115e5bc3 Mirror orbit.server into the sandbox via the state snapshot 2026-07-06 17:52:06 +00:00
5c179eaa4a sandbox: accept the guest init (which evals plugin source) only from the host frame, once 2026-07-05 23:03:32 +00:00
0d89bc701a onboarding: honest TLS badge, localized hero + nick hint, channel picker with suggestions 2026-07-05 20:13:07 +00:00
b615339ae1 app: refresh in place on a new deploy instead of a hard reload
You had to reload the tab by hand to pick up a new build, and when the service
worker did reload it was an abrupt white flash. Now the build stamps version.json
with the commit and the running app (which already knows its own __GIT_COMMIT__)
polls it whenever the tab regains focus. When a newer build is live it cross-fades
a themed curtain (the theme's own --bg + accent spinner) and reloads, then holds
that curtain over the fresh load until the app mounts and fades it out - so it reads
as an in-place refresh, no flash, no manual reload.

If you're mid-message it waits until the composer is empty (or the tab is hidden)
before reloading, and a loop guard stops it re-reloading for a commit it already
tried. sw.js serves version.json network-only so the probe always sees the live id;
index.html restores the themed bg pre-paint so dark themes don't flash light.

Existing open tabs need one manual reload to pick up this machinery; after that it's
automatic.
2026-07-05 03:12:44 +00:00
e92e505302 Reported by Juest: fix dark flip/roll buttons in yomirc
The dice feature's buttons styled themselves with var(--panel) and var(--green-soft),
neither of which exists: --panel was never a token and --green-soft got renamed to
--accent-soft. So the buttons had no fill and the bare <button> picked up the OS dark
UA chrome (the sandbox iframe declared color-scheme: light dark, following the visitor's
OS, not the app). On a dark desktop the flip/roll buttons came out dark in a light theme.

Use the real, mirrored tokens (--accent-soft fill, --accent hover) so the buttons always
carry the theme's own accent, and pin the sandbox iframe's color-scheme to the app theme
(from its --bg) so no plugin's native controls track the OS instead of the skin. Drop the
dead --panel from the mirror list.
2026-07-05 02:40:34 +00:00
3998849930 multi-network: i18n the network UI (10 locales) + enable on production 2026-07-04 09:27:28 +00:00
b90d404438 multi-network: 2nd-network switcher, add-network modal, global-state sync + per-network storage (gated: features.multiNetwork) 2026-07-04 09:18:36 +00:00
75f69c6a66 chat: link-preview cards via the server unfurl endpoint (lazy, proxied image) 2026-07-04 08:10:36 +00:00
3a842d5099 sandbox: gate built-in features behind config.builtins (opt-in) 2026-07-04 06:38:59 +00:00
42657f352c sandbox: promote to a core subsystem the app mounts itself (bundled builtins) 2026-07-04 06:28:56 +00:00
8a5bc2781f Revert "chat: built-in /roll and /flip commands"
This reverts commit 5b989f48c0.
2026-07-04 06:19:31 +00:00
5b989f48c0 chat: built-in /roll and /flip commands 2026-07-04 06:16:39 +00:00
b3da7c29e9 sandbox: measure a wrapper sizer so a plugin restyling its root can't collapse the frame 2026-07-04 06:06:51 +00:00
29c6197aed plugins: orbit-dice, a real themed sandboxed plugin 2026-07-04 06:04:30 +00:00
2c6f6e18be sandbox: mirror the app theme vars into sandboxed plugins 2026-07-04 06:04:30 +00:00
221057cfa8 config: drop the sandbox demo from production 2026-07-04 06:04:30 +00:00
7e881d78d6 sandbox: re-handshake on iframe reload + size to content (fixes invisible UI) 2026-07-04 05:43:22 +00:00
f680484a0e config: enable the sandboxed demo plugin 2026-07-04 05:24:00 +00:00
86a7072581 sandbox: iframe host, guest bootstrap and loader routing 2026-07-04 05:12:13 +00:00
889f8e017b plugins: add orbit.modal() for plugin dialogs 2026-07-04 03:37:50 +00:00
87a4a75809 config: branding.accent to override the accent colour token 2026-07-04 03:17:57 +00:00
3d6acc07f0 config: branding.links for extra links in Settings > About
deployers can add rules/donate/help links without a plugin.
2026-07-04 03:17:20 +00:00
a77f97531e plugins: add orbit.addShortcut() for global keyboard shortcuts
combos like mod+shift+k are matched in the chat keydown handler after the
built-in shortcuts. demo plugin binds mod+shift+d.
2026-07-04 03:14:20 +00:00
68ea01ebc6 plugins: add addCommand() so plugins can register slash commands
hooks into the existing command parser (built-ins still win) and into
tab-completion. demo plugin gets a /roll example.
2026-07-04 03:06:34 +00:00
d5db835626 Plugins: add a footer_item UI slot for buttons in the app footer bar
New addUi('footer_item', …) slot renders in the footer's actions area (next to
the away / settings buttons). Registry type + TabBar render site; demo plugin
gains a footer-button example using the native appbar__act class.
2026-07-04 01:49:16 +00:00
3ef6cd3077 config.json: add defaults.lang; document every option in CONFIG.md
config.json now lists all 24 options (added defaults.lang: "" = auto-detect).
CONFIG.md gains the four undocumented ones (server.guestIdent, branding.projectUrl,
report.service, defaults.lang), corrects the startup default (#accueil) and the
turnstile.enabled/features.register descriptions, and the example is now complete.
2026-07-03 20:09:44 +00:00
642a99ce20 Wire config.branding.icon/name into the real browser surfaces
branding.icon is documented as the favicon URL but was only used for the
in-app logo. Now it also drives the browser tab favicon (main.tsx), the
desktop-notification icon (notify.ts), and the iOS home-screen title uses
branding.name. Drop the dead hardcoded 'tchatou' ident fallback in client.ts.
2026-07-03 19:45:25 +00:00
a7686cb8f1 Localise the bundled plugins and PWA manifest (all 10 languages)
Plugins had no i18n path, so copy/clock/invite/games showed hardcoded
English and French in every language. Add orbit.i18n (language/t/pick) +
orbit.config() to the plugin API (v4), move every plugin string into the
app locales under plugins.*, and rewrite the four bundled plugins to use it.
Also re-serve the PWA manifest (blob) with the brand name + a localized
description instead of the static French one. All 10 locales: 654 keys, in
sync.
2026-07-03 19:09:08 +00:00
fa7b1bbe54 Complete i18n across all 10 languages; kill hardcoded French
- MessageList showed 'Nouveaux messages' and 'Chargement de l'historique…'
  hardcoded (all languages); route through i18n (messages.newMessages,
  messages.loadingHistory).
- 8 locales (de/es/it/ne/pt-BR/pt-PT/ru/tr) were each missing 25 keys, which
  fell back to French (fallbackLng=fr). Translated all 27 keys natively; every
  locale now has identical key coverage (590 keys, 0 missing).
- config.json: list report.service for completeness.
2026-07-03 18:06:05 +00:00
38c5179282 Default startup channel #taverne -> #accueil 2026-07-03 00:11:54 +00:00
326953c15a Make guestIdent explicit in config.json
It already took effect via the code default (config.json merges over it),
but listing it here makes the guest ident visible and editable.
2026-07-03 00:09:48 +00:00
20e8de960d PWA icons: use the Tchatou brand mark, not the Orbit logo
Regenerate the install/notification icons from tchatou.fr's own favicon
(France-blue tile + speech bubbles). Bump the SW cache version so clients
fetch the new icons; push handler unchanged.
2026-06-27 10:29:54 +00:00
db1a679df3 PWA: real PNG app icons for mobile install + push
iOS only delivers Web Push to a Home-Screen PWA and ignores SVG
apple-touch-icons, and Android can't use SVG notification icons — so the
SVG-only icons broke push on mobile while desktop worked. Add 180/192/512
PNG icons (rendered from the orbit mark) and point the manifest +
apple-touch-icon at them. Push delivery code untouched.
2026-06-27 03:21:00 +00:00
7a9dfe30ca Revert "Push notifications: keep them on screen until dismissed"
This reverts commit 9df1e4005e.
2026-06-27 03:04:24 +00:00
9df1e4005e Push notifications: keep them on screen until dismissed
Backgrounded mentions fired the notification (hence the sound) but it was
easy to miss — auto-dismissed / silent in the shade. Add requireInteraction
+ a short vibrate so it stays visible, and bump the SW cache so clients pick
up the change.
2026-06-27 02:52:08 +00:00
6cdc11b022 Guest chess duels through GameServ (server-refereed)
GameServ already refereees guests (identity falls back to nick; ranked
stats only when both are registered), so route the duel link through it:
orbit-games auto-challenges via GameServ on a /app/?duel=chess&vs= link,
and the invite plugin offers that link again. No client-side game logic;
casual for guests, ranked for accounts.
2026-06-26 19:39:11 +00:00
cf9a36ab85 Remove client-side chess; games stay server-authoritative
A client-run game is a game the client can cheat. Drop the peer-to-peer
chess plugin and its duel links; GameServ stays the only game engine.
Invite plugin reverts to plain room links.
2026-06-26 19:31:59 +00:00
de63df3e30 Shareable invite + no-account chess duel links
orbit-invite adds a topbar button that builds a room link (/i/<salon>) or
a chess-duel link to share. orbit-chess is restored as the engine behind
the duel: it plays peer-to-peer over the +tchatou.fr/chess client tag and
auto-starts when the invited friend connects — no account, no referee.
2026-06-26 19:10:55 +00:00
a1ec63fdb2 ux: styled alert card for content-policy rejections
Replace the plain ⚠ sysline with a prominent amber alert card (SVG
warning icon, left-accent border, stands out from normal system lines)
when an upload is blocked by content policy. The message now reads as
a clear consequence — 'blocked' rather than 'refused' — and tells the
user that operators have been notified. Malware rejections also get the
alert treatment.
2026-06-23 15:05:47 +00:00