diff --git a/src/components/structures/SpaceRoomView.tsx b/src/components/structures/SpaceRoomView.tsx
index 17ab75e707..cfa261bb9b 100644
--- a/src/components/structures/SpaceRoomView.tsx
+++ b/src/components/structures/SpaceRoomView.tsx
@@ -17,6 +17,7 @@ limitations under the License.
import React, {RefObject, useContext, useRef, useState} from "react";
import {EventType, RoomType} from "matrix-js-sdk/src/@types/event";
import {Room} from "matrix-js-sdk/src/models/room";
+import {EventSubscription} from "fbemitter";
import MatrixClientContext from "../../contexts/MatrixClientContext";
import RoomAvatar from "../views/avatars/RoomAvatar";
@@ -42,7 +43,6 @@ import ErrorBoundary from "../views/elements/ErrorBoundary";
import {ActionPayload} from "../../dispatcher/payloads";
import RightPanel from "./RightPanel";
import RightPanelStore from "../../stores/RightPanelStore";
-import {EventSubscription} from "fbemitter";
import {RightPanelPhases} from "../../stores/RightPanelStorePhases";
import {SetRightPanelPhasePayload} from "../../dispatcher/payloads/SetRightPanelPhasePayload";
import {useStateArray} from "../../hooks/useStateArray";
@@ -54,6 +54,7 @@ import {EnhancedMap} from "../../utils/maps";
import AutoHideScrollbar from "./AutoHideScrollbar";
import MemberAvatar from "../views/avatars/MemberAvatar";
import {useStateToggle} from "../../hooks/useStateToggle";
+import SpaceStore from "../../stores/SpaceStore";
interface IProps {
space: Room;
@@ -66,6 +67,7 @@ interface IProps {
interface IState {
phase: Phase;
showRightPanel: boolean;
+ myMembership: string;
}
enum Phase {
@@ -98,6 +100,8 @@ const SpacePreview = ({ space, onJoinButtonClicked, onRejectButtonClicked }) =>
const cli = useContext(MatrixClientContext);
const myMembership = useMyRoomMembership(space);
+ const [busy, setBusy] = useState(false);
+
let inviterSection;
let joinButtons;
if (myMembership === "invite") {
@@ -121,11 +125,35 @@ const SpacePreview = ({ space, onJoinButtonClicked, onRejectButtonClicked }) =>
}
joinButtons = <>
-
-
+ {
+ setBusy(true);
+ onRejectButtonClicked();
+ }} />
+ {
+ setBusy(true);
+ onJoinButtonClicked();
+ }}
+ />
>;
} else {
- joinButtons =
+ joinButtons = (
+ {
+ setBusy(true);
+ onJoinButtonClicked();
+ }}
+ />
+ )
+ }
+
+ if (busy) {
+ joinButtons = ;
}
let visibilitySection;
@@ -403,7 +431,7 @@ const SpaceSetupPublicShare = ({ space, onFinished }) => {
-
+
;
};
@@ -553,17 +581,26 @@ export default class SpaceRoomView extends React.PureComponent {
this.state = {
phase,
showRightPanel: RightPanelStore.getSharedInstance().isOpenForRoom,
+ myMembership: this.props.space.getMyMembership(),
};
this.dispatcherRef = defaultDispatcher.register(this.onAction);
this.rightPanelStoreToken = RightPanelStore.getSharedInstance().addListener(this.onRightPanelStoreUpdate);
+ this.context.on("Room.myMembership", this.onMyMembership);
}
componentWillUnmount() {
defaultDispatcher.unregister(this.dispatcherRef);
this.rightPanelStoreToken.remove();
+ this.context.off("Room.myMembership", this.onMyMembership);
}
+ private onMyMembership = (room: Room, myMembership: string) => {
+ if (room.roomId === this.props.space.roomId) {
+ this.setState({ myMembership });
+ }
+ };
+
private onRightPanelStoreUpdate = () => {
this.setState({
showRightPanel: RightPanelStore.getSharedInstance().isOpenForRoom,
@@ -600,10 +637,43 @@ export default class SpaceRoomView extends React.PureComponent {
}
};
+ private goToFirstRoom = async () => {
+ const childRooms = SpaceStore.instance.getChildRooms(this.props.space.roomId);
+ if (childRooms.length) {
+ const room = childRooms[0];
+ defaultDispatcher.dispatch({
+ action: "view_room",
+ room_id: room.roomId,
+ });
+ return;
+ }
+
+ let suggestedRooms = SpaceStore.instance.suggestedRooms;
+ if (SpaceStore.instance.activeSpace !== this.props.space) {
+ // the space store has the suggested rooms loaded for a different space, fetch the right ones
+ suggestedRooms = (await SpaceStore.instance.fetchSuggestedRooms(this.props.space, 1)).rooms;
+ }
+
+ if (suggestedRooms.length) {
+ const room = suggestedRooms[0];
+ defaultDispatcher.dispatch({
+ action: "view_room",
+ room_id: room.room_id,
+ oobData: {
+ avatarUrl: room.avatar_url,
+ name: room.name || room.canonical_alias || room.aliases.pop() || _t("Empty room"),
+ },
+ });
+ return;
+ }
+
+ this.setState({ phase: Phase.Landing });
+ };
+
private renderBody() {
switch (this.state.phase) {
case Phase.Landing:
- if (this.props.space.getMyMembership() === "join") {
+ if (this.state.myMembership === "join") {
return ;
} else {
return {
onFinished={() => this.setState({ phase: Phase.PublicShare })}
/>;
case Phase.PublicShare:
- return this.setState({ phase: Phase.Landing })}
- />;
+ return ;
case Phase.PrivateScope:
return {
}
if (space) {
- try {
- const data: {
- rooms: ISpaceSummaryRoom[];
- events: ISpaceSummaryEvent[];
- } = await this.matrixClient.getSpaceSummary(space.roomId, 0, true, false, MAX_SUGGESTED_ROOMS);
- if (this._activeSpace === space) {
- this._suggestedRooms = data.rooms.filter(roomInfo => {
- return roomInfo.room_type !== RoomType.Space && !this.matrixClient.getRoom(roomInfo.room_id);
- });
- this.emit(SUGGESTED_ROOMS, this._suggestedRooms);
- }
- } catch (e) {
- console.error(e);
+ const data = await this.fetchSuggestedRooms(space);
+ if (this._activeSpace === space) {
+ this._suggestedRooms = data.rooms.filter(roomInfo => {
+ return roomInfo.room_type !== RoomType.Space && !this.matrixClient.getRoom(roomInfo.room_id);
+ });
+ this.emit(SUGGESTED_ROOMS, this._suggestedRooms);
}
}
}
+ public fetchSuggestedRooms = async (space: Room, limit = MAX_SUGGESTED_ROOMS) => {
+ try {
+ const data: {
+ rooms: ISpaceSummaryRoom[];
+ events: ISpaceSummaryEvent[];
+ } = await this.matrixClient.getSpaceSummary(space.roomId, 0, true, false, limit);
+ return data;
+ } catch (e) {
+ console.error(e);
+ }
+ return {
+ rooms: [],
+ events: [],
+ };
+ };
+
public addRoomToSpace(space: Room, roomId: string, via: string[], suggested = false, autoJoin = false) {
return this.matrixClient.sendStateEvent(space.roomId, EventType.SpaceChild, {
via,