@100mslive/hms-video-store 0.2.82 → 0.2.83
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/common/ui-logger.d.ts +13 -13
- package/dist/core/IHMSActions.d.ts +266 -264
- package/dist/core/IHMSNotifications.d.ts +14 -15
- package/dist/core/IHMSStore.d.ts +54 -56
- package/dist/core/hmsSDKStore/HMSNotifications.d.ts +25 -25
- package/dist/core/hmsSDKStore/HMSPlaylist.d.ts +21 -21
- package/dist/core/hmsSDKStore/HMSReactiveStore.d.ts +79 -79
- package/dist/core/hmsSDKStore/HMSSDKActions.d.ts +157 -157
- package/dist/core/hmsSDKStore/adapter.d.ts +49 -49
- package/dist/core/hmsSDKStore/common/mapping.d.ts +7 -7
- package/dist/core/hmsSDKStore/internalTypes.d.ts +4 -4
- package/dist/core/hmsSDKStore/sdkTypes.d.ts +3 -2
- package/dist/core/hmsSDKStore/sdkUtils/ActionBatcher.d.ts +19 -19
- package/dist/core/hmsSDKStore/sdkUtils/sdkUtils.d.ts +2 -2
- package/dist/core/hmsSDKStore/sdkUtils/storeMergeUtils.d.ts +14 -14
- package/dist/core/index.d.ts +9 -7
- package/dist/core/schema/device-change.d.ts +13 -13
- package/dist/core/schema/error.d.ts +13 -13
- package/dist/core/schema/index.d.ts +11 -11
- package/dist/core/schema/message.d.ts +31 -31
- package/dist/core/schema/notification.d.ts +40 -40
- package/dist/core/schema/peer.d.ts +67 -67
- package/dist/core/schema/playlist.d.ts +127 -109
- package/dist/core/schema/requests.d.ts +31 -31
- package/dist/core/schema/role.d.ts +3 -3
- package/dist/core/schema/room.d.ts +23 -23
- package/dist/core/schema/schema.d.ts +29 -29
- package/dist/core/schema/settings.d.ts +5 -5
- package/dist/core/selectors/derivedSelectors.d.ts +29 -29
- package/dist/core/selectors/index.d.ts +5 -5
- package/dist/core/selectors/playlistselectors.d.ts +3 -3
- package/dist/core/selectors/selectorUtils.d.ts +18 -18
- package/dist/core/selectors/selectors.d.ts +185 -191
- package/dist/core/selectors/selectorsByID.d.ts +127 -128
- package/dist/core/selectors/selectorsByReference.d.ts +3 -3
- package/dist/hms-video-store.cjs.js +1 -0
- package/dist/hms-video-store.esm.js +1 -5376
- package/dist/index.d.ts +1 -1
- package/package.json +21 -84
- package/dist/hms-video-store.cjs.development.js +0 -5468
- package/dist/hms-video-store.cjs.development.js.map +0 -1
- package/dist/hms-video-store.cjs.production.min.js +0 -2
- package/dist/hms-video-store.cjs.production.min.js.map +0 -1
- package/dist/hms-video-store.esm.js.map +0 -1
- package/dist/index.js +0 -8
- package/dist/test/fakeStore.d.ts +0 -23
- package/dist/test/fixtures.d.ts +0 -3
- package/src/common/ui-logger.ts +0 -88
- package/src/core/IHMSActions.ts +0 -318
- package/src/core/IHMSNotifications.ts +0 -16
- package/src/core/IHMSStore.ts +0 -60
- package/src/core/hmsSDKStore/HMSNotifications.ts +0 -194
- package/src/core/hmsSDKStore/HMSPlaylist.ts +0 -78
- package/src/core/hmsSDKStore/HMSReactiveStore.ts +0 -271
- package/src/core/hmsSDKStore/HMSSDKActions.ts +0 -1156
- package/src/core/hmsSDKStore/adapter.ts +0 -244
- package/src/core/hmsSDKStore/common/mapping.ts +0 -32
- package/src/core/hmsSDKStore/internalTypes.ts +0 -8
- package/src/core/hmsSDKStore/sdkTypes.ts +0 -55
- package/src/core/hmsSDKStore/sdkUtils/ActionBatcher.ts +0 -63
- package/src/core/hmsSDKStore/sdkUtils/sdkUtils.ts +0 -5
- package/src/core/hmsSDKStore/sdkUtils/storeMergeUtils.ts +0 -98
- package/src/core/index.ts +0 -18
- package/src/core/schema/device-change.ts +0 -14
- package/src/core/schema/error.ts +0 -13
- package/src/core/schema/index.ts +0 -11
- package/src/core/schema/message.ts +0 -35
- package/src/core/schema/notification.ts +0 -41
- package/src/core/schema/peer.ts +0 -78
- package/src/core/schema/playlist.ts +0 -114
- package/src/core/schema/requests.ts +0 -36
- package/src/core/schema/role.ts +0 -5
- package/src/core/schema/room.ts +0 -26
- package/src/core/schema/schema.ts +0 -94
- package/src/core/schema/settings.ts +0 -5
- package/src/core/selectors/derivedSelectors.ts +0 -81
- package/src/core/selectors/index.ts +0 -5
- package/src/core/selectors/playlistselectors.ts +0 -67
- package/src/core/selectors/selectorUtils.ts +0 -63
- package/src/core/selectors/selectors.ts +0 -400
- package/src/core/selectors/selectorsByID.ts +0 -401
- package/src/core/selectors/selectorsByReference.ts +0 -45
- package/src/index.ts +0 -1
- package/src/test/fakeStore.ts +0 -272
- package/src/test/fixtures.ts +0 -22
- package/src/test/integration/.gitkeep +0 -0
- package/src/test/unit/HMSNotifications.test.ts +0 -123
- package/src/test/unit/reactiveStore.test.ts +0 -129
- package/src/test/unit/roleSelectors.test.ts +0 -85
- package/src/test/unit/selectors.test.ts +0 -316
- package/src/test/unit/selectorsByReference.test.ts +0 -27
- package/src/test/unit/storeMergeUtils.test.ts +0 -168
|
@@ -1,1156 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
createDefaultStoreState,
|
|
3
|
-
HMSMediaSettings,
|
|
4
|
-
HMSMessage,
|
|
5
|
-
HMSMessageInput,
|
|
6
|
-
HMSPeer,
|
|
7
|
-
HMSPeerID,
|
|
8
|
-
HMSPlaylistType,
|
|
9
|
-
HMSRoomState,
|
|
10
|
-
HMSStore,
|
|
11
|
-
HMSTrack,
|
|
12
|
-
HMSTrackID,
|
|
13
|
-
HMSTrackSource,
|
|
14
|
-
HMSChangeMultiTrackStateParams,
|
|
15
|
-
IHMSPlaylistActions,
|
|
16
|
-
} from '../schema';
|
|
17
|
-
import { IHMSActions } from '../IHMSActions';
|
|
18
|
-
import * as sdkTypes from './sdkTypes';
|
|
19
|
-
import { SDKToHMS } from './adapter';
|
|
20
|
-
import {
|
|
21
|
-
HMSRoleChangeRequest,
|
|
22
|
-
selectHMSMessagesCount,
|
|
23
|
-
selectIsLocalScreenShared,
|
|
24
|
-
selectIsLocalVideoDisplayEnabled,
|
|
25
|
-
selectIsLocalVideoEnabled,
|
|
26
|
-
selectLocalAudioTrackID,
|
|
27
|
-
selectLocalPeer,
|
|
28
|
-
selectLocalTrackIDs,
|
|
29
|
-
selectLocalVideoTrackID,
|
|
30
|
-
selectPeerByID,
|
|
31
|
-
selectPermissions,
|
|
32
|
-
selectRolesMap,
|
|
33
|
-
selectRoomStarted,
|
|
34
|
-
selectRoomState,
|
|
35
|
-
selectLocalMediaSettings,
|
|
36
|
-
selectTrackByID,
|
|
37
|
-
selectTracksMap,
|
|
38
|
-
} from '../selectors';
|
|
39
|
-
import { HMSLogger } from '../../common/ui-logger';
|
|
40
|
-
import {
|
|
41
|
-
HMSAudioPlugin,
|
|
42
|
-
HMSAudioTrack as SDKHMSAudioTrack,
|
|
43
|
-
HMSException as SDKHMSException,
|
|
44
|
-
HMSLeaveRoomRequest as SDKHMSLeaveRoomRequest,
|
|
45
|
-
HMSLocalAudioTrack as SDKHMSLocalAudioTrack,
|
|
46
|
-
HMSLocalTrack as SDKHMSLocalTrack,
|
|
47
|
-
HMSLocalVideoTrack as SDKHMSLocalVideoTrack,
|
|
48
|
-
HMSLogLevel,
|
|
49
|
-
HMSRemoteTrack as SDKHMSRemoteTrack,
|
|
50
|
-
HMSRemoteVideoTrack as SDKHMSRemoteVideoTrack,
|
|
51
|
-
HMSRoleChangeRequest as SDKHMSRoleChangeRequest,
|
|
52
|
-
HMSChangeTrackStateRequest as SDKHMSChangeTrackStateRequest,
|
|
53
|
-
HMSChangeMultiTrackStateParams as SDKHMSChangeMultiTrackStateParams,
|
|
54
|
-
HMSChangeMultiTrackStateRequest as SDKHMSChangeMultiTrackStateRequest,
|
|
55
|
-
HMSSdk,
|
|
56
|
-
HMSSimulcastLayer,
|
|
57
|
-
HMSTrack as SDKHMSTrack,
|
|
58
|
-
HMSVideoPlugin,
|
|
59
|
-
HMSVideoTrack as SDKHMSVideoTrack,
|
|
60
|
-
} from '@100mslive/hms-video';
|
|
61
|
-
import { IHMSStore } from '../IHMSStore';
|
|
62
|
-
|
|
63
|
-
import {
|
|
64
|
-
areArraysEqual,
|
|
65
|
-
mergeNewPeersInDraft,
|
|
66
|
-
mergeNewTracksInDraft,
|
|
67
|
-
} from './sdkUtils/storeMergeUtils';
|
|
68
|
-
import { HMSNotifications } from './HMSNotifications';
|
|
69
|
-
import { NamedSetState } from './internalTypes';
|
|
70
|
-
import { isRemoteTrack } from './sdkUtils/sdkUtils';
|
|
71
|
-
import { HMSPlaylist } from './HMSPlaylist';
|
|
72
|
-
import { ACTION_TYPES } from './common/mapping';
|
|
73
|
-
|
|
74
|
-
// import { ActionBatcher } from './sdkUtils/ActionBatcher';
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* This class implements the IHMSActions interface for 100ms SDK. It connects with SDK
|
|
78
|
-
* and takes control of data management by letting every action pass through it. The
|
|
79
|
-
* passed in store is ensured to be the single source of truth reflecting current
|
|
80
|
-
* room related data at any point in time.
|
|
81
|
-
*
|
|
82
|
-
* @privateRemarks
|
|
83
|
-
* Things to keep in mind while updating store -
|
|
84
|
-
* 1. Treat setState as an atomic operation, if an action results in multiple changes,
|
|
85
|
-
* the changes should all happen within single setState function.
|
|
86
|
-
* 2. While updating the state it's very important to not update the reference if
|
|
87
|
-
* something is unchanged. Copy data in same reference object don't assign new
|
|
88
|
-
* object.
|
|
89
|
-
* 3. Mental Model(1) - Actions from backend -> Listeners of this class -> update store -> views update themselves
|
|
90
|
-
* eg. for this - peer added, remote muted etc.
|
|
91
|
-
* 4. Mental Model(2) - Actions from local -> View calls actions -> update store -> views update themselves
|
|
92
|
-
* eg. local track enabled, join, leave etc.
|
|
93
|
-
* 5. State is immutable, a new copy with new references is created when there is a change,
|
|
94
|
-
* if you try to modify state outside of setState, there'll be an error.
|
|
95
|
-
*/
|
|
96
|
-
export class HMSSDKActions implements IHMSActions {
|
|
97
|
-
private hmsSDKTracks: Record<string, SDKHMSTrack> = {};
|
|
98
|
-
private hmsSDKPeers: Record<string, sdkTypes.HMSPeer> = {};
|
|
99
|
-
private readonly sdk: HMSSdk;
|
|
100
|
-
private readonly store: IHMSStore;
|
|
101
|
-
private isRoomJoinCalled: boolean = false;
|
|
102
|
-
private hmsNotifications: HMSNotifications;
|
|
103
|
-
// private actionBatcher: ActionBatcher;
|
|
104
|
-
audioPlaylist!: IHMSPlaylistActions;
|
|
105
|
-
videoPlaylist!: IHMSPlaylistActions;
|
|
106
|
-
|
|
107
|
-
constructor(store: IHMSStore, sdk: HMSSdk, notificationManager: HMSNotifications) {
|
|
108
|
-
this.store = store;
|
|
109
|
-
this.sdk = sdk;
|
|
110
|
-
this.hmsNotifications = notificationManager;
|
|
111
|
-
// this.actionBatcher = new ActionBatcher(store);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
async unblockAudio() {
|
|
115
|
-
await this.sdk.getAudioOutput().unblockAutoplay();
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
setVolume(value: number, trackId?: HMSTrackID): void {
|
|
119
|
-
if (trackId) {
|
|
120
|
-
this.setTrackVolume(value, trackId);
|
|
121
|
-
} else {
|
|
122
|
-
this.sdk.getAudioOutput().setVolume(value);
|
|
123
|
-
this.syncRoomState('setOutputVolume');
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
setAudioOutputDevice(deviceId: string): void {
|
|
128
|
-
const deviceInfo = this.sdk.getAudioOutput().setDevice(deviceId);
|
|
129
|
-
if (deviceInfo) {
|
|
130
|
-
this.setState(draftStore => {
|
|
131
|
-
draftStore.settings.audioOutputDeviceId = deviceId;
|
|
132
|
-
}, 'setAudioOutputDevice');
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
setPreferredLayer(trackId: string, layer: HMSSimulcastLayer) {
|
|
137
|
-
const track = this.hmsSDKTracks[trackId];
|
|
138
|
-
if (track) {
|
|
139
|
-
if (track instanceof SDKHMSRemoteVideoTrack) {
|
|
140
|
-
track.preferLayer(layer);
|
|
141
|
-
this.updateVideoLayer(trackId, 'setPreferredLayer');
|
|
142
|
-
} else {
|
|
143
|
-
HMSLogger.w(`track ${trackId} is not an video track`);
|
|
144
|
-
}
|
|
145
|
-
} else {
|
|
146
|
-
this.logPossibleInconsistency(`track ${trackId} not present, unable to set preffer layer`);
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
async preview(config: sdkTypes.HMSConfig) {
|
|
151
|
-
if (this.isRoomJoinCalled) {
|
|
152
|
-
this.logPossibleInconsistency('attempting to call preview after join was called');
|
|
153
|
-
return; // ignore
|
|
154
|
-
}
|
|
155
|
-
const roomState = this.store.getState(selectRoomState);
|
|
156
|
-
if (roomState === HMSRoomState.Preview || roomState === HMSRoomState.Connecting) {
|
|
157
|
-
this.logPossibleInconsistency(
|
|
158
|
-
'attempting to call preview while room is in preview/connecting',
|
|
159
|
-
);
|
|
160
|
-
return;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
try {
|
|
164
|
-
await this.sdkPreviewWithListeners(config);
|
|
165
|
-
this.setState(store => {
|
|
166
|
-
store.room.roomState = HMSRoomState.Connecting;
|
|
167
|
-
}, 'preview');
|
|
168
|
-
} catch (err) {
|
|
169
|
-
HMSLogger.e('Cannot show preview. Failed to connect to room - ', err);
|
|
170
|
-
throw err;
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
join(config: sdkTypes.HMSConfig) {
|
|
175
|
-
if (this.isRoomJoinCalled) {
|
|
176
|
-
this.logPossibleInconsistency('room join is called again');
|
|
177
|
-
return; // ignore
|
|
178
|
-
}
|
|
179
|
-
try {
|
|
180
|
-
this.sdkJoinWithListeners(config);
|
|
181
|
-
this.isRoomJoinCalled = true;
|
|
182
|
-
this.setState(store => {
|
|
183
|
-
store.room.roomState = HMSRoomState.Connecting;
|
|
184
|
-
}, 'join');
|
|
185
|
-
} catch (err) {
|
|
186
|
-
this.isRoomJoinCalled = false; // so it can be called again if needed
|
|
187
|
-
HMSLogger.e('Failed to connect to room - ', err);
|
|
188
|
-
throw err;
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
async leave() {
|
|
193
|
-
const hasRoomStarted = this.store.getState(selectRoomStarted);
|
|
194
|
-
if (!hasRoomStarted) {
|
|
195
|
-
this.logPossibleInconsistency('room leave is called when no room is connected');
|
|
196
|
-
return; // ignore
|
|
197
|
-
}
|
|
198
|
-
return this.sdk
|
|
199
|
-
.leave()
|
|
200
|
-
.then(() => {
|
|
201
|
-
this.resetState('leave');
|
|
202
|
-
HMSLogger.i('left room');
|
|
203
|
-
})
|
|
204
|
-
.catch(err => {
|
|
205
|
-
HMSLogger.e('error in leaving room - ', err);
|
|
206
|
-
});
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
async setScreenShareEnabled(enabled: boolean, audioOnly?: boolean) {
|
|
210
|
-
if (enabled) {
|
|
211
|
-
await this.startScreenShare(audioOnly);
|
|
212
|
-
} else {
|
|
213
|
-
await this.stopScreenShare();
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
async addTrack(track: MediaStreamTrack, type: HMSTrackSource = 'regular') {
|
|
218
|
-
await this.sdk.addTrack(track, type);
|
|
219
|
-
this.syncRoomState('addTrack');
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
async removeTrack(trackId: string) {
|
|
223
|
-
await this.sdk.removeTrack(trackId);
|
|
224
|
-
this.syncRoomState('removeTrack');
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
async setLocalAudioEnabled(enabled: boolean) {
|
|
228
|
-
const trackID = this.store.getState(selectLocalAudioTrackID);
|
|
229
|
-
if (trackID) {
|
|
230
|
-
await this.setEnabledTrack(trackID, enabled);
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
async setLocalVideoEnabled(enabled: boolean) {
|
|
235
|
-
const trackID = this.store.getState(selectLocalVideoTrackID);
|
|
236
|
-
if (trackID) {
|
|
237
|
-
await this.setEnabledTrack(trackID, enabled);
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
async setEnabledTrack(trackID: string, enabled: boolean) {
|
|
242
|
-
// if mute/unmute is clicked multiple times for same operation, ignore repeated ones
|
|
243
|
-
const alreadyInSameState = this.store.getState().tracks[trackID]?.enabled === enabled;
|
|
244
|
-
if (alreadyInSameState) {
|
|
245
|
-
// it could also be a case of possible inconsistency where UI state is out of sync with truth
|
|
246
|
-
this.logPossibleInconsistency(`local track[${trackID}] enabled state - ${enabled}`);
|
|
247
|
-
return;
|
|
248
|
-
}
|
|
249
|
-
this.setState(store => {
|
|
250
|
-
// show on UI immediately
|
|
251
|
-
if (!store.tracks[trackID]) {
|
|
252
|
-
this.logPossibleInconsistency('track id not found for setEnabled');
|
|
253
|
-
} else {
|
|
254
|
-
store.tracks[trackID].displayEnabled = enabled;
|
|
255
|
-
}
|
|
256
|
-
}, 'displayEnabled');
|
|
257
|
-
try {
|
|
258
|
-
await this.setEnabledSDKTrack(trackID, enabled); // do the operation
|
|
259
|
-
this.syncRoomState('setEnabled');
|
|
260
|
-
} catch (err) {
|
|
261
|
-
// rollback on failure
|
|
262
|
-
this.setState(store => {
|
|
263
|
-
store.tracks[trackID].displayEnabled = !enabled;
|
|
264
|
-
}, 'rollbackDisplayEnabled');
|
|
265
|
-
this.hmsNotifications.sendError(SDKToHMS.convertException(err as SDKHMSException));
|
|
266
|
-
throw err;
|
|
267
|
-
}
|
|
268
|
-
const type = enabled
|
|
269
|
-
? sdkTypes.HMSTrackUpdate.TRACK_UNMUTED
|
|
270
|
-
: sdkTypes.HMSTrackUpdate.TRACK_MUTED;
|
|
271
|
-
this.hmsNotifications.sendTrackUpdate(type, trackID);
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
async setAudioSettings(settings: Partial<sdkTypes.HMSAudioTrackSettings>) {
|
|
275
|
-
const trackID = this.store.getState(selectLocalAudioTrackID);
|
|
276
|
-
if (trackID) {
|
|
277
|
-
await this.setSDKLocalAudioTrackSettings(trackID, settings);
|
|
278
|
-
this.syncRoomState('setAudioSettings');
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
async setVideoSettings(settings: Partial<sdkTypes.HMSVideoTrackSettings>) {
|
|
283
|
-
const trackID = this.store.getState(selectLocalVideoTrackID);
|
|
284
|
-
if (trackID) {
|
|
285
|
-
await this.setSDKLocalVideoTrackSettings(trackID, settings);
|
|
286
|
-
this.syncRoomState('setVideoSettings');
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
sendMessage(message: string) {
|
|
291
|
-
this.sendBroadcastMessage(message);
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
async sendBroadcastMessage(message: string, type?: string) {
|
|
295
|
-
const sdkMessage = await this.sdk.sendBroadcastMessage(message, type);
|
|
296
|
-
this.updateMessageInStore(sdkMessage, { message, type });
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
async sendGroupMessage(message: string, roles: string[], type?: string) {
|
|
300
|
-
const storeRoles = this.store.getState(selectRolesMap);
|
|
301
|
-
const hmsRoles = roles.map(roleName => {
|
|
302
|
-
return storeRoles[roleName];
|
|
303
|
-
});
|
|
304
|
-
const sdkMessage = await this.sdk.sendGroupMessage(message, hmsRoles, type);
|
|
305
|
-
this.updateMessageInStore(sdkMessage, { message, recipientRoles: roles, type });
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
async sendDirectMessage(message: string, peerID: string, type?: string) {
|
|
309
|
-
const hmsPeer = this.hmsSDKPeers[peerID];
|
|
310
|
-
const sdkMessage = await this.sdk.sendDirectMessage(message, hmsPeer);
|
|
311
|
-
this.updateMessageInStore(sdkMessage, { message, recipientPeer: hmsPeer.peerId, type });
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
private updateMessageInStore(
|
|
315
|
-
sdkMessage: sdkTypes.HMSMessage | void,
|
|
316
|
-
messageInput: string | HMSMessageInput,
|
|
317
|
-
) {
|
|
318
|
-
if (!sdkMessage) {
|
|
319
|
-
HMSLogger.w('sendMessage', 'Failed to send message', messageInput);
|
|
320
|
-
throw Error(`sendMessage Failed - ${JSON.stringify(messageInput)}`);
|
|
321
|
-
}
|
|
322
|
-
const hmsMessage = SDKToHMS.convertMessage(sdkMessage) as HMSMessage;
|
|
323
|
-
hmsMessage.read = true;
|
|
324
|
-
hmsMessage.senderName = 'You';
|
|
325
|
-
this.onHMSMessage(hmsMessage);
|
|
326
|
-
return hmsMessage;
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
setMessageRead(readStatus: boolean, messageId?: string) {
|
|
330
|
-
this.setState(store => {
|
|
331
|
-
if (messageId) {
|
|
332
|
-
if (!store.messages.byID[messageId]) {
|
|
333
|
-
this.logPossibleInconsistency('no message with id is found');
|
|
334
|
-
} else {
|
|
335
|
-
store.messages.byID[messageId].read = readStatus;
|
|
336
|
-
}
|
|
337
|
-
} else {
|
|
338
|
-
store.messages.allIDs.forEach((id: string) => {
|
|
339
|
-
store.messages.byID[id].read = readStatus;
|
|
340
|
-
});
|
|
341
|
-
}
|
|
342
|
-
}, 'setMessageRead');
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
async attachVideo(trackID: string, videoElement: HTMLVideoElement) {
|
|
346
|
-
if (this.localAndVideoUnmuting(trackID)) {
|
|
347
|
-
// wait till video unmute has finished
|
|
348
|
-
return new Promise<void>(resolve => {
|
|
349
|
-
const unsub = this.store.subscribe(async enabled => {
|
|
350
|
-
if (enabled) {
|
|
351
|
-
await this.attachVideoInternal(trackID, videoElement);
|
|
352
|
-
unsub();
|
|
353
|
-
resolve();
|
|
354
|
-
}
|
|
355
|
-
}, selectIsLocalVideoEnabled);
|
|
356
|
-
});
|
|
357
|
-
} else {
|
|
358
|
-
await this.attachVideoInternal(trackID, videoElement);
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
async detachVideo(trackID: string, videoElement: HTMLVideoElement) {
|
|
363
|
-
const sdkTrack = this.hmsSDKTracks[trackID];
|
|
364
|
-
if (sdkTrack && sdkTrack.type === 'video') {
|
|
365
|
-
await (sdkTrack as SDKHMSVideoTrack).removeSink(videoElement);
|
|
366
|
-
this.updateVideoLayer(trackID, 'detachVideo');
|
|
367
|
-
} else {
|
|
368
|
-
this.logPossibleInconsistency('no video track found to remove sink');
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
async addPluginToVideoTrack(plugin: HMSVideoPlugin, pluginFrameRate?: number): Promise<void> {
|
|
373
|
-
return this.addRemoveVideoPlugin(plugin, 'add', pluginFrameRate);
|
|
374
|
-
}
|
|
375
|
-
async addPluginToAudioTrack(plugin: HMSAudioPlugin): Promise<void> {
|
|
376
|
-
return this.addRemoveAudioPlugin(plugin, 'add');
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
async removePluginFromVideoTrack(plugin: HMSVideoPlugin): Promise<void> {
|
|
380
|
-
return this.addRemoveVideoPlugin(plugin, 'remove');
|
|
381
|
-
}
|
|
382
|
-
async removePluginFromAudioTrack(plugin: HMSAudioPlugin): Promise<void> {
|
|
383
|
-
return this.addRemoveAudioPlugin(plugin, 'remove');
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
async changeRole(forPeerId: string, toRole: string, force: boolean = false) {
|
|
387
|
-
const peer = this.hmsSDKPeers[forPeerId];
|
|
388
|
-
if (!peer) {
|
|
389
|
-
this.logPossibleInconsistency(`Unknown peer ID given ${forPeerId} for changerole`);
|
|
390
|
-
return;
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
await this.sdk.changeRole(peer, toRole, force);
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
// TODO: separate out role related things in another file
|
|
397
|
-
async acceptChangeRole(request: HMSRoleChangeRequest) {
|
|
398
|
-
let sdkPeer: sdkTypes.HMSPeer | undefined = request.requestedBy
|
|
399
|
-
? this.hmsSDKPeers[request.requestedBy.id]
|
|
400
|
-
: undefined;
|
|
401
|
-
if (!sdkPeer) {
|
|
402
|
-
HMSLogger.w(
|
|
403
|
-
`peer for which role change is requested no longer available - ${request.requestedBy}`,
|
|
404
|
-
);
|
|
405
|
-
}
|
|
406
|
-
const sdkRequest = {
|
|
407
|
-
requestedBy: sdkPeer,
|
|
408
|
-
role: request.role,
|
|
409
|
-
token: request.token,
|
|
410
|
-
};
|
|
411
|
-
// TODO: hotfix for HMS-3639. Needs a better solution
|
|
412
|
-
//@ts-ignore
|
|
413
|
-
await this.sdk.acceptChangeRole(sdkRequest);
|
|
414
|
-
this.removeRoleChangeRequest(request);
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
/**
|
|
418
|
-
* @privateRemarks
|
|
419
|
-
* there is no corresponding sdk method for rejecting change role but as the store also maintains the full
|
|
420
|
-
* state of current pending requests, this method allows it to clean up when the request is rejected
|
|
421
|
-
*/
|
|
422
|
-
rejectChangeRole(request: HMSRoleChangeRequest) {
|
|
423
|
-
this.removeRoleChangeRequest(request);
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
async endRoom(lock: boolean, reason: string) {
|
|
427
|
-
const permissions = this.store.getState(selectPermissions);
|
|
428
|
-
if (!permissions?.endRoom) {
|
|
429
|
-
HMSLogger.w('You are not allowed to perform this action - endRoom');
|
|
430
|
-
return;
|
|
431
|
-
}
|
|
432
|
-
await this.sdk.endRoom(lock, reason);
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
async removePeer(peerID: string, reason: string) {
|
|
436
|
-
const peer = this.hmsSDKPeers[peerID];
|
|
437
|
-
if (peer && !peer.isLocal) {
|
|
438
|
-
await this.sdk.removePeer(peer as sdkTypes.HMSRemotePeer, reason);
|
|
439
|
-
} else {
|
|
440
|
-
this.logPossibleInconsistency(`No remote peer found for peerID - ${peerID}`);
|
|
441
|
-
return;
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
async startRTMPOrRecording(params: sdkTypes.RTMPRecordingConfig) {
|
|
446
|
-
await this.sdk.startRTMPOrRecording(params);
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
async stopRTMPAndRecording() {
|
|
450
|
-
await this.sdk.stopRTMPAndRecording();
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
async changeName(name: string) {
|
|
454
|
-
await this.sdk.changeName(name);
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
async changeMetadata(metadata: string | any) {
|
|
458
|
-
if (typeof metadata !== 'string') {
|
|
459
|
-
metadata = JSON.stringify(metadata);
|
|
460
|
-
}
|
|
461
|
-
await this.sdk.changeMetadata(metadata);
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
async setRemoteTrackEnabled(trackID: HMSTrackID | HMSTrackID[], enabled: boolean) {
|
|
465
|
-
if (typeof trackID === 'string') {
|
|
466
|
-
const track = this.hmsSDKTracks[trackID];
|
|
467
|
-
if (track && isRemoteTrack(track)) {
|
|
468
|
-
await this.sdk.changeTrackState(track as SDKHMSRemoteTrack, enabled);
|
|
469
|
-
} else {
|
|
470
|
-
this.logPossibleInconsistency(
|
|
471
|
-
`No remote track with ID ${trackID} found for change track state`,
|
|
472
|
-
);
|
|
473
|
-
}
|
|
474
|
-
} else if (Array.isArray(trackID)) {
|
|
475
|
-
trackID.forEach(id => this.setRemoteTrackEnabled(id, enabled));
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
async setRemoteTracksEnabled(params: HMSChangeMultiTrackStateParams) {
|
|
480
|
-
const sdkRequest: SDKHMSChangeMultiTrackStateParams = {
|
|
481
|
-
enabled: params.enabled,
|
|
482
|
-
type: params.type,
|
|
483
|
-
source: params.source,
|
|
484
|
-
};
|
|
485
|
-
if (params.roles) {
|
|
486
|
-
const rolesMap = this.store.getState(selectRolesMap);
|
|
487
|
-
sdkRequest.roles = params.roles.map(role => rolesMap[role]);
|
|
488
|
-
}
|
|
489
|
-
await this.sdk.changeMultiTrackState(sdkRequest);
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
setLogLevel(level: HMSLogLevel) {
|
|
493
|
-
HMSLogger.level = level;
|
|
494
|
-
this.sdk.setLogLevel(level);
|
|
495
|
-
}
|
|
496
|
-
|
|
497
|
-
private resetState(reason: string = 'resetState') {
|
|
498
|
-
this.setState(store => {
|
|
499
|
-
Object.assign(store, createDefaultStoreState());
|
|
500
|
-
}, reason);
|
|
501
|
-
this.isRoomJoinCalled = false;
|
|
502
|
-
this.hmsSDKTracks = {};
|
|
503
|
-
HMSLogger.cleanUp();
|
|
504
|
-
}
|
|
505
|
-
|
|
506
|
-
private sdkJoinWithListeners(config: sdkTypes.HMSConfig) {
|
|
507
|
-
this.sdk.join(config, {
|
|
508
|
-
onJoin: this.onJoin.bind(this),
|
|
509
|
-
onRoomUpdate: this.onRoomUpdate.bind(this),
|
|
510
|
-
onPeerUpdate: this.onPeerUpdate.bind(this),
|
|
511
|
-
onTrackUpdate: this.onTrackUpdate.bind(this),
|
|
512
|
-
onMessageReceived: this.onMessageReceived.bind(this),
|
|
513
|
-
onError: this.onError.bind(this),
|
|
514
|
-
onReconnected: this.onReconnected.bind(this),
|
|
515
|
-
onReconnecting: this.onReconnecting.bind(this),
|
|
516
|
-
onRoleChangeRequest: this.onRoleChangeRequest.bind(this),
|
|
517
|
-
onRoleUpdate: this.onRoleUpdate.bind(this),
|
|
518
|
-
onDeviceChange: this.onDeviceChange.bind(this),
|
|
519
|
-
onChangeTrackStateRequest: this.onChangeTrackStateRequest.bind(this),
|
|
520
|
-
onChangeMultiTrackStateRequest: this.onChangeMultiTrackStateRequest.bind(this),
|
|
521
|
-
onRemovedFromRoom: this.onRemovedFromRoom.bind(this),
|
|
522
|
-
});
|
|
523
|
-
this.sdk.addAudioListener({
|
|
524
|
-
onAudioLevelUpdate: this.onAudioLevelUpdate.bind(this),
|
|
525
|
-
});
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
private onRemovedFromRoom(request: SDKHMSLeaveRoomRequest) {
|
|
529
|
-
const requestedBy = this.store.getState(selectPeerByID(request.requestedBy?.peerId));
|
|
530
|
-
this.hmsNotifications.sendLeaveRoom({
|
|
531
|
-
...request,
|
|
532
|
-
requestedBy: requestedBy || undefined,
|
|
533
|
-
});
|
|
534
|
-
HMSLogger.i('resetting state after peer removed', request);
|
|
535
|
-
this.resetState(request.roomEnded || !requestedBy ? 'roomEnded' : 'removedFromRoom');
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
private onDeviceChange(event: sdkTypes.HMSDeviceChangeEvent) {
|
|
539
|
-
const devices = event.devices;
|
|
540
|
-
if (!devices) {
|
|
541
|
-
return;
|
|
542
|
-
}
|
|
543
|
-
const localPeer = this.store.getState(selectLocalPeer);
|
|
544
|
-
this.setState(store => {
|
|
545
|
-
if (!areArraysEqual(store.devices.audioInput, devices.audioInput)) {
|
|
546
|
-
store.devices.audioInput = devices.audioInput;
|
|
547
|
-
}
|
|
548
|
-
if (!areArraysEqual(store.devices.videoInput, devices.videoInput)) {
|
|
549
|
-
store.devices.videoInput = devices.videoInput;
|
|
550
|
-
}
|
|
551
|
-
if (!areArraysEqual(store.devices.audioOutput, devices.audioOutput)) {
|
|
552
|
-
store.devices.audioOutput = devices.audioOutput;
|
|
553
|
-
}
|
|
554
|
-
if (this.hmsSDKPeers[localPeer?.id]) {
|
|
555
|
-
Object.assign(store.settings, this.getMediaSettings(this.hmsSDKPeers[localPeer?.id]));
|
|
556
|
-
}
|
|
557
|
-
}, 'deviceChange');
|
|
558
|
-
// sync is needed to update the current selected device
|
|
559
|
-
// this.syncRoomState('deviceChangeSync');
|
|
560
|
-
// send notification only on device change - selection is present
|
|
561
|
-
if (event.selection) {
|
|
562
|
-
const notification = SDKToHMS.convertDeviceChangeUpdate(event);
|
|
563
|
-
this.hmsNotifications.sendDeviceChange(notification);
|
|
564
|
-
}
|
|
565
|
-
}
|
|
566
|
-
|
|
567
|
-
private async sdkPreviewWithListeners(config: sdkTypes.HMSConfig) {
|
|
568
|
-
await this.sdk.preview(config, {
|
|
569
|
-
onPreview: this.onPreview.bind(this),
|
|
570
|
-
onError: this.onError.bind(this),
|
|
571
|
-
onDeviceChange: this.onDeviceChange.bind(this),
|
|
572
|
-
});
|
|
573
|
-
this.sdk.addAudioListener({
|
|
574
|
-
onAudioLevelUpdate: this.onAudioLevelUpdate.bind(this),
|
|
575
|
-
});
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
private async startScreenShare(audioOnly?: boolean) {
|
|
579
|
-
const isScreenShared = this.store.getState(selectIsLocalScreenShared);
|
|
580
|
-
if (!isScreenShared) {
|
|
581
|
-
await this.sdk.startScreenShare(() => this.syncRoomState('screenshareStopped'), audioOnly);
|
|
582
|
-
this.syncRoomState('startScreenShare');
|
|
583
|
-
} else {
|
|
584
|
-
this.logPossibleInconsistency("start screenshare is called while it's on");
|
|
585
|
-
}
|
|
586
|
-
}
|
|
587
|
-
|
|
588
|
-
private async stopScreenShare() {
|
|
589
|
-
const isScreenShared = this.store.getState(selectIsLocalScreenShared);
|
|
590
|
-
if (isScreenShared) {
|
|
591
|
-
await this.sdk.stopScreenShare();
|
|
592
|
-
this.syncRoomState('stopScreenShare');
|
|
593
|
-
} else {
|
|
594
|
-
this.logPossibleInconsistency("stop screenshare is called while it's not on");
|
|
595
|
-
}
|
|
596
|
-
}
|
|
597
|
-
|
|
598
|
-
private async attachVideoInternal(trackID: string, videoElement: HTMLVideoElement) {
|
|
599
|
-
const sdkTrack = this.hmsSDKTracks[trackID];
|
|
600
|
-
if (sdkTrack && sdkTrack.type === 'video') {
|
|
601
|
-
await (sdkTrack as SDKHMSVideoTrack).addSink(videoElement);
|
|
602
|
-
this.updateVideoLayer(trackID, 'attachVideo');
|
|
603
|
-
} else {
|
|
604
|
-
this.logPossibleInconsistency('no video track found to add sink');
|
|
605
|
-
}
|
|
606
|
-
}
|
|
607
|
-
|
|
608
|
-
/**
|
|
609
|
-
* This is a very important function as it's responsible for maintaining the source of
|
|
610
|
-
* truth with maximum efficiency. The efficiency comes from the fact that the only
|
|
611
|
-
* those portions of the store are updated which have actually changed.
|
|
612
|
-
* While making a change in this function don't use functions like map, reduce etc.
|
|
613
|
-
* which return a new copy of the data. Use Object.assign etc. to ensure that if the data
|
|
614
|
-
* doesn't change reference is also not changed.
|
|
615
|
-
* The UI and selectors rely on the fact that the store is immutable that is if there is
|
|
616
|
-
* any change and only if there is a change, they'll get a new copy of the data they're
|
|
617
|
-
* interested in with a new reference.
|
|
618
|
-
* @protected
|
|
619
|
-
*/
|
|
620
|
-
protected syncRoomState(action?: string) {
|
|
621
|
-
HMSLogger.time(`store-sync-${action}`);
|
|
622
|
-
const newHmsPeers: Record<HMSPeerID, Partial<HMSPeer>> = {};
|
|
623
|
-
const newHmsPeerIDs: HMSPeerID[] = []; // to add in room.peers
|
|
624
|
-
const newHmsTracks: Record<HMSTrackID, Partial<HMSTrack>> = {};
|
|
625
|
-
const newHmsSDkTracks: Record<HMSTrackID, SDKHMSTrack> = {};
|
|
626
|
-
const newMediaSettings: Partial<HMSMediaSettings> = {};
|
|
627
|
-
|
|
628
|
-
const sdkPeers: sdkTypes.HMSPeer[] = this.sdk.getPeers();
|
|
629
|
-
|
|
630
|
-
// first convert everything in the new format
|
|
631
|
-
for (let sdkPeer of sdkPeers) {
|
|
632
|
-
const hmsPeer = SDKToHMS.convertPeer(sdkPeer);
|
|
633
|
-
newHmsPeers[hmsPeer.id] = hmsPeer;
|
|
634
|
-
newHmsPeerIDs.push(hmsPeer.id);
|
|
635
|
-
this.hmsSDKPeers[hmsPeer.id] = sdkPeer;
|
|
636
|
-
|
|
637
|
-
const sdkTracks = [sdkPeer.audioTrack, sdkPeer.videoTrack, ...sdkPeer.auxiliaryTracks];
|
|
638
|
-
for (let sdkTrack of sdkTracks) {
|
|
639
|
-
if (!sdkTrack) {
|
|
640
|
-
continue;
|
|
641
|
-
}
|
|
642
|
-
const hmsTrack = SDKToHMS.convertTrack(sdkTrack);
|
|
643
|
-
newHmsTracks[hmsTrack.id] = hmsTrack;
|
|
644
|
-
newHmsSDkTracks[sdkTrack.trackId] = sdkTrack;
|
|
645
|
-
}
|
|
646
|
-
|
|
647
|
-
if (hmsPeer.isLocal) {
|
|
648
|
-
Object.assign(newMediaSettings, this.getMediaSettings(sdkPeer));
|
|
649
|
-
}
|
|
650
|
-
}
|
|
651
|
-
|
|
652
|
-
const recording = this.sdk.getRecordingState();
|
|
653
|
-
const rtmp = this.sdk.getRTMPState();
|
|
654
|
-
|
|
655
|
-
// then merge them carefully with our store so if something hasn't changed
|
|
656
|
-
// the reference shouldn't change. Note that the draftStore is an immer draft
|
|
657
|
-
// object.
|
|
658
|
-
this.setState(draftStore => {
|
|
659
|
-
draftStore.room.peers = newHmsPeerIDs;
|
|
660
|
-
const draftPeers = draftStore.peers;
|
|
661
|
-
const draftTracks = draftStore.tracks;
|
|
662
|
-
// the order of below statements are important as merge functions are mutating
|
|
663
|
-
mergeNewPeersInDraft(draftPeers, newHmsPeers);
|
|
664
|
-
mergeNewTracksInDraft(draftTracks, newHmsTracks);
|
|
665
|
-
Object.assign(draftStore.settings, newMediaSettings);
|
|
666
|
-
this.hmsSDKTracks = newHmsSDkTracks;
|
|
667
|
-
Object.assign(draftStore.roles, SDKToHMS.convertRoles(this.sdk.getRoles()));
|
|
668
|
-
Object.assign(draftStore.playlist, SDKToHMS.convertPlaylist(this.sdk.getPlaylistManager()));
|
|
669
|
-
Object.assign(draftStore.room, SDKToHMS.convertRecordingRTMPState(recording, rtmp));
|
|
670
|
-
}, action);
|
|
671
|
-
HMSLogger.timeEnd(`store-sync-${action}`);
|
|
672
|
-
}
|
|
673
|
-
|
|
674
|
-
protected onPreview(sdkRoom: sdkTypes.HMSRoom) {
|
|
675
|
-
this.setState(store => {
|
|
676
|
-
Object.assign(store.room, SDKToHMS.convertRoom(sdkRoom));
|
|
677
|
-
store.room.roomState = HMSRoomState.Preview;
|
|
678
|
-
}, 'previewStart');
|
|
679
|
-
this.syncRoomState('previewSync');
|
|
680
|
-
}
|
|
681
|
-
|
|
682
|
-
protected onJoin(sdkRoom: sdkTypes.HMSRoom) {
|
|
683
|
-
const playlistManager = this.sdk.getPlaylistManager();
|
|
684
|
-
this.audioPlaylist = new HMSPlaylist(
|
|
685
|
-
playlistManager,
|
|
686
|
-
HMSPlaylistType.audio,
|
|
687
|
-
this.syncPlaylistState.bind(this),
|
|
688
|
-
this.store,
|
|
689
|
-
);
|
|
690
|
-
this.videoPlaylist = new HMSPlaylist(
|
|
691
|
-
playlistManager,
|
|
692
|
-
HMSPlaylistType.video,
|
|
693
|
-
this.syncRoomState.bind(this),
|
|
694
|
-
this.store,
|
|
695
|
-
);
|
|
696
|
-
this.syncRoomState('joinSync');
|
|
697
|
-
this.setState(store => {
|
|
698
|
-
Object.assign(store.room, SDKToHMS.convertRoom(sdkRoom));
|
|
699
|
-
store.room.isConnected = true;
|
|
700
|
-
store.room.roomState = HMSRoomState.Connected;
|
|
701
|
-
}, 'joined');
|
|
702
|
-
playlistManager.onProgress(this.setProgress);
|
|
703
|
-
playlistManager.onNewTrackStart((item: sdkTypes.HMSPlaylistItem<any>) => {
|
|
704
|
-
this.syncPlaylistState(`${item.type}PlaylistUpdate`);
|
|
705
|
-
});
|
|
706
|
-
playlistManager.onPlaylistEnded((type: HMSPlaylistType) => {
|
|
707
|
-
this.syncPlaylistState(`${type}PlaylistEnded`);
|
|
708
|
-
});
|
|
709
|
-
playlistManager.onCurrentTrackEnded((item: sdkTypes.HMSPlaylistItem<any>) => {
|
|
710
|
-
this.hmsNotifications.sendPlaylistTrackEnded(
|
|
711
|
-
SDKToHMS.convertPlaylistItem(playlistManager, item),
|
|
712
|
-
);
|
|
713
|
-
this.syncPlaylistState(`${item.type}PlaylistItemEnded`);
|
|
714
|
-
});
|
|
715
|
-
}
|
|
716
|
-
|
|
717
|
-
//@ts-ignore
|
|
718
|
-
protected onRoomUpdate(type: sdkTypes.HMSRoomUpdate, room: sdkTypes.HMSRoom) {
|
|
719
|
-
this.setState(store => {
|
|
720
|
-
Object.assign(store.room, SDKToHMS.convertRoom(room));
|
|
721
|
-
}, 'RoomUpdate');
|
|
722
|
-
}
|
|
723
|
-
|
|
724
|
-
protected onPeerUpdate(
|
|
725
|
-
type: sdkTypes.HMSPeerUpdate,
|
|
726
|
-
sdkPeer: sdkTypes.HMSPeer | sdkTypes.HMSPeer[],
|
|
727
|
-
) {
|
|
728
|
-
if (
|
|
729
|
-
[
|
|
730
|
-
sdkTypes.HMSPeerUpdate.BECAME_DOMINANT_SPEAKER,
|
|
731
|
-
sdkTypes.HMSPeerUpdate.RESIGNED_DOMINANT_SPEAKER,
|
|
732
|
-
].includes(type)
|
|
733
|
-
) {
|
|
734
|
-
return; // ignore, high frequency update so no point of syncing peers
|
|
735
|
-
}
|
|
736
|
-
if (Array.isArray(sdkPeer)) {
|
|
737
|
-
this.syncRoomState('peersJoined');
|
|
738
|
-
const hmsPeers = [];
|
|
739
|
-
for (let peer of sdkPeer) {
|
|
740
|
-
const hmsPeer = this.store.getState(selectPeerByID(peer.peerId));
|
|
741
|
-
if (hmsPeer) {
|
|
742
|
-
hmsPeers.push(hmsPeer);
|
|
743
|
-
}
|
|
744
|
-
}
|
|
745
|
-
this.hmsNotifications.sendPeerList(hmsPeers);
|
|
746
|
-
return;
|
|
747
|
-
}
|
|
748
|
-
this.sendPeerUpdateNotification(type, sdkPeer);
|
|
749
|
-
}
|
|
750
|
-
|
|
751
|
-
protected onTrackUpdate(
|
|
752
|
-
type: sdkTypes.HMSTrackUpdate,
|
|
753
|
-
track: SDKHMSTrack,
|
|
754
|
-
peer: sdkTypes.HMSPeer,
|
|
755
|
-
) {
|
|
756
|
-
// this check is needed because for track removed case, the notification needs to
|
|
757
|
-
// be send before the track is removed from store
|
|
758
|
-
if (type === sdkTypes.HMSTrackUpdate.TRACK_REMOVED) {
|
|
759
|
-
this.hmsNotifications.sendTrackUpdate(type, track.trackId);
|
|
760
|
-
this.handleTrackRemove(track, peer);
|
|
761
|
-
} else {
|
|
762
|
-
const actionName =
|
|
763
|
-
type === sdkTypes.HMSTrackUpdate.TRACK_ADDED ? 'trackAdded' : 'trackUpdate';
|
|
764
|
-
this.syncRoomState(actionName);
|
|
765
|
-
this.hmsNotifications.sendTrackUpdate(type, track.trackId);
|
|
766
|
-
}
|
|
767
|
-
}
|
|
768
|
-
|
|
769
|
-
protected onMessageReceived(sdkMessage: sdkTypes.HMSMessage) {
|
|
770
|
-
const hmsMessage = SDKToHMS.convertMessage(sdkMessage) as HMSMessage;
|
|
771
|
-
hmsMessage.read = false;
|
|
772
|
-
this.onHMSMessage(hmsMessage);
|
|
773
|
-
this.hmsNotifications.sendMessageReceived(hmsMessage);
|
|
774
|
-
}
|
|
775
|
-
|
|
776
|
-
protected onHMSMessage(hmsMessage: HMSMessage) {
|
|
777
|
-
this.setState(store => {
|
|
778
|
-
hmsMessage.id = String(this.store.getState(selectHMSMessagesCount) + 1);
|
|
779
|
-
store.messages.byID[hmsMessage.id] = hmsMessage;
|
|
780
|
-
store.messages.allIDs.push(hmsMessage.id);
|
|
781
|
-
}, 'newMessage');
|
|
782
|
-
}
|
|
783
|
-
|
|
784
|
-
/*
|
|
785
|
-
* Note: speakers array contain the value only for peers who have audioLevel != 0
|
|
786
|
-
*/
|
|
787
|
-
protected onAudioLevelUpdate(sdkSpeakers: sdkTypes.HMSSpeaker[]) {
|
|
788
|
-
this.setState(store => {
|
|
789
|
-
const trackIDAudioLevelMap: Record<HMSPeerID, number> = {};
|
|
790
|
-
sdkSpeakers.forEach(sdkSpeaker => {
|
|
791
|
-
if (!sdkSpeaker.track || !sdkSpeaker.peer) {
|
|
792
|
-
return;
|
|
793
|
-
}
|
|
794
|
-
const trackID = sdkSpeaker.track.trackId;
|
|
795
|
-
trackIDAudioLevelMap[trackID] = sdkSpeaker.audioLevel;
|
|
796
|
-
if (!store.speakers[trackID]) {
|
|
797
|
-
// Set store instances(peers, tracks) references in speaker, not the new ones received.
|
|
798
|
-
store.speakers[trackID] = {
|
|
799
|
-
audioLevel: sdkSpeaker.audioLevel,
|
|
800
|
-
peerID: sdkSpeaker.peer.peerId,
|
|
801
|
-
trackID: trackID,
|
|
802
|
-
};
|
|
803
|
-
}
|
|
804
|
-
});
|
|
805
|
-
const speakerEntries = Object.entries(store.speakers);
|
|
806
|
-
for (let [trackID, speaker] of speakerEntries) {
|
|
807
|
-
speaker.audioLevel = trackIDAudioLevelMap[trackID] || 0;
|
|
808
|
-
if (speaker.audioLevel === 0) {
|
|
809
|
-
delete store.speakers[trackID];
|
|
810
|
-
}
|
|
811
|
-
}
|
|
812
|
-
}, 'audioLevel');
|
|
813
|
-
}
|
|
814
|
-
|
|
815
|
-
protected onChangeTrackStateRequest(request: SDKHMSChangeTrackStateRequest) {
|
|
816
|
-
const requestedBy = this.store.getState(selectPeerByID(request.requestedBy.peerId));
|
|
817
|
-
const storeTrackID = this.getStoreLocalTrackIDfromSDKTrack(request.track);
|
|
818
|
-
const track = this.store.getState(selectTrackByID(storeTrackID));
|
|
819
|
-
|
|
820
|
-
if (!requestedBy) {
|
|
821
|
-
return this.logPossibleInconsistency(
|
|
822
|
-
`Not found peer who requested track state change, ${request.requestedBy}`,
|
|
823
|
-
);
|
|
824
|
-
}
|
|
825
|
-
if (!track) {
|
|
826
|
-
return this.logPossibleInconsistency(
|
|
827
|
-
`Not found track for which track state change was requested, ${request.track}`,
|
|
828
|
-
);
|
|
829
|
-
}
|
|
830
|
-
|
|
831
|
-
if (!request.enabled) {
|
|
832
|
-
this.syncRoomState('changeTrackStateRequest');
|
|
833
|
-
}
|
|
834
|
-
|
|
835
|
-
this.hmsNotifications.sendChangeTrackStateRequest({
|
|
836
|
-
requestedBy,
|
|
837
|
-
track,
|
|
838
|
-
enabled: request.enabled,
|
|
839
|
-
});
|
|
840
|
-
}
|
|
841
|
-
|
|
842
|
-
protected onChangeMultiTrackStateRequest(request: SDKHMSChangeMultiTrackStateRequest) {
|
|
843
|
-
const requestedBy = this.store.getState(selectPeerByID(request.requestedBy.peerId));
|
|
844
|
-
|
|
845
|
-
if (!requestedBy) {
|
|
846
|
-
return this.logPossibleInconsistency(
|
|
847
|
-
`Not found peer who requested track state change, ${request.requestedBy}`,
|
|
848
|
-
);
|
|
849
|
-
}
|
|
850
|
-
|
|
851
|
-
if (!request.enabled) {
|
|
852
|
-
this.syncRoomState('changeMultiTrackStateRequest');
|
|
853
|
-
}
|
|
854
|
-
|
|
855
|
-
const tracks: HMSTrack[] = [];
|
|
856
|
-
const tracksMap = this.store.getState(selectTracksMap);
|
|
857
|
-
for (const track of request.tracks) {
|
|
858
|
-
const storeTrackID = this.getStoreLocalTrackIDfromSDKTrack(track);
|
|
859
|
-
if (storeTrackID && tracksMap[storeTrackID]) {
|
|
860
|
-
tracks.push(tracksMap[storeTrackID]);
|
|
861
|
-
}
|
|
862
|
-
}
|
|
863
|
-
|
|
864
|
-
this.hmsNotifications.sendChangeMultiTrackStateRequest({
|
|
865
|
-
requestedBy,
|
|
866
|
-
tracks,
|
|
867
|
-
enabled: request.enabled,
|
|
868
|
-
type: request.type,
|
|
869
|
-
source: request.source,
|
|
870
|
-
});
|
|
871
|
-
}
|
|
872
|
-
|
|
873
|
-
protected onReconnected() {
|
|
874
|
-
this.syncRoomState('reconnectedSync');
|
|
875
|
-
this.hmsNotifications.sendReconnected();
|
|
876
|
-
this.setState(store => {
|
|
877
|
-
store.room.roomState = HMSRoomState.Connected;
|
|
878
|
-
}, 'reconnected');
|
|
879
|
-
}
|
|
880
|
-
|
|
881
|
-
protected onReconnecting(sdkError: SDKHMSException) {
|
|
882
|
-
const error = SDKToHMS.convertException(sdkError);
|
|
883
|
-
HMSLogger.e('Reconnection: received error from sdk', error);
|
|
884
|
-
this.hmsNotifications.sendReconnecting(error);
|
|
885
|
-
this.setState(store => {
|
|
886
|
-
store.room.roomState = HMSRoomState.Reconnecting;
|
|
887
|
-
store.errors.push(error);
|
|
888
|
-
}, 'reconnecting');
|
|
889
|
-
}
|
|
890
|
-
|
|
891
|
-
protected onError(sdkException: SDKHMSException) {
|
|
892
|
-
const error = SDKToHMS.convertException(sdkException);
|
|
893
|
-
if (error.isTerminal) {
|
|
894
|
-
// terminal error leave room as it is not recoverable
|
|
895
|
-
this.leave().then(() => console.log('error from SDK, left room.'));
|
|
896
|
-
this.setState(store => {
|
|
897
|
-
store.room.roomState = HMSRoomState.Failed;
|
|
898
|
-
store.errors.push(error);
|
|
899
|
-
}, 'errorTerminal');
|
|
900
|
-
} else {
|
|
901
|
-
const numExistingErrors = this.store.getState().errors.length;
|
|
902
|
-
// just in case there is some infinite loop sending errors
|
|
903
|
-
if (numExistingErrors < 50) {
|
|
904
|
-
this.setState(store => {
|
|
905
|
-
store.errors.push(error);
|
|
906
|
-
}, 'error');
|
|
907
|
-
}
|
|
908
|
-
}
|
|
909
|
-
// send notification
|
|
910
|
-
this.hmsNotifications.sendError(error);
|
|
911
|
-
HMSLogger.e('received error from sdk', error);
|
|
912
|
-
}
|
|
913
|
-
|
|
914
|
-
/**
|
|
915
|
-
* the layer gets updated on addsink/removesink/preferlayer calls, for simulcast there
|
|
916
|
-
* can be multiple layers, while for non simulcast there will be None and High.
|
|
917
|
-
*/
|
|
918
|
-
private updateVideoLayer(trackID: string, action: string) {
|
|
919
|
-
const sdkTrack = this.hmsSDKTracks[trackID];
|
|
920
|
-
if (sdkTrack && sdkTrack instanceof SDKHMSRemoteVideoTrack) {
|
|
921
|
-
this.setState(draft => {
|
|
922
|
-
draft.tracks[trackID].layer = sdkTrack.getSimulcastLayer();
|
|
923
|
-
}, action);
|
|
924
|
-
}
|
|
925
|
-
}
|
|
926
|
-
|
|
927
|
-
private handleTrackRemove(sdkTrack: SDKHMSTrack, sdkPeer: sdkTypes.HMSPeer) {
|
|
928
|
-
this.setState(draftStore => {
|
|
929
|
-
const hmsPeer = draftStore.peers[sdkPeer.peerId];
|
|
930
|
-
const draftTracks = draftStore.tracks;
|
|
931
|
-
const trackId = sdkTrack.trackId;
|
|
932
|
-
// find and remove the exact track from hmsPeer
|
|
933
|
-
if (this.isSameStoreSDKTrack(trackId, hmsPeer?.audioTrack)) {
|
|
934
|
-
delete hmsPeer?.audioTrack;
|
|
935
|
-
} else if (this.isSameStoreSDKTrack(trackId, hmsPeer?.videoTrack)) {
|
|
936
|
-
delete hmsPeer?.videoTrack;
|
|
937
|
-
} else {
|
|
938
|
-
const auxiliaryIndex = hmsPeer?.auxiliaryTracks.indexOf(trackId);
|
|
939
|
-
if (
|
|
940
|
-
auxiliaryIndex > -1 &&
|
|
941
|
-
this.isSameStoreSDKTrack(trackId, hmsPeer?.auxiliaryTracks[auxiliaryIndex])
|
|
942
|
-
) {
|
|
943
|
-
hmsPeer?.auxiliaryTracks.splice(auxiliaryIndex, 1);
|
|
944
|
-
}
|
|
945
|
-
}
|
|
946
|
-
delete draftTracks[trackId];
|
|
947
|
-
delete this.hmsSDKTracks[trackId];
|
|
948
|
-
}, 'trackRemoved');
|
|
949
|
-
}
|
|
950
|
-
|
|
951
|
-
private async setEnabledSDKTrack(trackID: string, enabled: boolean) {
|
|
952
|
-
const track = this.hmsSDKTracks[trackID];
|
|
953
|
-
if (track) {
|
|
954
|
-
await track.setEnabled(enabled);
|
|
955
|
-
} else {
|
|
956
|
-
this.logPossibleInconsistency(`track ${trackID} not present, unable to enabled/disable`);
|
|
957
|
-
}
|
|
958
|
-
}
|
|
959
|
-
|
|
960
|
-
private async setSDKLocalVideoTrackSettings(
|
|
961
|
-
trackID: string,
|
|
962
|
-
settings: Partial<sdkTypes.HMSVideoTrackSettings>,
|
|
963
|
-
) {
|
|
964
|
-
const track = this.hmsSDKTracks[trackID] as SDKHMSLocalVideoTrack;
|
|
965
|
-
if (track) {
|
|
966
|
-
await track.setSettings(settings);
|
|
967
|
-
} else {
|
|
968
|
-
this.logPossibleInconsistency(`local track ${trackID} not present, unable to set settings`);
|
|
969
|
-
}
|
|
970
|
-
}
|
|
971
|
-
|
|
972
|
-
private async setSDKLocalAudioTrackSettings(
|
|
973
|
-
trackID: string,
|
|
974
|
-
settings: Partial<sdkTypes.HMSAudioTrackSettings>,
|
|
975
|
-
) {
|
|
976
|
-
const track = this.hmsSDKTracks[trackID] as SDKHMSLocalAudioTrack;
|
|
977
|
-
if (track) {
|
|
978
|
-
await track.setSettings(settings);
|
|
979
|
-
} else {
|
|
980
|
-
this.logPossibleInconsistency(`local track ${trackID} not present, unable to set settings`);
|
|
981
|
-
}
|
|
982
|
-
}
|
|
983
|
-
|
|
984
|
-
private getMediaSettings(sdkPeer: sdkTypes.HMSPeer): Partial<HMSMediaSettings> {
|
|
985
|
-
const settings = this.store.getState(selectLocalMediaSettings);
|
|
986
|
-
const audioTrack = sdkPeer.audioTrack as SDKHMSLocalAudioTrack;
|
|
987
|
-
const videoTrack = sdkPeer.videoTrack as SDKHMSLocalVideoTrack;
|
|
988
|
-
return {
|
|
989
|
-
audioInputDeviceId: audioTrack?.settings.deviceId || settings.audioInputDeviceId,
|
|
990
|
-
videoInputDeviceId: videoTrack?.settings.deviceId || settings.videoInputDeviceId,
|
|
991
|
-
audioOutputDeviceId: this.sdk.getAudioOutput().getDevice()?.deviceId,
|
|
992
|
-
};
|
|
993
|
-
}
|
|
994
|
-
|
|
995
|
-
private setTrackVolume(value: number, trackId: HMSTrackID) {
|
|
996
|
-
const track = this.hmsSDKTracks[trackId];
|
|
997
|
-
if (track) {
|
|
998
|
-
if (track instanceof SDKHMSAudioTrack) {
|
|
999
|
-
track.setVolume(value);
|
|
1000
|
-
this.setState(draftStore => {
|
|
1001
|
-
const track = draftStore.tracks[trackId];
|
|
1002
|
-
if (track) {
|
|
1003
|
-
track.volume = value;
|
|
1004
|
-
}
|
|
1005
|
-
}, 'trackVolume');
|
|
1006
|
-
} else {
|
|
1007
|
-
HMSLogger.w(`track ${trackId} is not an audio track`);
|
|
1008
|
-
}
|
|
1009
|
-
} else {
|
|
1010
|
-
this.logPossibleInconsistency(`track ${trackId} not present, unable to set volume`);
|
|
1011
|
-
}
|
|
1012
|
-
}
|
|
1013
|
-
|
|
1014
|
-
/**
|
|
1015
|
-
* Tells if the trackID is for local peer and video unmute is in process
|
|
1016
|
-
* @private
|
|
1017
|
-
*/
|
|
1018
|
-
private localAndVideoUnmuting(trackID: string) {
|
|
1019
|
-
const localPeer = this.store.getState(selectLocalPeer);
|
|
1020
|
-
if (localPeer.videoTrack !== trackID) {
|
|
1021
|
-
return false;
|
|
1022
|
-
}
|
|
1023
|
-
const displayEnabled = this.store.getState(selectIsLocalVideoDisplayEnabled);
|
|
1024
|
-
const actuallyEnabled = this.store.getState(selectIsLocalVideoEnabled);
|
|
1025
|
-
return displayEnabled && !actuallyEnabled;
|
|
1026
|
-
}
|
|
1027
|
-
|
|
1028
|
-
private logPossibleInconsistency(inconsistency: string) {
|
|
1029
|
-
HMSLogger.w('possible inconsistency detected - ', inconsistency);
|
|
1030
|
-
}
|
|
1031
|
-
|
|
1032
|
-
private async addRemoveVideoPlugin(
|
|
1033
|
-
plugin: HMSVideoPlugin,
|
|
1034
|
-
action: 'add' | 'remove',
|
|
1035
|
-
pluginFrameRate?: number,
|
|
1036
|
-
) {
|
|
1037
|
-
if (!plugin) {
|
|
1038
|
-
HMSLogger.w('Invalid plugin received in store');
|
|
1039
|
-
return;
|
|
1040
|
-
}
|
|
1041
|
-
const trackID = this.store.getState(selectLocalVideoTrackID);
|
|
1042
|
-
if (trackID) {
|
|
1043
|
-
const sdkTrack = this.hmsSDKTracks[trackID];
|
|
1044
|
-
if (sdkTrack) {
|
|
1045
|
-
if (action === 'add') {
|
|
1046
|
-
await (sdkTrack as SDKHMSLocalVideoTrack).addPlugin(plugin, pluginFrameRate);
|
|
1047
|
-
} else if (action === 'remove') {
|
|
1048
|
-
await (sdkTrack as SDKHMSLocalVideoTrack).removePlugin(plugin);
|
|
1049
|
-
}
|
|
1050
|
-
this.syncRoomState(`${action}VideoPlugin`);
|
|
1051
|
-
} else {
|
|
1052
|
-
this.logPossibleInconsistency(`track ${trackID} not present, unable to remove plugin`);
|
|
1053
|
-
}
|
|
1054
|
-
}
|
|
1055
|
-
}
|
|
1056
|
-
private async addRemoveAudioPlugin(plugin: HMSAudioPlugin, action: 'add' | 'remove') {
|
|
1057
|
-
if (!plugin) {
|
|
1058
|
-
HMSLogger.w('Invalid plugin received in store');
|
|
1059
|
-
return;
|
|
1060
|
-
}
|
|
1061
|
-
const trackID = this.store.getState(selectLocalAudioTrackID);
|
|
1062
|
-
if (trackID) {
|
|
1063
|
-
const sdkTrack = this.hmsSDKTracks[trackID];
|
|
1064
|
-
if (sdkTrack) {
|
|
1065
|
-
if (action === 'add') {
|
|
1066
|
-
await (sdkTrack as SDKHMSLocalAudioTrack).addPlugin(plugin);
|
|
1067
|
-
} else if (action === 'remove') {
|
|
1068
|
-
await (sdkTrack as SDKHMSLocalAudioTrack).removePlugin(plugin);
|
|
1069
|
-
}
|
|
1070
|
-
this.syncRoomState(`${action}AudioPlugin`);
|
|
1071
|
-
} else {
|
|
1072
|
-
this.logPossibleInconsistency(`track ${trackID} not present, unable to remove plugin`);
|
|
1073
|
-
}
|
|
1074
|
-
}
|
|
1075
|
-
}
|
|
1076
|
-
|
|
1077
|
-
/**
|
|
1078
|
-
* In case of replace track id is changed but not in store. Given the store id, check the real id
|
|
1079
|
-
* sdk is using to refer to the track and match them.
|
|
1080
|
-
*/
|
|
1081
|
-
private isSameStoreSDKTrack(sdkTrackID: string, storeTrackID?: string): boolean {
|
|
1082
|
-
if (!storeTrackID) {
|
|
1083
|
-
return false;
|
|
1084
|
-
}
|
|
1085
|
-
return this.hmsSDKTracks[storeTrackID]?.trackId === sdkTrackID;
|
|
1086
|
-
}
|
|
1087
|
-
|
|
1088
|
-
/**
|
|
1089
|
-
* convert new role change requests to store format and save.
|
|
1090
|
-
* keep only one request at a time in store till we figure out how to handle multiple requests at the same time
|
|
1091
|
-
*/
|
|
1092
|
-
private onRoleChangeRequest(request: SDKHMSRoleChangeRequest) {
|
|
1093
|
-
this.setState(store => {
|
|
1094
|
-
if (store.roleChangeRequests.length === 0) {
|
|
1095
|
-
store.roleChangeRequests.push(SDKToHMS.convertRoleChangeRequest(request));
|
|
1096
|
-
}
|
|
1097
|
-
}, 'roleChangeRequest');
|
|
1098
|
-
}
|
|
1099
|
-
|
|
1100
|
-
private removeRoleChangeRequest(toRemove: HMSRoleChangeRequest) {
|
|
1101
|
-
this.setState(store => {
|
|
1102
|
-
const index = store.roleChangeRequests.findIndex(req => {
|
|
1103
|
-
return req.token === toRemove.token;
|
|
1104
|
-
});
|
|
1105
|
-
if (index !== -1) {
|
|
1106
|
-
store.roleChangeRequests.splice(index, 1);
|
|
1107
|
-
}
|
|
1108
|
-
}, 'removeRoleChangeRequest');
|
|
1109
|
-
}
|
|
1110
|
-
|
|
1111
|
-
private onRoleUpdate() {
|
|
1112
|
-
this.syncRoomState('roleUpdate');
|
|
1113
|
-
}
|
|
1114
|
-
|
|
1115
|
-
private getStoreLocalTrackIDfromSDKTrack(sdkTrack: SDKHMSLocalTrack) {
|
|
1116
|
-
const trackIDs = this.store.getState(selectLocalTrackIDs);
|
|
1117
|
-
return trackIDs.find(trackID => this.hmsSDKTracks[trackID].trackId === sdkTrack.trackId);
|
|
1118
|
-
}
|
|
1119
|
-
|
|
1120
|
-
private setProgress = ({ type, progress }: sdkTypes.HMSPlaylistProgressEvent) => {
|
|
1121
|
-
this.setState(draftStore => {
|
|
1122
|
-
draftStore.playlist[type].progress = progress;
|
|
1123
|
-
draftStore.playlist[type].currentTime = this.sdk.getPlaylistManager().getCurrentTime(type);
|
|
1124
|
-
}, 'playlistProgress');
|
|
1125
|
-
};
|
|
1126
|
-
|
|
1127
|
-
private syncPlaylistState = (action: string) => {
|
|
1128
|
-
this.setState(draftStore => {
|
|
1129
|
-
Object.assign(draftStore.playlist, SDKToHMS.convertPlaylist(this.sdk.getPlaylistManager()));
|
|
1130
|
-
}, action);
|
|
1131
|
-
};
|
|
1132
|
-
|
|
1133
|
-
private sendPeerUpdateNotification = (
|
|
1134
|
-
type: sdkTypes.HMSPeerUpdate,
|
|
1135
|
-
sdkPeer: sdkTypes.HMSPeer,
|
|
1136
|
-
) => {
|
|
1137
|
-
let peer = this.store.getState(selectPeerByID(sdkPeer.peerId));
|
|
1138
|
-
let actionName = 'peerUpdate';
|
|
1139
|
-
actionName = ACTION_TYPES[type];
|
|
1140
|
-
this.syncRoomState(actionName);
|
|
1141
|
-
// if peer wasn't available before sync(will happen if event is peer join)
|
|
1142
|
-
if (!peer) {
|
|
1143
|
-
peer = this.store.getState(selectPeerByID(sdkPeer.peerId));
|
|
1144
|
-
}
|
|
1145
|
-
this.hmsNotifications.sendPeerUpdate(type, peer);
|
|
1146
|
-
};
|
|
1147
|
-
|
|
1148
|
-
/**
|
|
1149
|
-
* setState is separate so any future changes to how state change can be done from one place.
|
|
1150
|
-
* @param fn
|
|
1151
|
-
* @param name
|
|
1152
|
-
*/
|
|
1153
|
-
private setState: NamedSetState<HMSStore> = (fn, name) => {
|
|
1154
|
-
return this.store.namedSetState(fn, name);
|
|
1155
|
-
};
|
|
1156
|
-
}
|