mirror of
https://github.com/element-hq/element-web
synced 2024-11-23 17:56:01 +03:00
Handle missed calls
Signed-off-by: Šimon Brandner <simon.bra.ag@gmail.com>
This commit is contained in:
parent
5b3967a486
commit
0785997983
3 changed files with 38 additions and 11 deletions
|
@ -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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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">
|
||||||
|
|
Loading…
Reference in a new issue