@unwanted/matrix-sdk-mini 34.12.0-1 → 34.12.0-2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (185) hide show
  1. package/git-revision.txt +1 -1
  2. package/lib/@types/event.d.ts +0 -19
  3. package/lib/@types/event.d.ts.map +1 -1
  4. package/lib/@types/event.js.map +1 -1
  5. package/lib/client.d.ts +2 -50
  6. package/lib/client.d.ts.map +1 -1
  7. package/lib/client.js +391 -501
  8. package/lib/client.js.map +1 -1
  9. package/lib/embedded.d.ts.map +1 -1
  10. package/lib/embedded.js +0 -1
  11. package/lib/embedded.js.map +1 -1
  12. package/lib/matrix.d.ts +0 -6
  13. package/lib/matrix.d.ts.map +1 -1
  14. package/lib/matrix.js +1 -5
  15. package/lib/matrix.js.map +1 -1
  16. package/package.json +1 -1
  17. package/src/@types/event.ts +2 -36
  18. package/src/client.ts +1 -150
  19. package/src/embedded.ts +0 -2
  20. package/src/matrix.ts +0 -13
  21. package/lib/matrixrtc/CallMembership.d.ts +0 -66
  22. package/lib/matrixrtc/CallMembership.d.ts.map +0 -1
  23. package/lib/matrixrtc/CallMembership.js +0 -197
  24. package/lib/matrixrtc/CallMembership.js.map +0 -1
  25. package/lib/matrixrtc/LivekitFocus.d.ts +0 -16
  26. package/lib/matrixrtc/LivekitFocus.d.ts.map +0 -1
  27. package/lib/matrixrtc/LivekitFocus.js +0 -20
  28. package/lib/matrixrtc/LivekitFocus.js.map +0 -1
  29. package/lib/matrixrtc/MatrixRTCSession.d.ts +0 -295
  30. package/lib/matrixrtc/MatrixRTCSession.d.ts.map +0 -1
  31. package/lib/matrixrtc/MatrixRTCSession.js +0 -1043
  32. package/lib/matrixrtc/MatrixRTCSession.js.map +0 -1
  33. package/lib/matrixrtc/MatrixRTCSessionManager.d.ts +0 -40
  34. package/lib/matrixrtc/MatrixRTCSessionManager.d.ts.map +0 -1
  35. package/lib/matrixrtc/MatrixRTCSessionManager.js +0 -146
  36. package/lib/matrixrtc/MatrixRTCSessionManager.js.map +0 -1
  37. package/lib/matrixrtc/focus.d.ts +0 -10
  38. package/lib/matrixrtc/focus.d.ts.map +0 -1
  39. package/lib/matrixrtc/focus.js +0 -1
  40. package/lib/matrixrtc/focus.js.map +0 -1
  41. package/lib/matrixrtc/index.d.ts +0 -7
  42. package/lib/matrixrtc/index.d.ts.map +0 -1
  43. package/lib/matrixrtc/index.js +0 -21
  44. package/lib/matrixrtc/index.js.map +0 -1
  45. package/lib/matrixrtc/types.d.ts +0 -19
  46. package/lib/matrixrtc/types.d.ts.map +0 -1
  47. package/lib/matrixrtc/types.js +0 -1
  48. package/lib/matrixrtc/types.js.map +0 -1
  49. package/lib/webrtc/audioContext.d.ts +0 -15
  50. package/lib/webrtc/audioContext.d.ts.map +0 -1
  51. package/lib/webrtc/audioContext.js +0 -46
  52. package/lib/webrtc/audioContext.js.map +0 -1
  53. package/lib/webrtc/call.d.ts +0 -560
  54. package/lib/webrtc/call.d.ts.map +0 -1
  55. package/lib/webrtc/call.js +0 -2541
  56. package/lib/webrtc/call.js.map +0 -1
  57. package/lib/webrtc/callEventHandler.d.ts +0 -37
  58. package/lib/webrtc/callEventHandler.d.ts.map +0 -1
  59. package/lib/webrtc/callEventHandler.js +0 -344
  60. package/lib/webrtc/callEventHandler.js.map +0 -1
  61. package/lib/webrtc/callEventTypes.d.ts +0 -73
  62. package/lib/webrtc/callEventTypes.d.ts.map +0 -1
  63. package/lib/webrtc/callEventTypes.js +0 -13
  64. package/lib/webrtc/callEventTypes.js.map +0 -1
  65. package/lib/webrtc/callFeed.d.ts +0 -128
  66. package/lib/webrtc/callFeed.d.ts.map +0 -1
  67. package/lib/webrtc/callFeed.js +0 -289
  68. package/lib/webrtc/callFeed.js.map +0 -1
  69. package/lib/webrtc/groupCall.d.ts +0 -323
  70. package/lib/webrtc/groupCall.d.ts.map +0 -1
  71. package/lib/webrtc/groupCall.js +0 -1337
  72. package/lib/webrtc/groupCall.js.map +0 -1
  73. package/lib/webrtc/groupCallEventHandler.d.ts +0 -31
  74. package/lib/webrtc/groupCallEventHandler.d.ts.map +0 -1
  75. package/lib/webrtc/groupCallEventHandler.js +0 -178
  76. package/lib/webrtc/groupCallEventHandler.js.map +0 -1
  77. package/lib/webrtc/mediaHandler.d.ts +0 -89
  78. package/lib/webrtc/mediaHandler.d.ts.map +0 -1
  79. package/lib/webrtc/mediaHandler.js +0 -437
  80. package/lib/webrtc/mediaHandler.js.map +0 -1
  81. package/lib/webrtc/stats/callFeedStatsReporter.d.ts +0 -8
  82. package/lib/webrtc/stats/callFeedStatsReporter.d.ts.map +0 -1
  83. package/lib/webrtc/stats/callFeedStatsReporter.js +0 -82
  84. package/lib/webrtc/stats/callFeedStatsReporter.js.map +0 -1
  85. package/lib/webrtc/stats/callStatsReportGatherer.d.ts +0 -25
  86. package/lib/webrtc/stats/callStatsReportGatherer.d.ts.map +0 -1
  87. package/lib/webrtc/stats/callStatsReportGatherer.js +0 -199
  88. package/lib/webrtc/stats/callStatsReportGatherer.js.map +0 -1
  89. package/lib/webrtc/stats/callStatsReportSummary.d.ts +0 -17
  90. package/lib/webrtc/stats/callStatsReportSummary.d.ts.map +0 -1
  91. package/lib/webrtc/stats/callStatsReportSummary.js +0 -1
  92. package/lib/webrtc/stats/callStatsReportSummary.js.map +0 -1
  93. package/lib/webrtc/stats/connectionStats.d.ts +0 -28
  94. package/lib/webrtc/stats/connectionStats.d.ts.map +0 -1
  95. package/lib/webrtc/stats/connectionStats.js +0 -26
  96. package/lib/webrtc/stats/connectionStats.js.map +0 -1
  97. package/lib/webrtc/stats/connectionStatsBuilder.d.ts +0 -5
  98. package/lib/webrtc/stats/connectionStatsBuilder.d.ts.map +0 -1
  99. package/lib/webrtc/stats/connectionStatsBuilder.js +0 -27
  100. package/lib/webrtc/stats/connectionStatsBuilder.js.map +0 -1
  101. package/lib/webrtc/stats/connectionStatsReportBuilder.d.ts +0 -7
  102. package/lib/webrtc/stats/connectionStatsReportBuilder.d.ts.map +0 -1
  103. package/lib/webrtc/stats/connectionStatsReportBuilder.js +0 -121
  104. package/lib/webrtc/stats/connectionStatsReportBuilder.js.map +0 -1
  105. package/lib/webrtc/stats/groupCallStats.d.ts +0 -22
  106. package/lib/webrtc/stats/groupCallStats.d.ts.map +0 -1
  107. package/lib/webrtc/stats/groupCallStats.js +0 -78
  108. package/lib/webrtc/stats/groupCallStats.js.map +0 -1
  109. package/lib/webrtc/stats/media/mediaSsrcHandler.d.ts +0 -10
  110. package/lib/webrtc/stats/media/mediaSsrcHandler.d.ts.map +0 -1
  111. package/lib/webrtc/stats/media/mediaSsrcHandler.js +0 -57
  112. package/lib/webrtc/stats/media/mediaSsrcHandler.js.map +0 -1
  113. package/lib/webrtc/stats/media/mediaTrackHandler.d.ts +0 -12
  114. package/lib/webrtc/stats/media/mediaTrackHandler.d.ts.map +0 -1
  115. package/lib/webrtc/stats/media/mediaTrackHandler.js +0 -62
  116. package/lib/webrtc/stats/media/mediaTrackHandler.js.map +0 -1
  117. package/lib/webrtc/stats/media/mediaTrackStats.d.ts +0 -86
  118. package/lib/webrtc/stats/media/mediaTrackStats.d.ts.map +0 -1
  119. package/lib/webrtc/stats/media/mediaTrackStats.js +0 -142
  120. package/lib/webrtc/stats/media/mediaTrackStats.js.map +0 -1
  121. package/lib/webrtc/stats/media/mediaTrackStatsHandler.d.ts +0 -22
  122. package/lib/webrtc/stats/media/mediaTrackStatsHandler.d.ts.map +0 -1
  123. package/lib/webrtc/stats/media/mediaTrackStatsHandler.js +0 -76
  124. package/lib/webrtc/stats/media/mediaTrackStatsHandler.js.map +0 -1
  125. package/lib/webrtc/stats/statsReport.d.ts +0 -99
  126. package/lib/webrtc/stats/statsReport.d.ts.map +0 -1
  127. package/lib/webrtc/stats/statsReport.js +0 -32
  128. package/lib/webrtc/stats/statsReport.js.map +0 -1
  129. package/lib/webrtc/stats/statsReportEmitter.d.ts +0 -15
  130. package/lib/webrtc/stats/statsReportEmitter.d.ts.map +0 -1
  131. package/lib/webrtc/stats/statsReportEmitter.js +0 -33
  132. package/lib/webrtc/stats/statsReportEmitter.js.map +0 -1
  133. package/lib/webrtc/stats/summaryStatsReportGatherer.d.ts +0 -16
  134. package/lib/webrtc/stats/summaryStatsReportGatherer.d.ts.map +0 -1
  135. package/lib/webrtc/stats/summaryStatsReportGatherer.js +0 -116
  136. package/lib/webrtc/stats/summaryStatsReportGatherer.js.map +0 -1
  137. package/lib/webrtc/stats/trackStatsBuilder.d.ts +0 -19
  138. package/lib/webrtc/stats/trackStatsBuilder.d.ts.map +0 -1
  139. package/lib/webrtc/stats/trackStatsBuilder.js +0 -168
  140. package/lib/webrtc/stats/trackStatsBuilder.js.map +0 -1
  141. package/lib/webrtc/stats/transportStats.d.ts +0 -11
  142. package/lib/webrtc/stats/transportStats.d.ts.map +0 -1
  143. package/lib/webrtc/stats/transportStats.js +0 -1
  144. package/lib/webrtc/stats/transportStats.js.map +0 -1
  145. package/lib/webrtc/stats/transportStatsBuilder.d.ts +0 -5
  146. package/lib/webrtc/stats/transportStatsBuilder.d.ts.map +0 -1
  147. package/lib/webrtc/stats/transportStatsBuilder.js +0 -34
  148. package/lib/webrtc/stats/transportStatsBuilder.js.map +0 -1
  149. package/lib/webrtc/stats/valueFormatter.d.ts +0 -4
  150. package/lib/webrtc/stats/valueFormatter.d.ts.map +0 -1
  151. package/lib/webrtc/stats/valueFormatter.js +0 -25
  152. package/lib/webrtc/stats/valueFormatter.js.map +0 -1
  153. package/src/matrixrtc/CallMembership.ts +0 -247
  154. package/src/matrixrtc/LivekitFocus.ts +0 -39
  155. package/src/matrixrtc/MatrixRTCSession.ts +0 -1319
  156. package/src/matrixrtc/MatrixRTCSessionManager.ts +0 -166
  157. package/src/matrixrtc/focus.ts +0 -25
  158. package/src/matrixrtc/index.ts +0 -22
  159. package/src/matrixrtc/types.ts +0 -36
  160. package/src/webrtc/audioContext.ts +0 -44
  161. package/src/webrtc/call.ts +0 -3074
  162. package/src/webrtc/callEventHandler.ts +0 -425
  163. package/src/webrtc/callEventTypes.ts +0 -93
  164. package/src/webrtc/callFeed.ts +0 -364
  165. package/src/webrtc/groupCall.ts +0 -1735
  166. package/src/webrtc/groupCallEventHandler.ts +0 -234
  167. package/src/webrtc/mediaHandler.ts +0 -484
  168. package/src/webrtc/stats/callFeedStatsReporter.ts +0 -94
  169. package/src/webrtc/stats/callStatsReportGatherer.ts +0 -219
  170. package/src/webrtc/stats/callStatsReportSummary.ts +0 -30
  171. package/src/webrtc/stats/connectionStats.ts +0 -47
  172. package/src/webrtc/stats/connectionStatsBuilder.ts +0 -28
  173. package/src/webrtc/stats/connectionStatsReportBuilder.ts +0 -140
  174. package/src/webrtc/stats/groupCallStats.ts +0 -93
  175. package/src/webrtc/stats/media/mediaSsrcHandler.ts +0 -57
  176. package/src/webrtc/stats/media/mediaTrackHandler.ts +0 -76
  177. package/src/webrtc/stats/media/mediaTrackStats.ts +0 -176
  178. package/src/webrtc/stats/media/mediaTrackStatsHandler.ts +0 -90
  179. package/src/webrtc/stats/statsReport.ts +0 -133
  180. package/src/webrtc/stats/statsReportEmitter.ts +0 -49
  181. package/src/webrtc/stats/summaryStatsReportGatherer.ts +0 -148
  182. package/src/webrtc/stats/trackStatsBuilder.ts +0 -207
  183. package/src/webrtc/stats/transportStats.ts +0 -26
  184. package/src/webrtc/stats/transportStatsBuilder.ts +0 -48
  185. package/src/webrtc/stats/valueFormatter.ts +0 -27
@@ -1,1337 +0,0 @@
1
- import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
2
- import _defineProperty from "@babel/runtime/helpers/defineProperty";
3
- function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
4
- function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
5
- import { TypedEventEmitter } from "../models/typed-event-emitter.js";
6
- import { CallFeed, SPEAKING_THRESHOLD } from "./callFeed.js";
7
- import { CallErrorCode, CallEvent, CallState, genCallID, setTracksEnabled, createNewMatrixCall, CallError } from "./call.js";
8
- import { RoomStateEvent } from "../models/room-state.js";
9
- import { logger } from "../logger.js";
10
- import { ReEmitter } from "../ReEmitter.js";
11
- import { SDPStreamMetadataPurpose } from "./callEventTypes.js";
12
- import { EventType } from "../@types/event.js";
13
- import { CallEventHandlerEvent } from "./callEventHandler.js";
14
- import { GroupCallEventHandlerEvent } from "./groupCallEventHandler.js";
15
- import { mapsEqual } from "../utils.js";
16
- import { GroupCallStats } from "./stats/groupCallStats.js";
17
- import { StatsReport } from "./stats/statsReport.js";
18
- import { SummaryStatsReportGatherer } from "./stats/summaryStatsReportGatherer.js";
19
- import { CallFeedStatsReporter } from "./stats/callFeedStatsReporter.js";
20
- import { KnownMembership } from "../@types/membership.js";
21
- export var GroupCallIntent = /*#__PURE__*/function (GroupCallIntent) {
22
- GroupCallIntent["Ring"] = "m.ring";
23
- GroupCallIntent["Prompt"] = "m.prompt";
24
- GroupCallIntent["Room"] = "m.room";
25
- return GroupCallIntent;
26
- }({});
27
- export var GroupCallType = /*#__PURE__*/function (GroupCallType) {
28
- GroupCallType["Video"] = "m.video";
29
- GroupCallType["Voice"] = "m.voice";
30
- return GroupCallType;
31
- }({});
32
- export var GroupCallTerminationReason = /*#__PURE__*/function (GroupCallTerminationReason) {
33
- GroupCallTerminationReason["CallEnded"] = "call_ended";
34
- return GroupCallTerminationReason;
35
- }({});
36
- /**
37
- * Because event names are just strings, they do need
38
- * to be unique over all event types of event emitter.
39
- * Some objects could emit more then one set of events.
40
- */
41
- export var GroupCallEvent = /*#__PURE__*/function (GroupCallEvent) {
42
- GroupCallEvent["GroupCallStateChanged"] = "group_call_state_changed";
43
- GroupCallEvent["ActiveSpeakerChanged"] = "active_speaker_changed";
44
- GroupCallEvent["CallsChanged"] = "calls_changed";
45
- GroupCallEvent["UserMediaFeedsChanged"] = "user_media_feeds_changed";
46
- GroupCallEvent["ScreenshareFeedsChanged"] = "screenshare_feeds_changed";
47
- GroupCallEvent["LocalScreenshareStateChanged"] = "local_screenshare_state_changed";
48
- GroupCallEvent["LocalMuteStateChanged"] = "local_mute_state_changed";
49
- GroupCallEvent["ParticipantsChanged"] = "participants_changed";
50
- GroupCallEvent["Error"] = "group_call_error";
51
- return GroupCallEvent;
52
- }({});
53
- export var GroupCallStatsReportEvent = /*#__PURE__*/function (GroupCallStatsReportEvent) {
54
- GroupCallStatsReportEvent["ConnectionStats"] = "GroupCall.connection_stats";
55
- GroupCallStatsReportEvent["ByteSentStats"] = "GroupCall.byte_sent_stats";
56
- GroupCallStatsReportEvent["SummaryStats"] = "GroupCall.summary_stats";
57
- GroupCallStatsReportEvent["CallFeedStats"] = "GroupCall.call_feed_stats";
58
- return GroupCallStatsReportEvent;
59
- }({});
60
-
61
- /**
62
- * The final report-events that get consumed by client.
63
- */
64
-
65
- export var GroupCallErrorCode = /*#__PURE__*/function (GroupCallErrorCode) {
66
- GroupCallErrorCode["NoUserMedia"] = "no_user_media";
67
- GroupCallErrorCode["UnknownDevice"] = "unknown_device";
68
- GroupCallErrorCode["PlaceCallFailed"] = "place_call_failed";
69
- return GroupCallErrorCode;
70
- }({});
71
- export class GroupCallError extends Error {
72
- constructor(code, msg, err) {
73
- // Still don't think there's any way to have proper nested errors
74
- if (err) {
75
- super(msg + ": " + err);
76
- _defineProperty(this, "code", void 0);
77
- } else {
78
- super(msg);
79
- _defineProperty(this, "code", void 0);
80
- }
81
- this.code = code;
82
- }
83
- }
84
- export class GroupCallUnknownDeviceError extends GroupCallError {
85
- constructor(userId) {
86
- super(GroupCallErrorCode.UnknownDevice, "No device found for " + userId);
87
- this.userId = userId;
88
- }
89
- }
90
- export class OtherUserSpeakingError extends Error {
91
- constructor() {
92
- super("Cannot unmute: another user is speaking");
93
- }
94
- }
95
-
96
- // XXX: this hasn't made it into the MSC yet
97
-
98
- export var GroupCallState = /*#__PURE__*/function (GroupCallState) {
99
- GroupCallState["LocalCallFeedUninitialized"] = "local_call_feed_uninitialized";
100
- GroupCallState["InitializingLocalCallFeed"] = "initializing_local_call_feed";
101
- GroupCallState["LocalCallFeedInitialized"] = "local_call_feed_initialized";
102
- GroupCallState["Entered"] = "entered";
103
- GroupCallState["Ended"] = "ended";
104
- return GroupCallState;
105
- }({});
106
- var DEVICE_TIMEOUT = 1000 * 60 * 60; // 1 hour
107
-
108
- function getCallUserId(call) {
109
- var _call$getOpponentMemb;
110
- return ((_call$getOpponentMemb = call.getOpponentMember()) === null || _call$getOpponentMemb === void 0 ? void 0 : _call$getOpponentMemb.userId) || call.invitee || null;
111
- }
112
- export class GroupCall extends TypedEventEmitter {
113
- constructor(client, room, type, isPtt, intent, groupCallId, dataChannelsEnabled, dataChannelOptions, isCallWithoutVideoAndAudio) {
114
- var _room$currentState$ge, _room$currentState$ge2;
115
- var useLivekit = arguments.length > 9 && arguments[9] !== undefined ? arguments[9] : false;
116
- var livekitServiceURL = arguments.length > 10 ? arguments[10] : undefined;
117
- super();
118
- this.client = client;
119
- this.room = room;
120
- this.type = type;
121
- this.isPtt = isPtt;
122
- this.intent = intent;
123
- this.dataChannelsEnabled = dataChannelsEnabled;
124
- this.dataChannelOptions = dataChannelOptions;
125
- this.useLivekit = useLivekit;
126
- // Config
127
- _defineProperty(this, "activeSpeakerInterval", 1000);
128
- _defineProperty(this, "retryCallInterval", 5000);
129
- _defineProperty(this, "participantTimeout", 1000 * 15);
130
- _defineProperty(this, "pttMaxTransmitTime", 1000 * 20);
131
- _defineProperty(this, "activeSpeaker", void 0);
132
- _defineProperty(this, "localCallFeed", void 0);
133
- _defineProperty(this, "localScreenshareFeed", void 0);
134
- _defineProperty(this, "localDesktopCapturerSourceId", void 0);
135
- _defineProperty(this, "userMediaFeeds", []);
136
- _defineProperty(this, "screenshareFeeds", []);
137
- _defineProperty(this, "groupCallId", void 0);
138
- _defineProperty(this, "allowCallWithoutVideoAndAudio", void 0);
139
- _defineProperty(this, "calls", new Map());
140
- // user_id -> device_id -> MatrixCall
141
- _defineProperty(this, "callHandlers", new Map());
142
- // user_id -> device_id -> ICallHandlers
143
- _defineProperty(this, "activeSpeakerLoopInterval", void 0);
144
- _defineProperty(this, "retryCallLoopInterval", void 0);
145
- _defineProperty(this, "retryCallCounts", new Map());
146
- // user_id -> device_id -> count
147
- _defineProperty(this, "reEmitter", void 0);
148
- _defineProperty(this, "transmitTimer", null);
149
- _defineProperty(this, "participantsExpirationTimer", null);
150
- _defineProperty(this, "resendMemberStateTimer", null);
151
- _defineProperty(this, "initWithAudioMuted", false);
152
- _defineProperty(this, "initWithVideoMuted", false);
153
- _defineProperty(this, "initCallFeedPromise", void 0);
154
- _defineProperty(this, "_livekitServiceURL", void 0);
155
- _defineProperty(this, "stats", void 0);
156
- /**
157
- * Configure default webrtc stats collection interval in ms
158
- * Disable collecting webrtc stats by setting interval to 0
159
- */
160
- _defineProperty(this, "statsCollectIntervalTime", 0);
161
- _defineProperty(this, "onConnectionStats", report => {
162
- // Final emit of the summary event, to be consumed by the client
163
- this.emit(GroupCallStatsReportEvent.ConnectionStats, {
164
- report
165
- });
166
- });
167
- _defineProperty(this, "onByteSentStats", report => {
168
- // Final emit of the summary event, to be consumed by the client
169
- this.emit(GroupCallStatsReportEvent.ByteSentStats, {
170
- report
171
- });
172
- });
173
- _defineProperty(this, "onSummaryStats", report => {
174
- SummaryStatsReportGatherer.extendSummaryReport(report, this.participants);
175
- // Final emit of the summary event, to be consumed by the client
176
- this.emit(GroupCallStatsReportEvent.SummaryStats, {
177
- report
178
- });
179
- });
180
- _defineProperty(this, "onCallFeedReport", report => {
181
- if (this.localCallFeed) {
182
- report = CallFeedStatsReporter.expandCallFeedReport(report, [this.localCallFeed], "from-local-feed");
183
- }
184
- var callFeeds = [];
185
- this.forEachCall(call => {
186
- if (call.callId === report.callId) {
187
- call.getFeeds().forEach(f => callFeeds.push(f));
188
- }
189
- });
190
- report = CallFeedStatsReporter.expandCallFeedReport(report, callFeeds, "from-call-feed");
191
- this.emit(GroupCallStatsReportEvent.CallFeedStats, {
192
- report
193
- });
194
- });
195
- _defineProperty(this, "_state", GroupCallState.LocalCallFeedUninitialized);
196
- _defineProperty(this, "_participants", new Map());
197
- _defineProperty(this, "_creationTs", null);
198
- _defineProperty(this, "_enteredViaAnotherSession", false);
199
- /*
200
- * Call Setup
201
- *
202
- * There are two different paths for calls to be created:
203
- * 1. Incoming calls triggered by the Call.incoming event.
204
- * 2. Outgoing calls to the initial members of a room or new members
205
- * as they are observed by the RoomState.members event.
206
- */
207
- _defineProperty(this, "onIncomingCall", newCall => {
208
- var _newCall$getOpponentM, _this$calls$get;
209
- // The incoming calls may be for another room, which we will ignore.
210
- if (newCall.roomId !== this.room.roomId) {
211
- return;
212
- }
213
- if (newCall.state !== CallState.Ringing) {
214
- logger.warn("GroupCall ".concat(this.groupCallId, " onIncomingCall() incoming call no longer in ringing state - ignoring"));
215
- return;
216
- }
217
- if (!newCall.groupCallId || newCall.groupCallId !== this.groupCallId) {
218
- logger.log("GroupCall ".concat(this.groupCallId, " onIncomingCall() ignored because it doesn't match the current group call"));
219
- newCall.reject();
220
- return;
221
- }
222
- var opponentUserId = (_newCall$getOpponentM = newCall.getOpponentMember()) === null || _newCall$getOpponentM === void 0 ? void 0 : _newCall$getOpponentM.userId;
223
- if (opponentUserId === undefined) {
224
- logger.warn("GroupCall ".concat(this.groupCallId, " onIncomingCall() incoming call with no member - ignoring"));
225
- return;
226
- }
227
- if (this.useLivekit) {
228
- logger.info("Received incoming call whilst in signaling-only mode! Ignoring.");
229
- return;
230
- }
231
- var deviceMap = (_this$calls$get = this.calls.get(opponentUserId)) !== null && _this$calls$get !== void 0 ? _this$calls$get : new Map();
232
- var prevCall = deviceMap.get(newCall.getOpponentDeviceId());
233
- if ((prevCall === null || prevCall === void 0 ? void 0 : prevCall.callId) === newCall.callId) return;
234
- logger.log("GroupCall ".concat(this.groupCallId, " onIncomingCall() incoming call (userId=").concat(opponentUserId, ", callId=").concat(newCall.callId, ")"));
235
- if (prevCall) prevCall.hangup(CallErrorCode.Replaced, false);
236
- // We must do this before we start initialising / answering the call as we
237
- // need to know it is the active call for this user+deviceId and to not ignore
238
- // events from it.
239
- deviceMap.set(newCall.getOpponentDeviceId(), newCall);
240
- this.calls.set(opponentUserId, deviceMap);
241
- this.initCall(newCall);
242
- var feeds = this.getLocalFeeds().map(feed => feed.clone());
243
- if (!this.callExpected(newCall)) {
244
- // Disable our tracks for users not explicitly participating in the
245
- // call but trying to receive the feeds
246
- for (var feed of feeds) {
247
- setTracksEnabled(feed.stream.getAudioTracks(), false);
248
- setTracksEnabled(feed.stream.getVideoTracks(), false);
249
- }
250
- }
251
- newCall.answerWithCallFeeds(feeds);
252
- this.emit(GroupCallEvent.CallsChanged, this.calls);
253
- });
254
- _defineProperty(this, "onRetryCallLoop", () => {
255
- var needsRetry = false;
256
- for (var [{
257
- userId: _userId
258
- }, participantMap] of this.participants) {
259
- var callMap = this.calls.get(_userId);
260
- var retriesMap = this.retryCallCounts.get(_userId);
261
- for (var [deviceId, participant] of participantMap) {
262
- var _retriesMap$get, _retriesMap;
263
- var call = callMap === null || callMap === void 0 ? void 0 : callMap.get(deviceId);
264
- var retries = (_retriesMap$get = (_retriesMap = retriesMap) === null || _retriesMap === void 0 ? void 0 : _retriesMap.get(deviceId)) !== null && _retriesMap$get !== void 0 ? _retriesMap$get : 0;
265
- if ((call === null || call === void 0 ? void 0 : call.getOpponentSessionId()) !== participant.sessionId && this.wantsOutgoingCall(_userId, deviceId) && retries < 3) {
266
- if (retriesMap === undefined) {
267
- retriesMap = new Map();
268
- this.retryCallCounts.set(_userId, retriesMap);
269
- }
270
- retriesMap.set(deviceId, retries + 1);
271
- needsRetry = true;
272
- }
273
- }
274
- }
275
- if (needsRetry) this.placeOutgoingCalls();
276
- });
277
- _defineProperty(this, "onCallFeedsChanged", call => {
278
- var opponentMemberId = getCallUserId(call);
279
- var opponentDeviceId = call.getOpponentDeviceId();
280
- if (!opponentMemberId) {
281
- throw new Error("Cannot change call feeds without user id");
282
- }
283
- var currentUserMediaFeed = this.getUserMediaFeed(opponentMemberId, opponentDeviceId);
284
- var remoteUsermediaFeed = call.remoteUsermediaFeed;
285
- var remoteFeedChanged = remoteUsermediaFeed !== currentUserMediaFeed;
286
- var deviceMap = this.calls.get(opponentMemberId);
287
- var currentCallForUserDevice = deviceMap === null || deviceMap === void 0 ? void 0 : deviceMap.get(opponentDeviceId);
288
- if ((currentCallForUserDevice === null || currentCallForUserDevice === void 0 ? void 0 : currentCallForUserDevice.callId) !== call.callId) {
289
- // the call in question is not the current call for this user/deviceId
290
- // so ignore feed events from it otherwise we'll remove our real feeds
291
- return;
292
- }
293
- if (remoteFeedChanged) {
294
- if (!currentUserMediaFeed && remoteUsermediaFeed) {
295
- this.addUserMediaFeed(remoteUsermediaFeed);
296
- } else if (currentUserMediaFeed && remoteUsermediaFeed) {
297
- this.replaceUserMediaFeed(currentUserMediaFeed, remoteUsermediaFeed);
298
- } else if (currentUserMediaFeed && !remoteUsermediaFeed) {
299
- this.removeUserMediaFeed(currentUserMediaFeed);
300
- }
301
- }
302
- var currentScreenshareFeed = this.getScreenshareFeed(opponentMemberId, opponentDeviceId);
303
- var remoteScreensharingFeed = call.remoteScreensharingFeed;
304
- var remoteScreenshareFeedChanged = remoteScreensharingFeed !== currentScreenshareFeed;
305
- if (remoteScreenshareFeedChanged) {
306
- if (!currentScreenshareFeed && remoteScreensharingFeed) {
307
- this.addScreenshareFeed(remoteScreensharingFeed);
308
- } else if (currentScreenshareFeed && remoteScreensharingFeed) {
309
- this.replaceScreenshareFeed(currentScreenshareFeed, remoteScreensharingFeed);
310
- } else if (currentScreenshareFeed && !remoteScreensharingFeed) {
311
- this.removeScreenshareFeed(currentScreenshareFeed);
312
- }
313
- }
314
- });
315
- _defineProperty(this, "onCallStateChanged", (call, state, _oldState) => {
316
- var _call$getOpponentMemb2;
317
- if (state === CallState.Ended) return;
318
- var audioMuted = this.localCallFeed.isAudioMuted();
319
- if (call.localUsermediaStream && call.isMicrophoneMuted() !== audioMuted) {
320
- call.setMicrophoneMuted(audioMuted);
321
- }
322
- var videoMuted = this.localCallFeed.isVideoMuted();
323
- if (call.localUsermediaStream && call.isLocalVideoMuted() !== videoMuted) {
324
- call.setLocalVideoMuted(videoMuted);
325
- }
326
- var opponentUserId = (_call$getOpponentMemb2 = call.getOpponentMember()) === null || _call$getOpponentMemb2 === void 0 ? void 0 : _call$getOpponentMemb2.userId;
327
- if (state === CallState.Connected && opponentUserId) {
328
- var retriesMap = this.retryCallCounts.get(opponentUserId);
329
- retriesMap === null || retriesMap === void 0 || retriesMap.delete(call.getOpponentDeviceId());
330
- if ((retriesMap === null || retriesMap === void 0 ? void 0 : retriesMap.size) === 0) this.retryCallCounts.delete(opponentUserId);
331
- }
332
- });
333
- _defineProperty(this, "onCallHangup", call => {
334
- var _call$getOpponentMemb3, _call$getOpponentMemb4;
335
- if (call.hangupReason === CallErrorCode.Replaced) return;
336
- var opponentUserId = (_call$getOpponentMemb3 = (_call$getOpponentMemb4 = call.getOpponentMember()) === null || _call$getOpponentMemb4 === void 0 ? void 0 : _call$getOpponentMemb4.userId) !== null && _call$getOpponentMemb3 !== void 0 ? _call$getOpponentMemb3 : this.room.getMember(call.invitee).userId;
337
- var deviceMap = this.calls.get(opponentUserId);
338
-
339
- // Sanity check that this call is in fact in the map
340
- if ((deviceMap === null || deviceMap === void 0 ? void 0 : deviceMap.get(call.getOpponentDeviceId())) === call) {
341
- this.disposeCall(call, call.hangupReason);
342
- deviceMap.delete(call.getOpponentDeviceId());
343
- if (deviceMap.size === 0) this.calls.delete(opponentUserId);
344
- this.emit(GroupCallEvent.CallsChanged, this.calls);
345
- }
346
- });
347
- _defineProperty(this, "onCallReplaced", (prevCall, newCall) => {
348
- var opponentUserId = prevCall.getOpponentMember().userId;
349
- var deviceMap = this.calls.get(opponentUserId);
350
- if (deviceMap === undefined) {
351
- deviceMap = new Map();
352
- this.calls.set(opponentUserId, deviceMap);
353
- }
354
- prevCall.hangup(CallErrorCode.Replaced, false);
355
- this.initCall(newCall);
356
- deviceMap.set(prevCall.getOpponentDeviceId(), newCall);
357
- this.emit(GroupCallEvent.CallsChanged, this.calls);
358
- });
359
- _defineProperty(this, "onActiveSpeakerLoop", () => {
360
- var topAvg = undefined;
361
- var nextActiveSpeaker = undefined;
362
- for (var callFeed of this.userMediaFeeds) {
363
- if (callFeed.isLocal() && this.userMediaFeeds.length > 1) continue;
364
- var total = callFeed.speakingVolumeSamples.reduce((acc, volume) => acc + Math.max(volume, SPEAKING_THRESHOLD));
365
- var avg = total / callFeed.speakingVolumeSamples.length;
366
- if (!topAvg || avg > topAvg) {
367
- topAvg = avg;
368
- nextActiveSpeaker = callFeed;
369
- }
370
- }
371
- if (nextActiveSpeaker && this.activeSpeaker !== nextActiveSpeaker && topAvg && topAvg > SPEAKING_THRESHOLD) {
372
- this.activeSpeaker = nextActiveSpeaker;
373
- this.emit(GroupCallEvent.ActiveSpeakerChanged, this.activeSpeaker);
374
- }
375
- });
376
- _defineProperty(this, "onRoomState", () => this.updateParticipants());
377
- _defineProperty(this, "onParticipantsChanged", () => {
378
- // Re-run setTracksEnabled on all calls, so that participants that just
379
- // left get denied access to our media, and participants that just
380
- // joined get granted access
381
- this.forEachCall(call => {
382
- var expected = this.callExpected(call);
383
- for (var feed of call.getLocalFeeds()) {
384
- setTracksEnabled(feed.stream.getAudioTracks(), !feed.isAudioMuted() && expected);
385
- setTracksEnabled(feed.stream.getVideoTracks(), !feed.isVideoMuted() && expected);
386
- }
387
- });
388
- if (this.state === GroupCallState.Entered && !this.useLivekit) this.placeOutgoingCalls();
389
-
390
- // Update the participants stored in the stats object
391
- });
392
- _defineProperty(this, "onStateChanged", (newState, oldState) => {
393
- if (newState === GroupCallState.Entered || oldState === GroupCallState.Entered || newState === GroupCallState.Ended) {
394
- // We either entered, left, or ended the call
395
- this.updateParticipants();
396
- this.updateMemberState().catch(e => logger.error("GroupCall ".concat(this.groupCallId, " onStateChanged() failed to update member state devices\""), e));
397
- }
398
- });
399
- _defineProperty(this, "onLocalFeedsChanged", () => {
400
- if (this.state === GroupCallState.Entered) {
401
- this.updateMemberState().catch(e => logger.error("GroupCall ".concat(this.groupCallId, " onLocalFeedsChanged() failed to update member state feeds"), e));
402
- }
403
- });
404
- this.reEmitter = new ReEmitter(this);
405
- this.groupCallId = groupCallId !== null && groupCallId !== void 0 ? groupCallId : genCallID();
406
- this._livekitServiceURL = livekitServiceURL;
407
- this.creationTs = (_room$currentState$ge = (_room$currentState$ge2 = room.currentState.getStateEvents(EventType.GroupCallPrefix, this.groupCallId)) === null || _room$currentState$ge2 === void 0 ? void 0 : _room$currentState$ge2.getTs()) !== null && _room$currentState$ge !== void 0 ? _room$currentState$ge : null;
408
- this.updateParticipants();
409
- room.on(RoomStateEvent.Update, this.onRoomState);
410
- this.on(GroupCallEvent.ParticipantsChanged, this.onParticipantsChanged);
411
- this.on(GroupCallEvent.GroupCallStateChanged, this.onStateChanged);
412
- this.on(GroupCallEvent.LocalScreenshareStateChanged, this.onLocalFeedsChanged);
413
- this.allowCallWithoutVideoAndAudio = !!isCallWithoutVideoAndAudio;
414
- }
415
- create() {
416
- var _this = this;
417
- return _asyncToGenerator(function* () {
418
- _this.creationTs = Date.now();
419
- _this.client.groupCallEventHandler.groupCalls.set(_this.room.roomId, _this);
420
- _this.client.emit(GroupCallEventHandlerEvent.Outgoing, _this);
421
- yield _this.sendCallStateEvent();
422
- return _this;
423
- })();
424
- }
425
- sendCallStateEvent() {
426
- var _this2 = this;
427
- return _asyncToGenerator(function* () {
428
- var groupCallState = {
429
- "m.intent": _this2.intent,
430
- "m.type": _this2.type,
431
- "io.element.ptt": _this2.isPtt,
432
- // TODO: Specify data-channels better
433
- "dataChannelsEnabled": _this2.dataChannelsEnabled,
434
- "dataChannelOptions": _this2.dataChannelsEnabled ? _this2.dataChannelOptions : undefined
435
- };
436
- if (_this2.livekitServiceURL) {
437
- groupCallState["io.element.livekit_service_url"] = _this2.livekitServiceURL;
438
- }
439
- yield _this2.client.sendStateEvent(_this2.room.roomId, EventType.GroupCallPrefix, groupCallState, _this2.groupCallId);
440
- })();
441
- }
442
- get livekitServiceURL() {
443
- return this._livekitServiceURL;
444
- }
445
- updateLivekitServiceURL(newURL) {
446
- this._livekitServiceURL = newURL;
447
- return this.sendCallStateEvent();
448
- }
449
- /**
450
- * The group call's state.
451
- */
452
- get state() {
453
- return this._state;
454
- }
455
- set state(value) {
456
- var prevValue = this._state;
457
- if (value !== prevValue) {
458
- this._state = value;
459
- this.emit(GroupCallEvent.GroupCallStateChanged, value, prevValue);
460
- }
461
- }
462
- /**
463
- * The current participants in the call, as a map from members to device IDs
464
- * to participant info.
465
- */
466
- get participants() {
467
- return this._participants;
468
- }
469
- set participants(value) {
470
- var prevValue = this._participants;
471
- var participantStateEqual = (x, y) => x.sessionId === y.sessionId && x.screensharing === y.screensharing;
472
- var deviceMapsEqual = (x, y) => mapsEqual(x, y, participantStateEqual);
473
-
474
- // Only update if the map actually changed
475
- if (!mapsEqual(value, prevValue, deviceMapsEqual)) {
476
- this._participants = value;
477
- this.emit(GroupCallEvent.ParticipantsChanged, value);
478
- }
479
- }
480
- /**
481
- * The timestamp at which the call was created, or null if it has not yet
482
- * been created.
483
- */
484
- get creationTs() {
485
- return this._creationTs;
486
- }
487
- set creationTs(value) {
488
- this._creationTs = value;
489
- }
490
- /**
491
- * Whether the local device has entered this call via another session, such
492
- * as a widget.
493
- */
494
- get enteredViaAnotherSession() {
495
- return this._enteredViaAnotherSession;
496
- }
497
- set enteredViaAnotherSession(value) {
498
- this._enteredViaAnotherSession = value;
499
- this.updateParticipants();
500
- }
501
-
502
- /**
503
- * Executes the given callback on all calls in this group call.
504
- * @param f - The callback.
505
- */
506
- forEachCall(f) {
507
- for (var deviceMap of this.calls.values()) {
508
- for (var call of deviceMap.values()) f(call);
509
- }
510
- }
511
- getLocalFeeds() {
512
- var feeds = [];
513
- if (this.localCallFeed) feeds.push(this.localCallFeed);
514
- if (this.localScreenshareFeed) feeds.push(this.localScreenshareFeed);
515
- return feeds;
516
- }
517
- hasLocalParticipant() {
518
- var _this$participants$ge, _this$participants$ge2;
519
- return (_this$participants$ge = (_this$participants$ge2 = this.participants.get(this.room.getMember(this.client.getUserId()))) === null || _this$participants$ge2 === void 0 ? void 0 : _this$participants$ge2.has(this.client.getDeviceId())) !== null && _this$participants$ge !== void 0 ? _this$participants$ge : false;
520
- }
521
-
522
- /**
523
- * Determines whether the given call is one that we were expecting to exist
524
- * given our knowledge of who is participating in the group call.
525
- */
526
- callExpected(call) {
527
- var _this$participants$ge3;
528
- var userId = getCallUserId(call);
529
- var member = userId === null ? null : this.room.getMember(userId);
530
- var deviceId = call.getOpponentDeviceId();
531
- return member !== null && deviceId !== undefined && ((_this$participants$ge3 = this.participants.get(member)) === null || _this$participants$ge3 === void 0 ? void 0 : _this$participants$ge3.get(deviceId)) !== undefined;
532
- }
533
- initLocalCallFeed() {
534
- var _this3 = this;
535
- return _asyncToGenerator(function* () {
536
- if (_this3.useLivekit) {
537
- logger.info("Livekit group call: not starting local call feed.");
538
- return;
539
- }
540
- if (_this3.state !== GroupCallState.LocalCallFeedUninitialized) {
541
- throw new Error("Cannot initialize local call feed in the \"".concat(_this3.state, "\" state."));
542
- }
543
- _this3.state = GroupCallState.InitializingLocalCallFeed;
544
-
545
- // wraps the real method to serialise calls, because we don't want to try starting
546
- // multiple call feeds at once
547
- if (_this3.initCallFeedPromise) return _this3.initCallFeedPromise;
548
- try {
549
- _this3.initCallFeedPromise = _this3.initLocalCallFeedInternal();
550
- yield _this3.initCallFeedPromise;
551
- } finally {
552
- _this3.initCallFeedPromise = undefined;
553
- }
554
- })();
555
- }
556
- initLocalCallFeedInternal() {
557
- var _this4 = this;
558
- return _asyncToGenerator(function* () {
559
- logger.log("GroupCall ".concat(_this4.groupCallId, " initLocalCallFeedInternal() running"));
560
- var stream;
561
- try {
562
- stream = yield _this4.client.getMediaHandler().getUserMediaStream(true, _this4.type === GroupCallType.Video);
563
- } catch (error) {
564
- // If is allowed to join a call without a media stream, then we
565
- // don't throw an error here. But we need an empty Local Feed to establish
566
- // a connection later.
567
- if (_this4.allowCallWithoutVideoAndAudio) {
568
- stream = new MediaStream();
569
- } else {
570
- _this4.state = GroupCallState.LocalCallFeedUninitialized;
571
- throw error;
572
- }
573
- }
574
-
575
- // The call could've been disposed while we were waiting, and could
576
- // also have been started back up again (hello, React 18) so if we're
577
- // still in this 'initializing' state, carry on, otherwise bail.
578
- if (_this4._state !== GroupCallState.InitializingLocalCallFeed) {
579
- _this4.client.getMediaHandler().stopUserMediaStream(stream);
580
- throw new Error("Group call disposed while gathering media stream");
581
- }
582
- var callFeed = new CallFeed({
583
- client: _this4.client,
584
- roomId: _this4.room.roomId,
585
- userId: _this4.client.getUserId(),
586
- deviceId: _this4.client.getDeviceId(),
587
- stream,
588
- purpose: SDPStreamMetadataPurpose.Usermedia,
589
- audioMuted: _this4.initWithAudioMuted || stream.getAudioTracks().length === 0 || _this4.isPtt,
590
- videoMuted: _this4.initWithVideoMuted || stream.getVideoTracks().length === 0
591
- });
592
- setTracksEnabled(stream.getAudioTracks(), !callFeed.isAudioMuted());
593
- setTracksEnabled(stream.getVideoTracks(), !callFeed.isVideoMuted());
594
- _this4.localCallFeed = callFeed;
595
- _this4.addUserMediaFeed(callFeed);
596
- _this4.state = GroupCallState.LocalCallFeedInitialized;
597
- })();
598
- }
599
- updateLocalUsermediaStream(stream) {
600
- var _this5 = this;
601
- return _asyncToGenerator(function* () {
602
- if (_this5.localCallFeed) {
603
- var oldStream = _this5.localCallFeed.stream;
604
- _this5.localCallFeed.setNewStream(stream);
605
- var micShouldBeMuted = _this5.localCallFeed.isAudioMuted();
606
- var vidShouldBeMuted = _this5.localCallFeed.isVideoMuted();
607
- logger.log("GroupCall ".concat(_this5.groupCallId, " updateLocalUsermediaStream() (oldStreamId=").concat(oldStream.id, ", newStreamId=").concat(stream.id, ", micShouldBeMuted=").concat(micShouldBeMuted, ", vidShouldBeMuted=").concat(vidShouldBeMuted, ")"));
608
- setTracksEnabled(stream.getAudioTracks(), !micShouldBeMuted);
609
- setTracksEnabled(stream.getVideoTracks(), !vidShouldBeMuted);
610
- _this5.client.getMediaHandler().stopUserMediaStream(oldStream);
611
- }
612
- })();
613
- }
614
- enter() {
615
- var _this6 = this;
616
- return _asyncToGenerator(function* () {
617
- if (_this6.state === GroupCallState.LocalCallFeedUninitialized) {
618
- yield _this6.initLocalCallFeed();
619
- } else if (_this6.state !== GroupCallState.LocalCallFeedInitialized) {
620
- throw new Error("Cannot enter call in the \"".concat(_this6.state, "\" state"));
621
- }
622
- logger.log("GroupCall ".concat(_this6.groupCallId, " enter() running"));
623
- _this6.state = GroupCallState.Entered;
624
- _this6.client.on(CallEventHandlerEvent.Incoming, _this6.onIncomingCall);
625
- for (var call of _this6.client.callEventHandler.calls.values()) {
626
- _this6.onIncomingCall(call);
627
- }
628
- if (!_this6.useLivekit) {
629
- _this6.retryCallLoopInterval = setInterval(_this6.onRetryCallLoop, _this6.retryCallInterval);
630
- _this6.activeSpeaker = undefined;
631
- _this6.onActiveSpeakerLoop();
632
- _this6.activeSpeakerLoopInterval = setInterval(_this6.onActiveSpeakerLoop, _this6.activeSpeakerInterval);
633
- }
634
- })();
635
- }
636
- dispose() {
637
- var _this$stats;
638
- if (this.localCallFeed) {
639
- this.removeUserMediaFeed(this.localCallFeed);
640
- this.localCallFeed = undefined;
641
- }
642
- if (this.localScreenshareFeed) {
643
- this.client.getMediaHandler().stopScreensharingStream(this.localScreenshareFeed.stream);
644
- this.removeScreenshareFeed(this.localScreenshareFeed);
645
- this.localScreenshareFeed = undefined;
646
- this.localDesktopCapturerSourceId = undefined;
647
- }
648
- this.client.getMediaHandler().stopAllStreams();
649
- if (this.transmitTimer !== null) {
650
- clearTimeout(this.transmitTimer);
651
- this.transmitTimer = null;
652
- }
653
- if (this.retryCallLoopInterval !== undefined) {
654
- clearInterval(this.retryCallLoopInterval);
655
- this.retryCallLoopInterval = undefined;
656
- }
657
- if (this.participantsExpirationTimer !== null) {
658
- clearTimeout(this.participantsExpirationTimer);
659
- this.participantsExpirationTimer = null;
660
- }
661
- if (this.state !== GroupCallState.Entered) {
662
- return;
663
- }
664
- this.forEachCall(call => call.hangup(CallErrorCode.UserHangup, false));
665
- this.activeSpeaker = undefined;
666
- clearInterval(this.activeSpeakerLoopInterval);
667
- this.retryCallCounts.clear();
668
- clearInterval(this.retryCallLoopInterval);
669
- this.client.removeListener(CallEventHandlerEvent.Incoming, this.onIncomingCall);
670
- (_this$stats = this.stats) === null || _this$stats === void 0 || _this$stats.stop();
671
- }
672
- leave() {
673
- this.dispose();
674
- this.state = GroupCallState.LocalCallFeedUninitialized;
675
- }
676
- terminate() {
677
- var _arguments = arguments,
678
- _this7 = this;
679
- return _asyncToGenerator(function* () {
680
- var emitStateEvent = _arguments.length > 0 && _arguments[0] !== undefined ? _arguments[0] : true;
681
- _this7.dispose();
682
- _this7.room.off(RoomStateEvent.Update, _this7.onRoomState);
683
- _this7.client.groupCallEventHandler.groupCalls.delete(_this7.room.roomId);
684
- _this7.client.emit(GroupCallEventHandlerEvent.Ended, _this7);
685
- _this7.state = GroupCallState.Ended;
686
- if (emitStateEvent) {
687
- var existingStateEvent = _this7.room.currentState.getStateEvents(EventType.GroupCallPrefix, _this7.groupCallId);
688
- yield _this7.client.sendStateEvent(_this7.room.roomId, EventType.GroupCallPrefix, _objectSpread(_objectSpread({}, existingStateEvent.getContent()), {}, {
689
- "m.terminated": GroupCallTerminationReason.CallEnded
690
- }), _this7.groupCallId);
691
- }
692
- })();
693
- }
694
-
695
- /*
696
- * Local Usermedia
697
- */
698
-
699
- isLocalVideoMuted() {
700
- if (this.localCallFeed) {
701
- return this.localCallFeed.isVideoMuted();
702
- }
703
- return true;
704
- }
705
- isMicrophoneMuted() {
706
- if (this.localCallFeed) {
707
- return this.localCallFeed.isAudioMuted();
708
- }
709
- return true;
710
- }
711
-
712
- /**
713
- * Sets the mute state of the local participants's microphone.
714
- * @param muted - Whether to mute the microphone
715
- * @returns Whether muting/unmuting was successful
716
- */
717
- setMicrophoneMuted(muted) {
718
- var _this8 = this;
719
- return _asyncToGenerator(function* () {
720
- // hasAudioDevice can block indefinitely if the window has lost focus,
721
- // and it doesn't make much sense to keep a device from being muted, so
722
- // we always allow muted = true changes to go through
723
- if (!muted && !(yield _this8.client.getMediaHandler().hasAudioDevice())) {
724
- return false;
725
- }
726
- var sendUpdatesBefore = !muted && _this8.isPtt;
727
-
728
- // set a timer for the maximum transmit time on PTT calls
729
- if (_this8.isPtt) {
730
- // Set or clear the max transmit timer
731
- if (!muted && _this8.isMicrophoneMuted()) {
732
- _this8.transmitTimer = setTimeout(() => {
733
- _this8.setMicrophoneMuted(true);
734
- }, _this8.pttMaxTransmitTime);
735
- } else if (muted && !_this8.isMicrophoneMuted()) {
736
- if (_this8.transmitTimer !== null) clearTimeout(_this8.transmitTimer);
737
- _this8.transmitTimer = null;
738
- }
739
- }
740
- _this8.forEachCall(call => {
741
- var _call$localUsermediaF;
742
- return (_call$localUsermediaF = call.localUsermediaFeed) === null || _call$localUsermediaF === void 0 ? void 0 : _call$localUsermediaF.setAudioVideoMuted(muted, null);
743
- });
744
- var sendUpdates = /*#__PURE__*/function () {
745
- var _ref = _asyncToGenerator(function* () {
746
- var updates = [];
747
- _this8.forEachCall(call => updates.push(call.sendMetadataUpdate()));
748
- yield Promise.all(updates).catch(e => logger.info("GroupCall ".concat(_this8.groupCallId, " setMicrophoneMuted() failed to send some metadata updates"), e));
749
- });
750
- return function sendUpdates() {
751
- return _ref.apply(this, arguments);
752
- };
753
- }();
754
- if (sendUpdatesBefore) yield sendUpdates();
755
- if (_this8.localCallFeed) {
756
- logger.log("GroupCall ".concat(_this8.groupCallId, " setMicrophoneMuted() (streamId=").concat(_this8.localCallFeed.stream.id, ", muted=").concat(muted, ")"));
757
- var hasPermission = yield _this8.checkAudioPermissionIfNecessary(muted);
758
- if (!hasPermission) {
759
- return false;
760
- }
761
- _this8.localCallFeed.setAudioVideoMuted(muted, null);
762
- // I don't believe its actually necessary to enable these tracks: they
763
- // are the one on the GroupCall's own CallFeed and are cloned before being
764
- // given to any of the actual calls, so these tracks don't actually go
765
- // anywhere. Let's do it anyway to avoid confusion.
766
- setTracksEnabled(_this8.localCallFeed.stream.getAudioTracks(), !muted);
767
- } else {
768
- logger.log("GroupCall ".concat(_this8.groupCallId, " setMicrophoneMuted() no stream muted (muted=").concat(muted, ")"));
769
- _this8.initWithAudioMuted = muted;
770
- }
771
- _this8.forEachCall(call => setTracksEnabled(call.localUsermediaFeed.stream.getAudioTracks(), !muted && _this8.callExpected(call)));
772
- _this8.emit(GroupCallEvent.LocalMuteStateChanged, muted, _this8.isLocalVideoMuted());
773
- if (!sendUpdatesBefore) yield sendUpdates();
774
- return true;
775
- })();
776
- }
777
-
778
- /**
779
- * If we allow entering a call without a camera and without video, it can happen that the access rights to the
780
- * devices have not yet been queried. If a stream does not yet have an audio track, we assume that the rights have
781
- * not yet been checked.
782
- *
783
- * `this.client.getMediaHandler().getUserMediaStream` clones the current stream, so it only wanted to be called when
784
- * not Audio Track exists.
785
- * As such, this is a compromise, because, the access rights should always be queried before the call.
786
- */
787
- checkAudioPermissionIfNecessary(muted) {
788
- var _this9 = this;
789
- return _asyncToGenerator(function* () {
790
- // We needed this here to avoid an error in case user join a call without a device.
791
- try {
792
- if (!muted && _this9.localCallFeed && !_this9.localCallFeed.hasAudioTrack) {
793
- var stream = yield _this9.client.getMediaHandler().getUserMediaStream(true, !_this9.localCallFeed.isVideoMuted());
794
- if ((stream === null || stream === void 0 ? void 0 : stream.getTracks().length) === 0) {
795
- // if case permission denied to get a stream stop this here
796
- /* istanbul ignore next */
797
- logger.log("GroupCall ".concat(_this9.groupCallId, " setMicrophoneMuted() no device to receive local stream, muted=").concat(muted));
798
- return false;
799
- }
800
- }
801
- } catch (_unused) {
802
- /* istanbul ignore next */
803
- logger.log("GroupCall ".concat(_this9.groupCallId, " setMicrophoneMuted() no device or permission to receive local stream, muted=").concat(muted));
804
- return false;
805
- }
806
- return true;
807
- })();
808
- }
809
-
810
- /**
811
- * Sets the mute state of the local participants's video.
812
- * @param muted - Whether to mute the video
813
- * @returns Whether muting/unmuting was successful
814
- */
815
- setLocalVideoMuted(muted) {
816
- var _this10 = this;
817
- return _asyncToGenerator(function* () {
818
- // hasAudioDevice can block indefinitely if the window has lost focus,
819
- // and it doesn't make much sense to keep a device from being muted, so
820
- // we always allow muted = true changes to go through
821
- if (!muted && !(yield _this10.client.getMediaHandler().hasVideoDevice())) {
822
- return false;
823
- }
824
- if (_this10.localCallFeed) {
825
- /* istanbul ignore next */
826
- logger.log("GroupCall ".concat(_this10.groupCallId, " setLocalVideoMuted() (stream=").concat(_this10.localCallFeed.stream.id, ", muted=").concat(muted, ")"));
827
- try {
828
- var stream = yield _this10.client.getMediaHandler().getUserMediaStream(true, !muted);
829
- yield _this10.updateLocalUsermediaStream(stream);
830
- _this10.localCallFeed.setAudioVideoMuted(null, muted);
831
- setTracksEnabled(_this10.localCallFeed.stream.getVideoTracks(), !muted);
832
- } catch (_unused2) {
833
- // No permission to video device
834
- /* istanbul ignore next */
835
- logger.log("GroupCall ".concat(_this10.groupCallId, " setLocalVideoMuted() no device or permission to receive local stream, muted=").concat(muted));
836
- return false;
837
- }
838
- } else {
839
- logger.log("GroupCall ".concat(_this10.groupCallId, " setLocalVideoMuted() no stream muted (muted=").concat(muted, ")"));
840
- _this10.initWithVideoMuted = muted;
841
- }
842
- var updates = [];
843
- _this10.forEachCall(call => updates.push(call.setLocalVideoMuted(muted)));
844
- yield Promise.all(updates);
845
-
846
- // We setTracksEnabled again, independently from the call doing it
847
- // internally, since we might not be expecting the call
848
- _this10.forEachCall(call => setTracksEnabled(call.localUsermediaFeed.stream.getVideoTracks(), !muted && _this10.callExpected(call)));
849
- _this10.emit(GroupCallEvent.LocalMuteStateChanged, _this10.isMicrophoneMuted(), muted);
850
- return true;
851
- })();
852
- }
853
- setScreensharingEnabled(enabled) {
854
- var _arguments2 = arguments,
855
- _this11 = this;
856
- return _asyncToGenerator(function* () {
857
- var opts = _arguments2.length > 1 && _arguments2[1] !== undefined ? _arguments2[1] : {};
858
- if (enabled === _this11.isScreensharing()) {
859
- return enabled;
860
- }
861
- if (enabled) {
862
- try {
863
- logger.log("GroupCall ".concat(_this11.groupCallId, " setScreensharingEnabled() is asking for screensharing permissions"));
864
- var stream = yield _this11.client.getMediaHandler().getScreensharingStream(opts);
865
- var _loop = function* _loop(track) {
866
- var onTrackEnded = () => {
867
- _this11.setScreensharingEnabled(false);
868
- track.removeEventListener("ended", onTrackEnded);
869
- };
870
- track.addEventListener("ended", onTrackEnded);
871
- };
872
- for (var track of stream.getTracks()) {
873
- yield* _loop(track);
874
- }
875
- logger.log("GroupCall ".concat(_this11.groupCallId, " setScreensharingEnabled() granted screensharing permissions. Setting screensharing enabled on all calls"));
876
- _this11.localDesktopCapturerSourceId = opts.desktopCapturerSourceId;
877
- _this11.localScreenshareFeed = new CallFeed({
878
- client: _this11.client,
879
- roomId: _this11.room.roomId,
880
- userId: _this11.client.getUserId(),
881
- deviceId: _this11.client.getDeviceId(),
882
- stream,
883
- purpose: SDPStreamMetadataPurpose.Screenshare,
884
- audioMuted: false,
885
- videoMuted: false
886
- });
887
- _this11.addScreenshareFeed(_this11.localScreenshareFeed);
888
- _this11.emit(GroupCallEvent.LocalScreenshareStateChanged, true, _this11.localScreenshareFeed, _this11.localDesktopCapturerSourceId);
889
-
890
- // TODO: handle errors
891
- _this11.forEachCall(call => call.pushLocalFeed(_this11.localScreenshareFeed.clone()));
892
- return true;
893
- } catch (error) {
894
- if (opts.throwOnFail) throw error;
895
- logger.error("GroupCall ".concat(_this11.groupCallId, " setScreensharingEnabled() enabling screensharing error"), error);
896
- _this11.emit(GroupCallEvent.Error, new GroupCallError(GroupCallErrorCode.NoUserMedia, "Failed to get screen-sharing stream: ", error));
897
- return false;
898
- }
899
- } else {
900
- _this11.forEachCall(call => {
901
- if (call.localScreensharingFeed) call.removeLocalFeed(call.localScreensharingFeed);
902
- });
903
- _this11.client.getMediaHandler().stopScreensharingStream(_this11.localScreenshareFeed.stream);
904
- _this11.removeScreenshareFeed(_this11.localScreenshareFeed);
905
- _this11.localScreenshareFeed = undefined;
906
- _this11.localDesktopCapturerSourceId = undefined;
907
- _this11.emit(GroupCallEvent.LocalScreenshareStateChanged, false, undefined, undefined);
908
- return false;
909
- }
910
- })();
911
- }
912
- isScreensharing() {
913
- return !!this.localScreenshareFeed;
914
- }
915
- /**
916
- * Determines whether a given participant expects us to call them (versus
917
- * them calling us).
918
- * @param userId - The participant's user ID.
919
- * @param deviceId - The participant's device ID.
920
- * @returns Whether we need to place an outgoing call to the participant.
921
- */
922
- wantsOutgoingCall(userId, deviceId) {
923
- var localUserId = this.client.getUserId();
924
- var localDeviceId = this.client.getDeviceId();
925
- return (
926
- // If a user's ID is less than our own, they'll call us
927
- userId >= localUserId && (
928
- // If this is another one of our devices, compare device IDs to tell whether it'll call us
929
- userId !== localUserId || deviceId > localDeviceId)
930
- );
931
- }
932
-
933
- /**
934
- * Places calls to all participants that we're responsible for calling.
935
- */
936
- placeOutgoingCalls() {
937
- var _this12 = this;
938
- var callsChanged = false;
939
- var _loop2 = function _loop2(_userId2) {
940
- var _this12$calls$get;
941
- var callMap = (_this12$calls$get = _this12.calls.get(_userId2)) !== null && _this12$calls$get !== void 0 ? _this12$calls$get : new Map();
942
- var _loop3 = function _loop3(deviceId) {
943
- var prevCall = callMap.get(deviceId);
944
- if ((prevCall === null || prevCall === void 0 ? void 0 : prevCall.getOpponentSessionId()) !== participant.sessionId && _this12.wantsOutgoingCall(_userId2, deviceId)) {
945
- callsChanged = true;
946
- if (prevCall !== undefined) {
947
- logger.debug("GroupCall ".concat(_this12.groupCallId, " placeOutgoingCalls() replacing call (userId=").concat(_userId2, ", deviceId=").concat(deviceId, ", callId=").concat(prevCall.callId, ")"));
948
- prevCall.hangup(CallErrorCode.NewSession, false);
949
- }
950
- var newCall = createNewMatrixCall(_this12.client, _this12.room.roomId, {
951
- invitee: _userId2,
952
- opponentDeviceId: deviceId,
953
- opponentSessionId: participant.sessionId,
954
- groupCallId: _this12.groupCallId
955
- });
956
- if (newCall === null) {
957
- logger.error("GroupCall ".concat(_this12.groupCallId, " placeOutgoingCalls() failed to create call (userId=").concat(_userId2, ", device=").concat(deviceId, ")"));
958
- callMap.delete(deviceId);
959
- } else {
960
- _this12.initCall(newCall);
961
- callMap.set(deviceId, newCall);
962
- logger.debug("GroupCall ".concat(_this12.groupCallId, " placeOutgoingCalls() placing call (userId=").concat(_userId2, ", deviceId=").concat(deviceId, ", sessionId=").concat(participant.sessionId, ")"));
963
- newCall.placeCallWithCallFeeds(_this12.getLocalFeeds().map(feed => feed.clone()), participant.screensharing).then(() => {
964
- if (_this12.dataChannelsEnabled) {
965
- newCall.createDataChannel("datachannel", _this12.dataChannelOptions);
966
- }
967
- }).catch(e => {
968
- logger.warn("GroupCall ".concat(_this12.groupCallId, " placeOutgoingCalls() failed to place call (userId=").concat(_userId2, ")"), e);
969
- if (e instanceof CallError && e.code === GroupCallErrorCode.UnknownDevice) {
970
- _this12.emit(GroupCallEvent.Error, e);
971
- } else {
972
- _this12.emit(GroupCallEvent.Error, new GroupCallError(GroupCallErrorCode.PlaceCallFailed, "Failed to place call to ".concat(_userId2)));
973
- }
974
- newCall.hangup(CallErrorCode.SignallingFailed, false);
975
- if (callMap.get(deviceId) === newCall) callMap.delete(deviceId);
976
- });
977
- }
978
- }
979
- };
980
- for (var [deviceId, participant] of participantMap) {
981
- _loop3(deviceId);
982
- }
983
- if (callMap.size > 0) {
984
- _this12.calls.set(_userId2, callMap);
985
- } else {
986
- _this12.calls.delete(_userId2);
987
- }
988
- };
989
- for (var [{
990
- userId: _userId2
991
- }, participantMap] of this.participants) {
992
- _loop2(_userId2);
993
- }
994
- if (callsChanged) this.emit(GroupCallEvent.CallsChanged, this.calls);
995
- }
996
-
997
- /*
998
- * Room Member State
999
- */
1000
-
1001
- getMemberStateEvents(userId) {
1002
- return userId === undefined ? this.room.currentState.getStateEvents(EventType.GroupCallMemberPrefix) : this.room.currentState.getStateEvents(EventType.GroupCallMemberPrefix, userId);
1003
- }
1004
- initCall(call) {
1005
- var opponentMemberId = getCallUserId(call);
1006
- if (!opponentMemberId) {
1007
- throw new Error("Cannot init call without user id");
1008
- }
1009
- var onCallFeedsChanged = () => this.onCallFeedsChanged(call);
1010
- var onCallStateChanged = (state, oldState) => this.onCallStateChanged(call, state, oldState);
1011
- var onCallHangup = this.onCallHangup;
1012
- var onCallReplaced = newCall => this.onCallReplaced(call, newCall);
1013
- var deviceMap = this.callHandlers.get(opponentMemberId);
1014
- if (deviceMap === undefined) {
1015
- deviceMap = new Map();
1016
- this.callHandlers.set(opponentMemberId, deviceMap);
1017
- }
1018
- deviceMap.set(call.getOpponentDeviceId(), {
1019
- onCallFeedsChanged,
1020
- onCallStateChanged,
1021
- onCallHangup,
1022
- onCallReplaced
1023
- });
1024
- call.on(CallEvent.FeedsChanged, onCallFeedsChanged);
1025
- call.on(CallEvent.State, onCallStateChanged);
1026
- call.on(CallEvent.Hangup, onCallHangup);
1027
- call.on(CallEvent.Replaced, onCallReplaced);
1028
- call.isPtt = this.isPtt;
1029
- this.reEmitter.reEmit(call, Object.values(CallEvent));
1030
- call.initStats(this.getGroupCallStats());
1031
- onCallFeedsChanged();
1032
- }
1033
- disposeCall(call, hangupReason) {
1034
- var opponentMemberId = getCallUserId(call);
1035
- var opponentDeviceId = call.getOpponentDeviceId();
1036
- if (!opponentMemberId) {
1037
- throw new Error("Cannot dispose call without user id");
1038
- }
1039
- var deviceMap = this.callHandlers.get(opponentMemberId);
1040
- var {
1041
- onCallFeedsChanged,
1042
- onCallStateChanged,
1043
- onCallHangup,
1044
- onCallReplaced
1045
- } = deviceMap.get(opponentDeviceId);
1046
- call.removeListener(CallEvent.FeedsChanged, onCallFeedsChanged);
1047
- call.removeListener(CallEvent.State, onCallStateChanged);
1048
- call.removeListener(CallEvent.Hangup, onCallHangup);
1049
- call.removeListener(CallEvent.Replaced, onCallReplaced);
1050
- deviceMap.delete(opponentMemberId);
1051
- if (deviceMap.size === 0) this.callHandlers.delete(opponentMemberId);
1052
- if (call.hangupReason === CallErrorCode.Replaced) {
1053
- return;
1054
- }
1055
- var usermediaFeed = this.getUserMediaFeed(opponentMemberId, opponentDeviceId);
1056
- if (usermediaFeed) {
1057
- this.removeUserMediaFeed(usermediaFeed);
1058
- }
1059
- var screenshareFeed = this.getScreenshareFeed(opponentMemberId, opponentDeviceId);
1060
- if (screenshareFeed) {
1061
- this.removeScreenshareFeed(screenshareFeed);
1062
- }
1063
- }
1064
- /*
1065
- * UserMedia CallFeed Event Handlers
1066
- */
1067
-
1068
- getUserMediaFeed(userId, deviceId) {
1069
- return this.userMediaFeeds.find(f => f.userId === userId && f.deviceId === deviceId);
1070
- }
1071
- addUserMediaFeed(callFeed) {
1072
- this.userMediaFeeds.push(callFeed);
1073
- callFeed.measureVolumeActivity(true);
1074
- this.emit(GroupCallEvent.UserMediaFeedsChanged, this.userMediaFeeds);
1075
- }
1076
- replaceUserMediaFeed(existingFeed, replacementFeed) {
1077
- var feedIndex = this.userMediaFeeds.findIndex(f => f.userId === existingFeed.userId && f.deviceId === existingFeed.deviceId);
1078
- if (feedIndex === -1) {
1079
- throw new Error("Couldn't find user media feed to replace");
1080
- }
1081
- this.userMediaFeeds.splice(feedIndex, 1, replacementFeed);
1082
- existingFeed.dispose();
1083
- replacementFeed.measureVolumeActivity(true);
1084
- this.emit(GroupCallEvent.UserMediaFeedsChanged, this.userMediaFeeds);
1085
- }
1086
- removeUserMediaFeed(callFeed) {
1087
- var feedIndex = this.userMediaFeeds.findIndex(f => f.userId === callFeed.userId && f.deviceId === callFeed.deviceId);
1088
- if (feedIndex === -1) {
1089
- throw new Error("Couldn't find user media feed to remove");
1090
- }
1091
- this.userMediaFeeds.splice(feedIndex, 1);
1092
- callFeed.dispose();
1093
- this.emit(GroupCallEvent.UserMediaFeedsChanged, this.userMediaFeeds);
1094
- if (this.activeSpeaker === callFeed) {
1095
- this.activeSpeaker = this.userMediaFeeds[0];
1096
- this.emit(GroupCallEvent.ActiveSpeakerChanged, this.activeSpeaker);
1097
- }
1098
- }
1099
- /*
1100
- * Screenshare Call Feed Event Handlers
1101
- */
1102
-
1103
- getScreenshareFeed(userId, deviceId) {
1104
- return this.screenshareFeeds.find(f => f.userId === userId && f.deviceId === deviceId);
1105
- }
1106
- addScreenshareFeed(callFeed) {
1107
- this.screenshareFeeds.push(callFeed);
1108
- this.emit(GroupCallEvent.ScreenshareFeedsChanged, this.screenshareFeeds);
1109
- }
1110
- replaceScreenshareFeed(existingFeed, replacementFeed) {
1111
- var feedIndex = this.screenshareFeeds.findIndex(f => f.userId === existingFeed.userId && f.deviceId === existingFeed.deviceId);
1112
- if (feedIndex === -1) {
1113
- throw new Error("Couldn't find screenshare feed to replace");
1114
- }
1115
- this.screenshareFeeds.splice(feedIndex, 1, replacementFeed);
1116
- existingFeed.dispose();
1117
- this.emit(GroupCallEvent.ScreenshareFeedsChanged, this.screenshareFeeds);
1118
- }
1119
- removeScreenshareFeed(callFeed) {
1120
- var feedIndex = this.screenshareFeeds.findIndex(f => f.userId === callFeed.userId && f.deviceId === callFeed.deviceId);
1121
- if (feedIndex === -1) {
1122
- throw new Error("Couldn't find screenshare feed to remove");
1123
- }
1124
- this.screenshareFeeds.splice(feedIndex, 1);
1125
- callFeed.dispose();
1126
- this.emit(GroupCallEvent.ScreenshareFeedsChanged, this.screenshareFeeds);
1127
- }
1128
-
1129
- /**
1130
- * Recalculates and updates the participant map to match the room state.
1131
- */
1132
- updateParticipants() {
1133
- var localMember = this.room.getMember(this.client.getUserId());
1134
- if (!localMember) {
1135
- // The client hasn't fetched enough of the room state to get our own member
1136
- // event. This probably shouldn't happen, but sanity check & exit for now.
1137
- logger.warn("GroupCall ".concat(this.groupCallId, " updateParticipants() tried to update participants before local room member is available"));
1138
- return;
1139
- }
1140
- if (this.participantsExpirationTimer !== null) {
1141
- clearTimeout(this.participantsExpirationTimer);
1142
- this.participantsExpirationTimer = null;
1143
- }
1144
- if (this.state === GroupCallState.Ended) {
1145
- this.participants = new Map();
1146
- return;
1147
- }
1148
- var participants = new Map();
1149
- var now = Date.now();
1150
- var entered = this.state === GroupCallState.Entered || this.enteredViaAnotherSession;
1151
- var nextExpiration = Infinity;
1152
- for (var e of this.getMemberStateEvents()) {
1153
- var member = this.room.getMember(e.getStateKey());
1154
- var content = e.getContent();
1155
- var calls = Array.isArray(content["m.calls"]) ? content["m.calls"] : [];
1156
- var call = calls.find(call => call["m.call_id"] === this.groupCallId);
1157
- var devices = Array.isArray(call === null || call === void 0 ? void 0 : call["m.devices"]) ? call["m.devices"] : [];
1158
-
1159
- // Filter out invalid and expired devices
1160
- var validDevices = devices.filter(d => typeof d.device_id === "string" && typeof d.session_id === "string" && typeof d.expires_ts === "number" && d.expires_ts > now && Array.isArray(d.feeds));
1161
-
1162
- // Apply local echo for the unentered case
1163
- if (!entered && (member === null || member === void 0 ? void 0 : member.userId) === this.client.getUserId()) {
1164
- validDevices = validDevices.filter(d => d.device_id !== this.client.getDeviceId());
1165
- }
1166
-
1167
- // Must have a connected device and be joined to the room
1168
- if (validDevices.length > 0 && (member === null || member === void 0 ? void 0 : member.membership) === KnownMembership.Join) {
1169
- var deviceMap = new Map();
1170
- participants.set(member, deviceMap);
1171
- for (var d of validDevices) {
1172
- deviceMap.set(d.device_id, {
1173
- sessionId: d.session_id,
1174
- screensharing: d.feeds.some(f => f.purpose === SDPStreamMetadataPurpose.Screenshare)
1175
- });
1176
- if (d.expires_ts < nextExpiration) nextExpiration = d.expires_ts;
1177
- }
1178
- }
1179
- }
1180
-
1181
- // Apply local echo for the entered case
1182
- if (entered) {
1183
- var _deviceMap = participants.get(localMember);
1184
- if (_deviceMap === undefined) {
1185
- _deviceMap = new Map();
1186
- participants.set(localMember, _deviceMap);
1187
- }
1188
- if (!_deviceMap.has(this.client.getDeviceId())) {
1189
- _deviceMap.set(this.client.getDeviceId(), {
1190
- sessionId: this.client.getSessionId(),
1191
- screensharing: this.getLocalFeeds().some(f => f.purpose === SDPStreamMetadataPurpose.Screenshare)
1192
- });
1193
- }
1194
- }
1195
- this.participants = participants;
1196
- if (nextExpiration < Infinity) {
1197
- this.participantsExpirationTimer = setTimeout(() => this.updateParticipants(), nextExpiration - now);
1198
- }
1199
- }
1200
-
1201
- /**
1202
- * Updates the local user's member state with the devices returned by the given function.
1203
- * @param fn - A function from the current devices to the new devices. If it
1204
- * returns null, the update will be skipped.
1205
- * @param keepAlive - Whether the request should outlive the window.
1206
- */
1207
- updateDevices(fn) {
1208
- var _arguments3 = arguments,
1209
- _this13 = this;
1210
- return _asyncToGenerator(function* () {
1211
- var _event$getContent;
1212
- var keepAlive = _arguments3.length > 1 && _arguments3[1] !== undefined ? _arguments3[1] : false;
1213
- var now = Date.now();
1214
- var localUserId = _this13.client.getUserId();
1215
- var event = _this13.getMemberStateEvents(localUserId);
1216
- var content = (_event$getContent = event === null || event === void 0 ? void 0 : event.getContent()) !== null && _event$getContent !== void 0 ? _event$getContent : {};
1217
- var calls = Array.isArray(content["m.calls"]) ? content["m.calls"] : [];
1218
- var call = null;
1219
- var otherCalls = [];
1220
- for (var c of calls) {
1221
- if (c["m.call_id"] === _this13.groupCallId) {
1222
- call = c;
1223
- } else {
1224
- otherCalls.push(c);
1225
- }
1226
- }
1227
- if (call === null) call = {};
1228
- var devices = Array.isArray(call["m.devices"]) ? call["m.devices"] : [];
1229
-
1230
- // Filter out invalid and expired devices
1231
- var validDevices = devices.filter(d => typeof d.device_id === "string" && typeof d.session_id === "string" && typeof d.expires_ts === "number" && d.expires_ts > now && Array.isArray(d.feeds));
1232
- var newDevices = fn(validDevices);
1233
- if (newDevices === null) return;
1234
- var newCalls = [...otherCalls];
1235
- if (newDevices.length > 0) {
1236
- newCalls.push(_objectSpread(_objectSpread({}, call), {}, {
1237
- "m.call_id": _this13.groupCallId,
1238
- "m.devices": newDevices
1239
- }));
1240
- }
1241
- var newContent = {
1242
- "m.calls": newCalls
1243
- };
1244
- yield _this13.client.sendStateEvent(_this13.room.roomId, EventType.GroupCallMemberPrefix, newContent, localUserId, {
1245
- keepAlive
1246
- });
1247
- })();
1248
- }
1249
- addDeviceToMemberState() {
1250
- var _this14 = this;
1251
- return _asyncToGenerator(function* () {
1252
- yield _this14.updateDevices(devices => [...devices.filter(d => d.device_id !== _this14.client.getDeviceId()), {
1253
- device_id: _this14.client.getDeviceId(),
1254
- session_id: _this14.client.getSessionId(),
1255
- expires_ts: Date.now() + DEVICE_TIMEOUT,
1256
- feeds: _this14.getLocalFeeds().map(feed => ({
1257
- purpose: feed.purpose
1258
- }))
1259
- // TODO: Add data channels
1260
- }]);
1261
- })();
1262
- }
1263
- updateMemberState() {
1264
- var _this15 = this;
1265
- return _asyncToGenerator(function* () {
1266
- // Clear the old update interval before proceeding
1267
- if (_this15.resendMemberStateTimer !== null) {
1268
- clearInterval(_this15.resendMemberStateTimer);
1269
- _this15.resendMemberStateTimer = null;
1270
- }
1271
- if (_this15.state === GroupCallState.Entered) {
1272
- // Add the local device
1273
- yield _this15.addDeviceToMemberState();
1274
-
1275
- // Resend the state event every so often so it doesn't become stale
1276
- _this15.resendMemberStateTimer = setInterval(/*#__PURE__*/_asyncToGenerator(function* () {
1277
- logger.log("GroupCall ".concat(_this15.groupCallId, " updateMemberState() resending call member state\""));
1278
- try {
1279
- yield _this15.addDeviceToMemberState();
1280
- } catch (e) {
1281
- logger.error("GroupCall ".concat(_this15.groupCallId, " updateMemberState() failed to resend call member state"), e);
1282
- }
1283
- }), DEVICE_TIMEOUT * 3 / 4);
1284
- } else {
1285
- // Remove the local device
1286
- yield _this15.updateDevices(devices => devices.filter(d => d.device_id !== _this15.client.getDeviceId()), true);
1287
- }
1288
- })();
1289
- }
1290
-
1291
- /**
1292
- * Cleans up our member state by filtering out logged out devices, inactive
1293
- * devices, and our own device (if we know we haven't entered).
1294
- */
1295
- cleanMemberState() {
1296
- var _this16 = this;
1297
- return _asyncToGenerator(function* () {
1298
- var {
1299
- devices: myDevices
1300
- } = yield _this16.client.getDevices();
1301
- var deviceMap = new Map(myDevices.map(d => [d.device_id, d]));
1302
-
1303
- // updateDevices takes care of filtering out inactive devices for us
1304
- yield _this16.updateDevices(devices => {
1305
- var newDevices = devices.filter(d => {
1306
- var device = deviceMap.get(d.device_id);
1307
- return (device === null || device === void 0 ? void 0 : device.last_seen_ts) !== undefined && !(d.device_id === _this16.client.getDeviceId() && _this16.state !== GroupCallState.Entered && !_this16.enteredViaAnotherSession);
1308
- });
1309
-
1310
- // Skip the update if the devices are unchanged
1311
- return newDevices.length === devices.length ? null : newDevices;
1312
- });
1313
- })();
1314
- }
1315
- getGroupCallStats() {
1316
- if (this.stats === undefined) {
1317
- var userID = this.client.getUserId() || "unknown";
1318
- this.stats = new GroupCallStats(this.groupCallId, userID, this.statsCollectIntervalTime);
1319
- this.stats.reports.on(StatsReport.CONNECTION_STATS, this.onConnectionStats);
1320
- this.stats.reports.on(StatsReport.BYTE_SENT_STATS, this.onByteSentStats);
1321
- this.stats.reports.on(StatsReport.SUMMARY_STATS, this.onSummaryStats);
1322
- this.stats.reports.on(StatsReport.CALL_FEED_REPORT, this.onCallFeedReport);
1323
- }
1324
- return this.stats;
1325
- }
1326
- setGroupCallStatsInterval(interval) {
1327
- this.statsCollectIntervalTime = interval;
1328
- if (this.stats !== undefined) {
1329
- this.stats.stop();
1330
- this.stats.setInterval(interval);
1331
- if (interval > 0) {
1332
- this.stats.start();
1333
- }
1334
- }
1335
- }
1336
- }
1337
- //# sourceMappingURL=groupCall.js.map