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