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.
This commit is contained in:
2026-07-23 14:52:01 +10:00
parent 61d41900cc
commit 9509a9705e
30 changed files with 1749 additions and 168 deletions

View File

@@ -1,5 +1,5 @@
import { useCallback } from 'react';
import { NavigateOptions, useNavigate } from 'react-router-dom';
import { NavigateOptions, useLocation, useNavigate } from 'react-router-dom';
import { useAtomValue } from 'jotai';
import { getCanonicalAliasOrRoomId } from '../utils/matrix';
import {
@@ -7,21 +7,25 @@ import {
getHomeRoomPath,
getSpacePath,
getSpaceRoomPath,
withRoomEventId,
} from '../pages/pathUtils';
import { useMatrixClient } from './useMatrixClient';
import { getOrphanParents, guessPerfectParent, isSpace } from '../utils/room';
import { roomToParentsAtom } from '../state/room/roomToParents';
import { mDirectAtom } from '../state/mDirectList';
import { useSelectedRoom } from './router/useSelectedRoom';
import { useSelectedSpace } from './router/useSelectedSpace';
import { settingsAtom } from '../state/settings';
import { useSetting } from '../state/hooks/settings';
export const useRoomNavigate = () => {
const navigate = useNavigate();
const location = useLocation();
const mx = useMatrixClient();
const roomToParents = useAtomValue(roomToParentsAtom);
const mDirects = useAtomValue(mDirectAtom);
const spaceSelectedId = useSelectedSpace();
const selectedRoomId = useSelectedRoom();
const [developerTools] = useSetting(settingsAtom, 'developerTools');
const navigateSpace = useCallback(
@@ -34,6 +38,14 @@ export const useRoomNavigate = () => {
const navigateRoom = useCallback(
(roomId: string, eventId?: string, opts?: NavigateOptions) => {
// Already viewing this room — keep the current home/direct/space URL and only
// change the event id. Otherwise guessPerfectParent can yank the sidebar to
// wherever the room "belongs".
if (selectedRoomId === roomId) {
navigate(withRoomEventId(location.pathname, eventId), opts);
return;
}
const room = mx.getRoom(roomId);
const roomIdOrAlias = getCanonicalAliasOrRoomId(mx, roomId);
const openSpaceTimeline = developerTools && spaceSelectedId === roomId;
@@ -68,7 +80,16 @@ export const useRoomNavigate = () => {
navigate(getHomeRoomPath(roomIdOrAlias, eventId), opts);
},
[mx, navigate, spaceSelectedId, roomToParents, mDirects, developerTools]
[
mx,
navigate,
location.pathname,
selectedRoomId,
spaceSelectedId,
roomToParents,
mDirects,
developerTools,
]
);
return {