fix: rework compact nav and centralized back routing

Use master-detail layout on skinny windows so server and channel lists share one screen, with back returning to the space list instead of redirect loops. Add useBackRoute for title-bar and page-header back buttons with view transitions.
This commit is contained in:
2026-07-09 04:22:07 +10:00
parent b4258278d8
commit 9c7f71896c
11 changed files with 247 additions and 116 deletions

View File

@@ -1,23 +1,20 @@
import { ReactNode } from 'react';
import { useMatch } from 'react-router-dom';
import { ScreenSize, useScreenSizeContext } from '../hooks/useScreenSize';
import { DIRECT_PATH, EXPLORE_PATH, HOME_PATH, INBOX_PATH, SPACE_PATH } from './paths';
import { useCompactNav } from '../hooks/useCompactNav';
type MobileFriendlyClientNavProps = {
children: ReactNode;
};
export function MobileFriendlyClientNav({ children }: MobileFriendlyClientNavProps) {
const screenSize = useScreenSizeContext();
const compact = useCompactNav();
const homeMatch = useMatch({ path: HOME_PATH, caseSensitive: true, end: true });
const directMatch = useMatch({ path: DIRECT_PATH, caseSensitive: true, end: true });
const spaceMatch = useMatch({ path: SPACE_PATH, caseSensitive: true, end: true });
const exploreMatch = useMatch({ path: EXPLORE_PATH, caseSensitive: true, end: true });
const inboxMatch = useMatch({ path: INBOX_PATH, caseSensitive: true, end: true });
if (
screenSize === ScreenSize.Mobile &&
!(homeMatch || directMatch || spaceMatch || exploreMatch || inboxMatch)
) {
if (compact && !(homeMatch || directMatch || spaceMatch || exploreMatch || inboxMatch)) {
return null;
}
@@ -29,14 +26,14 @@ type MobileFriendlyPageNavProps = {
children: ReactNode;
};
export function MobileFriendlyPageNav({ path, children }: MobileFriendlyPageNavProps) {
const screenSize = useScreenSizeContext();
const compact = useCompactNav();
const exactPath = useMatch({
path,
caseSensitive: true,
end: true,
});
if (screenSize === ScreenSize.Mobile && !exactPath) {
if (compact && !exactPath) {
return null;
}

View File

@@ -5,17 +5,24 @@ import { useSpace } from '../../../hooks/useSpace';
import { shouldShowForumLobby } from '../../../utils/room';
import { getSpaceDefaultPath } from '../../pathUtils';
import { ForumFeedPage } from '../../../features/forum/ForumFeedPage';
import { useCompactNav } from '../../../hooks/useCompactNav';
/** Sends /:spaceId/ to the forum feed or space lobby. */
/** Sends /:spaceId/ to the forum feed or space lobby (desktop). On compact nav, stay on index for the channel list. */
export function SpaceIndexRedirect() {
const mx = useMatrixClient();
const space = useSpace();
const navigate = useNavigate();
const compact = useCompactNav();
const isForum = shouldShowForumLobby(space);
useEffect(() => {
if (compact) return;
navigate(getSpaceDefaultPath(mx, space.roomId), { replace: true });
}, [mx, navigate, space.roomId]);
}, [compact, mx, navigate, space.roomId]);
if (compact) {
return null;
}
// Avoid a blank main pane while redirecting forum spaces to /feed/.
if (isForum) {