@100mslive/react-native-hms 1.5.0 → 1.6.1

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.
Files changed (121) hide show
  1. package/android/src/main/java/com/reactnativehmssdk/HMSAudioshareActivity.kt +44 -44
  2. package/android/src/main/java/com/reactnativehmssdk/HMSDecoder.kt +12 -12
  3. package/android/src/main/java/com/reactnativehmssdk/HMSHelper.kt +35 -35
  4. package/android/src/main/java/com/reactnativehmssdk/HMSManager.kt +52 -24
  5. package/android/src/main/java/com/reactnativehmssdk/HMSRNSDK.kt +245 -62
  6. package/android/src/main/java/com/reactnativehmssdk/HMSSDKViewManager.kt +4 -3
  7. package/android/src/main/java/com/reactnativehmssdk/HMSView.kt +40 -33
  8. package/android/src/main/java/com/reactnativehmssdk/HmsScreenshareActivity.kt +41 -41
  9. package/android/src/main/java/com/reactnativehmssdk/PipActionReceiver.kt +2 -2
  10. package/ios/HMSConstants.swift +3 -1
  11. package/ios/HMSDecoder.swift +1 -1
  12. package/ios/HMSHelper.swift +44 -7
  13. package/ios/HMSManager.m +8 -0
  14. package/ios/HMSManager.swift +35 -1
  15. package/ios/HMSRNSDK.swift +268 -38
  16. package/lib/commonjs/classes/HMSAudioMixerSource.js.map +1 -1
  17. package/lib/commonjs/classes/HMSAudioTrackSettings.js +14 -0
  18. package/lib/commonjs/classes/HMSAudioTrackSettings.js.map +1 -1
  19. package/lib/commonjs/classes/HMSEncoder.js +2 -1
  20. package/lib/commonjs/classes/HMSEncoder.js.map +1 -1
  21. package/lib/commonjs/classes/HMSIOSAudioMode.js +13 -0
  22. package/lib/commonjs/classes/HMSIOSAudioMode.js.map +1 -0
  23. package/lib/commonjs/classes/HMSLocalAudioTrack.js.map +1 -1
  24. package/lib/commonjs/classes/HMSLocalVideoTrack.js.map +1 -1
  25. package/lib/commonjs/classes/HMSLogger.js.map +1 -1
  26. package/lib/commonjs/classes/HMSNativeEventEmitter.js.map +1 -1
  27. package/lib/commonjs/classes/HMSPeer.js.map +1 -1
  28. package/lib/commonjs/classes/HMSPeersCache.js.map +1 -1
  29. package/lib/commonjs/classes/HMSRemoteAudioTrack.js.map +1 -1
  30. package/lib/commonjs/classes/HMSRemoteVideoTrack.js.map +1 -1
  31. package/lib/commonjs/classes/HMSRoom.js.map +1 -1
  32. package/lib/commonjs/classes/HMSRoomCache.js.map +1 -1
  33. package/lib/commonjs/classes/HMSSDK.js +50 -0
  34. package/lib/commonjs/classes/HMSSDK.js.map +1 -1
  35. package/lib/commonjs/classes/HMSSessionStore.js +173 -0
  36. package/lib/commonjs/classes/HMSSessionStore.js.map +1 -0
  37. package/lib/commonjs/classes/HMSUpdateListenerActions.js +8 -0
  38. package/lib/commonjs/classes/HMSUpdateListenerActions.js.map +1 -1
  39. package/lib/commonjs/classes/HMSVideoTrackSettings.js +5 -0
  40. package/lib/commonjs/classes/HMSVideoTrackSettings.js.map +1 -1
  41. package/lib/commonjs/classes/HmsView.js +19 -29
  42. package/lib/commonjs/classes/HmsView.js.map +1 -1
  43. package/lib/commonjs/index.js +12 -0
  44. package/lib/commonjs/index.js.map +1 -1
  45. package/lib/commonjs/utils/emitter/EventEmitter.js +162 -0
  46. package/lib/commonjs/utils/emitter/EventEmitter.js.map +1 -0
  47. package/lib/commonjs/utils/emitter/_EmitterSubscription.js +46 -0
  48. package/lib/commonjs/utils/emitter/_EmitterSubscription.js.map +1 -0
  49. package/lib/commonjs/utils/emitter/_EventSubscription.js +36 -0
  50. package/lib/commonjs/utils/emitter/_EventSubscription.js.map +1 -0
  51. package/lib/commonjs/utils/emitter/_EventSubscriptionVendor.js +90 -0
  52. package/lib/commonjs/utils/emitter/_EventSubscriptionVendor.js.map +1 -0
  53. package/lib/commonjs/utils/index.js +17 -0
  54. package/lib/commonjs/utils/index.js.map +1 -0
  55. package/lib/module/classes/HMSAudioMixerSource.js.map +1 -1
  56. package/lib/module/classes/HMSAudioTrackSettings.js +14 -0
  57. package/lib/module/classes/HMSAudioTrackSettings.js.map +1 -1
  58. package/lib/module/classes/HMSEncoder.js +2 -1
  59. package/lib/module/classes/HMSEncoder.js.map +1 -1
  60. package/lib/module/classes/HMSIOSAudioMode.js +6 -0
  61. package/lib/module/classes/HMSIOSAudioMode.js.map +1 -0
  62. package/lib/module/classes/HMSLocalAudioTrack.js.map +1 -1
  63. package/lib/module/classes/HMSLocalVideoTrack.js.map +1 -1
  64. package/lib/module/classes/HMSLogger.js.map +1 -1
  65. package/lib/module/classes/HMSNativeEventEmitter.js.map +1 -1
  66. package/lib/module/classes/HMSPeer.js.map +1 -1
  67. package/lib/module/classes/HMSPeersCache.js.map +1 -1
  68. package/lib/module/classes/HMSRemoteAudioTrack.js.map +1 -1
  69. package/lib/module/classes/HMSRemoteVideoTrack.js.map +1 -1
  70. package/lib/module/classes/HMSRoom.js.map +1 -1
  71. package/lib/module/classes/HMSRoomCache.js.map +1 -1
  72. package/lib/module/classes/HMSSDK.js +50 -0
  73. package/lib/module/classes/HMSSDK.js.map +1 -1
  74. package/lib/module/classes/HMSSessionStore.js +166 -0
  75. package/lib/module/classes/HMSSessionStore.js.map +1 -0
  76. package/lib/module/classes/HMSUpdateListenerActions.js +8 -0
  77. package/lib/module/classes/HMSUpdateListenerActions.js.map +1 -1
  78. package/lib/module/classes/HMSVideoTrackSettings.js +5 -0
  79. package/lib/module/classes/HMSVideoTrackSettings.js.map +1 -1
  80. package/lib/module/classes/HmsView.js +21 -31
  81. package/lib/module/classes/HmsView.js.map +1 -1
  82. package/lib/module/index.js +1 -0
  83. package/lib/module/index.js.map +1 -1
  84. package/lib/module/utils/emitter/EventEmitter.js +151 -0
  85. package/lib/module/utils/emitter/EventEmitter.js.map +1 -0
  86. package/lib/module/utils/emitter/_EmitterSubscription.js +39 -0
  87. package/lib/module/utils/emitter/_EmitterSubscription.js.map +1 -0
  88. package/lib/module/utils/emitter/_EventSubscription.js +29 -0
  89. package/lib/module/utils/emitter/_EventSubscription.js.map +1 -0
  90. package/lib/module/utils/emitter/_EventSubscriptionVendor.js +83 -0
  91. package/lib/module/utils/emitter/_EventSubscriptionVendor.js.map +1 -0
  92. package/lib/module/utils/index.js +2 -0
  93. package/lib/module/utils/index.js.map +1 -0
  94. package/lib/typescript/classes/HMSAudioTrackSettings.d.ts +14 -0
  95. package/lib/typescript/classes/HMSIOSAudioMode.d.ts +4 -0
  96. package/lib/typescript/classes/HMSSDK.d.ts +16 -0
  97. package/lib/typescript/classes/HMSSessionStore.d.ts +63 -0
  98. package/lib/typescript/classes/HMSUpdateListenerActions.d.ts +9 -1
  99. package/lib/typescript/classes/HMSVideoTrackSettings.d.ts +5 -0
  100. package/lib/typescript/index.d.ts +2 -0
  101. package/lib/typescript/utils/emitter/EventEmitter.d.ts +91 -0
  102. package/lib/typescript/utils/emitter/_EmitterSubscription.d.ts +29 -0
  103. package/lib/typescript/utils/emitter/_EventSubscription.d.ts +19 -0
  104. package/lib/typescript/utils/emitter/_EventSubscriptionVendor.d.ts +44 -0
  105. package/lib/typescript/utils/index.d.ts +1 -0
  106. package/package.json +21 -2
  107. package/sdk-versions.json +2 -2
  108. package/src/classes/HMSAudioTrackSettings.ts +16 -0
  109. package/src/classes/HMSEncoder.ts +1 -0
  110. package/src/classes/HMSIOSAudioMode.ts +4 -0
  111. package/src/classes/HMSSDK.tsx +70 -4
  112. package/src/classes/HMSSessionStore.ts +209 -0
  113. package/src/classes/HMSUpdateListenerActions.ts +8 -0
  114. package/src/classes/HMSVideoTrackSettings.ts +5 -0
  115. package/src/classes/HmsView.tsx +21 -32
  116. package/src/index.ts +5 -0
  117. package/src/utils/emitter/EventEmitter.ts +160 -0
  118. package/src/utils/emitter/_EmitterSubscription.ts +44 -0
  119. package/src/utils/emitter/_EventSubscription.ts +28 -0
  120. package/src/utils/emitter/_EventSubscriptionVendor.ts +89 -0
  121. package/src/utils/index.ts +1 -0
@@ -25,10 +25,8 @@ import type { HMSAudioMixingMode } from './HMSAudioMixingMode';
25
25
  import type { HMSLogSettings } from './HMSLogSettings';
26
26
  import { HMSMessageType } from './HMSMessageType';
27
27
  import { HMSPIPListenerActions } from './HMSPIPListenerActions';
28
- import {
29
- type HMSEventSubscription,
30
- HMSNativeEventEmitter,
31
- } from './HMSNativeEventEmitter';
28
+ import type { HMSEventSubscription } from './HMSNativeEventEmitter';
29
+ import { HMSNativeEventEmitter } from './HMSNativeEventEmitter';
32
30
  import {
33
31
  clearHmsPeersCache,
34
32
  getHmsPeersCache,
@@ -42,6 +40,7 @@ import {
42
40
  setHmsRoomCache,
43
41
  } from './HMSRoomCache';
44
42
  import { HMSPeerUpdateOrdinals } from './HMSPeerUpdate';
43
+ import { HMSSessionStore } from './HMSSessionStore';
45
44
 
46
45
  type HmsViewProps = Omit<HmsComponentProps, 'id'>;
47
46
 
@@ -89,6 +88,7 @@ export class HMSSDK {
89
88
  private onRemoteAudioStatsDelegate?: any;
90
89
  private onRemoteVideoStatsDelegate?: any;
91
90
  private onAudioDeviceChangedDelegate?: any;
91
+ private onSessionStoreAvailableDelegate?: any;
92
92
  private onPIPRoomLeaveDelegate?: any;
93
93
 
94
94
  private emitterSubscriptions: Partial<
@@ -1058,6 +1058,12 @@ export class HMSSDK {
1058
1058
  }
1059
1059
  };
1060
1060
 
1061
+ /**
1062
+ * @deprecated Older SessionMetaData APIs has been deprecated in favour of newer Session Store APIs.
1063
+ * You can subscribe to `ON_SESSION_STORE_AVAILABLE` event to get notified when the `HMSSessionStore`
1064
+ * is available and use `set` method on `HMSSessionStore` instance
1065
+ * checkout {@link https://www.100ms.live/docs/react-native/v2/how-to-guides/}
1066
+ */
1061
1067
  setSessionMetaData = async (sessionMetaData: string | null) => {
1062
1068
  logger?.verbose('#Function setSessionMetaData', {
1063
1069
  id: this.id,
@@ -1069,6 +1075,12 @@ export class HMSSDK {
1069
1075
  });
1070
1076
  };
1071
1077
 
1078
+ /**
1079
+ * @deprecated Older SessionMetaData APIs has been deprecated in favour of newer Session Store APIs.
1080
+ * You can subscribe to `ON_SESSION_STORE_AVAILABLE` event to get notified when the `HMSSessionStore`
1081
+ * is available and use `get` or `addKeyChangeListener` method on `HMSSessionStore` instance
1082
+ * checkout {@link https://www.100ms.live/docs/react-native/v2/how-to-guides/}
1083
+ */
1072
1084
  getSessionMetaData = async () => {
1073
1085
  logger?.verbose('#Function getSessionMetaData', {
1074
1086
  id: this.id,
@@ -1470,6 +1482,27 @@ export class HMSSDK {
1470
1482
  this.onAudioDeviceChangedDelegate = callback;
1471
1483
  break;
1472
1484
  }
1485
+ case HMSUpdateListenerActions.ON_SESSION_STORE_AVAILABLE: {
1486
+ // Checking if we already have ON_SESSION_STORE_AVAILABLE subscription
1487
+ if (
1488
+ !this.emitterSubscriptions[
1489
+ HMSUpdateListenerActions.ON_SESSION_STORE_AVAILABLE
1490
+ ]
1491
+ ) {
1492
+ // Adding ON_SESSION_STORE_AVAILABLE native listener
1493
+ const sessionStoreAvailableSubscription = HmsEventEmitter.addListener(
1494
+ this.id,
1495
+ HMSUpdateListenerActions.ON_SESSION_STORE_AVAILABLE,
1496
+ this.onSessionStoreAvailableListener
1497
+ );
1498
+ this.emitterSubscriptions[
1499
+ HMSUpdateListenerActions.ON_SESSION_STORE_AVAILABLE
1500
+ ] = sessionStoreAvailableSubscription;
1501
+ }
1502
+ // Adding Session Store Available App Delegate listener
1503
+ this.onSessionStoreAvailableDelegate = callback;
1504
+ break;
1505
+ }
1473
1506
  case HMSPIPListenerActions.ON_PIP_ROOM_LEAVE: {
1474
1507
  if (Platform.OS === 'android') {
1475
1508
  // Checking if we already have ON_PIP_ROOM_LEAVE subscription
@@ -1796,6 +1829,23 @@ export class HMSSDK {
1796
1829
  this.onAudioDeviceChangedDelegate = null;
1797
1830
  break;
1798
1831
  }
1832
+ case HMSUpdateListenerActions.ON_SESSION_STORE_AVAILABLE: {
1833
+ const subscription =
1834
+ this.emitterSubscriptions[
1835
+ HMSUpdateListenerActions.ON_SESSION_STORE_AVAILABLE
1836
+ ];
1837
+ // Removing ON_SESSION_STORE_AVAILABLE native listener
1838
+ if (subscription) {
1839
+ subscription.remove();
1840
+
1841
+ this.emitterSubscriptions[
1842
+ HMSUpdateListenerActions.ON_SESSION_STORE_AVAILABLE
1843
+ ] = undefined;
1844
+ }
1845
+ // Removing App Delegate listener
1846
+ this.onSessionStoreAvailableDelegate = null;
1847
+ break;
1848
+ }
1799
1849
  case HMSPIPListenerActions.ON_PIP_ROOM_LEAVE: {
1800
1850
  if (Platform.OS === 'android') {
1801
1851
  const subscription =
@@ -2212,6 +2262,22 @@ export class HMSSDK {
2212
2262
  }
2213
2263
  };
2214
2264
 
2265
+ onSessionStoreAvailableListener = (data: { id: string }) => {
2266
+ if (data.id !== this.id) {
2267
+ return;
2268
+ }
2269
+ if (this.onSessionStoreAvailableDelegate) {
2270
+ logger?.verbose(
2271
+ '#Listener ON_SESSION_STORE_AVAILABLE_LISTENER_CALL',
2272
+ data
2273
+ );
2274
+ this.onSessionStoreAvailableDelegate({
2275
+ ...data,
2276
+ sessionStore: new HMSSessionStore(),
2277
+ });
2278
+ }
2279
+ };
2280
+
2215
2281
  onPIPRoomLeaveListener = (data: { id: string }) => {
2216
2282
  if (data.id !== this.id) {
2217
2283
  return;
@@ -0,0 +1,209 @@
1
+ import {
2
+ NativeModules,
3
+ DeviceEventEmitter,
4
+ EmitterSubscription as RNEmitterSubscription,
5
+ } from 'react-native';
6
+ import { HMSConstants } from './HMSConstants';
7
+ import { getLogger } from './HMSLogger';
8
+ import { HMSUpdateListenerActions } from './HMSUpdateListenerActions';
9
+ import { EventEmitter } from '../utils';
10
+ import type { EmitterSubscription } from '../utils';
11
+
12
+ const { HMSManager } = NativeModules;
13
+
14
+ type Nullable<T> = T | null | undefined;
15
+
16
+ export type HMSSessionStoreValue = Nullable<string>;
17
+
18
+ /**
19
+ * Session store is a shared realtime key-value store that is accessible by everyone in the room.
20
+ * It can be utilized to implement features such as pinned text, spotlight (which brings a particular
21
+ * peer to the center stage for everyone in the room) and more.
22
+ *
23
+ * To get an instance of `HMSSessionStore` class, You can add an event listener for `ON_SESSION_STORE_AVAILABLE`
24
+ * event on the `HMSSDK` instance
25
+ *
26
+ * For example:
27
+ * ```
28
+ * hmsInstance.addEventListener(HMSUpdateListenerActions.ON_SESSION_STORE_AVAILABLE, <your callback function>);
29
+ * ```
30
+ *
31
+ * Checkout Session Store docs fore more details ${@link https://www.100ms.live/docs/react-native/v2/how-to-guides/interact-with-room/room/session-store}
32
+ */
33
+ export class HMSSessionStore {
34
+ private _deviceEventEmitterSubscription?: RNEmitterSubscription;
35
+ private _eventEmitter?: EventEmitter;
36
+ private _addedKeyChangeListenerCount = 0;
37
+
38
+ /**
39
+ * This method sets a value for a specific key on session store.
40
+ * Once a value is assigned, it will be available for other peers in the room
41
+ * who are listening for changes in value for that specific key.
42
+ *
43
+ * @param {HMSSessionStoreValue} value
44
+ * @param {string} key
45
+ * @returns {Promise}
46
+ */
47
+ async set(value: HMSSessionStoreValue, key: string) {
48
+ const data: { success: true; finalValue: HMSSessionStoreValue } =
49
+ await HMSManager.setSessionMetadataForKey({
50
+ id: HMSConstants.DEFAULT_SDK_ID,
51
+ key,
52
+ value,
53
+ });
54
+ return data;
55
+ }
56
+
57
+ /**
58
+ * This method returns the value of any specified key on session store.
59
+ * Note that you will not get updates for any change in value of the specified key,
60
+ * It returns the latest value at the time it was called.
61
+ *
62
+ * To listen to value change updates use `addKeyChangeListener` method instead.
63
+ *
64
+ * @param {string} key
65
+ * @returns {Promise}
66
+ */
67
+ async get(key: string) {
68
+ const data: HMSSessionStoreValue =
69
+ await HMSManager.getSessionMetadataForKey({
70
+ id: HMSConstants.DEFAULT_SDK_ID,
71
+ key,
72
+ });
73
+ return data;
74
+ }
75
+
76
+ /**
77
+ * This method registers a callback function for listening to value changes of a particular key.
78
+ * Registered Callback function will be called initially with latest value and whenever the value updates
79
+ *
80
+ * @param {string[]} forKeys
81
+ * @param {Function} callback
82
+ * @returns {Object} subscription object
83
+ */
84
+ addKeyChangeListener<T extends string[]>(
85
+ forKeys: T,
86
+ callback: (
87
+ error: string | null,
88
+ data: { key: T[number]; value: HMSSessionStoreValue } | null
89
+ ) => void
90
+ ) {
91
+ // Add Native Device Event Emitter if it is not already added
92
+ if (!this._deviceEventEmitterSubscription) {
93
+ this._deviceEventEmitterSubscription = DeviceEventEmitter.addListener(
94
+ HMSUpdateListenerActions.ON_SESSION_STORE_CHANGED,
95
+ this._deviceEventEmitterListener.bind(this)
96
+ );
97
+ }
98
+
99
+ // Create JS side EventEmitter
100
+ if (!this._eventEmitter) {
101
+ this._eventEmitter = new EventEmitter();
102
+ }
103
+
104
+ // Unique Identifier for adding native event listener
105
+ const uniqueId = forKeys.join('') + '_' + Date.now().toString();
106
+
107
+ const eventEmitter = this._eventEmitter;
108
+
109
+ // Add listeners on eventEmitter for each key
110
+ const subscriptions = forKeys.map((key) =>
111
+ eventEmitter.addListener(key, callback, { uniqueId })
112
+ );
113
+
114
+ //
115
+ let cleanupHandler: (() => void) | null = () => {
116
+ this._cleanup(subscriptions);
117
+ };
118
+
119
+ // Adding 'KeyChangeListener' on native side
120
+ HMSManager.addKeyChangeListener({
121
+ id: HMSConstants.DEFAULT_SDK_ID,
122
+ keys: forKeys,
123
+ uniqueId,
124
+ })
125
+ // Adding 'KeyChangeListener' fails on native side
126
+ .catch((err: any) => {
127
+ if (typeof cleanupHandler === 'function') {
128
+ callback(err, null);
129
+ cleanupHandler();
130
+ cleanupHandler = null;
131
+ }
132
+ });
133
+
134
+ this._addedKeyChangeListenerCount += 1;
135
+
136
+ return {
137
+ remove: () => {
138
+ if (typeof cleanupHandler === 'function') {
139
+ cleanupHandler();
140
+ cleanupHandler = null;
141
+ }
142
+ },
143
+ };
144
+ }
145
+
146
+ private _cleanup(subscriptionsToRemove: EmitterSubscription[]) {
147
+ // Extracting `uniqueId` from first subscription (all subscriptions have same uniqueId)
148
+ // this `uniqueId` will be used to remove 'KeyChangeListener' from native side
149
+ const uniqueId =
150
+ subscriptionsToRemove.length > 0
151
+ ? (subscriptionsToRemove[0].context as { uniqueId: string }).uniqueId
152
+ : null;
153
+
154
+ // Removing required subscriptions from 'eventEmitter'
155
+ subscriptionsToRemove.forEach((subscription) => subscription.remove());
156
+
157
+ // Removing 'KeyChangeListener' from native side
158
+ HMSManager.removeKeyChangeListener({
159
+ id: HMSConstants.DEFAULT_SDK_ID,
160
+ uniqueId,
161
+ }).catch((error: any) => {
162
+ const logger = getLogger();
163
+ logger?.verbose(
164
+ "Error while removing key change listener, Listener didn't get registerred at first place or was already removed",
165
+ error
166
+ );
167
+ });
168
+
169
+ this._addedKeyChangeListenerCount -= 1;
170
+
171
+ if (this._addedKeyChangeListenerCount <= 0) {
172
+ this._addedKeyChangeListenerCount = 0;
173
+ if (
174
+ this._deviceEventEmitterSubscription &&
175
+ Object.getOwnPropertyNames(
176
+ this._deviceEventEmitterSubscription
177
+ ).includes('remove') &&
178
+ typeof this._deviceEventEmitterSubscription.remove === 'function'
179
+ ) {
180
+ this._deviceEventEmitterSubscription.remove();
181
+ } else {
182
+ DeviceEventEmitter.removeListener(
183
+ HMSUpdateListenerActions.ON_SESSION_STORE_CHANGED,
184
+ this._deviceEventEmitterListener
185
+ );
186
+ }
187
+
188
+ this._deviceEventEmitterSubscription = undefined;
189
+
190
+ this._eventEmitter = undefined;
191
+ }
192
+ }
193
+
194
+ private _deviceEventEmitterListener(data: {
195
+ id: string;
196
+ key: string;
197
+ value: HMSSessionStoreValue;
198
+ }) {
199
+ // if id is different from default sdk_id, return early
200
+ if (data.id !== HMSConstants.DEFAULT_SDK_ID) {
201
+ return;
202
+ }
203
+
204
+ // emit event for the key
205
+ getLogger()?.verbose('#Listener ON_SESSION_STORE_CHANGED event: ', data);
206
+
207
+ this._eventEmitter?.emit(data.key, null, data);
208
+ }
209
+ }
@@ -1,3 +1,9 @@
1
+ /**
2
+ * These are the available events emitted by the `HMSSDK`
3
+ *
4
+ * For more info about these events, checkout Event Listener docs
5
+ * {@link https://www.100ms.live/docs/react-native/v2/how-to-guides/listen-to-room-updates/event-listeners}
6
+ */
1
7
  export enum HMSUpdateListenerActions {
2
8
  ON_PREVIEW = 'ON_PREVIEW',
3
9
  ON_JOIN = 'ON_JOIN',
@@ -18,4 +24,6 @@ export enum HMSUpdateListenerActions {
18
24
  ON_REMOTE_AUDIO_STATS = 'ON_REMOTE_AUDIO_STATS',
19
25
  ON_REMOTE_VIDEO_STATS = 'ON_REMOTE_VIDEO_STATS',
20
26
  ON_AUDIO_DEVICE_CHANGED = 'ON_AUDIO_DEVICE_CHANGED',
27
+ ON_SESSION_STORE_AVAILABLE = 'ON_SESSION_STORE_AVAILABLE',
28
+ ON_SESSION_STORE_CHANGED = 'ON_SESSION_STORE_CHANGED',
21
29
  }
@@ -2,6 +2,11 @@ import type { HMSSimulcastLayerSettings } from './HMSSimulcastLayerSettings';
2
2
  import type { HMSCameraFacing } from './HMSCameraFacing';
3
3
  import type { HMSTrackSettingsInitState } from './HMSTrackSettingsInitState';
4
4
 
5
+ /**
6
+ * Customize local peer's Video track settings before Joining the Room.
7
+ *
8
+ * Checkout Track Settings docs for more details {@link https://www.100ms.live/docs/react-native/v2/how-to-guides/interact-with-room/track/track-settings}
9
+ */
5
10
  export class HMSVideoTrackSettings {
6
11
  readonly simulcastSettings?: HMSSimulcastLayerSettings[];
7
12
  initialState?: HMSTrackSettingsInitState;
@@ -1,10 +1,11 @@
1
- import React, { useState, useEffect, useImperativeHandle, useRef } from 'react';
1
+ import React, { useState, useImperativeHandle, useRef } from 'react';
2
2
  import {
3
3
  findNodeHandle,
4
4
  requireNativeComponent,
5
5
  StyleSheet,
6
6
  UIManager,
7
7
  ViewStyle,
8
+ Platform,
8
9
  } from 'react-native';
9
10
  import { HMSConstants } from './HMSConstants';
10
11
  import { HMSVideoViewMode } from './HMSVideoViewMode';
@@ -14,6 +15,7 @@ interface HmsViewProps {
14
15
  trackId: string;
15
16
  id: string;
16
17
  mirror: boolean;
18
+ scaleType: HMSVideoViewMode;
17
19
  };
18
20
  autoSimulcast: boolean;
19
21
  setZOrderMediaOverlay: boolean;
@@ -41,7 +43,7 @@ export const HmsViewComponent = React.forwardRef<any, HmsComponentProps>(
41
43
  (props, ref) => {
42
44
  const {
43
45
  trackId,
44
- style = temporaryStyles.customStyle,
46
+ style = styles.hmsView,
45
47
  id = HMSConstants.DEFAULT_SDK_ID,
46
48
  mirror = false,
47
49
  setZOrderMediaOverlay = false,
@@ -50,34 +52,24 @@ export const HmsViewComponent = React.forwardRef<any, HmsComponentProps>(
50
52
  } = props;
51
53
 
52
54
  const hmsViewRef: any = useRef();
53
- const timerRef = useRef<null | NodeJS.Timeout>(null);
54
- const [tempVal, setTempVal] = useState(0);
55
+ const [applyStyles_ANDROID, setApplyStyles_ANDROID] = useState(false);
55
56
  const data = {
56
57
  trackId,
57
58
  id,
58
59
  mirror,
60
+ scaleType,
59
61
  };
60
62
 
61
- useEffect(() => {
62
- return () => {
63
- if (timerRef.current) {
64
- clearTimeout(timerRef.current);
65
- }
66
- };
67
- }, []);
68
-
69
- const onChange = (values: any) => {
70
- console.log(values, 'values');
71
- if (timerRef.current) {
72
- clearTimeout(timerRef.current);
73
- }
74
-
75
- timerRef.current = setTimeout(() => {
76
- setTempVal(1);
77
- timerRef.current = null;
78
- }, 2000);
79
- };
63
+ /**
64
+ * This method is passed to `onChange` prop of `HmsView` Native Component.
65
+ * It is invoked when `HmsView` emits 'topChange' event.
66
+ */
67
+ const onChange = () => setApplyStyles_ANDROID(true);
80
68
 
69
+ /**
70
+ * This method is passed to `onDataReturned` prop of `HmsView` Native Component.
71
+ * It is invoked when `HmsView` emits 'captureFrame' event.
72
+ */
81
73
  const _onDataReturned = (event: {
82
74
  nativeEvent: { requestId: any; result: any; error: any };
83
75
  }) => {
@@ -120,16 +112,14 @@ export const HmsViewComponent = React.forwardRef<any, HmsComponentProps>(
120
112
  };
121
113
  });
122
114
 
123
- useEffect(() => {
124
- setTempVal(0);
125
- }, [tempVal]);
126
-
127
115
  return (
128
116
  <HmsView
129
117
  ref={hmsViewRef}
130
118
  onChange={onChange}
131
119
  data={data}
132
- style={tempVal === 0 ? style : temporaryStyles.customStyle}
120
+ style={
121
+ Platform.OS === 'android' ? (applyStyles_ANDROID ? style : {}) : style
122
+ }
133
123
  autoSimulcast={autoSimulcast}
134
124
  scaleType={scaleType}
135
125
  setZOrderMediaOverlay={setZOrderMediaOverlay}
@@ -139,9 +129,8 @@ export const HmsViewComponent = React.forwardRef<any, HmsComponentProps>(
139
129
  }
140
130
  );
141
131
 
142
- const temporaryStyles = StyleSheet.create({
143
- customStyle: {
144
- width: '100%',
145
- height: '50%',
132
+ const styles = StyleSheet.create({
133
+ hmsView: {
134
+ flex: 1,
146
135
  },
147
136
  });
package/src/index.ts CHANGED
@@ -80,6 +80,11 @@ export * from './classes/HMSSimulcastLayerDefinition';
80
80
  export * from './classes/HMSQualityLimitationReasons';
81
81
  export * from './classes/HMSQualityLimitationReason';
82
82
  export * from './classes/HMSCameraControl';
83
+ export * from './classes/HMSIOSAudioMode';
84
+ export type {
85
+ HMSSessionStore,
86
+ HMSSessionStoreValue,
87
+ } from './classes/HMSSessionStore';
83
88
  export type { HmsViewComponent as HMSView } from './classes/HmsView';
84
89
 
85
90
  import { HMSSDK as HmsManager } from './classes/HMSSDK';
@@ -0,0 +1,160 @@
1
+ import { EmitterSubscription } from './_EmitterSubscription';
2
+ import { EventSubscriptionVendor } from './_EventSubscriptionVendor';
3
+
4
+ const sparseFilterPredicate = () => true;
5
+
6
+ export { EmitterSubscription } from './_EmitterSubscription';
7
+
8
+ /**
9
+ * @class EventEmitter
10
+ * @description
11
+ * An EventEmitter is responsible for managing a set of listeners and publishing
12
+ * events to them when it is told that such events happened. In addition to the
13
+ * data for the given event it also sends a event control object which allows
14
+ * the listeners/handlers to prevent the default behavior of the given event.
15
+ *
16
+ * The emitter is designed to be generic enough to support all the different
17
+ * contexts in which one might want to emit events. It is a simple multicast
18
+ * mechanism on top of which extra functionality can be composed. For example, a
19
+ * more advanced emitter may use an EventHolder and EventFactory.
20
+ */
21
+ export class EventEmitter {
22
+ _subscriber: EventSubscriptionVendor;
23
+
24
+ /**
25
+ * @constructor
26
+ *
27
+ * @param {EventSubscriptionVendor} subscriber - Optional subscriber instance
28
+ * to use. If omitted, a new subscriber will be created for the emitter.
29
+ */
30
+ constructor(subscriber?: EventSubscriptionVendor | null) {
31
+ this._subscriber = subscriber || new EventSubscriptionVendor();
32
+ }
33
+
34
+ /**
35
+ * Adds a listener to be invoked when events of the specified type are
36
+ * emitted. An optional calling context may be provided. The data arguments
37
+ * emitted will be passed to the listener function.
38
+ *
39
+ * TODO: Annotate the listener arg's type. This is tricky because listeners
40
+ * can be invoked with varargs.
41
+ *
42
+ * @param {string} eventType - Name of the event to listen to
43
+ * @param {function} listener - Function to invoke when the specified event is
44
+ * emitted
45
+ * @param {*} context - Optional context object to use when invoking the
46
+ * listener
47
+ */
48
+ addListener(
49
+ eventType: string,
50
+ listener: Function,
51
+ context: Object | null | undefined
52
+ ): EmitterSubscription {
53
+ return this._subscriber.addSubscription(
54
+ eventType,
55
+ new EmitterSubscription(this, this._subscriber, listener, context)
56
+ ) as EmitterSubscription;
57
+ }
58
+
59
+ /**
60
+ * Removes all of the registered listeners, including those registered as
61
+ * listener maps.
62
+ *
63
+ * @param {?string} eventType - Optional name of the event whose registered
64
+ * listeners to remove
65
+ */
66
+ removeAllListeners(eventType: string | undefined | null) {
67
+ this._subscriber.removeAllSubscriptions(eventType);
68
+ }
69
+
70
+ /**
71
+ * Removes a specific subscription. Called by the `remove()` method of the
72
+ * subscription itself to ensure any necessary cleanup is performed.
73
+ */
74
+ removeSubscription(subscription: EmitterSubscription) {
75
+ if (subscription.emitter !== this) {
76
+ console.warn('Subscription does not belong to this emitter.'); // TODO: use HMSLogger here
77
+ return;
78
+ }
79
+
80
+ this._subscriber.removeSubscription(subscription);
81
+ }
82
+
83
+ /**
84
+ * Returns the number of listeners that are currently registered for the given
85
+ * event.
86
+ *
87
+ * @param {string} eventType - Name of the event to query
88
+ * @returns {number}
89
+ */
90
+ listenerCount(eventType: string): number {
91
+ const subscriptions = this._subscriber.getSubscriptionsForType(eventType);
92
+ return subscriptions
93
+ ? // We filter out missing entries because the array is sparse.
94
+ // "callbackfn is called only for elements of the array which actually
95
+ // exist; it is not called for missing elements of the array."
96
+ // https://www.ecma-international.org/ecma-262/9.0/index.html#sec-array.prototype.filter
97
+ subscriptions.filter(sparseFilterPredicate).length
98
+ : 0;
99
+ }
100
+
101
+ /**
102
+ * Emits an event of the given type with the given data. All handlers of that
103
+ * particular type will be notified.
104
+ *
105
+ * @param {string} eventType - Name of the event to emit
106
+ * @param {...*} Arbitrary arguments to be passed to each registered listener
107
+ *
108
+ * @example
109
+ * emitter.addListener('someEvent', function(message) {
110
+ * console.log(message);
111
+ * });
112
+ *
113
+ * emitter.emit('someEvent', 'abc'); // logs 'abc'
114
+ */
115
+ emit(eventType: string, ...args: any[]) {
116
+ const subscriptions = this._subscriber.getSubscriptionsForType(
117
+ eventType
118
+ ) as EmitterSubscription[] | null | undefined;
119
+ if (subscriptions) {
120
+ for (let i = 0, l = subscriptions.length; i < l; i++) {
121
+ const subscription = subscriptions[i];
122
+
123
+ // The subscription may have been removed during this event loop.
124
+ if (subscription && subscription.listener) {
125
+ subscription.listener.apply(subscription.context, args);
126
+ }
127
+ }
128
+ }
129
+ }
130
+
131
+ /**
132
+ * Removes the given listener for event of specific type.
133
+ *
134
+ * @param {string} eventType - Name of the event to emit
135
+ * @param {function} listener - Function to invoke when the specified event is
136
+ * emitted
137
+ *
138
+ * @example
139
+ * emitter.removeListener('someEvent', function(message) {
140
+ * console.log(message);
141
+ * }); // removes the listener if already registered
142
+ *
143
+ */
144
+ removeListener(eventType: string, listener: Function) {
145
+ const subscriptions = this._subscriber.getSubscriptionsForType(
146
+ eventType
147
+ ) as EmitterSubscription[] | null | undefined;
148
+ if (subscriptions) {
149
+ for (let i = 0, l = subscriptions.length; i < l; i++) {
150
+ const subscription = subscriptions[i];
151
+
152
+ // The subscription may have been removed during this event loop.
153
+ // its listener matches the listener in method parameters
154
+ if (subscription && subscription.listener === listener) {
155
+ subscription.remove();
156
+ }
157
+ }
158
+ }
159
+ }
160
+ }
@@ -0,0 +1,44 @@
1
+ import { EventSubscription } from './_EventSubscription';
2
+ import type { EventEmitter } from './EventEmitter';
3
+ import type { EventSubscriptionVendor } from './_EventSubscriptionVendor';
4
+
5
+ /**
6
+ * EmitterSubscription represents a subscription with listener and context data.
7
+ */
8
+ export class EmitterSubscription extends EventSubscription {
9
+ emitter: EventEmitter;
10
+ listener: Function;
11
+ context: Object | null | undefined;
12
+
13
+ /**
14
+ * @param {EventEmitter} emitter - The event emitter that registered this
15
+ * subscription
16
+ * @param {EventSubscriptionVendor} subscriber - The subscriber that controls
17
+ * this subscription
18
+ * @param {function} listener - Function to invoke when the specified event is
19
+ * emitted
20
+ * @param {*} context - Optional context object to use when invoking the
21
+ * listener
22
+ */
23
+ constructor(
24
+ emitter: EventEmitter,
25
+ subscriber: EventSubscriptionVendor,
26
+ listener: Function,
27
+ context: Object | undefined | null
28
+ ) {
29
+ super(subscriber);
30
+ this.emitter = emitter;
31
+ this.listener = listener;
32
+ this.context = context;
33
+ }
34
+
35
+ /**
36
+ * Removes this subscription from the emitter that registered it.
37
+ * Note: we're overriding the `remove()` method of EventSubscription here
38
+ * but deliberately not calling `super.remove()` as the responsibility
39
+ * for removing the subscription lies with the EventEmitter.
40
+ */
41
+ remove() {
42
+ this.emitter.removeSubscription(this);
43
+ }
44
+ }