Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Commit

Permalink
Add connecting state
Browse files Browse the repository at this point in the history
  • Loading branch information
robintown committed Apr 11, 2022
1 parent 6d81169 commit 0485acd
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 31 deletions.
57 changes: 48 additions & 9 deletions src/components/views/rooms/RoomTile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ import { RoomViewStore } from "../../../stores/RoomViewStore";

enum VideoStatus {
Disconnected,
Connecting,
Connected,
}

Expand Down Expand Up @@ -105,17 +106,26 @@ export default class RoomTile extends React.PureComponent<IProps, IState> {
constructor(props: IProps) {
super(props);

const videoConnected = VideoChannelStore.instance.roomId === this.props.room.roomId;
let videoStatus;
if (VideoChannelStore.instance.roomId === this.props.room.roomId) {
if (VideoChannelStore.instance.connected) {
videoStatus = VideoStatus.Connected;
} else {
videoStatus = VideoStatus.Connecting;
}
} else {
videoStatus = VideoStatus.Disconnected;
}

this.state = {
selected: RoomViewStore.instance.getRoomId() === this.props.room.roomId,
notificationsMenuPosition: null,
generalMenuPosition: null,
// generatePreview() will return nothing if the user has previews disabled
messagePreview: "",
videoStatus: videoConnected ? VideoStatus.Connected : VideoStatus.Disconnected,
videoStatus,
videoMembers: getConnectedMembers(this.props.room.currentState),
jitsiParticipants: videoConnected ? VideoChannelStore.instance.participants : [],
jitsiParticipants: VideoChannelStore.instance.participants,
};
this.generatePreview();

Expand Down Expand Up @@ -185,8 +195,9 @@ export default class RoomTile extends React.PureComponent<IProps, IState> {
this.props.room.on(RoomEvent.Name, this.onRoomNameUpdate);
this.props.room.currentState.on(RoomStateEvent.Events, this.updateVideoMembers);

VideoChannelStore.instance.on(VideoChannelEvent.Connect, this.updateVideoStatus);
VideoChannelStore.instance.on(VideoChannelEvent.Disconnect, this.updateVideoStatus);
VideoChannelStore.instance.on(VideoChannelEvent.Connect, this.onConnectVideo);
VideoChannelStore.instance.on(VideoChannelEvent.StartConnect, this.onStartConnectVideo);
VideoChannelStore.instance.on(VideoChannelEvent.Disconnect, this.onDisconnectVideo);
if (VideoChannelStore.instance.roomId === this.props.room.roomId) {
VideoChannelStore.instance.on(VideoChannelEvent.Participants, this.updateJitsiParticipants);
}
Expand All @@ -204,8 +215,9 @@ export default class RoomTile extends React.PureComponent<IProps, IState> {
this.notificationState.off(NotificationStateEvents.Update, this.onNotificationUpdate);
this.roomProps.off(PROPERTY_UPDATED, this.onRoomPropertyUpdate);

VideoChannelStore.instance.off(VideoChannelEvent.Connect, this.updateVideoStatus);
VideoChannelStore.instance.off(VideoChannelEvent.Disconnect, this.updateVideoStatus);
VideoChannelStore.instance.off(VideoChannelEvent.Connect, this.onConnectVideo);
VideoChannelStore.instance.off(VideoChannelEvent.StartConnect, this.onStartConnectVideo);
VideoChannelStore.instance.off(VideoChannelEvent.Disconnect, this.onDisconnectVideo);
}

private onAction = (payload: ActionPayload) => {
Expand Down Expand Up @@ -586,15 +598,37 @@ export default class RoomTile extends React.PureComponent<IProps, IState> {

private updateVideoStatus = () => {
if (VideoChannelStore.instance.roomId === this.props.room?.roomId) {
if (VideoChannelStore.instance.connected) {
this.onConnectVideo(this.props.room?.roomId);
} else {
this.onStartConnectVideo(this.props.room?.roomId);
}
} else {
this.onDisconnectVideo(this.props.room?.roomId);
}
};

private onConnectVideo = (roomId: string) => {
if (roomId === this.props.room?.roomId) {
this.setState({ videoStatus: VideoStatus.Connected });
VideoChannelStore.instance.on(VideoChannelEvent.Participants, this.updateJitsiParticipants);
} else {
}
};

private onStartConnectVideo = (roomId: string) => {
if (roomId === this.props.room?.roomId) {
this.setState({ videoStatus: VideoStatus.Connecting });
}
};

private onDisconnectVideo = (roomId: string) => {
if (roomId === this.props.room?.roomId) {
this.setState({ videoStatus: VideoStatus.Disconnected });
VideoChannelStore.instance.off(VideoChannelEvent.Participants, this.updateJitsiParticipants);
}
};

private updateJitsiParticipants = (participants: IJitsiParticipant[]) => {
private updateJitsiParticipants = (roomId: string, participants: IJitsiParticipant[]) => {
this.setState({ jitsiParticipants: participants });
};

Expand Down Expand Up @@ -636,6 +670,11 @@ export default class RoomTile extends React.PureComponent<IProps, IState> {
videoActive = false;
participantCount = this.state.videoMembers.length;
break;
case VideoStatus.Connecting:
videoText = _t("Connecting...");
videoActive = true;
participantCount = this.state.videoMembers.length;
break;
case VideoStatus.Connected:
videoText = _t("Connected");
videoActive = true;
Expand Down
1 change: 1 addition & 0 deletions src/i18n/strings/en_EN.json
Original file line number Diff line number Diff line change
Expand Up @@ -1862,6 +1862,7 @@
"Copy room link": "Copy room link",
"Leave": "Leave",
"Video": "Video",
"Connecting...": "Connecting...",
"Connected": "Connected",
"%(count)s participants|other": "%(count)s participants",
"%(count)s participants|one": "1 participant",
Expand Down
39 changes: 20 additions & 19 deletions src/stores/VideoChannelStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { timeout } from "../utils/promise";
import WidgetUtils from "../utils/WidgetUtils";

export enum VideoChannelEvent {
StartConnect = "start_connect",
Connect = "connect",
Disconnect = "disconnect",
Participants = "participants",
Expand Down Expand Up @@ -57,24 +58,18 @@ export default class VideoChannelStore extends EventEmitter {

private readonly cli = MatrixClientPeg.get();
private activeChannel: ClientWidgetApi;

private _roomId: string;
private _participants: IJitsiParticipant[];
public get roomId(): string { return this._roomId; }
private set roomId(value: string) { this._roomId = value; }

public get roomId(): string {
return this._roomId;
}
private _connected = false;
public get connected(): boolean { return this._connected; }
private set connected(value: boolean) { this._connected = value; }

private set roomId(value: string) {
this._roomId = value;
}

public get participants(): IJitsiParticipant[] {
return this._participants;
}

private set participants(value: IJitsiParticipant[]) {
this._participants = value;
}
private _participants: IJitsiParticipant[] = [];
public get participants(): IJitsiParticipant[] { return this._participants; }
private set participants(value: IJitsiParticipant[]) { this._participants = value; }

public connect = async (roomId: string, audioDevice: MediaDeviceInfo, videoDevice: MediaDeviceInfo) => {
if (this.activeChannel) await this.disconnect();
Expand All @@ -91,6 +86,8 @@ export default class VideoChannelStore extends EventEmitter {
// Participant data will come down the event pipeline quickly, so prepare in advance
messaging.on(`action:${ElementWidgetActions.CallParticipants}`, this.onParticipants);

this.emit(VideoChannelEvent.StartConnect, roomId);

// Actually perform the join
const waitForJoin = this.waitForAction(ElementWidgetActions.JoinCall);
messaging.transport.send(ElementWidgetActions.JoinCall, {
Expand All @@ -105,12 +102,15 @@ export default class VideoChannelStore extends EventEmitter {
this.roomId = null;
messaging.off(`action:${ElementWidgetActions.CallParticipants}`, this.onParticipants);

this.emit(VideoChannelEvent.Disconnect, roomId);

throw e;
}

this.connected = true;
messaging.once(`action:${ElementWidgetActions.HangupCall}`, this.onHangup);

this.emit(VideoChannelEvent.Connect);
this.emit(VideoChannelEvent.Connect, roomId);

// Tell others that we're connected, by adding our device to room state
this.updateDevices(roomId, devices => Array.from(new Set(devices).add(this.cli.getDeviceId())));
Expand Down Expand Up @@ -163,9 +163,10 @@ export default class VideoChannelStore extends EventEmitter {
const roomId = this.roomId;
this.activeChannel = null;
this.roomId = null;
this.participants = null;
this.connected = false;
this.participants = [];

this.emit(VideoChannelEvent.Disconnect);
this.emit(VideoChannelEvent.Disconnect, roomId);

// Tell others that we're disconnected, by removing our device from room state
await this.updateDevices(roomId, devices => {
Expand All @@ -177,7 +178,7 @@ export default class VideoChannelStore extends EventEmitter {

private onParticipants = (ev: CustomEvent<IWidgetApiRequest>) => {
this.participants = ev.detail.data.participants as IJitsiParticipant[];
this.emit(VideoChannelEvent.Participants, ev.detail.data.participants);
this.emit(VideoChannelEvent.Participants, this.roomId, ev.detail.data.participants);
this.ack(ev);
};
}
4 changes: 4 additions & 0 deletions test/components/views/rooms/RoomTile-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ describe("RoomTile", () => {
);
expect(tile.find(".mx_RoomTile_videoIndicator").text()).toEqual("Video");

act(() => { store.startConnect("!1:example.org"); });
tile.update();
expect(tile.find(".mx_RoomTile_videoIndicator").text()).toEqual("Connecting...");

act(() => { store.connect("!1:example.org"); });
tile.update();
expect(tile.find(".mx_RoomTile_videoIndicator").text()).toEqual("Connected");
Expand Down
12 changes: 9 additions & 3 deletions test/test-utils/video.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,25 @@ limitations under the License.

import { EventEmitter } from "events";

import VideoChannelStore, { VideoChannelEvent } from "../../src/stores/VideoChannelStore";
import VideoChannelStore, { VideoChannelEvent, IJitsiParticipant } from "../../src/stores/VideoChannelStore";

class StubVideoChannelStore extends EventEmitter {
private _roomId: string;
public get roomId(): string { return this._roomId; }
public get participants(): IJitsiParticipant[] { return []; }

public startConnect = (roomId: string) => {
this._roomId = roomId;
this.emit(VideoChannelEvent.StartConnect, roomId);
};
public connect = (roomId: string) => {
this._roomId = roomId;
this.emit(VideoChannelEvent.Connect);
this.emit(VideoChannelEvent.Connect, roomId);
};
public disconnect = () => {
const roomId = this._roomId;
this._roomId = null;
this.emit(VideoChannelEvent.Disconnect);
this.emit(VideoChannelEvent.Disconnect, roomId);
};
}

Expand Down

0 comments on commit 0485acd

Please sign in to comment.