You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-08-09 10:22:46 +03:00
Add the call object to Call events
As explained in the comment. I've added it to the end so this should be completely backwards compatible (although it would be much nicer if it were the first arg, probably).
This commit is contained in:
@@ -737,7 +737,7 @@ describe("Call", function () {
|
||||
|
||||
const dataChannel = call.createDataChannel("data_channel_label", { id: 123 });
|
||||
|
||||
expect(dataChannelCallback).toHaveBeenCalledWith(dataChannel);
|
||||
expect(dataChannelCallback).toHaveBeenCalledWith(dataChannel, call);
|
||||
expect(dataChannel.label).toBe("data_channel_label");
|
||||
expect(dataChannel.id).toBe(123);
|
||||
});
|
||||
@@ -1604,7 +1604,7 @@ describe("Call", function () {
|
||||
hasAdvancedBy += advanceBy;
|
||||
|
||||
expect(lengthChangedListener).toHaveBeenCalledTimes(hasAdvancedBy);
|
||||
expect(lengthChangedListener).toHaveBeenCalledWith(hasAdvancedBy);
|
||||
expect(lengthChangedListener).toHaveBeenCalledWith(hasAdvancedBy, call);
|
||||
}
|
||||
});
|
||||
|
||||
|
@@ -102,7 +102,7 @@ describe("CallFeed", () => {
|
||||
[CallState.Connected, true],
|
||||
[CallState.Connecting, false],
|
||||
])("should react to call state, when !isLocal()", (state: CallState, expected: Boolean) => {
|
||||
call.emit(CallEvent.State, state);
|
||||
call.emit(CallEvent.State, state, CallState.InviteSent, call.typed());
|
||||
|
||||
expect(feed.connected).toBe(expected);
|
||||
});
|
||||
|
@@ -792,7 +792,7 @@ describe("Group Call", function () {
|
||||
call.isLocalVideoMuted = jest.fn().mockReturnValue(true);
|
||||
call.setLocalVideoMuted = jest.fn();
|
||||
|
||||
call.emit(CallEvent.State, CallState.Connected);
|
||||
call.emit(CallEvent.State, CallState.Connected, CallState.InviteSent, call);
|
||||
|
||||
expect(call.setMicrophoneMuted).toHaveBeenCalledWith(false);
|
||||
expect(call.setLocalVideoMuted).toHaveBeenCalledWith(false);
|
||||
@@ -1080,7 +1080,7 @@ describe("Group Call", function () {
|
||||
});
|
||||
|
||||
it("handles regular case", () => {
|
||||
oldMockCall.emit(CallEvent.Replaced, newMockCall.typed());
|
||||
oldMockCall.emit(CallEvent.Replaced, newMockCall.typed(), oldMockCall.typed());
|
||||
|
||||
expect(oldMockCall.hangup).toHaveBeenCalled();
|
||||
expect(callChangedListener).toHaveBeenCalledWith(newCallsMap);
|
||||
@@ -1091,7 +1091,7 @@ describe("Group Call", function () {
|
||||
it("handles case where call is missing from the calls map", () => {
|
||||
// @ts-ignore
|
||||
groupCall.calls = new Map();
|
||||
oldMockCall.emit(CallEvent.Replaced, newMockCall.typed());
|
||||
oldMockCall.emit(CallEvent.Replaced, newMockCall.typed(), oldMockCall.typed());
|
||||
|
||||
expect(oldMockCall.hangup).toHaveBeenCalled();
|
||||
expect(callChangedListener).toHaveBeenCalledWith(newCallsMap);
|
||||
|
@@ -296,20 +296,34 @@ export interface VoipEvent {
|
||||
content: Record<string, unknown>;
|
||||
}
|
||||
|
||||
/**
|
||||
* These now all have the call object as an argument. Why? Well, to know which call a given event is
|
||||
* about you have three options:
|
||||
* 1. Use a closure as the callback that remembers what call it's listening to. This can be
|
||||
* a pain because you need to pass the listener function again when you remove the listener,
|
||||
* which might be somewhere else.
|
||||
* 2. Use not-very-well-known fact that EventEmitter sets 'this' to the emitter object in the
|
||||
* callback. This doesn't really play well with modern Typescript and eslint and doesn't work
|
||||
* with our pattern of re-emitting events.
|
||||
* 3. Pass the object in question as an argument to the callback.
|
||||
*
|
||||
* Now that we have group calls which have to deal with multiple call objects, this will
|
||||
* become more important, and I think methods 1 and 2 are just going to cause issues.
|
||||
*/
|
||||
export type CallEventHandlerMap = {
|
||||
[CallEvent.DataChannel]: (channel: RTCDataChannel) => void;
|
||||
[CallEvent.FeedsChanged]: (feeds: CallFeed[]) => void;
|
||||
[CallEvent.Replaced]: (newCall: MatrixCall) => void;
|
||||
[CallEvent.Error]: (error: CallError) => void;
|
||||
[CallEvent.RemoteHoldUnhold]: (onHold: boolean) => void;
|
||||
[CallEvent.LocalHoldUnhold]: (onHold: boolean) => void;
|
||||
[CallEvent.LengthChanged]: (length: number) => void;
|
||||
[CallEvent.State]: (state: CallState, oldState?: CallState) => void;
|
||||
[CallEvent.DataChannel]: (channel: RTCDataChannel, call: MatrixCall) => void;
|
||||
[CallEvent.FeedsChanged]: (feeds: CallFeed[], call: MatrixCall) => void;
|
||||
[CallEvent.Replaced]: (newCall: MatrixCall, oldCall: MatrixCall) => void;
|
||||
[CallEvent.Error]: (error: CallError, call: MatrixCall) => void;
|
||||
[CallEvent.RemoteHoldUnhold]: (onHold: boolean, call: MatrixCall) => void;
|
||||
[CallEvent.LocalHoldUnhold]: (onHold: boolean, call: MatrixCall) => void;
|
||||
[CallEvent.LengthChanged]: (length: number, call: MatrixCall) => void;
|
||||
[CallEvent.State]: (state: CallState, oldState: CallState, call: MatrixCall) => void;
|
||||
[CallEvent.Hangup]: (call: MatrixCall) => void;
|
||||
[CallEvent.AssertedIdentityChanged]: () => void;
|
||||
[CallEvent.AssertedIdentityChanged]: (call: MatrixCall) => void;
|
||||
/* @deprecated */
|
||||
[CallEvent.HoldUnhold]: (onHold: boolean) => void;
|
||||
[CallEvent.SendVoipEvent]: (event: VoipEvent) => void;
|
||||
[CallEvent.SendVoipEvent]: (event: VoipEvent, call: MatrixCall) => void;
|
||||
};
|
||||
|
||||
// The key of the transceiver map (purpose + media type, separated by ':')
|
||||
@@ -459,7 +473,7 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
|
||||
*/
|
||||
public createDataChannel(label: string, options: RTCDataChannelInit | undefined): RTCDataChannel {
|
||||
const dataChannel = this.peerConn!.createDataChannel(label, options);
|
||||
this.emit(CallEvent.DataChannel, dataChannel);
|
||||
this.emit(CallEvent.DataChannel, dataChannel, this);
|
||||
return dataChannel;
|
||||
}
|
||||
|
||||
@@ -494,7 +508,7 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
|
||||
private set state(state: CallState) {
|
||||
const oldState = this._state;
|
||||
this._state = state;
|
||||
this.emit(CallEvent.State, state, oldState);
|
||||
this.emit(CallEvent.State, state, oldState, this);
|
||||
}
|
||||
|
||||
public get type(): CallType {
|
||||
@@ -684,7 +698,7 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
|
||||
}),
|
||||
);
|
||||
|
||||
this.emit(CallEvent.FeedsChanged, this.feeds);
|
||||
this.emit(CallEvent.FeedsChanged, this.feeds, this);
|
||||
|
||||
logger.info(
|
||||
`Call ${this.callId} pushRemoteFeed() pushed stream (streamId=${stream.id}, active=${stream.active}, purpose=${purpose})`,
|
||||
@@ -732,7 +746,7 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
|
||||
}),
|
||||
);
|
||||
|
||||
this.emit(CallEvent.FeedsChanged, this.feeds);
|
||||
this.emit(CallEvent.FeedsChanged, this.feeds, this);
|
||||
|
||||
logger.info(
|
||||
`Call ${this.callId} pushRemoteFeedWithoutMetadata() pushed stream (streamId=${stream.id}, active=${stream.active})`,
|
||||
@@ -832,7 +846,7 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
|
||||
`Call ${this.callId} pushLocalFeed() pushed stream (id=${callFeed.stream.id}, active=${callFeed.stream.active}, purpose=${callFeed.purpose})`,
|
||||
);
|
||||
|
||||
this.emit(CallEvent.FeedsChanged, this.feeds);
|
||||
this.emit(CallEvent.FeedsChanged, this.feeds, this);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -869,7 +883,7 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
|
||||
}
|
||||
|
||||
this.feeds = [];
|
||||
this.emit(CallEvent.FeedsChanged, this.feeds);
|
||||
this.emit(CallEvent.FeedsChanged, this.feeds, this);
|
||||
}
|
||||
|
||||
private deleteFeedByStream(stream: MediaStream): void {
|
||||
@@ -886,7 +900,7 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
|
||||
private deleteFeed(feed: CallFeed): void {
|
||||
feed.dispose();
|
||||
this.feeds.splice(this.feeds.indexOf(feed), 1);
|
||||
this.emit(CallEvent.FeedsChanged, this.feeds);
|
||||
this.emit(CallEvent.FeedsChanged, this.feeds, this);
|
||||
}
|
||||
|
||||
// The typescript definitions have this type as 'any' :(
|
||||
@@ -1117,7 +1131,7 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
|
||||
}
|
||||
}
|
||||
this.successor = newCall;
|
||||
this.emit(CallEvent.Replaced, newCall);
|
||||
this.emit(CallEvent.Replaced, newCall, this);
|
||||
this.hangup(CallErrorCode.Replaced, true);
|
||||
}
|
||||
|
||||
@@ -1188,6 +1202,7 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
|
||||
this.emit(
|
||||
CallEvent.Error,
|
||||
new CallError(CallErrorCode.NoUserMedia, "Failed to get camera access: ", <Error>error),
|
||||
this,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1513,7 +1528,7 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
|
||||
this.updateMuteStatus();
|
||||
this.sendMetadataUpdate();
|
||||
|
||||
this.emit(CallEvent.RemoteHoldUnhold, this.remoteOnHold);
|
||||
this.emit(CallEvent.RemoteHoldUnhold, this.remoteOnHold, this);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1638,7 +1653,7 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
|
||||
code = CallErrorCode.UnknownDevices;
|
||||
message = "Unknown devices present in the room";
|
||||
}
|
||||
this.emit(CallEvent.Error, new CallError(code, message, <Error>error));
|
||||
this.emit(CallEvent.Error, new CallError(code, message, <Error>error), this);
|
||||
throw error;
|
||||
}
|
||||
|
||||
@@ -1987,7 +2002,7 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
|
||||
|
||||
const newLocalOnHold = this.isLocalOnHold();
|
||||
if (prevLocalOnHold !== newLocalOnHold) {
|
||||
this.emit(CallEvent.LocalHoldUnhold, newLocalOnHold);
|
||||
this.emit(CallEvent.LocalHoldUnhold, newLocalOnHold, this);
|
||||
// also this one for backwards compat
|
||||
this.emit(CallEvent.HoldUnhold, newLocalOnHold);
|
||||
}
|
||||
@@ -2018,7 +2033,7 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
|
||||
id: content.asserted_identity.id,
|
||||
displayName: content.asserted_identity.display_name,
|
||||
};
|
||||
this.emit(CallEvent.AssertedIdentityChanged);
|
||||
this.emit(CallEvent.AssertedIdentityChanged, this);
|
||||
}
|
||||
|
||||
public callHasEnded(): boolean {
|
||||
@@ -2134,7 +2149,7 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
|
||||
message = "Unknown devices present in the room";
|
||||
}
|
||||
|
||||
this.emit(CallEvent.Error, new CallError(code, message, <Error>error));
|
||||
this.emit(CallEvent.Error, new CallError(code, message, <Error>error), this);
|
||||
this.terminate(CallParty.Local, code, false);
|
||||
|
||||
// no need to carry on & send the candidate queue, but we also
|
||||
@@ -2158,7 +2173,11 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
|
||||
private getLocalOfferFailed = (err: Error): void => {
|
||||
logger.error(`Call ${this.callId} getLocalOfferFailed() running`, err);
|
||||
|
||||
this.emit(CallEvent.Error, new CallError(CallErrorCode.LocalOfferFailed, "Failed to get local offer!", err));
|
||||
this.emit(
|
||||
CallEvent.Error,
|
||||
new CallError(CallErrorCode.LocalOfferFailed, "Failed to get local offer!", err),
|
||||
this,
|
||||
);
|
||||
this.terminate(CallParty.Local, CallErrorCode.LocalOfferFailed, false);
|
||||
};
|
||||
|
||||
@@ -2177,6 +2196,7 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
|
||||
"Couldn't start capturing media! Is your microphone set up and " + "does this app have permission?",
|
||||
err,
|
||||
),
|
||||
this,
|
||||
);
|
||||
this.terminate(CallParty.Local, CallErrorCode.NoUserMedia, false);
|
||||
};
|
||||
@@ -2200,7 +2220,7 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
|
||||
this.callStartTime = Date.now();
|
||||
|
||||
this.callLengthInterval = setInterval(() => {
|
||||
this.emit(CallEvent.LengthChanged, Math.round((Date.now() - this.callStartTime!) / 1000));
|
||||
this.emit(CallEvent.LengthChanged, Math.round((Date.now() - this.callStartTime!) / 1000), this);
|
||||
}, CALL_LENGTH_INTERVAL);
|
||||
}
|
||||
} else if (this.peerConn?.iceConnectionState == "failed") {
|
||||
@@ -2267,7 +2287,7 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
|
||||
};
|
||||
|
||||
private onDataChannel = (ev: RTCDataChannelEvent): void => {
|
||||
this.emit(CallEvent.DataChannel, ev.channel);
|
||||
this.emit(CallEvent.DataChannel, ev.channel, this);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -2380,13 +2400,17 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
|
||||
[ToDeviceMessageId]: uuidv4(),
|
||||
};
|
||||
|
||||
this.emit(CallEvent.SendVoipEvent, {
|
||||
this.emit(
|
||||
CallEvent.SendVoipEvent,
|
||||
{
|
||||
type: "toDevice",
|
||||
eventType,
|
||||
userId: this.invitee || this.getOpponentMember()?.userId,
|
||||
opponentDeviceId: this.opponentDeviceId,
|
||||
content,
|
||||
});
|
||||
},
|
||||
this,
|
||||
);
|
||||
|
||||
const userId = this.invitee || this.getOpponentMember()!.userId;
|
||||
if (this.client.getUseE2eForGroupCall()) {
|
||||
@@ -2415,13 +2439,17 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
|
||||
});
|
||||
}
|
||||
} else {
|
||||
this.emit(CallEvent.SendVoipEvent, {
|
||||
this.emit(
|
||||
CallEvent.SendVoipEvent,
|
||||
{
|
||||
type: "sendEvent",
|
||||
eventType,
|
||||
roomId: this.roomId,
|
||||
content: realContent,
|
||||
userId: this.invitee || this.getOpponentMember()?.userId,
|
||||
});
|
||||
},
|
||||
this,
|
||||
);
|
||||
|
||||
await this.client.sendEvent(this.roomId!, eventType, realContent);
|
||||
}
|
||||
@@ -2670,7 +2698,7 @@ export class MatrixCall extends TypedEventEmitter<CallEvent, CallEventHandlerMap
|
||||
const code = CallErrorCode.SignallingFailed;
|
||||
const message = "Signalling failed";
|
||||
|
||||
this.emit(CallEvent.Error, new CallError(code, message, <Error>error));
|
||||
this.emit(CallEvent.Error, new CallError(code, message, <Error>error), this);
|
||||
this.hangup(code, false);
|
||||
|
||||
return;
|
||||
|
Reference in New Issue
Block a user