Commit graph

120 commits

Author SHA1 Message Date
e6fb177740 filehost: friendly message for violence-rejected images 2026-06-23 02:38:45 +00:00
ee6cbf3788 filehost: friendly message for NSFW-rejected images
Images are now moderated by a local NudeNet service; explicit uploads
get 422 nsfw_image. Map that to a clear 'image rejected: explicit
content' notice instead of a raw error code.
2026-06-23 02:19:59 +00:00
055d8314ca filehost: clear message when AV scanner is down (503)
Server now fails closed when ClamAV can't scan (refuses with 503
scanner_unavailable instead of storing an unverified file). Map that to
a friendly 'virus scanning temporarily unavailable' notice instead of a
raw error code.
2026-06-23 02:03:12 +00:00
6ed2fdc692 filehost: precise not-identified match (don't reject the success lines)
The module sends the token line first, then 'No need to log in again' —
which the previous heuristic matched as not-identified. Match the real
guest line ('must be logged in to use file hosting') instead, and also
swallow it (it lacks the FILEHOST prefix).
2026-06-22 22:49:40 +00:00
4b150735ac filehost: always hide FILEHOST service notices
The automatic /FILEHOST command behind image/voice uploads emitted help
notices that leaked into chat once the token line resolved. Suppress all
FILEHOST notices unconditionally (still extract the token when an upload
is pending), and tighten not-identified detection so it no longer matches
the 'Your logged in account: …' success line.
2026-06-22 22:47:06 +00:00
39e7e403d7 composer: voice messages (record + inline player)
Record a voice message in the composer (MediaRecorder → opus/webm) and
share it through the same /FILEHOST upload flow as images; received audio
URLs render as an inline player. Works in channels and PMs.
2026-06-22 22:00:58 +00:00
6f9df4cd01 games: per-game-type stats and ladders
Each game (chess / Connect 4 / tic-tac-toe) now has its own rank, points
and record. The panel shows a rank row per game played, the leaderboard
gains a per-game tab, and the profile chip shows a player's strongest
game. Reads the per-type GS$ / GS$TOP lines GameServ now sends.
2026-06-22 14:18:47 +00:00
868e2b1732 games: read GameServ state from invisible client-only tag
GameServ now pushes board/stats state in a +tchatou.fr/gs tag on a
bodiless TAGMSG instead of a GS# NOTICE, so plain IRC clients never see
the machine lines and only get the human-readable NOTICE. The web client
reads the tag to drive the UI and hides GameServ's NOTICEs from chat.
2026-06-22 13:56:56 +00:00
2351a99b9d games: board games refereed by GameServ + ranked ladder
chess, tic-tac-toe and Connect Four played against the GameServ services
referee (it validates moves + keeps the account-keyed Bronze→Master
ladder); the client only sends commands and renders the pushed state.
adds a generic plugin message-filter so a service's machine lines stay
out of chat.
2026-06-22 12:12:39 +00:00
fd3be15704 report: route ReportServ command + replies to the Status window
filing a report echoed our REPORT command into a ReportServ PM buffer
and ReportServ's confirmation landed in the active channel. route both
(by sender/recipient = report.service) to Status instead, and put the
optimistic confirmation there too.
2026-06-22 12:12:07 +00:00
904a7167ce report: file abuse reports through ReportServ via a window
the report action opened a hardcoded PRIVMSG to #staff, which a +n
staff channel silently drops for non-members. now it opens a report
window (target + reason) and sends REPORT to the ReportServ service,
which queues it for staff and isn't blocked by +n. config gains
report.service (default ReportServ); empty falls back to the channel.
2026-06-22 12:12:07 +00:00
50fdeba879 sidebar: show the server name under the Status row
the Home list's Status row now shows where you're connected (the ircd
hostname) instead of the generic "System", falling back to System
until 004 arrives.
2026-06-22 12:12:07 +00:00
6f296f01d6 topbar: mIRC-style Status title on the server buffer
rename the server/console window to Status everywhere and render its
title as "Status: <nick> [+<umodes>] on <servername>". track the ircd
hostname from RPL_MYINFO (004) and query our user modes on register so
the line is populated.
2026-06-22 12:12:07 +00:00
09d3c020c5 connect: auto-connect from the site entry-form handoff
The Tchatou entry form now sends visitors to /app/?nick=&channel= and parks
any SASL password in same-origin sessionStorage (kept out of the URL). On
boot we consume that one-shot marker and connect right away, so a visitor who
already chose a pseudo on the site never sees the join form a second time.

A new autoConnecting flag shows a small splash while the handoff connects;
any failure clears it and falls back to the join form with the nick and
channel still prefilled from the URL.
2026-06-21 01:13:46 +00:00
reverse
624acf8d7e main: static-import the error boundary so recovery code is in the core bundle 2026-06-20 18:18:11 +00:00
reverse
c126711d00 Add a top-level error boundary (crash recovery instead of white screen)
A render error anywhere previously unmounted the whole tree into a blank
page. AppErrorBoundary now wraps the app and shows a localized recovery
screen with a reload button, logging the error. Mirrors the proven
PluginBoundary pattern.
2026-06-20 18:16:10 +00:00
reverse
ea133001f1 MemberList: browser-native virtualization for large channels
Off-screen member rows now skip layout & paint via content-visibility,
with contain-intrinsic-size for correct scrollbar sizing (yomirc gets a
smaller estimate). A 2k-member panel only renders the visible rows; small
channels are unchanged. Together with the earlier per-message re-render
fixes, this closes the large-channel lag (layout/paint + re-render cost).
2026-06-20 18:01:25 +00:00
reverse
668e2aec78 Topbar: narrow store selects so it doesn't re-render per message
Was subscribing to the whole active buffer (new object on every message)
and recounting members each time. Now selects name/isChannel/topic/modes/
members individually — re-renders only when those change, not on each line.
Audited the rest: MessageList must track messages (capped 500, virtualise
later); Sidebar is bounded; the typing indicator is trivial and benefits
from frequent renders; modal selectors only run while open.
2026-06-20 17:51:01 +00:00
reverse
db443c5990 MemberList: stop re-rendering/re-sorting on every message
Subscribe to buffer.members by reference (updated immutably) instead of
the whole active buffer, and memoise the role grouping + name sort. The
list now recomputes only when membership/mode/filter actually changes —
not on each incoming line, which was O(members) work per message in big
channels.
2026-06-20 16:53:11 +00:00
reverse
b4a41ef481 config: optional defaults.lang to pin a default UI language
When set (and the user hasn't explicitly chosen one), it overrides
browser detection after the runtime config loads. Omitted = auto-detect
as before.
2026-06-20 16:28:25 +00:00
reverse
5a374adb92 tchatou: drop the misleading zéro-inscription claim from the connect subtitle 2026-06-20 15:46:11 +00:00
reverse
e796a7a332 Plugins: hand decorators/actions formatting-stripped text (+ raw)
MessageInfo.text is now the human-readable text with mIRC formatting/
colour codes stripped, so orbit-copy copies clean text instead of raw
control codes; the original is available as MessageInfo.raw.
2026-06-20 09:12:58 +00:00
reverse
29566ce277 Add message_action plugin slot; move orbit-copy into the action toolbar
New addMessageAction() puts a plugin button in each message's hover
toolbar next to reply/react (inherits its styling), distinct from the
inline addMessageDecorator. orbit-copy now lives there with its green
check-on-copy feedback — tidier than a copy icon on every line.
2026-06-20 09:05:20 +00:00
reverse
d478f2f1e5 orbit-copy: flip the copy button to a green check on copy 2026-06-20 08:56:25 +00:00
reverse
41aeecc166 Enable orbit-clock and orbit-copy example plugins on tchatou 2026-06-20 08:48:47 +00:00
reverse
c7a3a5dba0 Plugin SRI support + documented deployment CSP
Plugin entries may now be { url, integrity, crossorigin } so off-origin
plugins can be pinned with Subresource Integrity (crossorigin defaults to
anonymous when a hash is set). Documents a sample CSP header and SRI hash
generation in SECURITY.md; the policy is a header (deployment-specific
origins) rather than a baked meta tag.
2026-06-20 08:37:17 +00:00
reverse
dad10e80f7 Accessibility pass: focus ring, skip link, landmarks, labels
Adds a clear :focus-visible keyboard ring for buttons/links/menu items,
a skip-to-messages link, landmark labels on the message log (role=log),
conversation sidebar and member list, and aria-labels on the emoji-only
message action buttons. New a11y i18n namespace across all locales.
2026-06-20 08:33:41 +00:00
reverse
228973992a Plugin maturity: more UI slots, message decorators, two examples
Adds topbar_item and sidebar_item slots, plus addMessageDecorator() —
a per-message hook handed a stable read-only view {id,nick,text,kind,
ts,mine}, each rendered inside its own error boundary. Ships orbit-clock
(topbar) and orbit-copy (decorator) examples and documents both.
2026-06-20 08:30:27 +00:00
reverse
6a42d30812 Per-channel notification level (All / Mentions / Mute)
Replaces the binary mute with a three-way level stored per channel
(legacy muted channels migrate to Mute). The topbar bell opens an
accessible popover; the notify decision honours the level — All alerts
on every line, Mentions only on your nick/highlights, Mute never.
2026-06-20 08:24:07 +00:00
reverse
53fb774009 Add keyboard shortcuts, a ? help sheet, and mark-all-read
Global hotkeys (chat view): Ctrl/Cmd-K switcher, Alt+Up/Down to cycle
conversations, Shift+Esc to mark everything read, ? for the help sheet.
Composer arrow handler now ignores Alt so buffer-nav passes through.
2026-06-20 08:18:13 +00:00
reverse
ad60d14e44 feat: Ctrl/⌘-K quick switcher — fuzzy-jump to any channel, DM or person, or join a channel by name (keyboard-navigable command palette); pure result builder with tests, i18n in 10 languages 2026-06-20 08:05:33 +00:00
reverse
1201231ea0 feat: text-size control (Appearance), Orbit.apiVersion for plugins, and remove dangling privacy/advanced settings labels 2026-06-20 07:51:03 +00:00
reverse
bb6591ba91 chore: project credibility bundle — CONTRIBUTING/CODE_OF_CONDUCT/SECURITY/issue+PR templates, .editorconfig, CHANGELOG; add plugin-bus & mode-parsing tests; replace ineffective try/catch plugin slots with a real error boundary (fixes lint, actually isolates plugin render errors) 2026-06-20 07:31:04 +00:00
reverse
8717821673 feat(plugins): compiled-plugin support — expose React/ReactDOM/jsx-runtime/Fragment as externalization targets, add settings_section slot (addSettingsSection) wired into Settings, + plugin-template/ (Vite build with React externalized) and docs 2026-06-20 05:42:02 +00:00
reverse
59e67ac621 config: disable demo plugin in production (system ships, example stays available) 2026-06-20 05:10:39 +00:00
reverse
3fa22e76bc fix(plugins): composer plugin-button selector returned a new array each render (zustand v5 infinite loop crashed the chat view) — select stable ref, filter in body 2026-06-20 05:05:41 +00:00
reverse
479138e2c0 feat: operator-controlled plugin system — Orbit global (events/state/irc/themes/storage), config-listed loader, composer-button UI slot (HTM), example plugin + docs/PLUGINS.md 2026-06-20 05:03:28 +00:00
reverse
95308a6450 feat(plugins): webchat-style operator-controlled plugin system — window.Orbit (plugin/on/emit/state/irc/themes/storage/addUi), config plugins[], HTM render, composer_button slot, demo plugin + docs/PLUGINS.md 2026-06-20 05:01:20 +00:00
reverse
485c873914 add orbit-avatar.png (1024px raster of the project icon) to public for download 2026-06-20 03:52:55 +00:00
reverse
48561b329c app: use the Orbit project icon as the favicon / apple-touch-icon / PWA manifest icon 2026-06-20 03:41:30 +00:00
reverse
b8668d3af7 settings: inline IRCv3 chat-bubble v3 mark for the section icon (no official IRCv3 glyph exists) 2026-06-20 03:33:15 +00:00
reverse
8737ab212f settings: use a plug icon for the IRCv3 section (capabilities/plugins) instead of a satellite 2026-06-20 03:18:08 +00:00
reverse
1bd4a3ca8c settings: About hero uses the Orbit project icon, not the deployment/server icon 2026-06-20 03:03:53 +00:00
reverse
978defcbf9 settings: add About section (app version/build/commit injected at build, AGPL source/project links); bump version to 1.0.0 2026-06-20 02:58:33 +00:00
reverse
b6b9f3d2dc settings: Server section gains max-channels row + collapsible raw ISUPPORT (005) viewer 2026-06-20 02:50:29 +00:00
reverse
45124dd4c2 settings: move Server info into its own section (separate from IRCv3 capabilities) 2026-06-20 02:44:54 +00:00
reverse
a57f5e2faf settings: add Server info card to IRCv3 panel (network, software/version, TLS, users online, casemapping, channel types, roles, limits) 2026-06-20 02:38:31 +00:00
reverse
fd92779075 settings: fix scroll on mobile — cards no longer shrink/clip inside the scroll area (IRCv3 list now fully reachable) 2026-06-20 02:29:47 +00:00
reverse
52777d7eab settings: 2-column responsive grid for IRCv3 capabilities so the full set is visible 2026-06-20 02:22:49 +00:00
reverse
3188c2643b settings: add IRCv3 capabilities panel (live cap state per server) + i18n in 10 languages 2026-06-20 02:15:46 +00:00