From e6c7a40af2c2c92079b8052918c0ca03072aaffd Mon Sep 17 00:00:00 2001 From: Salastil Date: Sun, 13 Sep 2026 13:37:49 -0400 Subject: [PATCH] Mark the server's own room, and stop offering to leave it Its own glyph in the list, because the fact worth knowing is that it is not one of the others - a notice about a quota is easy to scroll past when it arrives in what looks like a room a stranger made. The Leave entry becomes a sentence saying the server keeps it open, rather than disappearing. An absent entry reads as a client that forgot and leaves somebody hunting for the gesture; this says what is actually true. Co-Authored-By: Claude Opus 5 --- nobilis | 2 +- src/renderer/src/components/BufferList.tsx | 6 +++++ src/renderer/src/lib/buffermenu.ts | 29 ++++++++++++++++------ src/renderer/src/lib/util.ts | 13 ++++++++++ src/shared/wire.ts | 9 +++++++ 5 files changed, 50 insertions(+), 9 deletions(-) diff --git a/nobilis b/nobilis index 873a908..4f7ba9b 160000 --- a/nobilis +++ b/nobilis @@ -1 +1 @@ -Subproject commit 873a9083d274e96e95ae98355e6ba1fb5a63ed09 +Subproject commit 4f7ba9bc214a739defdf160cdcc9b40a760b6f68 diff --git a/src/renderer/src/components/BufferList.tsx b/src/renderer/src/components/BufferList.tsx index 577e31e..852b3ed 100644 --- a/src/renderer/src/components/BufferList.tsx +++ b/src/renderer/src/components/BufferList.tsx @@ -23,6 +23,7 @@ import type { BufferGroup } from '../../../shared/wire' import { bufferDisplayName, bufferKindGlyph, + serviceRoomGlyph, classes, resolveMediaUrl, serviceIcon @@ -808,6 +809,11 @@ function BufferRow({ ) : buffer.avatarUrl ? ( + ) : buffer.serviceRoom ? ( + // The server's own room. Marked here because the fact worth knowing is + // that it is not one of the others - a notice about a quota is easy to + // scroll past when it arrives in what looks like a room a stranger made. + ) : ( ) diff --git a/src/renderer/src/lib/buffermenu.ts b/src/renderer/src/lib/buffermenu.ts index 086dd5c..ba10a00 100644 --- a/src/renderer/src/lib/buffermenu.ts +++ b/src/renderer/src/lib/buffermenu.ts @@ -228,13 +228,26 @@ export function bufferMenuEntries({ { label: 'Hide', icon: 'visibility_off', onClick: onHide }, ...(buffer.kind === 'server' ? [] - : ([ - { - label: leaveLabel(buffer, account?.service), - icon: 'close', - danger: true, - onClick: onClose - } - ] as MenuEntry[])) + : buffer.serviceRoom + ? // The server's own room, which the server will not let anybody + // leave. Said rather than hidden: an entry that is simply absent + // reads as a client that forgot, where this reads as the fact it + // is - and hiding it would leave somebody hunting for the gesture. + ([ + { + label: 'Your server keeps this room open', + icon: 'lock', + disabled: true, + onClick: () => {} + } + ] as MenuEntry[]) + : ([ + { + label: leaveLabel(buffer, account?.service), + icon: 'close', + danger: true, + onClick: onClose + } + ] as MenuEntry[])) ] } diff --git a/src/renderer/src/lib/util.ts b/src/renderer/src/lib/util.ts index 97bceaf..e91cd62 100644 --- a/src/renderer/src/lib/util.ts +++ b/src/renderer/src/lib/util.ts @@ -175,6 +175,19 @@ export function bufferKindGlyph(kind: string): string { return 'tag' } +/** + * The mark on a conversation that is the service talking rather than a + * person: Matrix's server notices room. + * + * Its own glyph rather than the channel hash, because the thing worth knowing + * about that room is precisely that it is not one of the others - a message + * about a quota or an account restriction is easy to scroll past when it + * arrives in what looks like a room a stranger made. + */ +export function serviceRoomGlyph(): string { + return 'campaign' +} + /** * Deterministic per-nick colour, so the same person keeps the same colour * across sessions and buffers. Hue-only variation against a fixed saturation diff --git a/src/shared/wire.ts b/src/shared/wire.ts index dcdb493..02f5417 100644 --- a/src/shared/wire.ts +++ b/src/shared/wire.ts @@ -127,6 +127,15 @@ export interface Buffer { * just stops competing for the top of the rail. */ lowPriority?: boolean + /** + * This conversation is the service itself talking to the account. + * + * Matrix's server notices room - a terms-of-service change, a quota, an + * account restriction. Marked because it otherwise looks exactly like an + * ordinary room from a stranger, and because it cannot be left: the server + * refuses, so offering to leave it is offering something that fails. + */ + serviceRoom?: boolean /** * Set while the buffer exists but the service has not yet said what is in * it - a Matrix room between joining it and its first sync. The list draws