Handle missed calls

Signed-off-by: Šimon Brandner <simon.bra.ag@gmail.com>
This commit is contained in:
Šimon Brandner 2021-06-01 11:28:45 +02:00
parent 5b3967a486
commit 0785997983
No known key found for this signature in database
GPG key ID: 9760693FDD98A790
3 changed files with 38 additions and 11 deletions

View file

@ -48,5 +48,10 @@ limitations under the License.
.mx_CallEvent_content { .mx_CallEvent_content {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
align-items: center;
.mx_CallEvent_content_callBack {
margin-left: 10px; // To match mx_callEvent
}
} }
} }

View file

@ -17,9 +17,11 @@ limitations under the License.
import { EventType } from "matrix-js-sdk/src/@types/event"; import { EventType } from "matrix-js-sdk/src/@types/event";
import { MatrixEvent } from "matrix-js-sdk/src/models/event"; import { MatrixEvent } from "matrix-js-sdk/src/models/event";
import { CallEvent, CallState, MatrixCall } from "matrix-js-sdk/src/webrtc/call"; import { CallEvent, CallState, CallType, MatrixCall } from "matrix-js-sdk/src/webrtc/call";
import CallHandler from '../../CallHandler'; import CallHandler from '../../CallHandler';
import { EventEmitter } from 'events'; import { EventEmitter } from 'events';
import { MatrixClientPeg } from "../../MatrixClientPeg";
import defaultDispatcher from "../../dispatcher/dispatcher";
export enum CallEventGrouperEvent { export enum CallEventGrouperEvent {
StateChanged = "state_changed", StateChanged = "state_changed",
@ -32,10 +34,14 @@ const SUPPORTED_STATES = [
CallState.Ringing, CallState.Ringing,
]; ];
export enum CustomCallState {
Missed = "missed",
}
export default class CallEventGrouper extends EventEmitter { export default class CallEventGrouper extends EventEmitter {
events: Array<MatrixEvent> = []; events: Array<MatrixEvent> = [];
call: MatrixCall; call: MatrixCall;
state: CallState; state: CallState | CustomCallState;
private get invite(): MatrixEvent { private get invite(): MatrixEvent {
return this.events.find((event) => event.getType() === EventType.CallInvite); return this.events.find((event) => event.getType() === EventType.CallInvite);
@ -50,7 +56,11 @@ export default class CallEventGrouper extends EventEmitter {
} }
public callBack = () => { public callBack = () => {
defaultDispatcher.dispatch({
action: 'place_call',
type: this.isVoice ? CallType.Voice : CallType.Video,
room_id: this.events[0]?.getRoomId(),
});
} }
public isVoice(): boolean { public isVoice(): boolean {
@ -68,7 +78,7 @@ export default class CallEventGrouper extends EventEmitter {
return isVoice; return isVoice;
} }
public getState() { public getState(): CallState | CustomCallState {
return this.state; return this.state;
} }
@ -86,7 +96,10 @@ export default class CallEventGrouper extends EventEmitter {
if (lastEventType === EventType.CallHangup) this.state = CallState.Ended; if (lastEventType === EventType.CallHangup) this.state = CallState.Ended;
else if (lastEventType === EventType.CallReject) this.state = CallState.Ended; else if (lastEventType === EventType.CallReject) this.state = CallState.Ended;
else if (lastEventType === EventType.CallInvite) this.state = CallState.Connecting; else if (lastEventType === EventType.CallInvite && this.call) this.state = CallState.Connecting;
else if (this.invite?.sender?.userId !== MatrixClientPeg.get().getUserId()) {
this.state = CustomCallState.Missed;
}
} }
this.emit(CallEventGrouperEvent.StateChanged, this.state); this.emit(CallEventGrouperEvent.StateChanged, this.state);
} }

View file

@ -19,7 +19,7 @@ import React from 'react';
import { MatrixEvent } from "matrix-js-sdk/src/models/event"; import { MatrixEvent } from "matrix-js-sdk/src/models/event";
import { _t, _td } from '../../../languageHandler'; import { _t, _td } from '../../../languageHandler';
import MemberAvatar from '../avatars/MemberAvatar'; import MemberAvatar from '../avatars/MemberAvatar';
import CallEventGrouper, { CallEventGrouperEvent } from '../../structures/CallEventGrouper'; import CallEventGrouper, { CallEventGrouperEvent, CustomCallState } from '../../structures/CallEventGrouper';
import FormButton from '../elements/FormButton'; import FormButton from '../elements/FormButton';
import { CallState } from 'matrix-js-sdk/src/webrtc/call'; import { CallState } from 'matrix-js-sdk/src/webrtc/call';
@ -29,10 +29,10 @@ interface IProps {
} }
interface IState { interface IState {
callState: CallState; callState: CallState | CustomCallState;
} }
const TEXTUAL_STATES = new Map([ const TEXTUAL_STATES: Map<CallState | CustomCallState, string> = new Map([
[CallState.Connected, _td("Connected")], [CallState.Connected, _td("Connected")],
[CallState.Connecting, _td("Connecting")], [CallState.Connecting, _td("Connecting")],
[CallState.Ended, _td("This call has ended")], [CallState.Ended, _td("This call has ended")],
@ -69,14 +69,11 @@ export default class CallEvent extends React.Component<IProps, IState> {
content = ( content = (
<div className="mx_CallEvent_content"> <div className="mx_CallEvent_content">
<FormButton <FormButton
className={"mx_IncomingCallBox_decline"}
onClick={this.props.callEventGrouper.rejectCall} onClick={this.props.callEventGrouper.rejectCall}
kind="danger" kind="danger"
label={_t("Decline")} label={_t("Decline")}
/> />
<div className="mx_IncomingCallBox_spacer" />
<FormButton <FormButton
className={"mx_IncomingCallBox_accept"}
onClick={this.props.callEventGrouper.answerCall} onClick={this.props.callEventGrouper.answerCall}
kind="primary" kind="primary"
label={_t("Accept")} label={_t("Accept")}
@ -89,6 +86,18 @@ export default class CallEvent extends React.Component<IProps, IState> {
{ TEXTUAL_STATES.get(state) } { TEXTUAL_STATES.get(state) }
</div> </div>
); );
} else if (state === CustomCallState.Missed) {
content = (
<div className="mx_CallEvent_content">
{ _t("You missed this call") }
<FormButton
className="mx_CallEvent_content_callBack"
onClick={this.props.callEventGrouper.callBack}
kind="primary"
label={_t("Call back")}
/>
</div>
);
} else { } else {
content = ( content = (
<div className="mx_CallEvent_content"> <div className="mx_CallEvent_content">