mirror of
https://github.com/element-hq/element-web
synced 2024-11-23 17:56:01 +03:00
Fix space hierarchy not updating when user mutates it
This commit is contained in:
parent
5d9e421de0
commit
ed950875e7
5 changed files with 57 additions and 42 deletions
|
@ -44,11 +44,13 @@ import { getChildOrder } from "../../stores/SpaceStore";
|
||||||
import AccessibleTooltipButton from "../views/elements/AccessibleTooltipButton";
|
import AccessibleTooltipButton from "../views/elements/AccessibleTooltipButton";
|
||||||
import { linkifyElement } from "../../HtmlUtils";
|
import { linkifyElement } from "../../HtmlUtils";
|
||||||
import { getDisplayAliasForAliasSet } from "../../Rooms";
|
import { getDisplayAliasForAliasSet } from "../../Rooms";
|
||||||
|
import { useDispatcher } from "../../hooks/useDispatcher";
|
||||||
|
import defaultDispatcher from "../../dispatcher/dispatcher";
|
||||||
|
import { Action } from "../../dispatcher/actions";
|
||||||
|
|
||||||
interface IHierarchyProps {
|
interface IHierarchyProps {
|
||||||
space: Room;
|
space: Room;
|
||||||
initialText?: string;
|
initialText?: string;
|
||||||
refreshToken?: any;
|
|
||||||
additionalButtons?: ReactNode;
|
additionalButtons?: ReactNode;
|
||||||
showRoom(room: ISpaceSummaryRoom, viaServers?: string[], autoJoin?: boolean): void;
|
showRoom(room: ISpaceSummaryRoom, viaServers?: string[], autoJoin?: boolean): void;
|
||||||
}
|
}
|
||||||
|
@ -315,18 +317,25 @@ export const HierarchyLevel = ({
|
||||||
</React.Fragment>;
|
</React.Fragment>;
|
||||||
};
|
};
|
||||||
|
|
||||||
// mutate argument refreshToken to force a reload
|
export const useSpaceSummary = (space: Room): [
|
||||||
export const useSpaceSummary = (cli: MatrixClient, space: Room, refreshToken?: any): [
|
|
||||||
null,
|
null,
|
||||||
ISpaceSummaryRoom[],
|
ISpaceSummaryRoom[],
|
||||||
Map<string, Map<string, ISpaceSummaryEvent>>?,
|
Map<string, Map<string, ISpaceSummaryEvent>>?,
|
||||||
Map<string, Set<string>>?,
|
Map<string, Set<string>>?,
|
||||||
Map<string, Set<string>>?,
|
Map<string, Set<string>>?,
|
||||||
] | [Error] => {
|
] | [Error] => {
|
||||||
|
// crude temporary refresh token approach until we have pagination and rework the data flow here
|
||||||
|
const [refreshToken, setRefreshToken] = useState(0);
|
||||||
|
useDispatcher(defaultDispatcher, (payload => {
|
||||||
|
if (payload.action === Action.UpdateSpaceHierarchy) {
|
||||||
|
setRefreshToken(t => t + 1);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
// TODO pagination
|
// TODO pagination
|
||||||
return useAsyncMemo(async () => {
|
return useAsyncMemo(async () => {
|
||||||
try {
|
try {
|
||||||
const data = await cli.getSpaceSummary(space.roomId);
|
const data = await space.client.getSpaceSummary(space.roomId);
|
||||||
|
|
||||||
const parentChildRelations = new EnhancedMap<string, Map<string, ISpaceSummaryEvent>>();
|
const parentChildRelations = new EnhancedMap<string, Map<string, ISpaceSummaryEvent>>();
|
||||||
const childParentRelations = new EnhancedMap<string, Set<string>>();
|
const childParentRelations = new EnhancedMap<string, Set<string>>();
|
||||||
|
@ -354,7 +363,6 @@ export const SpaceHierarchy: React.FC<IHierarchyProps> = ({
|
||||||
space,
|
space,
|
||||||
initialText = "",
|
initialText = "",
|
||||||
showRoom,
|
showRoom,
|
||||||
refreshToken,
|
|
||||||
additionalButtons,
|
additionalButtons,
|
||||||
children,
|
children,
|
||||||
}) => {
|
}) => {
|
||||||
|
@ -364,7 +372,7 @@ export const SpaceHierarchy: React.FC<IHierarchyProps> = ({
|
||||||
|
|
||||||
const [selected, setSelected] = useState(new Map<string, Set<string>>()); // Map<parentId, Set<childId>>
|
const [selected, setSelected] = useState(new Map<string, Set<string>>()); // Map<parentId, Set<childId>>
|
||||||
|
|
||||||
const [summaryError, rooms, parentChildMap, viaMap, childParentMap] = useSpaceSummary(cli, space, refreshToken);
|
const [summaryError, rooms, parentChildMap, viaMap, childParentMap] = useSpaceSummary(space);
|
||||||
|
|
||||||
const roomsMap = useMemo(() => {
|
const roomsMap = useMemo(() => {
|
||||||
if (!rooms) return null;
|
if (!rooms) return null;
|
||||||
|
|
|
@ -56,7 +56,6 @@ import {
|
||||||
} from "../../utils/space";
|
} from "../../utils/space";
|
||||||
import { showRoom, SpaceHierarchy } from "./SpaceRoomDirectory";
|
import { showRoom, SpaceHierarchy } from "./SpaceRoomDirectory";
|
||||||
import MemberAvatar from "../views/avatars/MemberAvatar";
|
import MemberAvatar from "../views/avatars/MemberAvatar";
|
||||||
import { useStateToggle } from "../../hooks/useStateToggle";
|
|
||||||
import SpaceStore from "../../stores/SpaceStore";
|
import SpaceStore from "../../stores/SpaceStore";
|
||||||
import FacePile from "../views/elements/FacePile";
|
import FacePile from "../views/elements/FacePile";
|
||||||
import {
|
import {
|
||||||
|
@ -318,7 +317,7 @@ const SpacePreview = ({ space, onJoinButtonClicked, onRejectButtonClicked }) =>
|
||||||
</div>;
|
</div>;
|
||||||
};
|
};
|
||||||
|
|
||||||
const SpaceLandingAddButton = ({ space, onNewRoomAdded }) => {
|
const SpaceLandingAddButton = ({ space }) => {
|
||||||
const [menuDisplayed, handle, openMenu, closeMenu] = useContextMenu();
|
const [menuDisplayed, handle, openMenu, closeMenu] = useContextMenu();
|
||||||
|
|
||||||
let contextMenu;
|
let contextMenu;
|
||||||
|
@ -342,36 +341,28 @@ const SpaceLandingAddButton = ({ space, onNewRoomAdded }) => {
|
||||||
closeMenu();
|
closeMenu();
|
||||||
|
|
||||||
if (await showCreateNewRoom(space)) {
|
if (await showCreateNewRoom(space)) {
|
||||||
onNewRoomAdded();
|
defaultDispatcher.fire(Action.UpdateSpaceHierarchy);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<IconizedContextMenuOption
|
<IconizedContextMenuOption
|
||||||
label={_t("Add existing room")}
|
label={_t("Add existing room")}
|
||||||
iconClassName="mx_RoomList_iconHash"
|
iconClassName="mx_RoomList_iconHash"
|
||||||
onClick={async (e) => {
|
onClick={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
closeMenu();
|
closeMenu();
|
||||||
|
showAddExistingRooms(space);
|
||||||
const [added] = await showAddExistingRooms(space);
|
|
||||||
if (added) {
|
|
||||||
onNewRoomAdded();
|
|
||||||
}
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<IconizedContextMenuOption
|
<IconizedContextMenuOption
|
||||||
label={_t("Add subspace")}
|
label={_t("Add subspace")}
|
||||||
iconClassName="mx_RoomList_iconPlus"
|
iconClassName="mx_RoomList_iconPlus"
|
||||||
onClick={async (e) => {
|
onClick={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
closeMenu();
|
closeMenu();
|
||||||
|
showCreateNewSubspace(space);
|
||||||
const [added] = await showCreateNewSubspace(space);
|
|
||||||
if (added) {
|
|
||||||
onNewRoomAdded();
|
|
||||||
}
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<BetaPill />
|
<BetaPill />
|
||||||
|
@ -416,11 +407,9 @@ const SpaceLanding = ({ space }) => {
|
||||||
|
|
||||||
const canAddRooms = myMembership === "join" && space.currentState.maySendStateEvent(EventType.SpaceChild, userId);
|
const canAddRooms = myMembership === "join" && space.currentState.maySendStateEvent(EventType.SpaceChild, userId);
|
||||||
|
|
||||||
const [refreshToken, forceUpdate] = useStateToggle(false);
|
|
||||||
|
|
||||||
let addRoomButton;
|
let addRoomButton;
|
||||||
if (canAddRooms) {
|
if (canAddRooms) {
|
||||||
addRoomButton = <SpaceLandingAddButton space={space} onNewRoomAdded={forceUpdate} />;
|
addRoomButton = <SpaceLandingAddButton space={space} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
let settingsButton;
|
let settingsButton;
|
||||||
|
@ -470,12 +459,7 @@ const SpaceLanding = ({ space }) => {
|
||||||
<SpaceFeedbackPrompt />
|
<SpaceFeedbackPrompt />
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
<SpaceHierarchy
|
<SpaceHierarchy space={space} showRoom={showRoom} additionalButtons={addRoomButton} />
|
||||||
space={space}
|
|
||||||
showRoom={showRoom}
|
|
||||||
refreshToken={refreshToken}
|
|
||||||
additionalButtons={addRoomButton}
|
|
||||||
/>
|
|
||||||
</div>;
|
</div>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -249,7 +249,7 @@ export const AddExistingToSpace: React.FC<IAddExistingToSpaceProps> = ({
|
||||||
let noResults = true;
|
let noResults = true;
|
||||||
if ((roomsRenderer && rooms.length > 0) ||
|
if ((roomsRenderer && rooms.length > 0) ||
|
||||||
(dmsRenderer && dms.length > 0) ||
|
(dmsRenderer && dms.length > 0) ||
|
||||||
(!roomsRenderer && !dmsRenderer && spacesRenderer && dms.length > 0) // only count spaces when alone
|
(!roomsRenderer && !dmsRenderer && spacesRenderer && spaces.length > 0) // only count spaces when alone
|
||||||
) {
|
) {
|
||||||
noResults = false;
|
noResults = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -193,4 +193,9 @@ export enum Action {
|
||||||
* Switches space. Should be used with SwitchSpacePayload.
|
* Switches space. Should be used with SwitchSpacePayload.
|
||||||
*/
|
*/
|
||||||
SwitchSpace = "switch_space",
|
SwitchSpace = "switch_space",
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Signals to the visible space hierarchy that a change has occurred an that it should refresh.
|
||||||
|
*/
|
||||||
|
UpdateSpaceHierarchy = "update_space_hierarchy",
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,9 @@ import InfoDialog from "../components/views/dialogs/InfoDialog";
|
||||||
import { showRoomInviteDialog } from "../RoomInvite";
|
import { showRoomInviteDialog } from "../RoomInvite";
|
||||||
import CreateSubspaceDialog from "../components/views/dialogs/CreateSubspaceDialog";
|
import CreateSubspaceDialog from "../components/views/dialogs/CreateSubspaceDialog";
|
||||||
import AddExistingSubspaceDialog from "../components/views/dialogs/AddExistingSubspaceDialog";
|
import AddExistingSubspaceDialog from "../components/views/dialogs/AddExistingSubspaceDialog";
|
||||||
|
import defaultDispatcher from "../dispatcher/dispatcher";
|
||||||
|
import RoomViewStore from "../stores/RoomViewStore";
|
||||||
|
import { Action } from "../dispatcher/actions";
|
||||||
|
|
||||||
export const shouldShowSpaceSettings = (space: Room) => {
|
export const shouldShowSpaceSettings = (space: Room) => {
|
||||||
const userId = space.client.getUserId();
|
const userId = space.client.getUserId();
|
||||||
|
@ -56,8 +59,8 @@ export const showSpaceSettings = (space: Room) => {
|
||||||
}, /*className=*/null, /*isPriority=*/false, /*isStatic=*/true);
|
}, /*className=*/null, /*isPriority=*/false, /*isStatic=*/true);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const showAddExistingRooms = async (space: Room): Promise<[boolean]> => {
|
export const showAddExistingRooms = (space: Room): void => {
|
||||||
return Modal.createTrackedDialog(
|
Modal.createTrackedDialog(
|
||||||
"Space Landing",
|
"Space Landing",
|
||||||
"Add Existing",
|
"Add Existing",
|
||||||
AddExistingToSpaceDialog,
|
AddExistingToSpaceDialog,
|
||||||
|
@ -65,12 +68,17 @@ export const showAddExistingRooms = async (space: Room): Promise<[boolean]> => {
|
||||||
onCreateRoomClick: () => showCreateNewRoom(space),
|
onCreateRoomClick: () => showCreateNewRoom(space),
|
||||||
onAddSubspaceClick: () => showAddExistingSubspace(space),
|
onAddSubspaceClick: () => showAddExistingSubspace(space),
|
||||||
space,
|
space,
|
||||||
|
onFinished: (added: boolean) => {
|
||||||
|
if (added && RoomViewStore.getRoomId() === space.roomId) {
|
||||||
|
defaultDispatcher.fire(Action.UpdateSpaceHierarchy);
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
"mx_AddExistingToSpaceDialog_wrapper",
|
"mx_AddExistingToSpaceDialog_wrapper",
|
||||||
).finished as Promise<[boolean]>;
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const showCreateNewRoom = async (space: Room) => {
|
export const showCreateNewRoom = async (space: Room): Promise<boolean> => {
|
||||||
const modal = Modal.createTrackedDialog<[boolean, IOpts]>(
|
const modal = Modal.createTrackedDialog<[boolean, IOpts]>(
|
||||||
"Space Landing",
|
"Space Landing",
|
||||||
"Create Room",
|
"Create Room",
|
||||||
|
@ -87,7 +95,7 @@ export const showCreateNewRoom = async (space: Room) => {
|
||||||
return shouldCreate;
|
return shouldCreate;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const showSpaceInvite = (space: Room, initialText = "") => {
|
export const showSpaceInvite = (space: Room, initialText = ""): void => {
|
||||||
if (space.getJoinRule() === "public") {
|
if (space.getJoinRule() === "public") {
|
||||||
const modal = Modal.createTrackedDialog("Space Invite", "User Menu", InfoDialog, {
|
const modal = Modal.createTrackedDialog("Space Invite", "User Menu", InfoDialog, {
|
||||||
title: _t("Invite to %(spaceName)s", { spaceName: space.name }),
|
title: _t("Invite to %(spaceName)s", { spaceName: space.name }),
|
||||||
|
@ -105,28 +113,38 @@ export const showSpaceInvite = (space: Room, initialText = "") => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const showAddExistingSubspace = async (space: Room): Promise<[boolean]> => {
|
export const showAddExistingSubspace = (space: Room): void => {
|
||||||
return Modal.createTrackedDialog(
|
Modal.createTrackedDialog(
|
||||||
"Space Landing",
|
"Space Landing",
|
||||||
"Create Subspace",
|
"Create Subspace",
|
||||||
AddExistingSubspaceDialog,
|
AddExistingSubspaceDialog,
|
||||||
{
|
{
|
||||||
space,
|
space,
|
||||||
onCreateSubspaceClick: () => showCreateNewSubspace(space),
|
onCreateSubspaceClick: () => showCreateNewSubspace(space),
|
||||||
|
onFinished: (added: boolean) => {
|
||||||
|
if (added && RoomViewStore.getRoomId() === space.roomId) {
|
||||||
|
defaultDispatcher.fire(Action.UpdateSpaceHierarchy);
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
"mx_AddExistingToSpaceDialog_wrapper",
|
"mx_AddExistingToSpaceDialog_wrapper",
|
||||||
).finished as Promise<[boolean]>;
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const showCreateNewSubspace = async (space: Room): Promise<[boolean]> => {
|
export const showCreateNewSubspace = (space: Room): void => {
|
||||||
return Modal.createTrackedDialog(
|
Modal.createTrackedDialog(
|
||||||
"Space Landing",
|
"Space Landing",
|
||||||
"Create Subspace",
|
"Create Subspace",
|
||||||
CreateSubspaceDialog,
|
CreateSubspaceDialog,
|
||||||
{
|
{
|
||||||
space,
|
space,
|
||||||
onAddExistingSpaceClick: () => showAddExistingSubspace(space),
|
onAddExistingSpaceClick: () => showAddExistingSubspace(space),
|
||||||
|
onFinished: (added: boolean) => {
|
||||||
|
if (added && RoomViewStore.getRoomId() === space.roomId) {
|
||||||
|
defaultDispatcher.fire(Action.UpdateSpaceHierarchy);
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
"mx_CreateSubspaceDialog_wrapper",
|
"mx_CreateSubspaceDialog_wrapper",
|
||||||
).finished as Promise<[boolean]>;
|
);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue