From 9b5ce37743b6195f1eec5fb8826cf7da710ac41d Mon Sep 17 00:00:00 2001 From: Gimle Larpes Date: Thu, 3 Jul 2025 22:51:26 +0200 Subject: [PATCH] bugfix and polishing --- src/app/features/lobby/Lobby.tsx | 13 +++++++++---- src/app/pages/client/space/Space.tsx | 20 ++++---------------- src/app/state/closedLobbyCategories.ts | 2 ++ src/app/state/closedNavCategories.ts | 2 ++ src/app/state/room/roomToChildren.ts | 16 ++++++++++++++++ 5 files changed, 33 insertions(+), 20 deletions(-) create mode 100644 src/app/state/room/roomToChildren.ts diff --git a/src/app/features/lobby/Lobby.tsx b/src/app/features/lobby/Lobby.tsx index ede695b4..5dd54fa0 100644 --- a/src/app/features/lobby/Lobby.tsx +++ b/src/app/features/lobby/Lobby.tsx @@ -32,7 +32,7 @@ import { useRoomsPowerLevels, } from '../../hooks/usePowerLevels'; import { mDirectAtom } from '../../state/mDirectList'; -import { makeLobbyCategoryId } from '../../state/closedLobbyCategories'; +import { makeLobbyCategoryId, getLobbyCategoryIdParts } from '../../state/closedLobbyCategories'; import { useCategoryHandler } from '../../hooks/useCategoryHandler'; import { useMatrixClient } from '../../hooks/useMatrixClient'; import { allRoomsAtom } from '../../state/room-list/roomList'; @@ -74,6 +74,11 @@ const useCanDropLobbyItem = ( const containerSpaceId = space.roomId; + // only allow to be dropped in parent space + if (item.parentId !== container.item.roomId && item.parentId !== container.item.parentId) { + return false; + } + if ( getRoom(containerSpaceId) === undefined || !canEditSpaceChild(roomsPowerLevels.get(containerSpaceId) ?? {}) @@ -368,7 +373,7 @@ export function Lobby() { // remove from current space if (item.parentId !== containerParentId) { - mx.sendStateEvent(item.parentId, StateEvent.SpaceChild as any, {}, item.roomId); + await mx.sendStateEvent(item.parentId, StateEvent.SpaceChild as any, {}, item.roomId); } if ( @@ -388,7 +393,7 @@ export function Lobby() { joinRuleContent.allow?.filter((allowRule) => allowRule.room_id !== item.parentId) ?? []; allow.push({ type: RestrictedAllowType.RoomMembership, room_id: containerParentId }); - mx.sendStateEvent(itemRoom.roomId, StateEvent.RoomJoinRules as any, { + await mx.sendStateEvent(itemRoom.roomId, StateEvent.RoomJoinRules as any, { ...joinRuleContent, allow, }); @@ -476,7 +481,7 @@ export function Lobby() { const handleCategoryClick = useCategoryHandler(setClosedCategories, (categoryId) => { const collapsed = closedCategories.has(categoryId); - const [spaceId, roomId] = categoryId.split('|').slice(-2); + const [spaceId, roomId] = getLobbyCategoryIdParts(categoryId); // Only prevent collapsing if all parents are collapsed const toggleable = !getAllAncestorsCollapsed(spaceId, roomId); diff --git a/src/app/pages/client/space/Space.tsx b/src/app/pages/client/space/Space.tsx index cb94b8af..015e014e 100644 --- a/src/app/pages/client/space/Space.tsx +++ b/src/app/pages/client/space/Space.tsx @@ -45,7 +45,7 @@ import { import { useSpace } from '../../../hooks/useSpace'; import { VirtualTile } from '../../../components/virtualizer'; import { RoomNavCategoryButton, RoomNavItem } from '../../../features/room-nav'; -import { makeNavCategoryId } from '../../../state/closedNavCategories'; +import { makeNavCategoryId, getNavCategoryIdParts } from '../../../state/closedNavCategories'; import { roomToUnreadAtom } from '../../../state/room/roomToUnread'; import { useCategoryHandler } from '../../../hooks/useCategoryHandler'; import { useNavToActivePathMapper } from '../../../hooks/useNavToActivePathMapper'; @@ -57,6 +57,7 @@ import { usePowerLevels, usePowerLevelsAPI } from '../../../hooks/usePowerLevels import { openInviteUser } from '../../../../client/action/navigation'; import { useRecursiveChildScopeFactory, useSpaceChildren } from '../../../state/hooks/roomList'; import { roomToParentsAtom } from '../../../state/room/roomToParents'; +import { roomToChildrenAtom } from '../../../state/room/roomToChildren'; import { markAsRead } from '../../../../client/action/notifications'; import { useRoomsUnread } from '../../../state/hooks/unread'; import { UseStateProvider } from '../../../components/UseStateProvider'; @@ -293,6 +294,7 @@ export function Space() { const mDirects = useAtomValue(mDirectAtom); const roomToUnread = useAtomValue(roomToUnreadAtom); const roomToParents = useAtomValue(roomToParentsAtom); + const roomToChildren = useAtomValue(roomToChildrenAtom); const allRooms = useAtomValue(allRoomsAtom); const allJoinedRooms = useMemo(() => new Set(allRooms), [allRooms]); const notificationPreferences = useRoomsNotificationPreferencesContext(); @@ -352,20 +354,6 @@ export function Space() { [closedCategories, getRoom, roomToParents] ); - // There are better ways to do this - const roomToChildren = useMemo(() => { - const map = new Map>(); - - roomToParents.forEach((parentSet, childId) => { - parentSet.forEach((parentId) => { - if (!map.has(parentId)) map.set(parentId, new Set()); - map.get(parentId)?.add(childId); - }); - }); - - return map; - }, [roomToParents]); - /** * Recursively checks if the given room or any of its descendants should be visible. * @@ -445,7 +433,7 @@ export function Space() { const handleCategoryClick = useCategoryHandler(setClosedCategories, (categoryId) => { const collapsed = closedCategories.has(categoryId); - const [spaceId, roomId] = categoryId.split('|').slice(-2); + const [spaceId, roomId] = getNavCategoryIdParts(categoryId); // Only prevent collapsing if all parents are collapsed const toggleable = !getAllAncestorsCollapsed(spaceId, roomId); diff --git a/src/app/state/closedLobbyCategories.ts b/src/app/state/closedLobbyCategories.ts index 40ecd163..22bf2d76 100644 --- a/src/app/state/closedLobbyCategories.ts +++ b/src/app/state/closedLobbyCategories.ts @@ -66,3 +66,5 @@ export const makeClosedLobbyCategoriesAtom = (userId: string): ClosedLobbyCatego }; export const makeLobbyCategoryId = (...args: string[]): string => args.join('|'); + +export const getLobbyCategoryIdParts = (categoryId: string): string[] => categoryId.split('|'); diff --git a/src/app/state/closedNavCategories.ts b/src/app/state/closedNavCategories.ts index ea61cb2e..f2e39a27 100644 --- a/src/app/state/closedNavCategories.ts +++ b/src/app/state/closedNavCategories.ts @@ -66,3 +66,5 @@ export const makeClosedNavCategoriesAtom = (userId: string): ClosedNavCategories }; export const makeNavCategoryId = (...args: string[]): string => args.join('|'); + +export const getNavCategoryIdParts = (categoryId: string): string[] => categoryId.split('|'); diff --git a/src/app/state/room/roomToChildren.ts b/src/app/state/room/roomToChildren.ts new file mode 100644 index 00000000..ae0f4f24 --- /dev/null +++ b/src/app/state/room/roomToChildren.ts @@ -0,0 +1,16 @@ +import { atom } from 'jotai'; +import { roomToParentsAtom } from './roomToParents'; + +export const roomToChildrenAtom = atom((get) => { + const roomToParents = get(roomToParentsAtom); + const map = new Map>(); + + roomToParents.forEach((parentSet, childId) => { + parentSet.forEach((parentId) => { + if (!map.has(parentId)) map.set(parentId, new Set()); + map.get(parentId)?.add(childId); + }); + }); + + return map; +});