feat(sidebar): implement home visibility toggle with hide/unhide functionality
This commit is contained in:
@@ -18,6 +18,7 @@ export type InCinnySpacesContent = {
|
|||||||
shortcut?: string[];
|
shortcut?: string[];
|
||||||
sidebar?: SidebarItems;
|
sidebar?: SidebarItems;
|
||||||
hidden?: string[];
|
hidden?: string[];
|
||||||
|
hideHome?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const parseSidebar = (
|
export const parseSidebar = (
|
||||||
@@ -238,3 +239,67 @@ export const makeUnhideSpaceContent = (
|
|||||||
hidden: currentHidden.filter((id) => id !== spaceId),
|
hidden: currentHidden.filter((id) => id !== spaceId),
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create content for hiding home
|
||||||
|
*/
|
||||||
|
export const makeHideHomeContent = (mx: MatrixClient): InCinnySpacesContent => {
|
||||||
|
const currentContent =
|
||||||
|
getAccountData(mx, AccountDataEvent.CinnySpaces)?.getContent<InCinnySpacesContent>() ?? {};
|
||||||
|
|
||||||
|
return {
|
||||||
|
...currentContent,
|
||||||
|
hideHome: true,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create content for unhiding home
|
||||||
|
*/
|
||||||
|
export const makeUnhideHomeContent = (mx: MatrixClient): InCinnySpacesContent => {
|
||||||
|
const currentContent =
|
||||||
|
getAccountData(mx, AccountDataEvent.CinnySpaces)?.getContent<InCinnySpacesContent>() ?? {};
|
||||||
|
|
||||||
|
return {
|
||||||
|
...currentContent,
|
||||||
|
hideHome: false,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook to get and manage home hidden state
|
||||||
|
*/
|
||||||
|
export const useHomeHidden = (): [boolean, Dispatch<SetStateAction<boolean>>] => {
|
||||||
|
const mx = useMatrixClient();
|
||||||
|
|
||||||
|
const [homeHidden, setHomeHidden] = useState(() => {
|
||||||
|
const content = getAccountData(
|
||||||
|
mx,
|
||||||
|
AccountDataEvent.CinnySpaces
|
||||||
|
)?.getContent<InCinnySpacesContent>();
|
||||||
|
return content?.hideHome ?? false;
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const content = getAccountData(
|
||||||
|
mx,
|
||||||
|
AccountDataEvent.CinnySpaces
|
||||||
|
)?.getContent<InCinnySpacesContent>();
|
||||||
|
setHomeHidden(content?.hideHome ?? false);
|
||||||
|
}, [mx]);
|
||||||
|
|
||||||
|
useAccountDataCallback(
|
||||||
|
mx,
|
||||||
|
useCallback(
|
||||||
|
(mEvent) => {
|
||||||
|
if (mEvent.getType() === AccountDataEvent.CinnySpaces) {
|
||||||
|
const newContent = mEvent.getContent<InCinnySpacesContent>();
|
||||||
|
setHomeHidden(newContent?.hideHome ?? false);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[mx]
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return [homeHidden, setHomeHidden];
|
||||||
|
};
|
||||||
|
|||||||
@@ -19,9 +19,11 @@ import {
|
|||||||
} from './sidebar';
|
} from './sidebar';
|
||||||
import { CreateTab } from './sidebar/CreateTab';
|
import { CreateTab } from './sidebar/CreateTab';
|
||||||
import { HiddenSpacesTabs } from './sidebar/SpaceTabs';
|
import { HiddenSpacesTabs } from './sidebar/SpaceTabs';
|
||||||
|
import { useHomeHidden } from '../../hooks/useSidebarItems';
|
||||||
|
|
||||||
export function SidebarNav() {
|
export function SidebarNav() {
|
||||||
const scrollRef = useRef<HTMLDivElement>(null);
|
const scrollRef = useRef<HTMLDivElement>(null);
|
||||||
|
const [homeHidden] = useHomeHidden();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Sidebar>
|
<Sidebar>
|
||||||
@@ -29,7 +31,7 @@ export function SidebarNav() {
|
|||||||
scrollable={
|
scrollable={
|
||||||
<Scroll ref={scrollRef} variant="Background" size="0">
|
<Scroll ref={scrollRef} variant="Background" size="0">
|
||||||
<SidebarStack>
|
<SidebarStack>
|
||||||
<HomeTab />
|
{!homeHidden && <HomeTab />}
|
||||||
<DirectTab />
|
<DirectTab />
|
||||||
</SidebarStack>
|
</SidebarStack>
|
||||||
<SpaceTabs scrollRef={scrollRef} />
|
<SpaceTabs scrollRef={scrollRef} />
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import React, { MouseEventHandler, forwardRef, useState } from 'react';
|
import React, { MouseEventHandler, forwardRef, useState } from 'react';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { Box, Icon, Icons, Menu, MenuItem, PopOut, RectCords, Text, config, toRem } from 'folds';
|
import { Box, Icon, Icons, Line, Menu, MenuItem, PopOut, RectCords, Text, config, toRem } from 'folds';
|
||||||
import { useAtomValue } from 'jotai';
|
import { useAtomValue } from 'jotai';
|
||||||
import FocusTrap from 'focus-trap-react';
|
import FocusTrap from 'focus-trap-react';
|
||||||
import { useOrphanRooms } from '../../../state/hooks/roomList';
|
import { useOrphanRooms } from '../../../state/hooks/roomList';
|
||||||
@@ -26,11 +26,15 @@ import { markAsRead } from '../../../utils/notifications';
|
|||||||
import { stopPropagation } from '../../../utils/keyboard';
|
import { stopPropagation } from '../../../utils/keyboard';
|
||||||
import { useSetting } from '../../../state/hooks/settings';
|
import { useSetting } from '../../../state/hooks/settings';
|
||||||
import { settingsAtom } from '../../../state/settings';
|
import { settingsAtom } from '../../../state/settings';
|
||||||
|
import { makeHideHomeContent, parseHiddenSpaces, parseSidebar, useHiddenSpaces, useSidebarItems } from '../../../hooks/useSidebarItems';
|
||||||
|
import { AccountDataEvent } from '../../../../types/matrix/accountData';
|
||||||
|
import { useOrphanSpaces } from '../../../state/hooks/roomList';
|
||||||
|
|
||||||
type HomeMenuProps = {
|
type HomeMenuProps = {
|
||||||
requestClose: () => void;
|
requestClose: () => void;
|
||||||
|
onHide?: () => void;
|
||||||
};
|
};
|
||||||
const HomeMenu = forwardRef<HTMLDivElement, HomeMenuProps>(({ requestClose }, ref) => {
|
const HomeMenu = forwardRef<HTMLDivElement, HomeMenuProps>(({ requestClose, onHide }, ref) => {
|
||||||
const orphanRooms = useHomeRooms();
|
const orphanRooms = useHomeRooms();
|
||||||
const [hideActivity] = useSetting(settingsAtom, 'hideActivity');
|
const [hideActivity] = useSetting(settingsAtom, 'hideActivity');
|
||||||
const unread = useRoomsUnread(orphanRooms, roomToUnreadAtom);
|
const unread = useRoomsUnread(orphanRooms, roomToUnreadAtom);
|
||||||
@@ -42,6 +46,11 @@ const HomeMenu = forwardRef<HTMLDivElement, HomeMenuProps>(({ requestClose }, re
|
|||||||
requestClose();
|
requestClose();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleHide = () => {
|
||||||
|
onHide?.();
|
||||||
|
requestClose();
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Menu ref={ref} style={{ maxWidth: toRem(160), width: '100vw' }}>
|
<Menu ref={ref} style={{ maxWidth: toRem(160), width: '100vw' }}>
|
||||||
<Box direction="Column" gap="100" style={{ padding: config.space.S100 }}>
|
<Box direction="Column" gap="100" style={{ padding: config.space.S100 }}>
|
||||||
@@ -56,6 +65,18 @@ const HomeMenu = forwardRef<HTMLDivElement, HomeMenuProps>(({ requestClose }, re
|
|||||||
Mark as Read
|
Mark as Read
|
||||||
</Text>
|
</Text>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
{onHide && (
|
||||||
|
<MenuItem
|
||||||
|
size="300"
|
||||||
|
radii="300"
|
||||||
|
onClick={handleHide}
|
||||||
|
after={<Icon size="100" src={Icons.EyeBlind} />}
|
||||||
|
>
|
||||||
|
<Text style={{ flexGrow: 1 }} as="span" size="T300" truncate>
|
||||||
|
Hide Home
|
||||||
|
</Text>
|
||||||
|
</MenuItem>
|
||||||
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
</Menu>
|
</Menu>
|
||||||
);
|
);
|
||||||
@@ -70,9 +91,12 @@ export function HomeTab() {
|
|||||||
const mDirects = useAtomValue(mDirectAtom);
|
const mDirects = useAtomValue(mDirectAtom);
|
||||||
const roomToParents = useAtomValue(roomToParentsAtom);
|
const roomToParents = useAtomValue(roomToParentsAtom);
|
||||||
const orphanRooms = useOrphanRooms(mx, allRoomsAtom, mDirects, roomToParents);
|
const orphanRooms = useOrphanRooms(mx, allRoomsAtom, mDirects, roomToParents);
|
||||||
|
const orphanSpaces = useOrphanSpaces(mx, allRoomsAtom, roomToParents);
|
||||||
const homeUnread = useRoomsUnread(orphanRooms, roomToUnreadAtom);
|
const homeUnread = useRoomsUnread(orphanRooms, roomToUnreadAtom);
|
||||||
const homeSelected = useHomeSelected();
|
const homeSelected = useHomeSelected();
|
||||||
const [menuAnchor, setMenuAnchor] = useState<RectCords>();
|
const [menuAnchor, setMenuAnchor] = useState<RectCords>();
|
||||||
|
const [, localEchoSidebarItem] = useSidebarItems(orphanSpaces);
|
||||||
|
const [, localEchoHiddenSpaces] = useHiddenSpaces();
|
||||||
|
|
||||||
const handleHomeClick = () => {
|
const handleHomeClick = () => {
|
||||||
const activePath = navToActivePath.get('home');
|
const activePath = navToActivePath.get('home');
|
||||||
@@ -93,6 +117,13 @@ export function HomeTab() {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleHide = () => {
|
||||||
|
const newContent = makeHideHomeContent(mx);
|
||||||
|
localEchoSidebarItem(parseSidebar(mx, orphanSpaces, newContent));
|
||||||
|
localEchoHiddenSpaces(parseHiddenSpaces(mx, newContent));
|
||||||
|
mx.setAccountData(AccountDataEvent.CinnySpaces, newContent);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SidebarItem active={homeSelected}>
|
<SidebarItem active={homeSelected}>
|
||||||
<SidebarItemTooltip tooltip="Home">
|
<SidebarItemTooltip tooltip="Home">
|
||||||
@@ -130,7 +161,7 @@ export function HomeTab() {
|
|||||||
escapeDeactivates: stopPropagation,
|
escapeDeactivates: stopPropagation,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<HomeMenu requestClose={() => setMenuAnchor(undefined)} />
|
<HomeMenu requestClose={() => setMenuAnchor(undefined)} onHide={handleHide} />
|
||||||
</FocusTrap>
|
</FocusTrap>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -40,14 +40,16 @@ import { autoScrollForElements } from '@atlaskit/pragmatic-drag-and-drop-auto-sc
|
|||||||
import { combine } from '@atlaskit/pragmatic-drag-and-drop/combine';
|
import { combine } from '@atlaskit/pragmatic-drag-and-drop/combine';
|
||||||
import FocusTrap from 'focus-trap-react';
|
import FocusTrap from 'focus-trap-react';
|
||||||
import {
|
import {
|
||||||
|
useOrphanRooms,
|
||||||
useOrphanSpaces,
|
useOrphanSpaces,
|
||||||
useRecursiveChildScopeFactory,
|
useRecursiveChildScopeFactory,
|
||||||
useSpaceChildren,
|
useSpaceChildren,
|
||||||
} from '../../../state/hooks/roomList';
|
} from '../../../state/hooks/roomList';
|
||||||
import { useMatrixClient } from '../../../hooks/useMatrixClient';
|
import { useMatrixClient } from '../../../hooks/useMatrixClient';
|
||||||
|
import { mDirectAtom } from '../../../state/mDirectList';
|
||||||
import { roomToParentsAtom } from '../../../state/room/roomToParents';
|
import { roomToParentsAtom } from '../../../state/room/roomToParents';
|
||||||
import { allRoomsAtom } from '../../../state/room-list/roomList';
|
import { allRoomsAtom } from '../../../state/room-list/roomList';
|
||||||
import { getSpaceLobbyPath, getSpacePath, joinPathComponent } from '../../pathUtils';
|
import { getHomePath, getSpaceLobbyPath, getSpacePath, joinPathComponent } from '../../pathUtils';
|
||||||
import {
|
import {
|
||||||
SidebarAvatar,
|
SidebarAvatar,
|
||||||
SidebarItem,
|
SidebarItem,
|
||||||
@@ -60,6 +62,7 @@ import {
|
|||||||
} from '../../../components/sidebar';
|
} from '../../../components/sidebar';
|
||||||
import { RoomUnreadProvider, RoomsUnreadProvider } from '../../../components/RoomUnreadProvider';
|
import { RoomUnreadProvider, RoomsUnreadProvider } from '../../../components/RoomUnreadProvider';
|
||||||
import { useSelectedSpace } from '../../../hooks/router/useSelectedSpace';
|
import { useSelectedSpace } from '../../../hooks/router/useSelectedSpace';
|
||||||
|
import { useHomeSelected } from '../../../hooks/router/useHomeSelected';
|
||||||
import { UnreadBadge } from '../../../components/unread-badge';
|
import { UnreadBadge } from '../../../components/unread-badge';
|
||||||
import { getCanonicalAliasOrRoomId, isRoomAlias } from '../../../utils/matrix';
|
import { getCanonicalAliasOrRoomId, isRoomAlias } from '../../../utils/matrix';
|
||||||
import { RoomAvatar } from '../../../components/room-avatar';
|
import { RoomAvatar } from '../../../components/room-avatar';
|
||||||
@@ -69,12 +72,15 @@ import {
|
|||||||
SidebarItems,
|
SidebarItems,
|
||||||
TSidebarItem,
|
TSidebarItem,
|
||||||
makeCinnySpacesContent,
|
makeCinnySpacesContent,
|
||||||
|
makeHideHomeContent,
|
||||||
makeHideSpaceContent,
|
makeHideSpaceContent,
|
||||||
|
makeUnhideHomeContent,
|
||||||
makeUnhideSpaceContent,
|
makeUnhideSpaceContent,
|
||||||
parseHiddenSpaces,
|
parseHiddenSpaces,
|
||||||
parseSidebar,
|
parseSidebar,
|
||||||
sidebarItemWithout,
|
sidebarItemWithout,
|
||||||
useHiddenSpaces,
|
useHiddenSpaces,
|
||||||
|
useHomeHidden,
|
||||||
useSidebarItems,
|
useSidebarItems,
|
||||||
} from '../../../hooks/useSidebarItems';
|
} from '../../../hooks/useSidebarItems';
|
||||||
import { AccountDataEvent } from '../../../../types/matrix/accountData';
|
import { AccountDataEvent } from '../../../../types/matrix/accountData';
|
||||||
@@ -670,10 +676,13 @@ function ClosedSpaceFolder({
|
|||||||
|
|
||||||
type HiddenSpacesFolderProps = {
|
type HiddenSpacesFolderProps = {
|
||||||
hiddenSpaces: string[];
|
hiddenSpaces: string[];
|
||||||
|
homeHidden?: boolean;
|
||||||
open: boolean;
|
open: boolean;
|
||||||
onToggle: () => void;
|
onToggle: () => void;
|
||||||
onSpaceClick: MouseEventHandler<HTMLButtonElement>;
|
onSpaceClick: MouseEventHandler<HTMLButtonElement>;
|
||||||
|
onHomeClick?: MouseEventHandler<HTMLButtonElement>;
|
||||||
onUnhide: (roomId: string) => void;
|
onUnhide: (roomId: string) => void;
|
||||||
|
onUnhideHome?: () => void;
|
||||||
selectedSpaceId?: string;
|
selectedSpaceId?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -682,21 +691,42 @@ type HiddenSpacesFolderProps = {
|
|||||||
*/
|
*/
|
||||||
function HiddenSpacesFolder({
|
function HiddenSpacesFolder({
|
||||||
hiddenSpaces,
|
hiddenSpaces,
|
||||||
|
homeHidden,
|
||||||
open,
|
open,
|
||||||
onToggle,
|
onToggle,
|
||||||
onSpaceClick,
|
onSpaceClick,
|
||||||
|
onHomeClick,
|
||||||
onUnhide,
|
onUnhide,
|
||||||
|
onUnhideHome,
|
||||||
selectedSpaceId,
|
selectedSpaceId,
|
||||||
}: HiddenSpacesFolderProps) {
|
}: HiddenSpacesFolderProps) {
|
||||||
const mx = useMatrixClient();
|
const mx = useMatrixClient();
|
||||||
const useAuthentication = useMediaAuthentication();
|
const useAuthentication = useMediaAuthentication();
|
||||||
|
const homeSelected = useHomeSelected();
|
||||||
const [menuAnchor, setMenuAnchor] = useState<RectCords>();
|
const [menuAnchor, setMenuAnchor] = useState<RectCords>();
|
||||||
const [menuSpaceId, setMenuSpaceId] = useState<string>();
|
const [menuSpaceId, setMenuSpaceId] = useState<string>();
|
||||||
|
const [menuIsHome, setMenuIsHome] = useState(false);
|
||||||
|
|
||||||
|
const mDirects = useAtomValue(mDirectAtom);
|
||||||
|
const roomToParents = useAtomValue(roomToParentsAtom);
|
||||||
|
const orphanRooms = useOrphanRooms(mx, allRoomsAtom, mDirects, roomToParents);
|
||||||
|
const homeUnread = useRoomsUnread(orphanRooms, roomToUnreadAtom);
|
||||||
|
|
||||||
const handleContextMenu = (spaceId: string): MouseEventHandler<HTMLButtonElement> => (evt) => {
|
const handleContextMenu = (spaceId: string): MouseEventHandler<HTMLButtonElement> => (evt) => {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
const cords = evt.currentTarget.getBoundingClientRect();
|
const cords = evt.currentTarget.getBoundingClientRect();
|
||||||
setMenuSpaceId(spaceId);
|
setMenuSpaceId(spaceId);
|
||||||
|
setMenuIsHome(false);
|
||||||
|
setMenuAnchor((currentState) => {
|
||||||
|
if (currentState) return undefined;
|
||||||
|
return cords;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleHomeContextMenu: MouseEventHandler<HTMLButtonElement> = (evt) => {
|
||||||
|
evt.preventDefault();
|
||||||
|
const cords = evt.currentTarget.getBoundingClientRect();
|
||||||
|
setMenuIsHome(true);
|
||||||
setMenuAnchor((currentState) => {
|
setMenuAnchor((currentState) => {
|
||||||
if (currentState) return undefined;
|
if (currentState) return undefined;
|
||||||
return cords;
|
return cords;
|
||||||
@@ -704,7 +734,9 @@ function HiddenSpacesFolder({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleUnhideClick = () => {
|
const handleUnhideClick = () => {
|
||||||
if (menuSpaceId) {
|
if (menuIsHome) {
|
||||||
|
onUnhideHome?.();
|
||||||
|
} else if (menuSpaceId) {
|
||||||
onUnhide(menuSpaceId);
|
onUnhide(menuSpaceId);
|
||||||
}
|
}
|
||||||
setMenuAnchor(undefined);
|
setMenuAnchor(undefined);
|
||||||
@@ -719,14 +751,31 @@ function HiddenSpacesFolder({
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!open) {
|
if (!open) {
|
||||||
// Only show when hovered, has unreads, or a hidden space is selected
|
// Only show when hovered, has unreads (from spaces or home), or a hidden space/home is selected
|
||||||
const isVisible = hovered || hasUnreads || (!!selectedSpaceId && hiddenSpaces.includes(selectedSpaceId));
|
const isVisible =
|
||||||
|
hovered ||
|
||||||
|
hasUnreads ||
|
||||||
|
(homeHidden && !!homeUnread) ||
|
||||||
|
(!!selectedSpaceId && hiddenSpaces.includes(selectedSpaceId)) ||
|
||||||
|
(homeHidden && homeSelected);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RoomsUnreadProvider rooms={hiddenSpaces}>
|
<RoomsUnreadProvider rooms={hiddenSpaces}>
|
||||||
{(unread) => (
|
{(unread) => {
|
||||||
|
// Combine space unreads with home unreads if home is hidden
|
||||||
|
const totalUnread = homeHidden && homeUnread
|
||||||
|
? {
|
||||||
|
total: (unread?.total ?? 0) + homeUnread.total,
|
||||||
|
highlight: (unread?.highlight ?? 0) + homeUnread.highlight,
|
||||||
|
}
|
||||||
|
: unread;
|
||||||
|
|
||||||
|
return (
|
||||||
<SidebarItem
|
<SidebarItem
|
||||||
active={!!selectedSpaceId && hiddenSpaces.includes(selectedSpaceId)}
|
active={
|
||||||
|
(!!selectedSpaceId && hiddenSpaces.includes(selectedSpaceId)) ||
|
||||||
|
(homeHidden && homeSelected)
|
||||||
|
}
|
||||||
onMouseEnter={() => setHovered(true)}
|
onMouseEnter={() => setHovered(true)}
|
||||||
onMouseLeave={() => setHovered(false)}
|
onMouseLeave={() => setHovered(false)}
|
||||||
style={{
|
style={{
|
||||||
@@ -741,13 +790,14 @@ function HiddenSpacesFolder({
|
|||||||
</SidebarAvatar>
|
</SidebarAvatar>
|
||||||
)}
|
)}
|
||||||
</SidebarItemTooltip>
|
</SidebarItemTooltip>
|
||||||
{unread && (
|
{totalUnread && (
|
||||||
<SidebarItemBadge hasCount={unread.total > 0}>
|
<SidebarItemBadge hasCount={totalUnread.total > 0}>
|
||||||
<UnreadBadge highlight={unread.highlight > 0} count={unread.total} />
|
<UnreadBadge highlight={totalUnread.highlight > 0} count={totalUnread.total} />
|
||||||
</SidebarItemBadge>
|
</SidebarItemBadge>
|
||||||
)}
|
)}
|
||||||
</SidebarItem>
|
</SidebarItem>
|
||||||
)}
|
);
|
||||||
|
}}
|
||||||
</RoomsUnreadProvider>
|
</RoomsUnreadProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -759,6 +809,29 @@ function HiddenSpacesFolder({
|
|||||||
<Icon size="400" src={Icons.ChevronTop} filled />
|
<Icon size="400" src={Icons.ChevronTop} filled />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</SidebarAvatar>
|
</SidebarAvatar>
|
||||||
|
{homeHidden && (
|
||||||
|
<SidebarItem active={homeSelected} data-inside-folder>
|
||||||
|
<SidebarItemTooltip tooltip="Home">
|
||||||
|
{(triggerRef) => (
|
||||||
|
<SidebarAvatar
|
||||||
|
as="button"
|
||||||
|
ref={triggerRef}
|
||||||
|
size="300"
|
||||||
|
outlined
|
||||||
|
onClick={onHomeClick}
|
||||||
|
onContextMenu={handleHomeContextMenu}
|
||||||
|
>
|
||||||
|
<Icon src={Icons.Home} filled={homeSelected} />
|
||||||
|
</SidebarAvatar>
|
||||||
|
)}
|
||||||
|
</SidebarItemTooltip>
|
||||||
|
{homeUnread && (
|
||||||
|
<SidebarItemBadge hasCount={homeUnread.total > 0}>
|
||||||
|
<UnreadBadge highlight={homeUnread.highlight > 0} count={homeUnread.total} />
|
||||||
|
</SidebarItemBadge>
|
||||||
|
)}
|
||||||
|
</SidebarItem>
|
||||||
|
)}
|
||||||
{hiddenSpaces.map((spaceId) => {
|
{hiddenSpaces.map((spaceId) => {
|
||||||
const space = mx.getRoom(spaceId);
|
const space = mx.getRoom(spaceId);
|
||||||
if (!space) return null;
|
if (!space) return null;
|
||||||
@@ -825,7 +898,7 @@ function HiddenSpacesFolder({
|
|||||||
after={<Icon size="100" src={Icons.Eye} />}
|
after={<Icon size="100" src={Icons.Eye} />}
|
||||||
>
|
>
|
||||||
<Text style={{ flexGrow: 1 }} as="span" size="T300" truncate>
|
<Text style={{ flexGrow: 1 }} as="span" size="T300" truncate>
|
||||||
Unhide Space
|
{menuIsHome ? 'Unhide Home' : 'Unhide Space'}
|
||||||
</Text>
|
</Text>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
</Box>
|
</Box>
|
||||||
@@ -1121,6 +1194,7 @@ export function HiddenSpacesTabs() {
|
|||||||
const navToActivePath = useAtomValue(useNavToActivePathAtom());
|
const navToActivePath = useAtomValue(useNavToActivePathAtom());
|
||||||
const orphanSpaces = useOrphanSpaces(mx, allRoomsAtom, useAtomValue(roomToParentsAtom));
|
const orphanSpaces = useOrphanSpaces(mx, allRoomsAtom, useAtomValue(roomToParentsAtom));
|
||||||
const [hiddenSpaces, localEchoHiddenSpaces] = useHiddenSpaces();
|
const [hiddenSpaces, localEchoHiddenSpaces] = useHiddenSpaces();
|
||||||
|
const [homeHidden, localEchoHomeHidden] = useHomeHidden();
|
||||||
const [, localEchoSidebarItem] = useSidebarItems(orphanSpaces);
|
const [, localEchoSidebarItem] = useSidebarItems(orphanSpaces);
|
||||||
const [hiddenFolderOpen, setHiddenFolderOpen] = useState(false);
|
const [hiddenFolderOpen, setHiddenFolderOpen] = useState(false);
|
||||||
|
|
||||||
@@ -1146,6 +1220,16 @@ export function HiddenSpacesTabs() {
|
|||||||
navigate(getSpaceLobbyPath(getCanonicalAliasOrRoomId(mx, targetSpaceId)));
|
navigate(getSpaceLobbyPath(getCanonicalAliasOrRoomId(mx, targetSpaceId)));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleHomeClick = () => {
|
||||||
|
const activePath = navToActivePath.get('home');
|
||||||
|
if (activePath && screenSize !== ScreenSize.Mobile) {
|
||||||
|
navigate(joinPathComponent(activePath));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
navigate(getHomePath());
|
||||||
|
};
|
||||||
|
|
||||||
const handleUnhide = useCallback(
|
const handleUnhide = useCallback(
|
||||||
(roomId: string) => {
|
(roomId: string) => {
|
||||||
const newContent = makeUnhideSpaceContent(mx, roomId);
|
const newContent = makeUnhideSpaceContent(mx, roomId);
|
||||||
@@ -1156,7 +1240,15 @@ export function HiddenSpacesTabs() {
|
|||||||
[mx, orphanSpaces, localEchoSidebarItem, localEchoHiddenSpaces]
|
[mx, orphanSpaces, localEchoSidebarItem, localEchoHiddenSpaces]
|
||||||
);
|
);
|
||||||
|
|
||||||
if (hiddenSpaces.length === 0) return null;
|
const handleUnhideHome = useCallback(() => {
|
||||||
|
const newContent = makeUnhideHomeContent(mx);
|
||||||
|
localEchoHomeHidden(false);
|
||||||
|
localEchoSidebarItem(parseSidebar(mx, orphanSpaces, newContent));
|
||||||
|
localEchoHiddenSpaces(parseHiddenSpaces(mx, newContent));
|
||||||
|
mx.setAccountData(AccountDataEvent.CinnySpaces, newContent);
|
||||||
|
}, [mx, orphanSpaces, localEchoHomeHidden, localEchoSidebarItem, localEchoHiddenSpaces]);
|
||||||
|
|
||||||
|
if (hiddenSpaces.length === 0 && !homeHidden) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -1164,10 +1256,13 @@ export function HiddenSpacesTabs() {
|
|||||||
<SidebarStack>
|
<SidebarStack>
|
||||||
<HiddenSpacesFolder
|
<HiddenSpacesFolder
|
||||||
hiddenSpaces={hiddenSpaces}
|
hiddenSpaces={hiddenSpaces}
|
||||||
|
homeHidden={homeHidden}
|
||||||
open={hiddenFolderOpen}
|
open={hiddenFolderOpen}
|
||||||
onToggle={() => setHiddenFolderOpen(!hiddenFolderOpen)}
|
onToggle={() => setHiddenFolderOpen(!hiddenFolderOpen)}
|
||||||
onSpaceClick={handleSpaceClick}
|
onSpaceClick={handleSpaceClick}
|
||||||
|
onHomeClick={handleHomeClick}
|
||||||
onUnhide={handleUnhide}
|
onUnhide={handleUnhide}
|
||||||
|
onUnhideHome={handleUnhideHome}
|
||||||
selectedSpaceId={selectedSpaceId}
|
selectedSpaceId={selectedSpaceId}
|
||||||
/>
|
/>
|
||||||
</SidebarStack>
|
</SidebarStack>
|
||||||
|
|||||||
Reference in New Issue
Block a user