diff --git a/src/app/features/lobby/Lobby.tsx b/src/app/features/lobby/Lobby.tsx index b01a0c78..7aa20ab3 100644 --- a/src/app/features/lobby/Lobby.tsx +++ b/src/app/features/lobby/Lobby.tsx @@ -233,6 +233,10 @@ export function Lobby() { categoryId={categoryId} closed={closedCategories.has(categoryId) || !!draggingItem?.space} handleClose={handleCategoryClick} + getRoom={getRoom} + canEditChild={canEditSpaceChild( + roomsPowerLevels.get(item.roomId) ?? {} + )} canReorder={ parentPowerLevels ? canEditSpaceChild(parentPowerLevels) : false } @@ -276,6 +280,7 @@ export function Lobby() { firstChild={!prevItem || prevItem.space === true} lastChild={!nextItem || nextItem.space === true} onOpen={handleOpenRoom} + getRoom={getRoom} canReorder={canEditSpaceChild(parentPowerLevels)} options={ canEditSpaceChild(parentPowerLevels) ? ( diff --git a/src/app/features/lobby/RoomItem.tsx b/src/app/features/lobby/RoomItem.tsx index ab85949c..9e0ea804 100644 --- a/src/app/features/lobby/RoomItem.tsx +++ b/src/app/features/lobby/RoomItem.tsx @@ -307,6 +307,7 @@ type RoomItemCardProps = { after?: ReactNode; onDragging: (item?: HierarchyItem) => void; canReorder: boolean; + getRoom: (roomId: string) => Room | undefined; }; export const RoomItemCard = as<'div', RoomItemCardProps>( ( @@ -322,13 +323,14 @@ export const RoomItemCard = as<'div', RoomItemCardProps>( after, onDragging, canReorder, + getRoom, ...props }, ref ) => { const mx = useMatrixClient(); const { roomId, content } = item; - const room = mx.getRoom(roomId); + const room = getRoom(roomId); const targetRef = useRef(null); const targetHandleRef = useRef(null); useDraggableItem(item, targetRef, onDragging, targetHandleRef); diff --git a/src/app/features/lobby/SpaceItem.tsx b/src/app/features/lobby/SpaceItem.tsx index 6eb17d95..d8f9773e 100644 --- a/src/app/features/lobby/SpaceItem.tsx +++ b/src/app/features/lobby/SpaceItem.tsx @@ -1,5 +1,22 @@ -import React, { MouseEventHandler, ReactNode, useCallback, useRef } from 'react'; -import { Box, Avatar, Text, Chip, Icon, Icons, as, Badge, toRem, Spinner } from 'folds'; +import React, { MouseEventHandler, ReactNode, useCallback, useRef, useState } from 'react'; +import { + Box, + Avatar, + Text, + Chip, + Icon, + Icons, + as, + Badge, + toRem, + Spinner, + PopOut, + Menu, + MenuItem, + RectCords, + config, +} from 'folds'; +import FocusTrap from 'focus-trap-react'; import classNames from 'classnames'; import { MatrixError, Room } from 'matrix-js-sdk'; import { HierarchyItem } from '../../hooks/useSpaceHierarchy'; @@ -16,6 +33,7 @@ import * as css from './SpaceItem.css'; import * as styleCss from './style.css'; import { ErrorCode } from '../../cs-errorcode'; import { useDraggableItem } from './DnD'; +import { openCreateRoom, openSpaceAddExisting } from '../../../client/action/navigation'; function SpaceProfileLoading() { return ( @@ -222,6 +240,81 @@ function RootSpaceProfile({ closed, categoryId, handleClose }: RootSpaceProfileP ); } +function AddRoomButton({ item }: { item: HierarchyItem }) { + const [cords, setCords] = useState(); + + const handleAddRoom: MouseEventHandler = (evt) => { + setCords(evt.currentTarget.getBoundingClientRect()); + }; + + const handleCreateRoom = () => { + openCreateRoom(false, item.roomId as any); + setCords(undefined); + }; + + const handleAddExisting = () => { + openSpaceAddExisting(item.roomId); + setCords(undefined); + }; + + return ( + setCords(undefined), + clickOutsideDeactivates: true, + isKeyForward: (evt: KeyboardEvent) => evt.key === 'ArrowDown', + isKeyBackward: (evt: KeyboardEvent) => evt.key === 'ArrowUp', + }} + > + + + New Room + + + Existing Room + + + + } + > + } + onClick={handleAddRoom} + aria-pressed={!!cords} + > + Add Room + + + ); +} + +function AddSpaceButton({ item }: { item: HierarchyItem }) { + return ( + } + onClick={() => openCreateRoom(true, item.roomId as any)} + > + Add Space + + ); +} + type SpaceItemCardProps = { item: HierarchyItem; joined?: boolean; @@ -231,8 +324,10 @@ type SpaceItemCardProps = { options?: ReactNode; before?: ReactNode; after?: ReactNode; + canEditChild: boolean; canReorder: boolean; onDragging: (item?: HierarchyItem) => void; + getRoom: (roomId: string) => Room | undefined; }; export const SpaceItemCard = as<'div', SpaceItemCardProps>( ( @@ -246,27 +341,31 @@ export const SpaceItemCard = as<'div', SpaceItemCardProps>( options, before, after, + canEditChild, canReorder, onDragging, + getRoom, ...props }, ref ) => { const mx = useMatrixClient(); const { roomId, content } = item; - const space = mx.getRoom(roomId); + const space = getRoom(roomId); const targetRef = useRef(null); useDraggableItem(item, targetRef, onDragging); return ( {before} - + {space ? ( @@ -323,6 +422,12 @@ export const SpaceItemCard = as<'div', SpaceItemCardProps>( )} + {canEditChild && ( + + + {item.parentId === undefined && } + + )} {options} {after} diff --git a/src/app/pages/client/ClientNavigation.tsx b/src/app/pages/client/ClientNavigation.tsx index 9b375faa..e3dcd9d4 100644 --- a/src/app/pages/client/ClientNavigation.tsx +++ b/src/app/pages/client/ClientNavigation.tsx @@ -9,7 +9,7 @@ import { SidebarAvatar, } from '../../components/sidebar'; import { DirectTab, HomeTab, SpaceTabs, InboxTab, ExploreTab } from './sidebar'; -import { openSearch, openSettings } from '../../../client/action/navigation'; +import { openCreateRoom, openSearch, openSettings } from '../../../client/action/navigation'; export function ClientNavigation() { return ( @@ -29,6 +29,7 @@ export function ClientNavigation() { outlined tooltip="Create Space" avatarChildren={} + onClick={() => openCreateRoom(true)} />