commit
90a6f251c7
|
@ -464,8 +464,66 @@ export default class CallHandler extends EventEmitter {
|
||||||
this.removeCallForRoom(mappedRoomId);
|
this.removeCallForRoom(mappedRoomId);
|
||||||
});
|
});
|
||||||
call.on(CallEvent.State, (newState: CallState, oldState: CallState) => {
|
call.on(CallEvent.State, (newState: CallState, oldState: CallState) => {
|
||||||
|
this.onCallStateChanged(newState, oldState, call);
|
||||||
|
});
|
||||||
|
call.on(CallEvent.Replaced, (newCall: MatrixCall) => {
|
||||||
if (!this.matchesCallForThisRoom(call)) return;
|
if (!this.matchesCallForThisRoom(call)) return;
|
||||||
|
|
||||||
|
console.log(`Call ID ${call.callId} is being replaced by call ID ${newCall.callId}`);
|
||||||
|
|
||||||
|
if (call.state === CallState.Ringing) {
|
||||||
|
this.pause(AudioID.Ring);
|
||||||
|
} else if (call.state === CallState.InviteSent) {
|
||||||
|
this.pause(AudioID.Ringback);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.calls.set(mappedRoomId, newCall);
|
||||||
|
this.emit(CallHandlerEvent.CallsChanged, this.calls);
|
||||||
|
this.setCallListeners(newCall);
|
||||||
|
this.setCallState(newCall, newCall.state);
|
||||||
|
});
|
||||||
|
call.on(CallEvent.AssertedIdentityChanged, async () => {
|
||||||
|
if (!this.matchesCallForThisRoom(call)) return;
|
||||||
|
|
||||||
|
console.log(`Call ID ${call.callId} got new asserted identity:`, call.getRemoteAssertedIdentity());
|
||||||
|
|
||||||
|
const newAssertedIdentity = call.getRemoteAssertedIdentity().id;
|
||||||
|
let newNativeAssertedIdentity = newAssertedIdentity;
|
||||||
|
if (newAssertedIdentity) {
|
||||||
|
const response = await this.sipNativeLookup(newAssertedIdentity);
|
||||||
|
if (response.length && response[0].fields.lookup_success) {
|
||||||
|
newNativeAssertedIdentity = response[0].userid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(`Asserted identity ${newAssertedIdentity} mapped to ${newNativeAssertedIdentity}`);
|
||||||
|
|
||||||
|
if (newNativeAssertedIdentity) {
|
||||||
|
this.assertedIdentityNativeUsers[call.callId] = newNativeAssertedIdentity;
|
||||||
|
|
||||||
|
// If we don't already have a room with this user, make one. This will be slightly odd
|
||||||
|
// if they called us because we'll be inviting them, but there's not much we can do about
|
||||||
|
// this if we want the actual, native room to exist (which we do). This is why it's
|
||||||
|
// important to only obey asserted identity in trusted environments, since anyone you're
|
||||||
|
// on a call with can cause you to send a room invite to someone.
|
||||||
|
await ensureDMExists(MatrixClientPeg.get(), newNativeAssertedIdentity);
|
||||||
|
|
||||||
|
const newMappedRoomId = this.roomIdForCall(call);
|
||||||
|
console.log(`Old room ID: ${mappedRoomId}, new room ID: ${newMappedRoomId}`);
|
||||||
|
if (newMappedRoomId !== mappedRoomId) {
|
||||||
|
this.removeCallForRoom(mappedRoomId);
|
||||||
|
mappedRoomId = newMappedRoomId;
|
||||||
|
console.log("Moving call to room " + mappedRoomId);
|
||||||
|
this.calls.set(mappedRoomId, call);
|
||||||
|
this.emit(CallHandlerEvent.CallChangeRoom, call);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private onCallStateChanged = (newState: CallState, oldState: CallState, call: MatrixCall): void => {
|
||||||
|
if (!this.matchesCallForThisRoom(call)) return;
|
||||||
|
|
||||||
|
const mappedRoomId = this.roomIdForCall(call);
|
||||||
this.setCallState(call, newState);
|
this.setCallState(call, newState);
|
||||||
|
|
||||||
switch (oldState) {
|
switch (oldState) {
|
||||||
|
@ -543,60 +601,7 @@ export default class CallHandler extends EventEmitter {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
call.on(CallEvent.Replaced, (newCall: MatrixCall) => {
|
|
||||||
if (!this.matchesCallForThisRoom(call)) return;
|
|
||||||
|
|
||||||
console.log(`Call ID ${call.callId} is being replaced by call ID ${newCall.callId}`);
|
|
||||||
|
|
||||||
if (call.state === CallState.Ringing) {
|
|
||||||
this.pause(AudioID.Ring);
|
|
||||||
} else if (call.state === CallState.InviteSent) {
|
|
||||||
this.pause(AudioID.Ringback);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.calls.set(mappedRoomId, newCall);
|
|
||||||
this.emit(CallHandlerEvent.CallsChanged, this.calls);
|
|
||||||
this.setCallListeners(newCall);
|
|
||||||
this.setCallState(newCall, newCall.state);
|
|
||||||
});
|
|
||||||
call.on(CallEvent.AssertedIdentityChanged, async () => {
|
|
||||||
if (!this.matchesCallForThisRoom(call)) return;
|
|
||||||
|
|
||||||
console.log(`Call ID ${call.callId} got new asserted identity:`, call.getRemoteAssertedIdentity());
|
|
||||||
|
|
||||||
const newAssertedIdentity = call.getRemoteAssertedIdentity().id;
|
|
||||||
let newNativeAssertedIdentity = newAssertedIdentity;
|
|
||||||
if (newAssertedIdentity) {
|
|
||||||
const response = await this.sipNativeLookup(newAssertedIdentity);
|
|
||||||
if (response.length && response[0].fields.lookup_success) {
|
|
||||||
newNativeAssertedIdentity = response[0].userid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
console.log(`Asserted identity ${newAssertedIdentity} mapped to ${newNativeAssertedIdentity}`);
|
|
||||||
|
|
||||||
if (newNativeAssertedIdentity) {
|
|
||||||
this.assertedIdentityNativeUsers[call.callId] = newNativeAssertedIdentity;
|
|
||||||
|
|
||||||
// If we don't already have a room with this user, make one. This will be slightly odd
|
|
||||||
// if they called us because we'll be inviting them, but there's not much we can do about
|
|
||||||
// this if we want the actual, native room to exist (which we do). This is why it's
|
|
||||||
// important to only obey asserted identity in trusted environments, since anyone you're
|
|
||||||
// on a call with can cause you to send a room invite to someone.
|
|
||||||
await ensureDMExists(MatrixClientPeg.get(), newNativeAssertedIdentity);
|
|
||||||
|
|
||||||
const newMappedRoomId = this.roomIdForCall(call);
|
|
||||||
console.log(`Old room ID: ${mappedRoomId}, new room ID: ${newMappedRoomId}`);
|
|
||||||
if (newMappedRoomId !== mappedRoomId) {
|
|
||||||
this.removeCallForRoom(mappedRoomId);
|
|
||||||
mappedRoomId = newMappedRoomId;
|
|
||||||
console.log("Moving call to room " + mappedRoomId);
|
|
||||||
this.calls.set(mappedRoomId, call);
|
|
||||||
this.emit(CallHandlerEvent.CallChangeRoom, call);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private async logCallStats(call: MatrixCall, mappedRoomId: string) {
|
private async logCallStats(call: MatrixCall, mappedRoomId: string) {
|
||||||
const stats = await call.getCurrentCallStats();
|
const stats = await call.getCurrentCallStats();
|
||||||
|
@ -861,6 +866,8 @@ export default class CallHandler extends EventEmitter {
|
||||||
this.calls.set(mappedRoomId, call);
|
this.calls.set(mappedRoomId, call);
|
||||||
this.emit(CallHandlerEvent.CallsChanged, this.calls);
|
this.emit(CallHandlerEvent.CallsChanged, this.calls);
|
||||||
this.setCallListeners(call);
|
this.setCallListeners(call);
|
||||||
|
// Explicitly handle first state change
|
||||||
|
this.onCallStateChanged(call.state, null, call);
|
||||||
|
|
||||||
// get ready to send encrypted events in the room, so if the user does answer
|
// get ready to send encrypted events in the room, so if the user does answer
|
||||||
// the call, we'll be ready to send. NB. This is the protocol-level room ID not
|
// the call, we'll be ready to send. NB. This is the protocol-level room ID not
|
||||||
|
|
|
@ -55,7 +55,7 @@ import { getKeyBindingsManager, NavigationAction, RoomAction } from '../../KeyBi
|
||||||
import { IOpts } from "../../createRoom";
|
import { IOpts } from "../../createRoom";
|
||||||
import SpacePanel from "../views/spaces/SpacePanel";
|
import SpacePanel from "../views/spaces/SpacePanel";
|
||||||
import { replaceableComponent } from "../../utils/replaceableComponent";
|
import { replaceableComponent } from "../../utils/replaceableComponent";
|
||||||
import CallHandler, { CallHandlerEvent } from '../../CallHandler';
|
import CallHandler from '../../CallHandler';
|
||||||
import { MatrixCall } from 'matrix-js-sdk/src/webrtc/call';
|
import { MatrixCall } from 'matrix-js-sdk/src/webrtc/call';
|
||||||
import AudioFeedArrayForCall from '../views/voip/AudioFeedArrayForCall';
|
import AudioFeedArrayForCall from '../views/voip/AudioFeedArrayForCall';
|
||||||
import RoomView from './RoomView';
|
import RoomView from './RoomView';
|
||||||
|
@ -142,6 +142,7 @@ interface IState {
|
||||||
class LoggedInView extends React.Component<IProps, IState> {
|
class LoggedInView extends React.Component<IProps, IState> {
|
||||||
static displayName = 'LoggedInView';
|
static displayName = 'LoggedInView';
|
||||||
|
|
||||||
|
private dispatcherRef: string;
|
||||||
protected readonly _matrixClient: MatrixClient;
|
protected readonly _matrixClient: MatrixClient;
|
||||||
protected readonly _roomView: React.RefObject<any>;
|
protected readonly _roomView: React.RefObject<any>;
|
||||||
protected readonly _resizeContainer: React.RefObject<ResizeHandle>;
|
protected readonly _resizeContainer: React.RefObject<ResizeHandle>;
|
||||||
|
@ -156,7 +157,7 @@ class LoggedInView extends React.Component<IProps, IState> {
|
||||||
// use compact timeline view
|
// use compact timeline view
|
||||||
useCompactLayout: SettingsStore.getValue('useCompactLayout'),
|
useCompactLayout: SettingsStore.getValue('useCompactLayout'),
|
||||||
usageLimitDismissed: false,
|
usageLimitDismissed: false,
|
||||||
activeCalls: [],
|
activeCalls: CallHandler.sharedInstance().getAllActiveCalls(),
|
||||||
};
|
};
|
||||||
|
|
||||||
// stash the MatrixClient in case we log out before we are unmounted
|
// stash the MatrixClient in case we log out before we are unmounted
|
||||||
|
@ -172,7 +173,7 @@ class LoggedInView extends React.Component<IProps, IState> {
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
document.addEventListener('keydown', this.onNativeKeyDown, false);
|
document.addEventListener('keydown', this.onNativeKeyDown, false);
|
||||||
CallHandler.sharedInstance().addListener(CallHandlerEvent.CallsChanged, this.onCallsChanged);
|
this.dispatcherRef = dis.register(this.onAction);
|
||||||
|
|
||||||
this.updateServerNoticeEvents();
|
this.updateServerNoticeEvents();
|
||||||
|
|
||||||
|
@ -197,7 +198,7 @@ class LoggedInView extends React.Component<IProps, IState> {
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
document.removeEventListener('keydown', this.onNativeKeyDown, false);
|
document.removeEventListener('keydown', this.onNativeKeyDown, false);
|
||||||
CallHandler.sharedInstance().removeListener(CallHandlerEvent.CallsChanged, this.onCallsChanged);
|
dis.unregister(this.dispatcherRef);
|
||||||
this._matrixClient.removeListener("accountData", this.onAccountData);
|
this._matrixClient.removeListener("accountData", this.onAccountData);
|
||||||
this._matrixClient.removeListener("sync", this.onSync);
|
this._matrixClient.removeListener("sync", this.onSync);
|
||||||
this._matrixClient.removeListener("RoomState.events", this.onRoomStateEvents);
|
this._matrixClient.removeListener("RoomState.events", this.onRoomStateEvents);
|
||||||
|
@ -205,10 +206,16 @@ class LoggedInView extends React.Component<IProps, IState> {
|
||||||
this.resizer.detach();
|
this.resizer.detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
private onCallsChanged = () => {
|
private onAction = (payload): void => {
|
||||||
this.setState({
|
switch (payload.action) {
|
||||||
activeCalls: CallHandler.sharedInstance().getAllActiveCalls(),
|
case 'call_state': {
|
||||||
});
|
const activeCalls = CallHandler.sharedInstance().getAllActiveCalls();
|
||||||
|
if (activeCalls !== this.state.activeCalls) {
|
||||||
|
this.setState({ activeCalls });
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public canResetTimelineInRoom = (roomId: string) => {
|
public canResetTimelineInRoom = (roomId: string) => {
|
||||||
|
|
|
@ -32,7 +32,7 @@ export default class AudioFeedArrayForCall extends React.Component<IProps, IStat
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
feeds: [],
|
feeds: this.props.call.getRemoteFeeds(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue