Documentation brought up to date: the settings pages, how a conversation opens, presence and the tray, link cards and Kick events, Discord mutes set on the account, the tests and the tidy step, and the daemon described as it is rather than as it was meant to be
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
This commit is contained in:
+32
-12
@@ -6,9 +6,10 @@ How the two halves fit together, what the daemon speaks, and where it puts thing
|
||||
## Why two parts
|
||||
|
||||
- **`nobilis`** (`nobilis/`, Rust) speaks each protocol directly and translates it into a small
|
||||
unified JSON model (accounts, buffers, messages) over a Unix socket. It never exposes
|
||||
protocol-specific concepts to the client; it speaks the unified model, and each backend module
|
||||
happens to be how that model gets populated for a given service.
|
||||
unified JSON model (accounts, buffers, messages) over a Unix socket. What every service has in
|
||||
common - sending, editing, reacting, backlog, search - is one set of calls and events. What
|
||||
only one service has - a Matrix room's power levels, a Discord poll, a Kick prediction - is a
|
||||
call of its own, so a client never has to pretend the services are the same where they are not.
|
||||
- **The Electron client** (`src/`) spawns and supervises `nobilis` and renders whatever it reports.
|
||||
|
||||
Keeping the protocol work in a separate long-lived daemon means connections, Tor circuits, and
|
||||
@@ -42,14 +43,29 @@ Three panes: an account-grouped buffer sidebar, the message log, and a member li
|
||||
sidebar and member list independently foldable. Closing the window hides it to the tray; nobilis
|
||||
keeps running, so connections and unread tracking survive.
|
||||
|
||||
- **Message rendering** - an IRC-style log by default, with nick colouring, BBCode and
|
||||
markdown, spoilers, code and quote blocks, inline image/video/YouTube embeds, custom emoji,
|
||||
emotes and stickers (Discord's animated Lottie ones included), reactions, replies, inline
|
||||
edit, and Sneedchat's bundled smilies. "Comfy" groups consecutive messages under one avatar,
|
||||
and "Bubbles" draws them as chat bubbles.
|
||||
- **Settings** - a category rail covering General, IRC, Sneedchat, Tor, Discord, Matrix, Kick
|
||||
- **Message rendering** - an IRC-style log by default ("Classic"), with nick colouring, BBCode and
|
||||
markdown, spoilers, code and quote blocks, inline image/video embeds, custom emoji, emotes and
|
||||
stickers (Discord's animated Lottie ones included), reactions, replies, inline edit, and
|
||||
Sneedchat's bundled smilies. "Comfy" groups consecutive messages under one avatar, and "Bubbles"
|
||||
draws them as chat bubbles. A link is described by the daemon for every service, not only the
|
||||
ones that do it themselves: a YouTube link becomes a titled card, a Tenor or Giphy link is drawn
|
||||
as the GIF, and a GIF picker sends one from the composer. What somebody did on a Kick stream -
|
||||
KICKs sent, subscriptions gifted and to whom, a raid, a redeemed reward - is drawn as a card.
|
||||
- **Settings** - a searchable rail of categories: Accounts and Downloads; General, Appearance,
|
||||
Notifications and Keybinds; a page for each network (IRC, Sneedchat, Tor, Discord, Matrix, Kick);
|
||||
and About. Message-kind filters (joins, parts, mode changes) are applied client-side, so toggling
|
||||
one takes effect immediately without a reconnect.
|
||||
- **Moving around** - Ctrl+K opens a quick switcher over every conversation on every account.
|
||||
A conversation opens at its first unread message when the unread run is short, and at its end,
|
||||
with a bar to go back by, when it is long - as Discord does it. Escape marks the conversation
|
||||
read and Shift+Escape the whole server; a muted conversation stays quiet but still counts the
|
||||
times your name was used in it.
|
||||
- **Presence and the tray** - the status menu offers only the statuses each service has (Discord
|
||||
all four, IRC away and back, Matrix online and offline) and sends nothing to a service that
|
||||
has no such thing. Do not disturb silences desktop notifications everywhere and is Discord's
|
||||
real do-not-disturb on Discord. When nothing has been used for a while an account is put on
|
||||
Idle and back, from the system's idle time where it will say and moho's own windows where it
|
||||
will not. The tray draws a number counted by the window by the rule the server rail uses.
|
||||
- **Per-protocol join pages** - each service's mechanism is genuinely different (IRC joins by
|
||||
channel name, Discord offers the friends list and sends joining, adding a friend and making
|
||||
a server to discord.com - see below - Matrix takes a room address
|
||||
@@ -165,7 +181,8 @@ called `subscribe` for that buffer.
|
||||
gateway. Messages with edit/delete/reactions/replies/forwarding, threads and forum posts, slash
|
||||
commands with buttons, menus and modal forms, polls that can be voted in, stickers sent and
|
||||
drawn, pinned messages, Discord's own search, invites, scheduled events, AutoMod's verdicts,
|
||||
and server and channel mutes read from the account itself.
|
||||
and server and channel mutes - read from the account itself, and set on it when a channel is muted
|
||||
here, so a phone is quiet too.
|
||||
|
||||
Voice and video are moho's own connections rather than a library's: voice, the camera and Go
|
||||
Live streams - hosted and watched, with sound - over Discord's RTP with DAVE end-to-end
|
||||
@@ -197,8 +214,9 @@ called `subscribe` for that buffer.
|
||||
is a renegotiation rather than a new call.
|
||||
- **Kick** - the streaming site's chat, over its Pusher socket. Joins by streamer handle, imports
|
||||
the account's follows, and carries the three emote tiers with subscriber gating (and 7TV and
|
||||
BTTV beside them), redemptions, subscriptions, gifted subs and raids, moderation, chat modes,
|
||||
and polls and predictions that can be answered rather than only watched. The stream itself
|
||||
BTTV beside them), KICKs sent to a streamer, redemptions, subscriptions, gifted subs with who
|
||||
received them, raids, moderation, chat modes, and polls and predictions that can be answered
|
||||
rather than only watched. The stream itself
|
||||
plays in the window over HLS, with its VODs and clips.
|
||||
|
||||
## On-disk state
|
||||
@@ -209,6 +227,8 @@ called `subscribe` for that buffer.
|
||||
| `~/.config/nobilis/scrollback.db` | SQLite scrollback |
|
||||
| `~/.config/nobilis/matrix-crypto/` | Matrix E2EE device keys and Olm sessions |
|
||||
| `~/.config/nobilis/voice.toml` | microphone, speakers, volumes and voice processing |
|
||||
| `~/.config/nobilis/highlights.toml`, `ignores.toml` | the words that count as a mention, and who is ignored |
|
||||
| `~/.config/nobilis/dcc.toml`, `irc-sts.toml` | DCC settings, and the IRC networks that have pinned TLS (STS) |
|
||||
| `~/.config/nobilis/tor-state/`, `tor-cache/` | the embedded Tor client's state |
|
||||
| `~/.cache/nobilis/` | re-derivable media caches (Matrix media, Discord thumbnails, stickers and sounds, Kick emotes, Sneedchat avatars and attachments), each held to a size and to thirty days, and fetched again when a missing file is looked at - see `nobilis/src/media_cache.rs` |
|
||||
| `~/.cache/moho/moho.log` | the app's log, the daemon's included |
|
||||
|
||||
@@ -17,8 +17,11 @@ again and everything is where you left it.
|
||||
the same reply, edit, react, search and tag-someone gestures on each — as far as each
|
||||
service actually supports them.
|
||||
- **A log, not a feed.** Compact IRC-style scrollback with nick colours, markdown and BBCode,
|
||||
spoilers, code blocks, inline images and video, and custom emoji. There's a roomier mode
|
||||
with avatars if you prefer one.
|
||||
spoilers, code blocks, inline images and video, GIFs, YouTube cards, and custom emoji. There
|
||||
are two roomier modes if you prefer one: Comfy, with avatars, and Bubbles.
|
||||
- **Made for being open all day.** A quick switcher on Ctrl+K, a tray with the number waiting
|
||||
and your status, Do not disturb that really silences everything, idle detection, and
|
||||
conversations that open where you stopped reading rather than a thousand messages back.
|
||||
- **It stays connected.** The daemon keeps IRC registered, Matrix syncing and Tor circuits
|
||||
open while the window is shut. Quitting says a proper goodbye rather than dropping the
|
||||
socket, so you don't come back to a ghosted nick.
|
||||
@@ -85,13 +88,18 @@ npm install-scripts approve electron esbuild
|
||||
## Test it
|
||||
|
||||
```bash
|
||||
npm test # the window's unit tests (Vitest)
|
||||
npm run test:ui # layout checks against the real app - popups must stay inside the window
|
||||
npm test # the window's unit tests (Vitest)
|
||||
npm run test:ui # layout checks against the real app - popups must stay inside the window
|
||||
npm run test:tray # the tray: its icon, tooltip, menu, statuses and restart
|
||||
npm run test:gif # GIFs drawn as pictures, and the GIF picker
|
||||
npm run test:scroll # scrolling and where a conversation opens
|
||||
npm run test:kick # where Kick event cards sit in each layout
|
||||
cd nobilis && cargo test --release
|
||||
```
|
||||
|
||||
`test:ui` builds the window, runs it against a scratch home and a fake IRC server, and needs the
|
||||
daemon built first. On a machine with no display, run it under `xvfb-run`.
|
||||
The `test:` scripts other than `test` build the window, run it against a scratch home and a
|
||||
fake IRC server, and need the daemon built first. On a machine with no display, run them under
|
||||
`xvfb-run`. `npm run shots` photographs the interface scene by scene, for looking at changes.
|
||||
|
||||
## Run it
|
||||
|
||||
@@ -107,9 +115,14 @@ npm run deploy
|
||||
```
|
||||
|
||||
Other ways out of the box: `npm run pack:dir` for a self-contained `dist/linux-unpacked/`
|
||||
directory to run in place, `npm run pack:win` for the Windows installer (cross-built with
|
||||
mingw-w64; packaging it also needs wine with 32-bit support), and `makepkg -si` against the
|
||||
bundled `PKGBUILD` to install it as an Arch package under `/opt/moho`.
|
||||
directory to run in place, `npm run pack:deb` for a Debian package, `npm run pack:win` for the
|
||||
Windows installer (cross-built with mingw-w64; packaging it also needs wine with 32-bit
|
||||
support), and `makepkg -si` against the bundled `PKGBUILD` to install it as an Arch package
|
||||
under `/opt/moho`.
|
||||
|
||||
Packaging leaves a lot behind - an AppImage per build, and Rust build output that Cargo never
|
||||
cleans up. `npm run deploy` first runs `npm run tidy`, which keeps the newest two AppImages and
|
||||
empties `nobilis/target/` once it passes 8 GB.
|
||||
|
||||
---
|
||||
|
||||
|
||||
+1
-1
Submodule nobilis updated: 1c70d322eb...6a1bb8e738
Reference in New Issue
Block a user