feat(room-settings): one-line "who can see this" under the room name (#133)
CI / Build & Quality Checks (push) Failing after 1m43s
CI / Trigger Desktop Build (push) Skipped
CI / Docker image build & smoke test (push) Skipped
CI / Playwright smoke (e2e) (push) Skipped
CI / Secret scan (gitleaks) (push) Successful in 9s

Room Settings → General now reads e.g. "Encrypted · Invite only ·
History visible to members since they joined" under the name — derived
from m.room.encryption, m.room.join_rules and m.room.history_visibility
with the same words the preview-card chips and the history setting use.
One Text line, no card, no icons, no controls; spec defaults (invite-only,
shared history) when a state event is absent. Unit-tested.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
This commit is contained in:
2026-09-20 15:18:08 -04:00
co-authored by Claude Opus 5
parent 492b57c60d
commit ad1cbcf792
3 changed files with 89 additions and 0 deletions
@@ -40,6 +40,8 @@ import { useMatrixClient } from '../../../hooks/useMatrixClient';
import { useMediaAuthentication } from '../../../hooks/useMediaAuthentication';
import { StateEvent } from '../../../../types/matrix/room';
import { sendStateEvent } from '../../../utils/room';
import { describeRoomVisibility } from '../../../utils/roomVisibilityLine';
import { useStateEvent } from '../../../hooks/useStateEvent';
import { CompactUploadCardRenderer } from '../../../components/upload-card';
import { useObjectURL } from '../../../hooks/useObjectURL';
import { createUploadAtom, UploadSuccess } from '../../../state/upload';
@@ -434,6 +436,14 @@ export function RoomProfile({ permissions }: RoomProfileProps) {
const name = useRoomName(room);
const topic = useRoomTopic(room);
const joinRule = useRoomJoinRule(room);
// [Gitea #133] One line, no controls: encryption · join rule · history.
const historyVisibilityEvent = useStateEvent(room, StateEvent.RoomHistoryVisibility);
const visibilityLine = describeRoomVisibility({
encrypted: room.hasEncryptionStateEvent(),
joinRule: joinRule?.join_rule,
historyVisibility: historyVisibilityEvent?.getContent<{ history_visibility?: string }>()
.history_visibility,
});
const canEditAvatar = permissions.stateEvent(StateEvent.RoomAvatar, mx.getSafeUserId());
const canEditName = permissions.stateEvent(StateEvent.RoomName, mx.getSafeUserId());
@@ -474,6 +484,9 @@ export function RoomProfile({ permissions }: RoomProfileProps) {
<Text className={BreakWord} size="H5">
{name ?? 'Unknown'}
</Text>
<Text size="T200" priority="300" className={BreakWord}>
{visibilityLine}
</Text>
{topic && (
<Text className={classNames(BreakWord, LineClamp3)} size="T200">
{topic.format === 'org.matrix.custom.html' &&