diff --git a/src/app/hooks/useRoomNavigate.ts b/src/app/hooks/useRoomNavigate.ts
index 0f9f365c..e626c06b 100644
--- a/src/app/hooks/useRoomNavigate.ts
+++ b/src/app/hooks/useRoomNavigate.ts
@@ -13,6 +13,8 @@ import { getOrphanParents } from '../utils/room';
import { roomToParentsAtom } from '../state/room/roomToParents';
import { mDirectAtom } from '../state/mDirectList';
import { useSelectedSpace } from './router/useSelectedSpace';
+import { settingsAtom } from '../state/settings';
+import { useSetting } from '../state/hooks/settings';
export const useRoomNavigate = () => {
const navigate = useNavigate();
@@ -20,6 +22,7 @@ export const useRoomNavigate = () => {
const roomToParents = useAtomValue(roomToParentsAtom);
const mDirects = useAtomValue(mDirectAtom);
const spaceSelectedId = useSelectedSpace();
+ const [developerTools] = useSetting(settingsAtom, 'developerTools');
const navigateSpace = useCallback(
(roomId: string) => {
@@ -32,15 +35,22 @@ export const useRoomNavigate = () => {
const navigateRoom = useCallback(
(roomId: string, eventId?: string, opts?: NavigateOptions) => {
const roomIdOrAlias = getCanonicalAliasOrRoomId(mx, roomId);
+ const openSpaceTimeline = developerTools && spaceSelectedId === roomId;
- const orphanParents = getOrphanParents(roomToParents, roomId);
+ const orphanParents = openSpaceTimeline ? [roomId] : getOrphanParents(roomToParents, roomId);
if (orphanParents.length > 0) {
const pSpaceIdOrAlias = getCanonicalAliasOrRoomId(
mx,
spaceSelectedId && orphanParents.includes(spaceSelectedId)
? spaceSelectedId
- : orphanParents[0]
+ : orphanParents[0] // TODO: better orphan parent selection.
);
+
+ if (openSpaceTimeline) {
+ navigate(getSpaceRoomPath(pSpaceIdOrAlias, roomId, eventId), opts);
+ return;
+ }
+
navigate(getSpaceRoomPath(pSpaceIdOrAlias, roomIdOrAlias, eventId), opts);
return;
}
@@ -52,7 +62,7 @@ export const useRoomNavigate = () => {
navigate(getHomeRoomPath(roomIdOrAlias, eventId), opts);
},
- [mx, navigate, spaceSelectedId, roomToParents, mDirects]
+ [mx, navigate, spaceSelectedId, roomToParents, mDirects, developerTools]
);
return {
diff --git a/src/app/pages/client/sidebar/SpaceTabs.tsx b/src/app/pages/client/sidebar/SpaceTabs.tsx
index 5b47cb52..011741ee 100644
--- a/src/app/pages/client/sidebar/SpaceTabs.tsx
+++ b/src/app/pages/client/sidebar/SpaceTabs.tsx
@@ -744,13 +744,14 @@ export function SpaceTabs({ scrollRef }: SpaceTabsProps) {
const targetSpaceId = target.getAttribute('data-id');
if (!targetSpaceId) return;
+ const spacePath = getSpacePath(getCanonicalAliasOrRoomId(mx, targetSpaceId));
if (screenSize === ScreenSize.Mobile) {
- navigate(getSpacePath(getCanonicalAliasOrRoomId(mx, targetSpaceId)));
+ navigate(spacePath);
return;
}
const activePath = navToActivePath.get(targetSpaceId);
- if (activePath) {
+ if (activePath && activePath.pathname.startsWith(spacePath)) {
navigate(joinPathComponent(activePath));
return;
}
diff --git a/src/app/pages/client/space/RoomProvider.tsx b/src/app/pages/client/space/RoomProvider.tsx
index a9632137..0fd52ab6 100644
--- a/src/app/pages/client/space/RoomProvider.tsx
+++ b/src/app/pages/client/space/RoomProvider.tsx
@@ -1,21 +1,24 @@
import React, { ReactNode } from 'react';
import { useParams } from 'react-router-dom';
-import { useAtomValue } from 'jotai';
+import { useAtom, useAtomValue } from 'jotai';
import { useSelectedRoom } from '../../../hooks/router/useSelectedRoom';
import { IsDirectRoomProvider, RoomProvider } from '../../../hooks/useRoom';
import { useMatrixClient } from '../../../hooks/useMatrixClient';
import { JoinBeforeNavigate } from '../../../features/join-before-navigate';
import { useSpace } from '../../../hooks/useSpace';
-import { getAllParents } from '../../../utils/room';
+import { getAllParents, getSpaceChildren } from '../../../utils/room';
import { roomToParentsAtom } from '../../../state/room/roomToParents';
import { allRoomsAtom } from '../../../state/room-list/roomList';
import { useSearchParamsViaServers } from '../../../hooks/router/useSearchParamsViaServers';
import { mDirectAtom } from '../../../state/mDirectList';
+import { settingsAtom } from '../../../state/settings';
+import { useSetting } from '../../../state/hooks/settings';
export function SpaceRouteRoomProvider({ children }: { children: ReactNode }) {
const mx = useMatrixClient();
const space = useSpace();
- const roomToParents = useAtomValue(roomToParentsAtom);
+ const [developerTools] = useSetting(settingsAtom, 'developerTools');
+ const [roomToParents, setRoomToParents] = useAtom(roomToParentsAtom);
const mDirects = useAtomValue(mDirectAtom);
const allRooms = useAtomValue(allRoomsAtom);
@@ -24,12 +27,36 @@ export function SpaceRouteRoomProvider({ children }: { children: ReactNode }) {
const roomId = useSelectedRoom();
const room = mx.getRoom(roomId);
- if (
- !room ||
- room.isSpaceRoom() ||
- !allRooms.includes(room.roomId) ||
- !getAllParents(roomToParents, room.roomId).has(space.roomId)
- ) {
+ if (!room || !allRooms.includes(room.roomId)) {
+ // room is not joined
+ return (
+
+ );
+ }
+
+ if (developerTools && room.isSpaceRoom() && room.roomId === space.roomId) {
+ // allow to view space timeline
+ return (
+
+ {children}
+
+ );
+ }
+
+ if (!getAllParents(roomToParents, room.roomId).has(space.roomId)) {
+ if (getSpaceChildren(space).includes(room.roomId)) {
+ // fill missing roomToParent mapping
+ setRoomToParents({
+ type: 'PUT',
+ parent: space.roomId,
+ children: [room.roomId],
+ });
+ }
+
return (
(({ room, requestClose }, ref) => {
const mx = useMatrixClient();
const [hideActivity] = useSetting(settingsAtom, 'hideActivity');
+ const [developerTools] = useSetting(settingsAtom, 'developerTools');
const roomToParents = useAtomValue(roomToParentsAtom);
const powerLevels = usePowerLevels(room);
const { getPowerLevel, canDoAction } = usePowerLevelsAPI(powerLevels);
const canInvite = canDoAction('invite', getPowerLevel(mx.getUserId() ?? ''));
const openSpaceSettings = useOpenSpaceSettings();
+ const { navigateRoom } = useRoomNavigate();
const allChild = useSpaceChildren(
allRoomsAtom,
@@ -118,6 +121,11 @@ const SpaceMenu = forwardRef(({ room, requestClo
requestClose();
};
+ const handleOpenTimeline = () => {
+ navigateRoom(room.roomId);
+ requestClose();
+ };
+
return (