@stream-io/video-client 1.27.3 → 1.27.5
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/CHANGELOG.md +12 -0
- package/dist/index.browser.es.js +239 -203
- package/dist/index.browser.es.js.map +1 -1
- package/dist/index.cjs.js +239 -203
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +239 -203
- package/dist/index.es.js.map +1 -1
- package/dist/src/StreamVideoClient.d.ts +6 -0
- package/dist/src/helpers/browsers.d.ts +7 -0
- package/dist/src/helpers/clientUtils.d.ts +7 -0
- package/dist/src/store/stateStore.d.ts +0 -7
- package/package.json +1 -1
- package/src/StreamVideoClient.ts +63 -64
- package/src/__tests__/StreamVideoClient.ringing.test.ts +167 -0
- package/src/__tests__/clientTestUtils.ts +72 -0
- package/src/__tests__/data.ts +621 -0
- package/src/helpers/__tests__/browsers.test.ts +191 -0
- package/src/helpers/__tests__/clientUtils.test.ts +8 -0
- package/src/helpers/browsers.ts +25 -0
- package/src/helpers/client-details.ts +18 -3
- package/src/helpers/clientUtils.ts +8 -0
- package/src/store/stateStore.ts +0 -8
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver).
|
|
4
4
|
|
|
5
|
+
## [1.27.5](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.27.4...@stream-io/video-client-1.27.5) (2025-08-15)
|
|
6
|
+
|
|
7
|
+
### Bug Fixes
|
|
8
|
+
|
|
9
|
+
- synchronize ring events ([#1888](https://github.com/GetStream/stream-video-js/issues/1888)) ([0951e6d](https://github.com/GetStream/stream-video-js/commit/0951e6d4c825806937d6bdc548df9f186c531466))
|
|
10
|
+
|
|
11
|
+
## [1.27.4](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.27.3...@stream-io/video-client-1.27.4) (2025-08-13)
|
|
12
|
+
|
|
13
|
+
### Bug Fixes
|
|
14
|
+
|
|
15
|
+
- expose isSupportedBrowser() utility ([#1859](https://github.com/GetStream/stream-video-js/issues/1859)) ([f51a434](https://github.com/GetStream/stream-video-js/commit/f51a4341f57407210ab2e9ba57f41818ddbd7ed9))
|
|
16
|
+
|
|
5
17
|
## [1.27.3](https://github.com/GetStream/stream-video-js/compare/@stream-io/video-client-1.27.2...@stream-io/video-client-1.27.3) (2025-08-07)
|
|
6
18
|
|
|
7
19
|
### Bug Fixes
|
package/dist/index.browser.es.js
CHANGED
|
@@ -4300,13 +4300,6 @@ class StreamVideoWriteableStateStore {
|
|
|
4300
4300
|
*/
|
|
4301
4301
|
class StreamVideoReadOnlyStateStore {
|
|
4302
4302
|
constructor(store) {
|
|
4303
|
-
/**
|
|
4304
|
-
* This method allows you the get the current value of a state variable.
|
|
4305
|
-
*
|
|
4306
|
-
* @param observable the observable to get the current value of.
|
|
4307
|
-
* @returns the current value of the observable.
|
|
4308
|
-
*/
|
|
4309
|
-
this.getCurrentValue = getCurrentValue;
|
|
4310
4303
|
// convert and expose subjects as observables
|
|
4311
4304
|
this.connectedUser$ = store.connectedUserSubject.asObservable();
|
|
4312
4305
|
this.calls$ = store.callsSubject.asObservable();
|
|
@@ -5643,6 +5636,151 @@ const getSdkVersion = (sdk) => {
|
|
|
5643
5636
|
return sdk ? `${sdk.major}.${sdk.minor}.${sdk.patch}` : '0.0.0-development';
|
|
5644
5637
|
};
|
|
5645
5638
|
|
|
5639
|
+
const version = "1.27.5";
|
|
5640
|
+
const [major, minor, patch] = version.split('.');
|
|
5641
|
+
let sdkInfo = {
|
|
5642
|
+
type: SdkType.PLAIN_JAVASCRIPT,
|
|
5643
|
+
major,
|
|
5644
|
+
minor,
|
|
5645
|
+
patch,
|
|
5646
|
+
};
|
|
5647
|
+
let osInfo;
|
|
5648
|
+
let deviceInfo;
|
|
5649
|
+
let webRtcInfo;
|
|
5650
|
+
let deviceState = { oneofKind: undefined };
|
|
5651
|
+
const setSdkInfo = (info) => {
|
|
5652
|
+
sdkInfo = info;
|
|
5653
|
+
};
|
|
5654
|
+
const getSdkInfo = () => {
|
|
5655
|
+
return sdkInfo;
|
|
5656
|
+
};
|
|
5657
|
+
const setOSInfo = (info) => {
|
|
5658
|
+
osInfo = info;
|
|
5659
|
+
};
|
|
5660
|
+
const setDeviceInfo = (info) => {
|
|
5661
|
+
deviceInfo = info;
|
|
5662
|
+
};
|
|
5663
|
+
const getWebRTCInfo = () => {
|
|
5664
|
+
return webRtcInfo;
|
|
5665
|
+
};
|
|
5666
|
+
const setWebRTCInfo = (info) => {
|
|
5667
|
+
webRtcInfo = info;
|
|
5668
|
+
};
|
|
5669
|
+
const setThermalState = (state) => {
|
|
5670
|
+
if (!osInfo) {
|
|
5671
|
+
deviceState = { oneofKind: undefined };
|
|
5672
|
+
return;
|
|
5673
|
+
}
|
|
5674
|
+
if (osInfo.name === 'android') {
|
|
5675
|
+
const thermalState = AndroidThermalState[state] ||
|
|
5676
|
+
AndroidThermalState.UNSPECIFIED;
|
|
5677
|
+
deviceState = {
|
|
5678
|
+
oneofKind: 'android',
|
|
5679
|
+
android: {
|
|
5680
|
+
thermalState,
|
|
5681
|
+
isPowerSaverMode: deviceState?.oneofKind === 'android' &&
|
|
5682
|
+
deviceState.android.isPowerSaverMode,
|
|
5683
|
+
},
|
|
5684
|
+
};
|
|
5685
|
+
}
|
|
5686
|
+
if (osInfo.name.toLowerCase() === 'ios') {
|
|
5687
|
+
const thermalState = AppleThermalState[state] ||
|
|
5688
|
+
AppleThermalState.UNSPECIFIED;
|
|
5689
|
+
deviceState = {
|
|
5690
|
+
oneofKind: 'apple',
|
|
5691
|
+
apple: {
|
|
5692
|
+
thermalState,
|
|
5693
|
+
isLowPowerModeEnabled: deviceState?.oneofKind === 'apple' &&
|
|
5694
|
+
deviceState.apple.isLowPowerModeEnabled,
|
|
5695
|
+
},
|
|
5696
|
+
};
|
|
5697
|
+
}
|
|
5698
|
+
};
|
|
5699
|
+
const setPowerState = (powerMode) => {
|
|
5700
|
+
if (!osInfo) {
|
|
5701
|
+
deviceState = { oneofKind: undefined };
|
|
5702
|
+
return;
|
|
5703
|
+
}
|
|
5704
|
+
if (osInfo.name === 'android') {
|
|
5705
|
+
deviceState = {
|
|
5706
|
+
oneofKind: 'android',
|
|
5707
|
+
android: {
|
|
5708
|
+
thermalState: deviceState?.oneofKind === 'android'
|
|
5709
|
+
? deviceState.android.thermalState
|
|
5710
|
+
: AndroidThermalState.UNSPECIFIED,
|
|
5711
|
+
isPowerSaverMode: powerMode,
|
|
5712
|
+
},
|
|
5713
|
+
};
|
|
5714
|
+
}
|
|
5715
|
+
if (osInfo.name.toLowerCase() === 'ios') {
|
|
5716
|
+
deviceState = {
|
|
5717
|
+
oneofKind: 'apple',
|
|
5718
|
+
apple: {
|
|
5719
|
+
thermalState: deviceState?.oneofKind === 'apple'
|
|
5720
|
+
? deviceState.apple.thermalState
|
|
5721
|
+
: AppleThermalState.UNSPECIFIED,
|
|
5722
|
+
isLowPowerModeEnabled: powerMode,
|
|
5723
|
+
},
|
|
5724
|
+
};
|
|
5725
|
+
}
|
|
5726
|
+
};
|
|
5727
|
+
const getDeviceState = () => {
|
|
5728
|
+
return deviceState;
|
|
5729
|
+
};
|
|
5730
|
+
const getClientDetails = async () => {
|
|
5731
|
+
if (isReactNative()) {
|
|
5732
|
+
// Since RN doesn't support web, sharing browser info is not required
|
|
5733
|
+
return {
|
|
5734
|
+
sdk: sdkInfo,
|
|
5735
|
+
os: osInfo,
|
|
5736
|
+
device: deviceInfo,
|
|
5737
|
+
};
|
|
5738
|
+
}
|
|
5739
|
+
// @ts-expect-error - userAgentData is not yet in the TS types
|
|
5740
|
+
const userAgentDataApi = navigator.userAgentData;
|
|
5741
|
+
let userAgentData;
|
|
5742
|
+
if (userAgentDataApi && userAgentDataApi.getHighEntropyValues) {
|
|
5743
|
+
try {
|
|
5744
|
+
userAgentData = await userAgentDataApi.getHighEntropyValues([
|
|
5745
|
+
'platform',
|
|
5746
|
+
'platformVersion',
|
|
5747
|
+
'fullVersionList',
|
|
5748
|
+
]);
|
|
5749
|
+
}
|
|
5750
|
+
catch {
|
|
5751
|
+
// Ignore the error
|
|
5752
|
+
}
|
|
5753
|
+
}
|
|
5754
|
+
const userAgent = new UAParser(navigator.userAgent);
|
|
5755
|
+
const { browser, os, device, cpu } = userAgent.getResult();
|
|
5756
|
+
// If userAgentData is available, it means we are in a modern Chromium browser,
|
|
5757
|
+
// and we can use it to get more accurate browser information.
|
|
5758
|
+
// We hook into the fullVersionList to find the browser name and version and
|
|
5759
|
+
// eventually detect exotic browsers like Samsung Internet, AVG Secure Browser, etc.
|
|
5760
|
+
// who by default they identify themselves as "Chromium" in the user agent string.
|
|
5761
|
+
// Eliminates the generic "Chromium" name and "Not)A_Brand" name from the list.
|
|
5762
|
+
// https://wicg.github.io/ua-client-hints/#create-arbitrary-brands-section
|
|
5763
|
+
const uaBrowser = userAgentData?.fullVersionList?.find((v) => !v.brand.includes('Chromium') && !v.brand.match(/[()\-./:;=?_]/g));
|
|
5764
|
+
return {
|
|
5765
|
+
sdk: sdkInfo,
|
|
5766
|
+
browser: {
|
|
5767
|
+
name: uaBrowser?.brand || browser.name || navigator.userAgent,
|
|
5768
|
+
version: uaBrowser?.version || browser.version || '',
|
|
5769
|
+
},
|
|
5770
|
+
os: {
|
|
5771
|
+
name: userAgentData?.platform || os.name || '',
|
|
5772
|
+
version: userAgentData?.platformVersion || os.version || '',
|
|
5773
|
+
architecture: cpu.architecture || '',
|
|
5774
|
+
},
|
|
5775
|
+
device: {
|
|
5776
|
+
name: [device.vendor, device.model, device.type]
|
|
5777
|
+
.filter(Boolean)
|
|
5778
|
+
.join(' '),
|
|
5779
|
+
version: '',
|
|
5780
|
+
},
|
|
5781
|
+
};
|
|
5782
|
+
};
|
|
5783
|
+
|
|
5646
5784
|
/**
|
|
5647
5785
|
* Checks whether the current browser is Safari.
|
|
5648
5786
|
*/
|
|
@@ -5667,12 +5805,34 @@ const isChrome = () => {
|
|
|
5667
5805
|
return false;
|
|
5668
5806
|
return navigator.userAgent?.includes('Chrome');
|
|
5669
5807
|
};
|
|
5808
|
+
/**
|
|
5809
|
+
* Checks whether the current browser is among the list of first-class supported browsers.
|
|
5810
|
+
* This includes Chrome, Edge, Firefox, and Safari.
|
|
5811
|
+
*
|
|
5812
|
+
* Although the Stream Video SDK may work in other browsers, these are the ones we officially support.
|
|
5813
|
+
*/
|
|
5814
|
+
const isSupportedBrowser = async () => {
|
|
5815
|
+
const { browser } = await getClientDetails();
|
|
5816
|
+
if (!browser)
|
|
5817
|
+
return false; // we aren't running in a browser
|
|
5818
|
+
const name = browser.name.toLowerCase();
|
|
5819
|
+
const [major] = browser.version.split('.');
|
|
5820
|
+
const version = parseInt(major, 10);
|
|
5821
|
+
return ((name.includes('chrome') && version >= 124) ||
|
|
5822
|
+
(name.includes('edge') && version >= 124) ||
|
|
5823
|
+
(name.includes('firefox') && version >= 124) ||
|
|
5824
|
+
(name.includes('safari') && version >= 17) ||
|
|
5825
|
+
(name.includes('webkit') && version >= 605) || // WebView on iOS
|
|
5826
|
+
(name.includes('webview') && version >= 124) // WebView on Android
|
|
5827
|
+
);
|
|
5828
|
+
};
|
|
5670
5829
|
|
|
5671
5830
|
var browsers = /*#__PURE__*/Object.freeze({
|
|
5672
5831
|
__proto__: null,
|
|
5673
5832
|
isChrome: isChrome,
|
|
5674
5833
|
isFirefox: isFirefox,
|
|
5675
|
-
isSafari: isSafari
|
|
5834
|
+
isSafari: isSafari,
|
|
5835
|
+
isSupportedBrowser: isSupportedBrowser
|
|
5676
5836
|
});
|
|
5677
5837
|
|
|
5678
5838
|
/**
|
|
@@ -5914,142 +6074,6 @@ const aggregate = (stats) => {
|
|
|
5914
6074
|
return report;
|
|
5915
6075
|
};
|
|
5916
6076
|
|
|
5917
|
-
const version = "1.27.3";
|
|
5918
|
-
const [major, minor, patch] = version.split('.');
|
|
5919
|
-
let sdkInfo = {
|
|
5920
|
-
type: SdkType.PLAIN_JAVASCRIPT,
|
|
5921
|
-
major,
|
|
5922
|
-
minor,
|
|
5923
|
-
patch,
|
|
5924
|
-
};
|
|
5925
|
-
let osInfo;
|
|
5926
|
-
let deviceInfo;
|
|
5927
|
-
let webRtcInfo;
|
|
5928
|
-
let deviceState = { oneofKind: undefined };
|
|
5929
|
-
const setSdkInfo = (info) => {
|
|
5930
|
-
sdkInfo = info;
|
|
5931
|
-
};
|
|
5932
|
-
const getSdkInfo = () => {
|
|
5933
|
-
return sdkInfo;
|
|
5934
|
-
};
|
|
5935
|
-
const setOSInfo = (info) => {
|
|
5936
|
-
osInfo = info;
|
|
5937
|
-
};
|
|
5938
|
-
const setDeviceInfo = (info) => {
|
|
5939
|
-
deviceInfo = info;
|
|
5940
|
-
};
|
|
5941
|
-
const getWebRTCInfo = () => {
|
|
5942
|
-
return webRtcInfo;
|
|
5943
|
-
};
|
|
5944
|
-
const setWebRTCInfo = (info) => {
|
|
5945
|
-
webRtcInfo = info;
|
|
5946
|
-
};
|
|
5947
|
-
const setThermalState = (state) => {
|
|
5948
|
-
if (!osInfo) {
|
|
5949
|
-
deviceState = { oneofKind: undefined };
|
|
5950
|
-
return;
|
|
5951
|
-
}
|
|
5952
|
-
if (osInfo.name === 'android') {
|
|
5953
|
-
const thermalState = AndroidThermalState[state] ||
|
|
5954
|
-
AndroidThermalState.UNSPECIFIED;
|
|
5955
|
-
deviceState = {
|
|
5956
|
-
oneofKind: 'android',
|
|
5957
|
-
android: {
|
|
5958
|
-
thermalState,
|
|
5959
|
-
isPowerSaverMode: deviceState?.oneofKind === 'android' &&
|
|
5960
|
-
deviceState.android.isPowerSaverMode,
|
|
5961
|
-
},
|
|
5962
|
-
};
|
|
5963
|
-
}
|
|
5964
|
-
if (osInfo.name.toLowerCase() === 'ios') {
|
|
5965
|
-
const thermalState = AppleThermalState[state] ||
|
|
5966
|
-
AppleThermalState.UNSPECIFIED;
|
|
5967
|
-
deviceState = {
|
|
5968
|
-
oneofKind: 'apple',
|
|
5969
|
-
apple: {
|
|
5970
|
-
thermalState,
|
|
5971
|
-
isLowPowerModeEnabled: deviceState?.oneofKind === 'apple' &&
|
|
5972
|
-
deviceState.apple.isLowPowerModeEnabled,
|
|
5973
|
-
},
|
|
5974
|
-
};
|
|
5975
|
-
}
|
|
5976
|
-
};
|
|
5977
|
-
const setPowerState = (powerMode) => {
|
|
5978
|
-
if (!osInfo) {
|
|
5979
|
-
deviceState = { oneofKind: undefined };
|
|
5980
|
-
return;
|
|
5981
|
-
}
|
|
5982
|
-
if (osInfo.name === 'android') {
|
|
5983
|
-
deviceState = {
|
|
5984
|
-
oneofKind: 'android',
|
|
5985
|
-
android: {
|
|
5986
|
-
thermalState: deviceState?.oneofKind === 'android'
|
|
5987
|
-
? deviceState.android.thermalState
|
|
5988
|
-
: AndroidThermalState.UNSPECIFIED,
|
|
5989
|
-
isPowerSaverMode: powerMode,
|
|
5990
|
-
},
|
|
5991
|
-
};
|
|
5992
|
-
}
|
|
5993
|
-
if (osInfo.name.toLowerCase() === 'ios') {
|
|
5994
|
-
deviceState = {
|
|
5995
|
-
oneofKind: 'apple',
|
|
5996
|
-
apple: {
|
|
5997
|
-
thermalState: deviceState?.oneofKind === 'apple'
|
|
5998
|
-
? deviceState.apple.thermalState
|
|
5999
|
-
: AppleThermalState.UNSPECIFIED,
|
|
6000
|
-
isLowPowerModeEnabled: powerMode,
|
|
6001
|
-
},
|
|
6002
|
-
};
|
|
6003
|
-
}
|
|
6004
|
-
};
|
|
6005
|
-
const getDeviceState = () => {
|
|
6006
|
-
return deviceState;
|
|
6007
|
-
};
|
|
6008
|
-
const getClientDetails = async () => {
|
|
6009
|
-
if (isReactNative()) {
|
|
6010
|
-
// Since RN doesn't support web, sharing browser info is not required
|
|
6011
|
-
return {
|
|
6012
|
-
sdk: sdkInfo,
|
|
6013
|
-
os: osInfo,
|
|
6014
|
-
device: deviceInfo,
|
|
6015
|
-
};
|
|
6016
|
-
}
|
|
6017
|
-
// @ts-expect-error - userAgentData is not yet in the TS types
|
|
6018
|
-
const userAgentDataApi = navigator.userAgentData;
|
|
6019
|
-
let userAgentData;
|
|
6020
|
-
if (userAgentDataApi && userAgentDataApi.getHighEntropyValues) {
|
|
6021
|
-
try {
|
|
6022
|
-
userAgentData = await userAgentDataApi.getHighEntropyValues([
|
|
6023
|
-
'platform',
|
|
6024
|
-
'platformVersion',
|
|
6025
|
-
]);
|
|
6026
|
-
}
|
|
6027
|
-
catch {
|
|
6028
|
-
// Ignore the error
|
|
6029
|
-
}
|
|
6030
|
-
}
|
|
6031
|
-
const userAgent = new UAParser(navigator.userAgent);
|
|
6032
|
-
const { browser, os, device, cpu } = userAgent.getResult();
|
|
6033
|
-
return {
|
|
6034
|
-
sdk: sdkInfo,
|
|
6035
|
-
browser: {
|
|
6036
|
-
name: browser.name || navigator.userAgent,
|
|
6037
|
-
version: browser.version || '',
|
|
6038
|
-
},
|
|
6039
|
-
os: {
|
|
6040
|
-
name: userAgentData?.platform || os.name || '',
|
|
6041
|
-
version: userAgentData?.platformVersion || os.version || '',
|
|
6042
|
-
architecture: cpu.architecture || '',
|
|
6043
|
-
},
|
|
6044
|
-
device: {
|
|
6045
|
-
name: [device.vendor, device.model, device.type]
|
|
6046
|
-
.filter(Boolean)
|
|
6047
|
-
.join(' '),
|
|
6048
|
-
version: '',
|
|
6049
|
-
},
|
|
6050
|
-
};
|
|
6051
|
-
};
|
|
6052
|
-
|
|
6053
6077
|
class SfuStatsReporter {
|
|
6054
6078
|
constructor(sfuClient, { options, clientDetails, subscriber, publisher, microphone, camera, state, tracer, unifiedSessionId, }) {
|
|
6055
6079
|
this.logger = getLogger(['SfuStatsReporter']);
|
|
@@ -14514,7 +14538,7 @@ class StreamClient {
|
|
|
14514
14538
|
this.getUserAgent = () => {
|
|
14515
14539
|
if (!this.cachedUserAgent) {
|
|
14516
14540
|
const { clientAppIdentifier = {} } = this.options;
|
|
14517
|
-
const { sdkName = 'js', sdkVersion = "1.27.
|
|
14541
|
+
const { sdkName = 'js', sdkVersion = "1.27.5", ...extras } = clientAppIdentifier;
|
|
14518
14542
|
this.cachedUserAgent = [
|
|
14519
14543
|
`stream-video-${sdkName}-v${sdkVersion}`,
|
|
14520
14544
|
...Object.entries(extras).map(([key, value]) => `${key}=${value}`),
|
|
@@ -14635,6 +14659,13 @@ class StreamClient {
|
|
|
14635
14659
|
const getInstanceKey = (apiKey, user) => {
|
|
14636
14660
|
return `${apiKey}/${user.id}`;
|
|
14637
14661
|
};
|
|
14662
|
+
/**
|
|
14663
|
+
* Returns a concurrency tag for call initialization.
|
|
14664
|
+
* @internal
|
|
14665
|
+
*
|
|
14666
|
+
* @param cid the call cid.
|
|
14667
|
+
*/
|
|
14668
|
+
const getCallInitConcurrencyTag = (cid) => `call.init-${cid}`;
|
|
14638
14669
|
/**
|
|
14639
14670
|
* Utility function to get the client app identifier.
|
|
14640
14671
|
*/
|
|
@@ -14703,7 +14734,7 @@ class StreamVideoClient {
|
|
|
14703
14734
|
this.registerEffects = () => {
|
|
14704
14735
|
if (this.effectsRegistered)
|
|
14705
14736
|
return;
|
|
14706
|
-
this.eventHandlersToUnregister.push(this.on('connection.changed', (event) => {
|
|
14737
|
+
this.eventHandlersToUnregister.push(this.on('call.created', (event) => this.initCallFromEvent(event)), this.on('call.ring', (event) => this.initCallFromEvent(event)), this.on('connection.changed', (event) => {
|
|
14707
14738
|
if (!event.online)
|
|
14708
14739
|
return;
|
|
14709
14740
|
const callsToReWatch = this.writeableStateStore.calls
|
|
@@ -14720,50 +14751,52 @@ class StreamVideoClient {
|
|
|
14720
14751
|
this.logger('error', 'Failed to re-watch calls', err);
|
|
14721
14752
|
});
|
|
14722
14753
|
}));
|
|
14723
|
-
this.
|
|
14724
|
-
|
|
14725
|
-
|
|
14726
|
-
|
|
14727
|
-
|
|
14728
|
-
|
|
14729
|
-
|
|
14730
|
-
|
|
14731
|
-
|
|
14732
|
-
|
|
14733
|
-
|
|
14734
|
-
|
|
14735
|
-
|
|
14736
|
-
|
|
14737
|
-
|
|
14738
|
-
|
|
14739
|
-
|
|
14740
|
-
|
|
14741
|
-
|
|
14742
|
-
|
|
14743
|
-
|
|
14744
|
-
|
|
14745
|
-
|
|
14746
|
-
|
|
14747
|
-
|
|
14748
|
-
|
|
14749
|
-
if (theCall) {
|
|
14750
|
-
await theCall.updateFromRingingEvent(event);
|
|
14751
|
-
}
|
|
14752
|
-
else {
|
|
14753
|
-
// if client doesn't have the call instance, create the instance and fetch the latest state
|
|
14754
|
-
// Note: related - we also have onRingingCall method to handle this case from push notifications
|
|
14755
|
-
const newCallInstance = new Call({
|
|
14754
|
+
this.effectsRegistered = true;
|
|
14755
|
+
};
|
|
14756
|
+
/**
|
|
14757
|
+
* Initializes a call from a call created or ringing event.
|
|
14758
|
+
* @param e the event.
|
|
14759
|
+
*/
|
|
14760
|
+
this.initCallFromEvent = async (e) => {
|
|
14761
|
+
if (this.state.connectedUser?.id === e.call.created_by.id) {
|
|
14762
|
+
this.logger('debug', `Ignoring ${e.type} event sent by the current user`);
|
|
14763
|
+
return;
|
|
14764
|
+
}
|
|
14765
|
+
try {
|
|
14766
|
+
const concurrencyTag = getCallInitConcurrencyTag(e.call_cid);
|
|
14767
|
+
await withoutConcurrency(concurrencyTag, async () => {
|
|
14768
|
+
const ringing = e.type === 'call.ring';
|
|
14769
|
+
let call = this.writeableStateStore.findCall(e.call.type, e.call.id);
|
|
14770
|
+
if (call) {
|
|
14771
|
+
if (ringing) {
|
|
14772
|
+
await call.updateFromRingingEvent(e);
|
|
14773
|
+
}
|
|
14774
|
+
else {
|
|
14775
|
+
call.state.updateFromCallResponse(e.call);
|
|
14776
|
+
}
|
|
14777
|
+
return;
|
|
14778
|
+
}
|
|
14779
|
+
call = new Call({
|
|
14756
14780
|
streamClient: this.streamClient,
|
|
14757
|
-
type: call.type,
|
|
14758
|
-
id: call.id,
|
|
14759
|
-
members,
|
|
14781
|
+
type: e.call.type,
|
|
14782
|
+
id: e.call.id,
|
|
14783
|
+
members: e.members,
|
|
14760
14784
|
clientStore: this.writeableStateStore,
|
|
14761
|
-
ringing
|
|
14785
|
+
ringing,
|
|
14762
14786
|
});
|
|
14763
|
-
|
|
14764
|
-
|
|
14765
|
-
|
|
14766
|
-
|
|
14787
|
+
call.state.updateFromCallResponse(e.call);
|
|
14788
|
+
if (ringing) {
|
|
14789
|
+
await call.get();
|
|
14790
|
+
}
|
|
14791
|
+
else {
|
|
14792
|
+
this.writeableStateStore.registerCall(call);
|
|
14793
|
+
this.logger('info', `New call created and registered: ${call.cid}`);
|
|
14794
|
+
}
|
|
14795
|
+
});
|
|
14796
|
+
}
|
|
14797
|
+
catch (err) {
|
|
14798
|
+
this.logger('error', `Failed to init call from event ${e.type}`, err);
|
|
14799
|
+
}
|
|
14767
14800
|
};
|
|
14768
14801
|
/**
|
|
14769
14802
|
* Connects the given user to the client.
|
|
@@ -14863,6 +14896,7 @@ class StreamVideoClient {
|
|
|
14863
14896
|
*
|
|
14864
14897
|
* @param type the type of the call.
|
|
14865
14898
|
* @param id the id of the call.
|
|
14899
|
+
* @param options additional options for call creation.
|
|
14866
14900
|
*/
|
|
14867
14901
|
this.call = (type, id, options = {}) => {
|
|
14868
14902
|
const call = options.reuseInstance
|
|
@@ -14993,22 +15027,24 @@ class StreamVideoClient {
|
|
|
14993
15027
|
* @returns
|
|
14994
15028
|
*/
|
|
14995
15029
|
this.onRingingCall = async (call_cid) => {
|
|
14996
|
-
|
|
14997
|
-
|
|
14998
|
-
|
|
14999
|
-
|
|
15000
|
-
|
|
15001
|
-
|
|
15002
|
-
|
|
15003
|
-
|
|
15004
|
-
|
|
15005
|
-
|
|
15006
|
-
|
|
15007
|
-
|
|
15008
|
-
|
|
15009
|
-
|
|
15010
|
-
|
|
15011
|
-
|
|
15030
|
+
return withoutConcurrency(getCallInitConcurrencyTag(call_cid), async () => {
|
|
15031
|
+
// if we find the call and is already ringing, we don't need to create a new call
|
|
15032
|
+
// as client would have received the call.ring state because the app had WS alive when receiving push notifications
|
|
15033
|
+
let call = this.state.calls.find((c) => c.cid === call_cid && c.ringing);
|
|
15034
|
+
if (!call) {
|
|
15035
|
+
// if not it means that WS is not alive when receiving the push notifications and we need to fetch the call
|
|
15036
|
+
const [callType, callId] = call_cid.split(':');
|
|
15037
|
+
call = new Call({
|
|
15038
|
+
streamClient: this.streamClient,
|
|
15039
|
+
type: callType,
|
|
15040
|
+
id: callId,
|
|
15041
|
+
clientStore: this.writeableStateStore,
|
|
15042
|
+
ringing: true,
|
|
15043
|
+
});
|
|
15044
|
+
await call.get();
|
|
15045
|
+
}
|
|
15046
|
+
return call;
|
|
15047
|
+
});
|
|
15012
15048
|
};
|
|
15013
15049
|
/**
|
|
15014
15050
|
* Connects the given anonymous user to the client.
|