Display spinner in user menu when joining a room

This commit is contained in:
Germain Souquet 2021-05-24 15:02:26 +01:00
parent 19569f3897
commit 36d95ff737
2 changed files with 53 additions and 7 deletions

View file

@ -57,7 +57,8 @@ import { IHostSignupConfig } from "../views/dialogs/HostSignupDialogTypes";
import SpaceStore, { UPDATE_SELECTED_SPACE } from "../../stores/SpaceStore"; import SpaceStore, { UPDATE_SELECTED_SPACE } from "../../stores/SpaceStore";
import RoomName from "../views/elements/RoomName"; import RoomName from "../views/elements/RoomName";
import {replaceableComponent} from "../../utils/replaceableComponent"; import {replaceableComponent} from "../../utils/replaceableComponent";
import InlineSpinner from "../views/elements/InlineSpinner";
import TooltipButton from "../views/elements/TooltipButton";
interface IProps { interface IProps {
isMinimized: boolean; isMinimized: boolean;
} }
@ -68,6 +69,7 @@ interface IState {
contextMenuPosition: PartialDOMRect; contextMenuPosition: PartialDOMRect;
isDarkTheme: boolean; isDarkTheme: boolean;
selectedSpace?: Room; selectedSpace?: Room;
pendingRoomJoin: string[]
} }
@replaceableComponent("structures.UserMenu") @replaceableComponent("structures.UserMenu")
@ -84,6 +86,7 @@ export default class UserMenu extends React.Component<IProps, IState> {
this.state = { this.state = {
contextMenuPosition: null, contextMenuPosition: null,
isDarkTheme: this.isUserOnDarkTheme(), isDarkTheme: this.isUserOnDarkTheme(),
pendingRoomJoin: [],
}; };
OwnProfileStore.instance.on(UPDATE_EVENT, this.onProfileUpdate); OwnProfileStore.instance.on(UPDATE_EVENT, this.onProfileUpdate);
@ -147,15 +150,48 @@ export default class UserMenu extends React.Component<IProps, IState> {
}; };
private onAction = (ev: ActionPayload) => { private onAction = (ev: ActionPayload) => {
if (ev.action !== Action.ToggleUserMenu) return; // not interested switch (ev.action) {
case Action.ToggleUserMenu:
if (this.state.contextMenuPosition) { if (this.state.contextMenuPosition) {
this.setState({contextMenuPosition: null}); this.setState({contextMenuPosition: null});
} else { } else {
if (this.buttonRef.current) this.buttonRef.current.click(); if (this.buttonRef.current) this.buttonRef.current.click();
}
break;
case Action.JoinRoom:
this.addPendingJoinRoom(ev.roomId);
break;
case Action.JoinRoomReady:
case Action.JoinRoomError:
this.removePendingJoinRoom(ev.roomId);
break;
} }
}; };
private addPendingJoinRoom(roomId) {
this.setState({
pendingRoomJoin: [
...this.state.pendingRoomJoin,
roomId,
],
});
}
private removePendingJoinRoom(roomId) {
const newPendingRoomJoin = this.state.pendingRoomJoin.filter(pendingJoinRoomId => {
return pendingJoinRoomId !== roomId;
});
if (newPendingRoomJoin.length !== this.state.pendingRoomJoin.length) {
this.setState({
pendingRoomJoin: newPendingRoomJoin,
})
}
}
get hasPendingActions(): boolean {
return this.state.pendingRoomJoin.length > 0;
}
private onOpenMenuClick = (ev: React.MouseEvent) => { private onOpenMenuClick = (ev: React.MouseEvent) => {
ev.preventDefault(); ev.preventDefault();
ev.stopPropagation(); ev.stopPropagation();
@ -617,6 +653,14 @@ export default class UserMenu extends React.Component<IProps, IState> {
/> />
</span> </span>
{name} {name}
{this.hasPendingActions && (
<InlineSpinner>
<TooltipButton helpText={_t(
"Currently joining %(count)s rooms",
{ count: this.state.pendingRoomJoin.length },
)} />
</InlineSpinner>
)}
{dnd} {dnd}
{buttons} {buttons}
</div> </div>

View file

@ -2753,6 +2753,8 @@
"Switch theme": "Switch theme", "Switch theme": "Switch theme",
"User menu": "User menu", "User menu": "User menu",
"Community and user menu": "Community and user menu", "Community and user menu": "Community and user menu",
"Currently joining %(count)s rooms|one": "Currently joining %(count)s room",
"Currently joining %(count)s rooms|other": "Currently joining %(count)s rooms",
"Could not load user profile": "Could not load user profile", "Could not load user profile": "Could not load user profile",
"Decrypted event source": "Decrypted event source", "Decrypted event source": "Decrypted event source",
"Original event source": "Original event source", "Original event source": "Original event source",