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

Commit 0e4c0ba

Browse files
committed
Expire video member events after 1 hour
1 parent 5da187d commit 0e4c0ba

File tree

12 files changed

+342
-244
lines changed

12 files changed

+342
-244
lines changed

res/css/_components.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,7 @@
275275
@import "./views/rooms/_ThreadSummary.scss";
276276
@import "./views/rooms/_TopUnreadMessagesBar.scss";
277277
@import "./views/rooms/_VoiceRecordComposerTile.scss";
278+
@import "./views/rooms/_VideoRoomSummary.scss";
278279
@import "./views/rooms/_WhoIsTypingTile.scss";
279280
@import "./views/settings/_AvatarSetting.scss";
280281
@import "./views/settings/_CrossSigningPanel.scss";

res/css/views/rooms/_RoomTile.scss

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -75,40 +75,6 @@ limitations under the License.
7575
.mx_RoomTile_subtitle {
7676
line-height: $font-18px;
7777
color: $secondary-content;
78-
79-
.mx_RoomTile_videoIndicator {
80-
&::before {
81-
display: inline-block;
82-
vertical-align: text-bottom;
83-
content: '';
84-
background-color: $secondary-content;
85-
mask-image: url('$(res)/img/element-icons/call/video-call.svg');
86-
mask-size: 16px;
87-
width: 16px;
88-
height: 16px;
89-
margin-right: 4px;
90-
}
91-
92-
&.mx_RoomTile_videoIndicator_active {
93-
color: $accent;
94-
95-
&::before {
96-
background-color: $accent;
97-
}
98-
}
99-
}
100-
101-
.mx_RoomTile_videoParticipants::before {
102-
display: inline-block;
103-
vertical-align: text-bottom;
104-
content: '';
105-
background-color: $secondary-content;
106-
mask-image: url('$(res)/img/element-icons/group-members.svg');
107-
mask-size: 16px;
108-
width: 16px;
109-
height: 16px;
110-
margin-right: 2px;
111-
}
11278
}
11379

11480
.mx_RoomTile_titleWithSubtitle {
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
Copyright 2022 The Matrix.org Foundation C.I.C.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
.mx_VideoRoomSummary {
18+
.mx_VideoRoomSummary_indicator {
19+
&::before {
20+
display: inline-block;
21+
vertical-align: text-bottom;
22+
content: '';
23+
background-color: $secondary-content;
24+
mask-image: url('$(res)/img/element-icons/call/video-call.svg');
25+
mask-size: 16px;
26+
width: 16px;
27+
height: 16px;
28+
margin-right: 4px;
29+
}
30+
31+
&.mx_VideoRoomSummary_indicator_active {
32+
color: $accent;
33+
34+
&::before {
35+
background-color: $accent;
36+
}
37+
}
38+
}
39+
40+
.mx_VideoRoomSummary_participants::before {
41+
display: inline-block;
42+
vertical-align: text-bottom;
43+
content: '';
44+
background-color: $secondary-content;
45+
mask-image: url('$(res)/img/element-icons/group-members.svg');
46+
mask-size: 16px;
47+
width: 16px;
48+
height: 16px;
49+
margin-right: 2px;
50+
}
51+
}

src/components/views/rooms/RoomTile.tsx

Lines changed: 2 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@ import React, { createRef } from "react";
1919
import { Room, RoomEvent } from "matrix-js-sdk/src/models/room";
2020
import classNames from "classnames";
2121
import { logger } from "matrix-js-sdk/src/logger";
22-
import { RoomMember } from "matrix-js-sdk/src/models/room-member";
23-
import { RoomStateEvent } from "matrix-js-sdk/src/models/room-state";
2422

2523
import { RovingTabIndexWrapper } from "../../../accessibility/RovingTabIndex";
2624
import AccessibleButton, { ButtonEvent } from "../../views/elements/AccessibleButton";
@@ -50,19 +48,12 @@ import IconizedContextMenu, {
5048
IconizedContextMenuOptionList,
5149
IconizedContextMenuRadio,
5250
} from "../context_menus/IconizedContextMenu";
53-
import VideoChannelStore, { VideoChannelEvent, IJitsiParticipant } from "../../../stores/VideoChannelStore";
54-
import { getConnectedMembers } from "../../../utils/VideoChannelUtils";
5551
import PosthogTrackers from "../../../PosthogTrackers";
5652
import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload";
5753
import { KeyBindingAction } from "../../../accessibility/KeyboardShortcuts";
5854
import { getKeyBindingsManager } from "../../../KeyBindingsManager";
5955
import { RoomViewStore } from "../../../stores/RoomViewStore";
60-
61-
enum VideoStatus {
62-
Disconnected,
63-
Connecting,
64-
Connected,
65-
}
56+
import VideoRoomSummary from "./VideoRoomSummary";
6657

6758
interface IProps {
6859
room: Room;
@@ -78,11 +69,6 @@ interface IState {
7869
notificationsMenuPosition: PartialDOMRect;
7970
generalMenuPosition: PartialDOMRect;
8071
messagePreview?: string;
81-
videoStatus: VideoStatus;
82-
// Active video channel members, according to room state
83-
videoMembers: Set<RoomMember>;
84-
// Active video channel members, according to Jitsi
85-
jitsiParticipants: IJitsiParticipant[];
8672
}
8773

8874
const messagePreviewId = (roomId: string) => `mx_RoomTile_messagePreview_${roomId}`;
@@ -105,26 +91,12 @@ export default class RoomTile extends React.PureComponent<IProps, IState> {
10591
constructor(props: IProps) {
10692
super(props);
10793

108-
let videoStatus;
109-
if (VideoChannelStore.instance.roomId === this.props.room.roomId) {
110-
if (VideoChannelStore.instance.connected) {
111-
videoStatus = VideoStatus.Connected;
112-
} else {
113-
videoStatus = VideoStatus.Connecting;
114-
}
115-
} else {
116-
videoStatus = VideoStatus.Disconnected;
117-
}
118-
11994
this.state = {
12095
selected: RoomViewStore.instance.getRoomId() === this.props.room.roomId,
12196
notificationsMenuPosition: null,
12297
generalMenuPosition: null,
12398
// generatePreview() will return nothing if the user has previews disabled
12499
messagePreview: "",
125-
videoStatus,
126-
videoMembers: getConnectedMembers(this.props.room, videoStatus === VideoStatus.Connected),
127-
jitsiParticipants: VideoChannelStore.instance.participants,
128100
};
129101
this.generatePreview();
130102

@@ -169,9 +141,6 @@ export default class RoomTile extends React.PureComponent<IProps, IState> {
169141
MessagePreviewStore.getPreviewChangedEventName(this.props.room),
170142
this.onRoomPreviewChanged,
171143
);
172-
prevProps.room?.currentState?.off(RoomStateEvent.Events, this.updateVideoMembers);
173-
this.props.room?.currentState?.on(RoomStateEvent.Events, this.updateVideoMembers);
174-
this.updateVideoStatus();
175144
prevProps.room?.off(RoomEvent.Name, this.onRoomNameUpdate);
176145
this.props.room?.on(RoomEvent.Name, this.onRoomNameUpdate);
177146
}
@@ -192,14 +161,6 @@ export default class RoomTile extends React.PureComponent<IProps, IState> {
192161
this.notificationState.on(NotificationStateEvents.Update, this.onNotificationUpdate);
193162
this.roomProps.on(PROPERTY_UPDATED, this.onRoomPropertyUpdate);
194163
this.props.room.on(RoomEvent.Name, this.onRoomNameUpdate);
195-
this.props.room.currentState.on(RoomStateEvent.Events, this.updateVideoMembers);
196-
197-
VideoChannelStore.instance.on(VideoChannelEvent.Connect, this.onConnectVideo);
198-
VideoChannelStore.instance.on(VideoChannelEvent.StartConnect, this.onStartConnectVideo);
199-
VideoChannelStore.instance.on(VideoChannelEvent.Disconnect, this.onDisconnectVideo);
200-
if (VideoChannelStore.instance.roomId === this.props.room.roomId) {
201-
VideoChannelStore.instance.on(VideoChannelEvent.Participants, this.updateJitsiParticipants);
202-
}
203164
}
204165

205166
public componentWillUnmount() {
@@ -209,14 +170,9 @@ export default class RoomTile extends React.PureComponent<IProps, IState> {
209170
this.onRoomPreviewChanged,
210171
);
211172
this.props.room.off(RoomEvent.Name, this.onRoomNameUpdate);
212-
this.props.room.currentState.off(RoomStateEvent.Events, this.updateVideoMembers);
213173
defaultDispatcher.unregister(this.dispatcherRef);
214174
this.notificationState.off(NotificationStateEvents.Update, this.onNotificationUpdate);
215175
this.roomProps.off(PROPERTY_UPDATED, this.onRoomPropertyUpdate);
216-
217-
VideoChannelStore.instance.off(VideoChannelEvent.Connect, this.onConnectVideo);
218-
VideoChannelStore.instance.off(VideoChannelEvent.StartConnect, this.onStartConnectVideo);
219-
VideoChannelStore.instance.off(VideoChannelEvent.Disconnect, this.onDisconnectVideo);
220176
}
221177

222178
private onAction = (payload: ActionPayload) => {
@@ -591,54 +547,6 @@ export default class RoomTile extends React.PureComponent<IProps, IState> {
591547
);
592548
}
593549

594-
private updateVideoMembers = () => {
595-
this.setState(state => ({
596-
videoMembers: getConnectedMembers(this.props.room, state.videoStatus === VideoStatus.Connected),
597-
}));
598-
};
599-
600-
private updateVideoStatus = () => {
601-
if (VideoChannelStore.instance.roomId === this.props.room?.roomId) {
602-
if (VideoChannelStore.instance.connected) {
603-
this.onConnectVideo(this.props.room?.roomId);
604-
} else {
605-
this.onStartConnectVideo(this.props.room?.roomId);
606-
}
607-
} else {
608-
this.onDisconnectVideo(this.props.room?.roomId);
609-
}
610-
};
611-
612-
private onConnectVideo = (roomId: string) => {
613-
if (roomId === this.props.room?.roomId) {
614-
this.setState({
615-
videoStatus: VideoStatus.Connected,
616-
videoMembers: getConnectedMembers(this.props.room, true),
617-
});
618-
VideoChannelStore.instance.on(VideoChannelEvent.Participants, this.updateJitsiParticipants);
619-
}
620-
};
621-
622-
private onStartConnectVideo = (roomId: string) => {
623-
if (roomId === this.props.room?.roomId) {
624-
this.setState({ videoStatus: VideoStatus.Connecting });
625-
}
626-
};
627-
628-
private onDisconnectVideo = (roomId: string) => {
629-
if (roomId === this.props.room?.roomId) {
630-
this.setState({
631-
videoStatus: VideoStatus.Disconnected,
632-
videoMembers: getConnectedMembers(this.props.room, false),
633-
});
634-
VideoChannelStore.instance.off(VideoChannelEvent.Participants, this.updateJitsiParticipants);
635-
}
636-
};
637-
638-
private updateJitsiParticipants = (roomId: string, participants: IJitsiParticipant[]) => {
639-
this.setState({ jitsiParticipants: participants });
640-
};
641-
642550
public render(): React.ReactElement {
643551
const classes = classNames({
644552
'mx_RoomTile': true,
@@ -667,46 +575,9 @@ export default class RoomTile extends React.PureComponent<IProps, IState> {
667575

668576
let subtitle;
669577
if (this.isVideoRoom) {
670-
let videoText: string;
671-
let videoActive: boolean;
672-
let participantCount: number;
673-
674-
switch (this.state.videoStatus) {
675-
case VideoStatus.Disconnected:
676-
videoText = _t("Video");
677-
videoActive = false;
678-
participantCount = this.state.videoMembers.size;
679-
break;
680-
case VideoStatus.Connecting:
681-
videoText = _t("Joining…");
682-
videoActive = true;
683-
participantCount = this.state.videoMembers.size;
684-
break;
685-
case VideoStatus.Connected:
686-
videoText = _t("Joined");
687-
videoActive = true;
688-
participantCount = this.state.jitsiParticipants.length;
689-
}
690-
691578
subtitle = (
692579
<div className="mx_RoomTile_subtitle">
693-
<span
694-
className={classNames({
695-
"mx_RoomTile_videoIndicator": true,
696-
"mx_RoomTile_videoIndicator_active": videoActive,
697-
})}
698-
>
699-
{ videoText }
700-
</span>
701-
{ participantCount ? <>
702-
{ " · " }
703-
<span
704-
className="mx_RoomTile_videoParticipants"
705-
aria-label={_t("%(count)s participants", { count: participantCount })}
706-
>
707-
{ participantCount }
708-
</span>
709-
</> : null }
580+
<VideoRoomSummary room={this.props.room} />
710581
</div>
711582
);
712583
} else if (this.showMessagePreview && this.state.messagePreview) {
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/*
2+
Copyright 2022 The Matrix.org Foundation C.I.C.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
import React, { FC } from "react";
18+
import classNames from "classnames";
19+
import { Room } from "matrix-js-sdk/src/models/room";
20+
21+
import { _t } from "../../../languageHandler";
22+
import {
23+
ConnectionState,
24+
useConnectionState,
25+
useConnectedMembers,
26+
useJitsiParticipants,
27+
} from "../../../utils/VideoChannelUtils";
28+
29+
interface IProps {
30+
room: Room;
31+
}
32+
33+
const VideoRoomSummary: FC<IProps> = ({ room }) => {
34+
const connectionState = useConnectionState(room);
35+
const videoMembers = useConnectedMembers(room, connectionState === ConnectionState.Connected);
36+
const jitsiParticipants = useJitsiParticipants(room);
37+
38+
let indicator: string;
39+
let active: boolean;
40+
let participantCount: number;
41+
42+
switch (connectionState) {
43+
case ConnectionState.Disconnected:
44+
indicator = _t("Video");
45+
active = false;
46+
participantCount = videoMembers.size;
47+
break;
48+
case ConnectionState.Connecting:
49+
indicator = _t("Joining…");
50+
active = true;
51+
participantCount = videoMembers.size;
52+
break;
53+
case ConnectionState.Connected:
54+
indicator = _t("Joined");
55+
active = true;
56+
participantCount = jitsiParticipants.length;
57+
}
58+
59+
return <span className="mx_VideoRoomSummary">
60+
<span
61+
className={classNames(
62+
"mx_VideoRoomSummary_indicator",
63+
{ "mx_VideoRoomSummary_indicator_active": active },
64+
)}
65+
>
66+
{ indicator }
67+
</span>
68+
{ participantCount ? <>
69+
{ " · " }
70+
<span
71+
className="mx_VideoRoomSummary_participants"
72+
aria-label={_t("%(count)s participants", { count: participantCount })}
73+
>
74+
{ participantCount }
75+
</span>
76+
</> : null }
77+
</span>;
78+
};
79+
80+
export default VideoRoomSummary;

0 commit comments

Comments
 (0)