feat: PiP mute indicator, export history, activity log, unverified device warning

- PiP call window: mute overlay using MutationObserver on EC iframe's
  [data-testid="incall_mute"] button (data-kind="primary" = muted),
  same pattern as screenshare detection in CallControl.ts

- P2-4 Export Room History: new tab in room settings — Plain Text / JSON /
  HTML formats, optional date range, progress counter, paginated via
  paginateEventTimeline, blob download; E2EE-aware (skips failed decryptions)

- P2-6 Room Activity Log: new tab in room settings — filterable log of
  m.room.member, m.room.power_levels, m.room.name/topic/avatar/server_acl
  events with human-readable descriptions, relative timestamps, Load More
  pagination

- P2-10 Unverified Device Warning: warnOnUnverifiedDevices setting (default
  off); Warning.Container banner above composer in encrypted rooms with
  unverified devices; toggle in Settings → General → Privacy

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-03 22:13:22 -04:00
parent 6d0b778755
commit ee717e8361
10 changed files with 1030 additions and 1 deletions
@@ -865,6 +865,10 @@ function Privacy() {
settingsAtom,
'privateReadReceipts',
);
const [warnOnUnverifiedDevices, setWarnOnUnverifiedDevices] = useSetting(
settingsAtom,
'warnOnUnverifiedDevices',
);
return (
<Box direction="Column" gap="100">
@@ -896,6 +900,19 @@ function Privacy() {
after={<Switch variant="Primary" value={hidePresence} onChange={setHidePresence} />}
/>
</SequenceCard>
<SequenceCard className={SequenceCardStyle} variant="SurfaceVariant" direction="Column">
<SettingTile
title="Warn before sending to unverified devices"
description="Show a warning in the composer when sending to a room with unverified devices."
after={
<Switch
variant="Primary"
value={warnOnUnverifiedDevices}
onChange={setWarnOnUnverifiedDevices}
/>
}
/>
</SequenceCard>
</Box>
);
}