Files
cinny/src/app/features/room/Room.tsx
litruv 9509a9705e Add Shared Media drawer and harden same-room navigation.
Widen the media panel, support skinny full-page mode, keep jump-to-latest and return-to-previous reliable, and stop same-room event jumps from remounting the outlet or yanking the sidebar.
2026-07-23 14:52:01 +10:00

86 lines
3.1 KiB
TypeScript

import React, { useCallback, useEffect } from 'react';
import { Box, Line } from 'folds';
import { decodeRouteParam } from '../../pages/pathUtils';
import { useParams } from 'react-router-dom';
import { isKeyHotkey } from 'is-hotkey';
import { useAtom, useSetAtom } from 'jotai';
import { RoomView } from './RoomView';
import { MembersDrawer } from './MembersDrawer';
import { MediaDrawer } from './room-media-menu';
import { ScreenSize, useScreenSizeContext } from '../../hooks/useScreenSize';
import { useSetting } from '../../state/hooks/settings';
import { settingsAtom } from '../../state/settings';
import { PowerLevelsContextProvider, usePowerLevels } from '../../hooks/usePowerLevels';
import { useRoom } from '../../hooks/useRoom';
import { useKeyDown } from '../../hooks/useKeyDown';
import { useMarkAsRead } from '../../hooks/useMarkAsRead';
import { useMatrixClient } from '../../hooks/useMatrixClient';
import { useRoomMembers } from '../../hooks/useRoomMembers';
import { activeRoomIdAtom } from '../../state/activeRoom';
import { isMediaDrawerAtom } from '../../state/mediaDrawer';
import { isForum } from '../../utils/room';
import { ForumRoomView } from './ForumRoomView';
export function Room() {
const { eventId: rawEventId } = useParams();
const eventId = decodeRouteParam(rawEventId);
const room = useRoom();
const mx = useMatrixClient();
const setActiveRoomId = useSetAtom(activeRoomIdAtom);
const [isPeopleDrawer] = useSetting(settingsAtom, 'isPeopleDrawer');
const [isMediaDrawer] = useAtom(isMediaDrawerAtom);
const [hideActivity] = useSetting(settingsAtom, 'hideActivity');
const screenSize = useScreenSizeContext();
const powerLevels = usePowerLevels(room);
const members = useRoomMembers(mx, room.roomId);
const markAsRead = useMarkAsRead(mx);
const forumRoom = isForum(room);
const skinny = screenSize !== ScreenSize.Desktop;
const showMediaSolo = skinny && isMediaDrawer;
const showRightDrawer =
!skinny && (isPeopleDrawer || isMediaDrawer);
// Update titlebar with current room ID
useEffect(() => {
setActiveRoomId(room.roomId);
return () => setActiveRoomId(undefined);
}, [room.roomId, setActiveRoomId]);
useKeyDown(
window,
useCallback(
(evt) => {
if (isKeyHotkey('escape', evt)) {
markAsRead(room.roomId, hideActivity);
}
},
[markAsRead, room.roomId, hideActivity]
)
);
return (
<PowerLevelsContextProvider value={powerLevels}>
<Box grow="Yes">
{!showMediaSolo &&
(forumRoom ? (
<ForumRoomView room={room} eventId={eventId} />
) : (
<RoomView room={room} eventId={eventId} />
))}
{showMediaSolo && <MediaDrawer room={room} solo />}
{!showMediaSolo && showRightDrawer && (
<>
<Line variant="Background" direction="Vertical" size="300" />
{isMediaDrawer ? (
<MediaDrawer room={room} />
) : (
<MembersDrawer key={room.roomId} room={room} members={members} />
)}
</>
)}
</Box>
</PowerLevelsContextProvider>
);
}