feat: P1 features — voice speed, private receipts, room filter, favorites, invite link, poll creation

P1-5: Voice message playback speed toggle (0.75×/1×/1.5×/2×) in AudioContent.tsx
P1-10: Private read receipts toggle in Privacy settings; wired to notifications.ts
P1-3: Room filter input on Home tab and DMs tab (client-side, clears on tab switch)
P1-8: Favorite rooms via m.favourite tag — Favorites section in Home sidebar, star/unstar in right-click menu
P1-9: Room invite link + QR code in room settings (Share Room tile, api.qrserver.com QR)
P1-6: Poll creation modal in composer (PollCreator.tsx, sends m.poll.start)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-02 19:31:30 -04:00
parent f07ff63ac1
commit afe957015b
11 changed files with 607 additions and 8 deletions
@@ -96,6 +96,22 @@ export function AudioContent({
useThrottle(handlePlayTimeCallback, PLAY_TIME_THROTTLE_OPS),
);
const [playbackSpeed, setPlaybackSpeed] = useState<0.75 | 1 | 1.5 | 2>(1);
useEffect(() => {
if (audioRef.current) {
audioRef.current.playbackRate = playbackSpeed;
}
}, [playbackSpeed]);
const SPEED_STEPS: Array<0.75 | 1 | 1.5 | 2> = [0.75, 1, 1.5, 2];
const handleSpeedClick = () => {
const currentIndex = SPEED_STEPS.indexOf(playbackSpeed);
const nextIndex = (currentIndex + 1) % SPEED_STEPS.length;
setPlaybackSpeed(SPEED_STEPS[nextIndex]);
};
const handlePlay = () => {
if (srcState.status === AsyncStatus.Success) {
setPlaying(!playing);
@@ -163,6 +179,15 @@ export function AudioContent({
<Text size="T200">{`${secondsToMinutesAndSeconds(
currentTime,
)} / ${secondsToMinutesAndSeconds(duration)}`}</Text>
<Chip
onClick={handleSpeedClick}
variant="SurfaceVariant"
radii="Pill"
aria-label={`Playback speed: ${playbackSpeed}×`}
>
<Text size="B300">{`${playbackSpeed}×`}</Text>
</Chip>
</>
),
rightControl: (