Merge branch 'develop' into sort-imports
Signed-off-by: Aaron Raimist <aaron@raim.ist>
This commit is contained in:
commit
7b94e13a84
642 changed files with 30052 additions and 8035 deletions
154
src/components/views/spaces/QuickSettingsButton.tsx
Normal file
154
src/components/views/spaces/QuickSettingsButton.tsx
Normal file
|
@ -0,0 +1,154 @@
|
|||
/*
|
||||
Copyright 2021 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { useMemo } from "react";
|
||||
|
||||
import { _t } from "../../../languageHandler";
|
||||
import AccessibleTooltipButton from "../elements/AccessibleTooltipButton";
|
||||
import ContextMenu, { alwaysAboveRightOf, ChevronFace, useContextMenu } from "../../structures/ContextMenu";
|
||||
import AccessibleButton from "../elements/AccessibleButton";
|
||||
import StyledCheckbox from "../elements/StyledCheckbox";
|
||||
import { MetaSpace } from "../../../stores/spaces";
|
||||
import { useSettingValue } from "../../../hooks/useSettings";
|
||||
import { onMetaSpaceChangeFactory } from "../settings/tabs/user/SidebarUserSettingsTab";
|
||||
import defaultDispatcher from "../../../dispatcher/dispatcher";
|
||||
import { Action } from "../../../dispatcher/actions";
|
||||
import { UserTab } from "../dialogs/UserSettingsDialog";
|
||||
import { findNonHighContrastTheme, getOrderedThemes } from "../../../theme";
|
||||
import Dropdown from "../elements/Dropdown";
|
||||
import ThemeChoicePanel from "../settings/ThemeChoicePanel";
|
||||
import SettingsStore from "../../../settings/SettingsStore";
|
||||
import { SettingLevel } from "../../../settings/SettingLevel";
|
||||
import dis from "../../../dispatcher/dispatcher";
|
||||
import { RecheckThemePayload } from "../../../dispatcher/payloads/RecheckThemePayload";
|
||||
import classNames from "classnames";
|
||||
|
||||
const QuickSettingsButton = ({ isPanelCollapsed = false }) => {
|
||||
const orderedThemes = useMemo(getOrderedThemes, []);
|
||||
const [menuDisplayed, handle, openMenu, closeMenu] = useContextMenu<HTMLDivElement>();
|
||||
|
||||
const {
|
||||
[MetaSpace.Favourites]: favouritesEnabled,
|
||||
[MetaSpace.People]: peopleEnabled,
|
||||
} = useSettingValue<Record<MetaSpace, boolean>>("Spaces.enabledMetaSpaces");
|
||||
|
||||
let contextMenu: JSX.Element;
|
||||
if (menuDisplayed) {
|
||||
const themeState = ThemeChoicePanel.calculateThemeState();
|
||||
const nonHighContrast = findNonHighContrastTheme(themeState.theme);
|
||||
const theme = nonHighContrast ? nonHighContrast : themeState.theme;
|
||||
|
||||
contextMenu = <ContextMenu
|
||||
{...alwaysAboveRightOf(handle.current.getBoundingClientRect(), ChevronFace.None, 16)}
|
||||
wrapperClassName="mx_QuickSettingsButton_ContextMenuWrapper"
|
||||
onFinished={closeMenu}
|
||||
managed={false}
|
||||
focusLock={true}
|
||||
>
|
||||
<h2>{ _t("Quick settings") }</h2>
|
||||
|
||||
<AccessibleButton
|
||||
onClick={() => {
|
||||
closeMenu();
|
||||
defaultDispatcher.dispatch({
|
||||
action: Action.ViewUserSettings,
|
||||
initialTabId: UserTab.Sidebar,
|
||||
});
|
||||
}}
|
||||
kind="primary_outline"
|
||||
>
|
||||
{ _t("All settings") }
|
||||
</AccessibleButton>
|
||||
|
||||
<h4 className="mx_QuickSettingsButton_pinToSidebarHeading">{ _t("Pin to sidebar") }</h4>
|
||||
|
||||
<StyledCheckbox
|
||||
className="mx_QuickSettingsButton_favouritesCheckbox"
|
||||
checked={!!favouritesEnabled}
|
||||
onChange={onMetaSpaceChangeFactory(MetaSpace.Favourites)}
|
||||
>
|
||||
{ _t("Favourites") }
|
||||
</StyledCheckbox>
|
||||
<StyledCheckbox
|
||||
className="mx_QuickSettingsButton_peopleCheckbox"
|
||||
checked={!!peopleEnabled}
|
||||
onChange={onMetaSpaceChangeFactory(MetaSpace.People)}
|
||||
>
|
||||
{ _t("People") }
|
||||
</StyledCheckbox>
|
||||
<AccessibleButton
|
||||
className="mx_QuickSettingsButton_moreOptionsButton"
|
||||
onClick={() => {
|
||||
closeMenu();
|
||||
defaultDispatcher.dispatch({
|
||||
action: Action.ViewUserSettings,
|
||||
initialTabId: UserTab.Sidebar,
|
||||
});
|
||||
}}
|
||||
>
|
||||
{ _t("More options") }
|
||||
</AccessibleButton>
|
||||
|
||||
<div className="mx_QuickSettingsButton_themePicker">
|
||||
<h4>{ _t("Theme") }</h4>
|
||||
<Dropdown
|
||||
id="mx_QuickSettingsButton_themePickerDropdown"
|
||||
onOptionChange={async (newTheme: string) => {
|
||||
// XXX: mostly copied from ThemeChoicePanel
|
||||
// doing getValue in the .catch will still return the value we failed to set,
|
||||
// so remember what the value was before we tried to set it so we can revert
|
||||
// const oldTheme: string = SettingsStore.getValue("theme");
|
||||
SettingsStore.setValue("theme", null, SettingLevel.DEVICE, newTheme).catch(() => {
|
||||
dis.dispatch<RecheckThemePayload>({ action: Action.RecheckTheme });
|
||||
});
|
||||
// The settings watcher doesn't fire until the echo comes back from the
|
||||
// server, so to make the theme change immediately we need to manually
|
||||
// do the dispatch now
|
||||
// XXX: The local echoed value appears to be unreliable, in particular
|
||||
// when settings custom themes(!) so adding forceTheme to override
|
||||
// the value from settings.
|
||||
dis.dispatch<RecheckThemePayload>({ action: Action.RecheckTheme, forceTheme: newTheme });
|
||||
closeMenu();
|
||||
}}
|
||||
value={theme}
|
||||
label={_t("Space selection")}
|
||||
>
|
||||
{ orderedThemes.map((theme) => (
|
||||
<div key={theme.id}>
|
||||
{ theme.name }
|
||||
</div>
|
||||
)) }
|
||||
</Dropdown>
|
||||
</div>
|
||||
</ContextMenu>;
|
||||
}
|
||||
|
||||
return <>
|
||||
<AccessibleTooltipButton
|
||||
className={classNames("mx_QuickSettingsButton", { expanded: !isPanelCollapsed })}
|
||||
onClick={openMenu}
|
||||
title={_t("Quick settings")}
|
||||
inputRef={handle}
|
||||
forceHide={!isPanelCollapsed}
|
||||
>
|
||||
{ !isPanelCollapsed ? _t("Settings") : null }
|
||||
</AccessibleTooltipButton>
|
||||
|
||||
{ contextMenu }
|
||||
</>;
|
||||
};
|
||||
|
||||
export default QuickSettingsButton;
|
|
@ -23,7 +23,7 @@ import { logger } from "matrix-js-sdk/src/logger";
|
|||
|
||||
import { _t } from "../../../languageHandler";
|
||||
import AccessibleTooltipButton from "../elements/AccessibleTooltipButton";
|
||||
import { ChevronFace, ContextMenu } from "../../structures/ContextMenu";
|
||||
import ContextMenu, { ChevronFace } from "../../structures/ContextMenu";
|
||||
import createRoom, { IOpts as ICreateOpts } from "../../../createRoom";
|
||||
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
||||
import SpaceBasicSettings, { SpaceAvatar } from "./SpaceBasicSettings";
|
||||
|
@ -118,6 +118,7 @@ export const SpaceFeedbackPrompt = ({ onClick }: { onClick?: () => void }) => {
|
|||
rageshakeLabel: "spaces-feedback",
|
||||
rageshakeData: Object.fromEntries([
|
||||
"Spaces.allRoomsInHome",
|
||||
"Spaces.enabledMetaSpaces",
|
||||
].map(k => [k, SettingsStore.getValue(k)])),
|
||||
});
|
||||
}}
|
||||
|
|
|
@ -34,14 +34,16 @@ import SpaceCreateMenu from "./SpaceCreateMenu";
|
|||
import { SpaceButton, SpaceItem } from "./SpaceTreeLevel";
|
||||
import AccessibleTooltipButton from "../elements/AccessibleTooltipButton";
|
||||
import { useEventEmitterState } from "../../../hooks/useEventEmitter";
|
||||
import SpaceStore, {
|
||||
HOME_SPACE,
|
||||
import SpaceStore from "../../../stores/spaces/SpaceStore";
|
||||
import {
|
||||
getMetaSpaceName,
|
||||
MetaSpace,
|
||||
SpaceKey,
|
||||
UPDATE_HOME_BEHAVIOUR,
|
||||
UPDATE_INVITED_SPACES,
|
||||
UPDATE_SELECTED_SPACE,
|
||||
UPDATE_TOP_LEVEL_SPACES,
|
||||
} from "../../../stores/SpaceStore";
|
||||
import AutoHideScrollbar from "../../structures/AutoHideScrollbar";
|
||||
} from "../../../stores/spaces";
|
||||
import { RovingTabIndexProvider } from "../../../accessibility/RovingTabIndex";
|
||||
import { RoomNotificationStateStore } from "../../../stores/notifications/RoomNotificationStateStore";
|
||||
import SpaceContextMenu from "../context_menus/SpaceContextMenu";
|
||||
|
@ -52,18 +54,31 @@ import IconizedContextMenu, {
|
|||
import SettingsStore from "../../../settings/SettingsStore";
|
||||
import { SettingLevel } from "../../../settings/SettingLevel";
|
||||
import UIStore from "../../../stores/UIStore";
|
||||
import QuickSettingsButton from "./QuickSettingsButton";
|
||||
import { useSettingValue } from "../../../hooks/useSettings";
|
||||
import UserMenu from "../../structures/UserMenu";
|
||||
import IndicatorScrollbar from "../../structures/IndicatorScrollbar";
|
||||
import { isMac } from "../../../Keyboard";
|
||||
import { useDispatcher } from "../../../hooks/useDispatcher";
|
||||
import defaultDispatcher from "../../../dispatcher/dispatcher";
|
||||
import { ActionPayload } from "../../../dispatcher/payloads";
|
||||
import { Action } from "../../../dispatcher/actions";
|
||||
|
||||
const useSpaces = (): [Room[], Room[], Room | null] => {
|
||||
const useSpaces = (): [Room[], MetaSpace[], Room[], SpaceKey] => {
|
||||
const invites = useEventEmitterState<Room[]>(SpaceStore.instance, UPDATE_INVITED_SPACES, () => {
|
||||
return SpaceStore.instance.invitedSpaces;
|
||||
});
|
||||
const spaces = useEventEmitterState<Room[]>(SpaceStore.instance, UPDATE_TOP_LEVEL_SPACES, () => {
|
||||
return SpaceStore.instance.spacePanelSpaces;
|
||||
});
|
||||
const activeSpace = useEventEmitterState<Room>(SpaceStore.instance, UPDATE_SELECTED_SPACE, () => {
|
||||
const [metaSpaces, actualSpaces] = useEventEmitterState<[MetaSpace[], Room[]]>(
|
||||
SpaceStore.instance, UPDATE_TOP_LEVEL_SPACES,
|
||||
() => [
|
||||
SpaceStore.instance.enabledMetaSpaces,
|
||||
SpaceStore.instance.spacePanelSpaces,
|
||||
],
|
||||
);
|
||||
const activeSpace = useEventEmitterState<SpaceKey>(SpaceStore.instance, UPDATE_SELECTED_SPACE, () => {
|
||||
return SpaceStore.instance.activeSpace;
|
||||
});
|
||||
return [invites, spaces, activeSpace];
|
||||
return [invites, metaSpaces, actualSpaces, activeSpace];
|
||||
};
|
||||
|
||||
interface IInnerSpacePanelProps {
|
||||
|
@ -72,7 +87,11 @@ interface IInnerSpacePanelProps {
|
|||
setPanelCollapsed: Dispatch<SetStateAction<boolean>>;
|
||||
}
|
||||
|
||||
const HomeButtonContextMenu = ({ onFinished, ...props }: ComponentProps<typeof SpaceContextMenu>) => {
|
||||
export const HomeButtonContextMenu = ({
|
||||
onFinished,
|
||||
hideHeader,
|
||||
...props
|
||||
}: ComponentProps<typeof SpaceContextMenu>) => {
|
||||
const allRoomsInHome = useEventEmitterState(SpaceStore.instance, UPDATE_HOME_BEHAVIOUR, () => {
|
||||
return SpaceStore.instance.allRoomsInHome;
|
||||
});
|
||||
|
@ -83,9 +102,9 @@ const HomeButtonContextMenu = ({ onFinished, ...props }: ComponentProps<typeof S
|
|||
className="mx_SpacePanel_contextMenu"
|
||||
compact
|
||||
>
|
||||
<div className="mx_SpacePanel_contextMenu_header">
|
||||
{ !hideHeader && <div className="mx_SpacePanel_contextMenu_header">
|
||||
{ _t("Home") }
|
||||
</div>
|
||||
</div> }
|
||||
<IconizedContextMenuOptionList first>
|
||||
<IconizedContextMenuCheckbox
|
||||
iconClassName="mx_SpacePanel_noIcon"
|
||||
|
@ -99,37 +118,76 @@ const HomeButtonContextMenu = ({ onFinished, ...props }: ComponentProps<typeof S
|
|||
</IconizedContextMenu>;
|
||||
};
|
||||
|
||||
interface IHomeButtonProps {
|
||||
interface IMetaSpaceButtonProps extends ComponentProps<typeof SpaceButton> {
|
||||
selected: boolean;
|
||||
isPanelCollapsed: boolean;
|
||||
}
|
||||
|
||||
const HomeButton = ({ selected, isPanelCollapsed }: IHomeButtonProps) => {
|
||||
const allRoomsInHome = useEventEmitterState(SpaceStore.instance, UPDATE_HOME_BEHAVIOUR, () => {
|
||||
return SpaceStore.instance.allRoomsInHome;
|
||||
});
|
||||
type MetaSpaceButtonProps = Pick<IMetaSpaceButtonProps, "selected" | "isPanelCollapsed">;
|
||||
|
||||
const MetaSpaceButton = ({ selected, isPanelCollapsed, ...props }: IMetaSpaceButtonProps) => {
|
||||
return <li
|
||||
className={classNames("mx_SpaceItem", {
|
||||
"collapsed": isPanelCollapsed,
|
||||
})}
|
||||
role="treeitem"
|
||||
>
|
||||
<SpaceButton
|
||||
className="mx_SpaceButton_home"
|
||||
onClick={() => SpaceStore.instance.setActiveSpace(null)}
|
||||
selected={selected}
|
||||
label={allRoomsInHome ? _t("All rooms") : _t("Home")}
|
||||
notificationState={allRoomsInHome
|
||||
? RoomNotificationStateStore.instance.globalState
|
||||
: SpaceStore.instance.getNotificationState(HOME_SPACE)}
|
||||
isNarrow={isPanelCollapsed}
|
||||
ContextMenuComponent={HomeButtonContextMenu}
|
||||
contextMenuTooltip={_t("Options")}
|
||||
/>
|
||||
<SpaceButton {...props} selected={selected} isNarrow={isPanelCollapsed} />
|
||||
</li>;
|
||||
};
|
||||
|
||||
const HomeButton = ({ selected, isPanelCollapsed }: MetaSpaceButtonProps) => {
|
||||
const allRoomsInHome = useEventEmitterState(SpaceStore.instance, UPDATE_HOME_BEHAVIOUR, () => {
|
||||
return SpaceStore.instance.allRoomsInHome;
|
||||
});
|
||||
|
||||
return <MetaSpaceButton
|
||||
spaceKey={MetaSpace.Home}
|
||||
className="mx_SpaceButton_home"
|
||||
selected={selected}
|
||||
isPanelCollapsed={isPanelCollapsed}
|
||||
label={getMetaSpaceName(MetaSpace.Home, allRoomsInHome)}
|
||||
notificationState={allRoomsInHome
|
||||
? RoomNotificationStateStore.instance.globalState
|
||||
: SpaceStore.instance.getNotificationState(MetaSpace.Home)}
|
||||
ContextMenuComponent={HomeButtonContextMenu}
|
||||
contextMenuTooltip={_t("Options")}
|
||||
/>;
|
||||
};
|
||||
|
||||
const FavouritesButton = ({ selected, isPanelCollapsed }: MetaSpaceButtonProps) => {
|
||||
return <MetaSpaceButton
|
||||
spaceKey={MetaSpace.Favourites}
|
||||
className="mx_SpaceButton_favourites"
|
||||
selected={selected}
|
||||
isPanelCollapsed={isPanelCollapsed}
|
||||
label={getMetaSpaceName(MetaSpace.Favourites)}
|
||||
notificationState={SpaceStore.instance.getNotificationState(MetaSpace.Favourites)}
|
||||
/>;
|
||||
};
|
||||
|
||||
const PeopleButton = ({ selected, isPanelCollapsed }: MetaSpaceButtonProps) => {
|
||||
return <MetaSpaceButton
|
||||
spaceKey={MetaSpace.People}
|
||||
className="mx_SpaceButton_people"
|
||||
selected={selected}
|
||||
isPanelCollapsed={isPanelCollapsed}
|
||||
label={getMetaSpaceName(MetaSpace.People)}
|
||||
notificationState={SpaceStore.instance.getNotificationState(MetaSpace.People)}
|
||||
/>;
|
||||
};
|
||||
|
||||
const OrphansButton = ({ selected, isPanelCollapsed }: MetaSpaceButtonProps) => {
|
||||
return <MetaSpaceButton
|
||||
spaceKey={MetaSpace.Orphans}
|
||||
className="mx_SpaceButton_orphans"
|
||||
selected={selected}
|
||||
isPanelCollapsed={isPanelCollapsed}
|
||||
label={getMetaSpaceName(MetaSpace.Orphans)}
|
||||
notificationState={SpaceStore.instance.getNotificationState(MetaSpace.Orphans)}
|
||||
/>;
|
||||
};
|
||||
|
||||
const CreateSpaceButton = ({
|
||||
isPanelCollapsed,
|
||||
setPanelCollapsed,
|
||||
|
@ -181,13 +239,25 @@ const CreateSpaceButton = ({
|
|||
</li>;
|
||||
};
|
||||
|
||||
const metaSpaceComponentMap: Record<MetaSpace, typeof HomeButton> = {
|
||||
[MetaSpace.Home]: HomeButton,
|
||||
[MetaSpace.Favourites]: FavouritesButton,
|
||||
[MetaSpace.People]: PeopleButton,
|
||||
[MetaSpace.Orphans]: OrphansButton,
|
||||
};
|
||||
|
||||
// Optimisation based on https://github.com/atlassian/react-beautiful-dnd/blob/master/docs/api/droppable.md#recommended-droppable--performance-optimisation
|
||||
const InnerSpacePanel = React.memo<IInnerSpacePanelProps>(({ children, isPanelCollapsed, setPanelCollapsed }) => {
|
||||
const [invites, spaces, activeSpace] = useSpaces();
|
||||
const [invites, metaSpaces, actualSpaces, activeSpace] = useSpaces();
|
||||
const activeSpaces = activeSpace ? [activeSpace] : [];
|
||||
|
||||
const metaSpacesSection = metaSpaces.map(key => {
|
||||
const Component = metaSpaceComponentMap[key];
|
||||
return <Component key={key} selected={activeSpace === key} isPanelCollapsed={isPanelCollapsed} />;
|
||||
});
|
||||
|
||||
return <div className="mx_SpaceTreeLevel">
|
||||
<HomeButton selected={!activeSpace} isPanelCollapsed={isPanelCollapsed} />
|
||||
{ metaSpacesSection }
|
||||
{ invites.map(s => (
|
||||
<SpaceItem
|
||||
key={s.roomId}
|
||||
|
@ -197,7 +267,7 @@ const InnerSpacePanel = React.memo<IInnerSpacePanelProps>(({ children, isPanelCo
|
|||
onExpand={() => setPanelCollapsed(false)}
|
||||
/>
|
||||
)) }
|
||||
{ spaces.map((s, i) => (
|
||||
{ actualSpaces.map((s, i) => (
|
||||
<Draggable key={s.roomId} draggableId={s.roomId} index={i}>
|
||||
{ (provided, snapshot) => (
|
||||
<SpaceItem
|
||||
|
@ -220,6 +290,7 @@ const InnerSpacePanel = React.memo<IInnerSpacePanelProps>(({ children, isPanelCo
|
|||
});
|
||||
|
||||
const SpacePanel = () => {
|
||||
const metaSpacesEnabled = useSettingValue("feature_spaces_metaspaces");
|
||||
const [isPanelCollapsed, setPanelCollapsed] = useState(true);
|
||||
const ref = useRef<HTMLUListElement>();
|
||||
useLayoutEffect(() => {
|
||||
|
@ -227,6 +298,12 @@ const SpacePanel = () => {
|
|||
return () => UIStore.instance.stopTrackingElementDimensions("SpacePanel");
|
||||
}, []);
|
||||
|
||||
useDispatcher(defaultDispatcher, (payload: ActionPayload) => {
|
||||
if (payload.action === Action.ToggleSpacePanel) {
|
||||
setPanelCollapsed(!isPanelCollapsed);
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<DragDropContext onDragEnd={result => {
|
||||
if (!result.destination) return; // dropped outside the list
|
||||
|
@ -241,9 +318,24 @@ const SpacePanel = () => {
|
|||
aria-label={_t("Spaces")}
|
||||
ref={ref}
|
||||
>
|
||||
<UserMenu isPanelCollapsed={isPanelCollapsed}>
|
||||
<AccessibleTooltipButton
|
||||
className={classNames("mx_SpacePanel_toggleCollapse", { expanded: !isPanelCollapsed })}
|
||||
onClick={() => setPanelCollapsed(!isPanelCollapsed)}
|
||||
title={isPanelCollapsed ? _t("Expand") : _t("Collapse")}
|
||||
tooltip={<div>
|
||||
<div className="mx_Tooltip_title">
|
||||
{ isPanelCollapsed ? _t("Expand") : _t("Collapse") }
|
||||
</div>
|
||||
<div className="mx_Tooltip_sub">
|
||||
{ isMac ? "⌘ + ⇧ + D" : "Ctrl + Shift + D" }
|
||||
</div>
|
||||
</div>}
|
||||
/>
|
||||
</UserMenu>
|
||||
<Droppable droppableId="top-level-spaces">
|
||||
{ (provided, snapshot) => (
|
||||
<AutoHideScrollbar
|
||||
<IndicatorScrollbar
|
||||
{...provided.droppableProps}
|
||||
wrappedRef={provided.innerRef}
|
||||
className="mx_SpacePanel_spaceTreeWrapper"
|
||||
|
@ -257,14 +349,11 @@ const SpacePanel = () => {
|
|||
>
|
||||
{ provided.placeholder }
|
||||
</InnerSpacePanel>
|
||||
</AutoHideScrollbar>
|
||||
</IndicatorScrollbar>
|
||||
) }
|
||||
</Droppable>
|
||||
<AccessibleTooltipButton
|
||||
className={classNames("mx_SpacePanel_toggleCollapse", { expanded: !isPanelCollapsed })}
|
||||
onClick={() => setPanelCollapsed(!isPanelCollapsed)}
|
||||
title={isPanelCollapsed ? _t("Expand space panel") : _t("Collapse space panel")}
|
||||
/>
|
||||
|
||||
{ metaSpacesEnabled && <QuickSettingsButton isPanelCollapsed={isPanelCollapsed} /> }
|
||||
</ul>
|
||||
) }
|
||||
</RovingTabIndexProvider>
|
||||
|
|
|
@ -16,7 +16,6 @@ limitations under the License.
|
|||
|
||||
import React, {
|
||||
createRef,
|
||||
MouseEvent,
|
||||
InputHTMLAttributes,
|
||||
LegacyRef,
|
||||
ComponentProps,
|
||||
|
@ -27,14 +26,15 @@ import { Room } from "matrix-js-sdk/src/models/room";
|
|||
import { DraggableProvidedDragHandleProps } from "react-beautiful-dnd";
|
||||
|
||||
import RoomAvatar from "../avatars/RoomAvatar";
|
||||
import SpaceStore from "../../../stores/SpaceStore";
|
||||
import SpaceTreeLevelLayoutStore from "../../../stores/SpaceTreeLevelLayoutStore";
|
||||
import SpaceStore from "../../../stores/spaces/SpaceStore";
|
||||
import { SpaceKey } from "../../../stores/spaces";
|
||||
import SpaceTreeLevelLayoutStore from "../../../stores/spaces/SpaceTreeLevelLayoutStore";
|
||||
import NotificationBadge from "../rooms/NotificationBadge";
|
||||
import { _t } from "../../../languageHandler";
|
||||
import { ContextMenuTooltipButton } from "../../../accessibility/context_menu/ContextMenuTooltipButton";
|
||||
import { toRightOf, useContextMenu } from "../../structures/ContextMenu";
|
||||
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
||||
import AccessibleButton from "../elements/AccessibleButton";
|
||||
import AccessibleButton, { ButtonEvent } from "../elements/AccessibleButton";
|
||||
import { StaticNotificationState } from "../../../stores/notifications/StaticNotificationState";
|
||||
import { NotificationColor } from "../../../stores/notifications/NotificationColor";
|
||||
import { getKeyBindingsManager, RoomListAction } from "../../../KeyBindingsManager";
|
||||
|
@ -43,8 +43,9 @@ import SpaceContextMenu from "../context_menus/SpaceContextMenu";
|
|||
import AccessibleTooltipButton from "../elements/AccessibleTooltipButton";
|
||||
import { useRovingTabIndex } from "../../../accessibility/RovingTabIndex";
|
||||
|
||||
interface IButtonProps extends Omit<ComponentProps<typeof AccessibleTooltipButton>, "title"> {
|
||||
interface IButtonProps extends Omit<ComponentProps<typeof AccessibleTooltipButton>, "title" | "onClick"> {
|
||||
space?: Room;
|
||||
spaceKey?: SpaceKey;
|
||||
className?: string;
|
||||
selected?: boolean;
|
||||
label: string;
|
||||
|
@ -53,14 +54,14 @@ interface IButtonProps extends Omit<ComponentProps<typeof AccessibleTooltipButto
|
|||
isNarrow?: boolean;
|
||||
avatarSize?: number;
|
||||
ContextMenuComponent?: ComponentType<ComponentProps<typeof SpaceContextMenu>>;
|
||||
onClick(ev: MouseEvent): void;
|
||||
onClick?(ev?: ButtonEvent): void;
|
||||
}
|
||||
|
||||
export const SpaceButton: React.FC<IButtonProps> = ({
|
||||
space,
|
||||
spaceKey,
|
||||
className,
|
||||
selected,
|
||||
onClick,
|
||||
label,
|
||||
contextMenuTooltip,
|
||||
notificationState,
|
||||
|
@ -88,7 +89,7 @@ export const SpaceButton: React.FC<IButtonProps> = ({
|
|||
|
||||
notifBadge = <div className="mx_SpacePanel_badgeContainer">
|
||||
<NotificationBadge
|
||||
onClick={() => SpaceStore.instance.setActiveRoomInSpace(space || null)}
|
||||
onClick={() => SpaceStore.instance.setActiveRoomInSpace(spaceKey ?? space.roomId)}
|
||||
forceCount={false}
|
||||
notification={notificationState}
|
||||
aria-label={ariaLabel}
|
||||
|
@ -116,7 +117,7 @@ export const SpaceButton: React.FC<IButtonProps> = ({
|
|||
mx_SpaceButton_narrow: isNarrow,
|
||||
})}
|
||||
title={label}
|
||||
onClick={onClick}
|
||||
onClick={spaceKey ? () => SpaceStore.instance.setActiveSpace(spaceKey) : props.onClick}
|
||||
onContextMenu={openMenu}
|
||||
forceHide={!isNarrow || menuDisplayed}
|
||||
inputRef={handle}
|
||||
|
@ -146,7 +147,7 @@ export const SpaceButton: React.FC<IButtonProps> = ({
|
|||
|
||||
interface IItemProps extends InputHTMLAttributes<HTMLLIElement> {
|
||||
space?: Room;
|
||||
activeSpaces: Room[];
|
||||
activeSpaces: SpaceKey[];
|
||||
isNested?: boolean;
|
||||
isPanelCollapsed?: boolean;
|
||||
onExpand?: Function;
|
||||
|
@ -258,7 +259,7 @@ export class SpaceItem extends React.PureComponent<IItemProps, IItemState> {
|
|||
private onClick = (ev: React.MouseEvent) => {
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
SpaceStore.instance.setActiveSpace(this.props.space);
|
||||
SpaceStore.instance.setActiveSpace(this.props.space.roomId);
|
||||
};
|
||||
|
||||
render() {
|
||||
|
@ -316,7 +317,7 @@ export class SpaceItem extends React.PureComponent<IItemProps, IItemState> {
|
|||
{...restDragHandleProps}
|
||||
space={space}
|
||||
className={isInvite ? "mx_SpaceButton_invite" : undefined}
|
||||
selected={activeSpaces.includes(space)}
|
||||
selected={activeSpaces.includes(space.roomId)}
|
||||
label={space.name}
|
||||
contextMenuTooltip={_t("Space options")}
|
||||
notificationState={notificationState}
|
||||
|
@ -337,7 +338,7 @@ export class SpaceItem extends React.PureComponent<IItemProps, IItemState> {
|
|||
|
||||
interface ITreeLevelProps {
|
||||
spaces: Room[];
|
||||
activeSpaces: Room[];
|
||||
activeSpaces: SpaceKey[];
|
||||
isNested?: boolean;
|
||||
parents: Set<string>;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue