Hook up CallEventGrouper

Signed-off-by: Šimon Brandner <simon.bra.ag@gmail.com>
This commit is contained in:
Šimon Brandner 2021-05-30 16:28:30 +02:00
parent 8dc0e2a7ab
commit 85bcf8ed52
No known key found for this signature in database
GPG key ID: 9760693FDD98A790
4 changed files with 29 additions and 140 deletions

View file

@ -26,7 +26,6 @@ import * as sdk from '../../index';
import {MatrixClientPeg} from '../../MatrixClientPeg';
import SettingsStore from '../../settings/SettingsStore';
import TimelineCallEventStore from "../../stores/TimelineCallEventStore";
import {Layout, LayoutPropType} from "../../settings/Layout";
import {_t} from "../../languageHandler";
import {haveTileForEvent} from "../views/rooms/EventTile";
@ -36,6 +35,7 @@ import DMRoomMap from "../../utils/DMRoomMap";
import NewRoomIntro from "../views/rooms/NewRoomIntro";
import {replaceableComponent} from "../../utils/replaceableComponent";
import defaultDispatcher from '../../dispatcher/dispatcher';
import CallEventGrouper from "./CallEventGrouper";
const CONTINUATION_MAX_INTERVAL = 5 * 60 * 1000; // 5 minutes
const continuedTypes = ['m.sticker', 'm.room.message'];
@ -210,6 +210,9 @@ export default class MessagePanel extends React.Component {
this._showTypingNotificationsWatcherRef =
SettingsStore.watchSetting("showTypingNotifications", null, this.onShowTypingNotificationsChange);
// A map of <callId, CallEventGrouper>
this._callEventGroupers = new Map();
}
componentDidMount() {
@ -530,7 +533,20 @@ export default class MessagePanel extends React.Component {
const last = (mxEv === lastShownEvent);
const {nextEvent, nextTile} = this._getNextEventInfo(this.props.events, i);
TimelineCallEventStore.instance.addEvent(mxEv);
if (
mxEv.getType().indexOf("m.call.") === 0 ||
mxEv.getType().indexOf("org.matrix.call.") === 0
) {
const callId = mxEv.getContent().call_id;
if (this._callEventGroupers.has(callId)) {
this._callEventGroupers.get(callId).add(mxEv);
} else {
const callEventGrouper = new CallEventGrouper();
callEventGrouper.add(mxEv);
this._callEventGroupers.set(callId, callEventGrouper);
}
}
if (grouper) {
if (grouper.shouldGroup(mxEv)) {
@ -646,6 +662,8 @@ export default class MessagePanel extends React.Component {
// it's successful: we received it.
isLastSuccessful = isLastSuccessful && mxEv.getSender() === MatrixClientPeg.get().getUserId();
const callState = this._callEventGroupers.get(mxEv.getContent().call_id)?.getState();
// use txnId as key if available so that we don't remount during sending
ret.push(
<li
@ -678,6 +696,7 @@ export default class MessagePanel extends React.Component {
layout={this.props.layout}
enableFlair={this.props.enableFlair}
showReadReceipts={this.props.showReadReceipts}
callState={callState}
/>
</TileErrorBoundary>
</li>,

View file

@ -18,62 +18,18 @@ import React from 'react';
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
import { _t } from '../../../languageHandler';
import TimelineCallEventStore, {
TimelineCall as TimelineCallSt,
TimelineCallEventStoreEvent,
TimelineCallState,
} from "../../../stores/TimelineCallEventStore";
import MemberAvatar from '../avatars/MemberAvatar';
import { TimelineCallState } from '../../structures/CallEventGrouper';
interface IProps {
mxEvent: MatrixEvent;
}
interface IState {
callState: TimelineCallState;
}
export default class CallEvent extends React.Component<IProps, IState> {
constructor(props: IProps) {
super(props);
this.state = {
callState: null,
}
}
componentDidMount() {
TimelineCallEventStore.instance.addListener(TimelineCallEventStoreEvent.CallsChanged, this.onCallsChanged);
}
componentWillUnmount() {
TimelineCallEventStore.instance.removeListener(TimelineCallEventStoreEvent.CallsChanged, this.onCallsChanged);
}
private onCallsChanged = (calls: Map<string, TimelineCallSt>) => {
const callId = this.props.mxEvent.getContent().call_id;
const call = calls.get(callId);
if (!call) return;
this.setState({callState: call.state});
}
private isVoice(): boolean {
const event = this.props.mxEvent;
// FIXME: Find a better way to determine this from the event?
let isVoice = true;
if (event.getContent().offer && event.getContent().offer.sdp &&
event.getContent().offer.sdp.indexOf('m=video') !== -1) {
isVoice = false;
}
return isVoice;
}
export default class CallEvent extends React.Component<IProps> {
render() {
const event = this.props.mxEvent;
const sender = event.sender ? event.sender.name : event.getSender();
const state = this.state.callState;
return (
<div className="mx_CallEvent">
@ -87,8 +43,7 @@ export default class CallEvent extends React.Component<IProps, IState> {
{sender}
</div>
<div className="mx_CallEvent_type">
{ this.isVoice() ? _t("Voice call") : _t("Video call") }
{ state ? state : TimelineCallState.Unknown }
{ this.props.callState.isVoice ? _t("Voice call") : _t("Video call") }
</div>
</div>
</div>

View file

@ -46,6 +46,7 @@ import { EditorStateTransfer } from "../../../utils/EditorStateTransfer";
import { RoomPermalinkCreator } from '../../../utils/permalinks/Permalinks';
import {StaticNotificationState} from "../../../stores/notifications/StaticNotificationState";
import NotificationBadge from "./NotificationBadge";
import { TimelineCallState } from "../../structures/CallEventGrouper";
const eventTileTypes = {
[EventType.RoomMessage]: 'messages.MessageEvent',
@ -274,6 +275,9 @@ interface IProps {
// Helper to build permalinks for the room
permalinkCreator?: RoomPermalinkCreator;
// CallEventGrouper for this event
callState?: TimelineCallState;
}
interface IState {
@ -1139,6 +1143,7 @@ export default class EventTile extends React.Component<IProps, IState> {
showUrlPreview={this.props.showUrlPreview}
permalinkCreator={this.props.permalinkCreator}
onHeightChanged={this.props.onHeightChanged}
callState={this.props.callState}
/>
{ keyRequestInfo }
{ reactionsRow }