mirror of https://github.com/vector-im/riot-web
Iterate space creation and previews
parent
90d87122bc
commit
c6f6d24b32
|
@ -17,6 +17,7 @@ limitations under the License.
|
||||||
import React, {RefObject, useContext, useRef, useState} from "react";
|
import React, {RefObject, useContext, useRef, useState} from "react";
|
||||||
import {EventType, RoomType} from "matrix-js-sdk/src/@types/event";
|
import {EventType, RoomType} from "matrix-js-sdk/src/@types/event";
|
||||||
import {Room} from "matrix-js-sdk/src/models/room";
|
import {Room} from "matrix-js-sdk/src/models/room";
|
||||||
|
import {EventSubscription} from "fbemitter";
|
||||||
|
|
||||||
import MatrixClientContext from "../../contexts/MatrixClientContext";
|
import MatrixClientContext from "../../contexts/MatrixClientContext";
|
||||||
import RoomAvatar from "../views/avatars/RoomAvatar";
|
import RoomAvatar from "../views/avatars/RoomAvatar";
|
||||||
|
@ -42,7 +43,6 @@ import ErrorBoundary from "../views/elements/ErrorBoundary";
|
||||||
import {ActionPayload} from "../../dispatcher/payloads";
|
import {ActionPayload} from "../../dispatcher/payloads";
|
||||||
import RightPanel from "./RightPanel";
|
import RightPanel from "./RightPanel";
|
||||||
import RightPanelStore from "../../stores/RightPanelStore";
|
import RightPanelStore from "../../stores/RightPanelStore";
|
||||||
import {EventSubscription} from "fbemitter";
|
|
||||||
import {RightPanelPhases} from "../../stores/RightPanelStorePhases";
|
import {RightPanelPhases} from "../../stores/RightPanelStorePhases";
|
||||||
import {SetRightPanelPhasePayload} from "../../dispatcher/payloads/SetRightPanelPhasePayload";
|
import {SetRightPanelPhasePayload} from "../../dispatcher/payloads/SetRightPanelPhasePayload";
|
||||||
import {useStateArray} from "../../hooks/useStateArray";
|
import {useStateArray} from "../../hooks/useStateArray";
|
||||||
|
@ -54,6 +54,7 @@ import {EnhancedMap} from "../../utils/maps";
|
||||||
import AutoHideScrollbar from "./AutoHideScrollbar";
|
import AutoHideScrollbar from "./AutoHideScrollbar";
|
||||||
import MemberAvatar from "../views/avatars/MemberAvatar";
|
import MemberAvatar from "../views/avatars/MemberAvatar";
|
||||||
import {useStateToggle} from "../../hooks/useStateToggle";
|
import {useStateToggle} from "../../hooks/useStateToggle";
|
||||||
|
import SpaceStore from "../../stores/SpaceStore";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
space: Room;
|
space: Room;
|
||||||
|
@ -66,6 +67,7 @@ interface IProps {
|
||||||
interface IState {
|
interface IState {
|
||||||
phase: Phase;
|
phase: Phase;
|
||||||
showRightPanel: boolean;
|
showRightPanel: boolean;
|
||||||
|
myMembership: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Phase {
|
enum Phase {
|
||||||
|
@ -98,6 +100,8 @@ const SpacePreview = ({ space, onJoinButtonClicked, onRejectButtonClicked }) =>
|
||||||
const cli = useContext(MatrixClientContext);
|
const cli = useContext(MatrixClientContext);
|
||||||
const myMembership = useMyRoomMembership(space);
|
const myMembership = useMyRoomMembership(space);
|
||||||
|
|
||||||
|
const [busy, setBusy] = useState(false);
|
||||||
|
|
||||||
let inviterSection;
|
let inviterSection;
|
||||||
let joinButtons;
|
let joinButtons;
|
||||||
if (myMembership === "invite") {
|
if (myMembership === "invite") {
|
||||||
|
@ -121,11 +125,35 @@ const SpacePreview = ({ space, onJoinButtonClicked, onRejectButtonClicked }) =>
|
||||||
}
|
}
|
||||||
|
|
||||||
joinButtons = <>
|
joinButtons = <>
|
||||||
<FormButton label={_t("Reject")} kind="secondary" onClick={onRejectButtonClicked} />
|
<FormButton
|
||||||
<FormButton label={_t("Accept")} onClick={onJoinButtonClicked} />
|
label={_t("Reject")}
|
||||||
|
kind="secondary"
|
||||||
|
onClick={() => {
|
||||||
|
setBusy(true);
|
||||||
|
onRejectButtonClicked();
|
||||||
|
}} />
|
||||||
|
<FormButton
|
||||||
|
label={_t("Accept")}
|
||||||
|
onClick={() => {
|
||||||
|
setBusy(true);
|
||||||
|
onJoinButtonClicked();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</>;
|
</>;
|
||||||
} else {
|
} else {
|
||||||
joinButtons = <FormButton label={_t("Join")} onClick={onJoinButtonClicked} />
|
joinButtons = (
|
||||||
|
<FormButton
|
||||||
|
label={_t("Join")}
|
||||||
|
onClick={() => {
|
||||||
|
setBusy(true);
|
||||||
|
onJoinButtonClicked();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (busy) {
|
||||||
|
joinButtons = <InlineSpinner />;
|
||||||
}
|
}
|
||||||
|
|
||||||
let visibilitySection;
|
let visibilitySection;
|
||||||
|
@ -403,7 +431,7 @@ const SpaceSetupPublicShare = ({ space, onFinished }) => {
|
||||||
<SpacePublicShare space={space} onFinished={onFinished} />
|
<SpacePublicShare space={space} onFinished={onFinished} />
|
||||||
|
|
||||||
<div className="mx_SpaceRoomView_buttons">
|
<div className="mx_SpaceRoomView_buttons">
|
||||||
<FormButton label={_t("Finish")} onClick={onFinished} />
|
<FormButton label={_t("Go to my first room")} onClick={onFinished} />
|
||||||
</div>
|
</div>
|
||||||
</div>;
|
</div>;
|
||||||
};
|
};
|
||||||
|
@ -553,17 +581,26 @@ export default class SpaceRoomView extends React.PureComponent<IProps, IState> {
|
||||||
this.state = {
|
this.state = {
|
||||||
phase,
|
phase,
|
||||||
showRightPanel: RightPanelStore.getSharedInstance().isOpenForRoom,
|
showRightPanel: RightPanelStore.getSharedInstance().isOpenForRoom,
|
||||||
|
myMembership: this.props.space.getMyMembership(),
|
||||||
};
|
};
|
||||||
|
|
||||||
this.dispatcherRef = defaultDispatcher.register(this.onAction);
|
this.dispatcherRef = defaultDispatcher.register(this.onAction);
|
||||||
this.rightPanelStoreToken = RightPanelStore.getSharedInstance().addListener(this.onRightPanelStoreUpdate);
|
this.rightPanelStoreToken = RightPanelStore.getSharedInstance().addListener(this.onRightPanelStoreUpdate);
|
||||||
|
this.context.on("Room.myMembership", this.onMyMembership);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
defaultDispatcher.unregister(this.dispatcherRef);
|
defaultDispatcher.unregister(this.dispatcherRef);
|
||||||
this.rightPanelStoreToken.remove();
|
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 = () => {
|
private onRightPanelStoreUpdate = () => {
|
||||||
this.setState({
|
this.setState({
|
||||||
showRightPanel: RightPanelStore.getSharedInstance().isOpenForRoom,
|
showRightPanel: RightPanelStore.getSharedInstance().isOpenForRoom,
|
||||||
|
@ -600,10 +637,43 @@ export default class SpaceRoomView extends React.PureComponent<IProps, IState> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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() {
|
private renderBody() {
|
||||||
switch (this.state.phase) {
|
switch (this.state.phase) {
|
||||||
case Phase.Landing:
|
case Phase.Landing:
|
||||||
if (this.props.space.getMyMembership() === "join") {
|
if (this.state.myMembership === "join") {
|
||||||
return <SpaceLanding space={this.props.space} />;
|
return <SpaceLanding space={this.props.space} />;
|
||||||
} else {
|
} else {
|
||||||
return <SpacePreview
|
return <SpacePreview
|
||||||
|
@ -620,10 +690,7 @@ export default class SpaceRoomView extends React.PureComponent<IProps, IState> {
|
||||||
onFinished={() => this.setState({ phase: Phase.PublicShare })}
|
onFinished={() => this.setState({ phase: Phase.PublicShare })}
|
||||||
/>;
|
/>;
|
||||||
case Phase.PublicShare:
|
case Phase.PublicShare:
|
||||||
return <SpaceSetupPublicShare
|
return <SpaceSetupPublicShare space={this.props.space} onFinished={this.goToFirstRoom} />;
|
||||||
space={this.props.space}
|
|
||||||
onFinished={() => this.setState({ phase: Phase.Landing })}
|
|
||||||
/>;
|
|
||||||
|
|
||||||
case Phase.PrivateScope:
|
case Phase.PrivateScope:
|
||||||
return <SpaceSetupPrivateScope
|
return <SpaceSetupPrivateScope
|
||||||
|
|
|
@ -2631,6 +2631,7 @@
|
||||||
"Creating rooms...": "Creating rooms...",
|
"Creating rooms...": "Creating rooms...",
|
||||||
"It's just you at the moment.": "It's just you at the moment.",
|
"It's just you at the moment.": "It's just you at the moment.",
|
||||||
"%(spaceName)s will be even better with others": "%(spaceName)s will be even better with others",
|
"%(spaceName)s will be even better with others": "%(spaceName)s will be even better with others",
|
||||||
|
"Go to my first room": "Go to my first room",
|
||||||
"Who are you working with?": "Who are you working with?",
|
"Who are you working with?": "Who are you working with?",
|
||||||
"Ensure the right people have access to the space.": "Ensure the right people have access to the space.",
|
"Ensure the right people have access to the space.": "Ensure the right people have access to the space.",
|
||||||
"Just Me": "Just Me",
|
"Just Me": "Just Me",
|
||||||
|
|
|
@ -118,23 +118,32 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (space) {
|
if (space) {
|
||||||
try {
|
const data = await this.fetchSuggestedRooms(space);
|
||||||
const data: {
|
if (this._activeSpace === space) {
|
||||||
rooms: ISpaceSummaryRoom[];
|
this._suggestedRooms = data.rooms.filter(roomInfo => {
|
||||||
events: ISpaceSummaryEvent[];
|
return roomInfo.room_type !== RoomType.Space && !this.matrixClient.getRoom(roomInfo.room_id);
|
||||||
} = await this.matrixClient.getSpaceSummary(space.roomId, 0, true, false, MAX_SUGGESTED_ROOMS);
|
});
|
||||||
if (this._activeSpace === space) {
|
this.emit(SUGGESTED_ROOMS, this._suggestedRooms);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
public addRoomToSpace(space: Room, roomId: string, via: string[], suggested = false, autoJoin = false) {
|
||||||
return this.matrixClient.sendStateEvent(space.roomId, EventType.SpaceChild, {
|
return this.matrixClient.sendStateEvent(space.roomId, EventType.SpaceChild, {
|
||||||
via,
|
via,
|
||||||
|
|
Loading…
Reference in New Issue