@sendbird/uikit-react-native 3.10.3 → 3.11.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 (73) hide show
  1. package/README.md +9 -7
  2. package/lib/commonjs/components/ChannelInput/VoiceMessageInput.js +1 -1
  3. package/lib/commonjs/components/ChannelInput/VoiceMessageInput.js.map +1 -1
  4. package/lib/commonjs/components/ChannelInput/index.js +2 -25
  5. package/lib/commonjs/components/ChannelInput/index.js.map +1 -1
  6. package/lib/commonjs/hooks/useVoiceMessageInput.js +10 -2
  7. package/lib/commonjs/hooks/useVoiceMessageInput.js.map +1 -1
  8. package/lib/commonjs/platform/createFileService.native.js +1 -1
  9. package/lib/commonjs/platform/createFileService.native.js.map +1 -1
  10. package/lib/commonjs/platform/createMediaService.expo.js +83 -12
  11. package/lib/commonjs/platform/createMediaService.expo.js.map +1 -1
  12. package/lib/commonjs/platform/createPlayerService.expo.js +214 -113
  13. package/lib/commonjs/platform/createPlayerService.expo.js.map +1 -1
  14. package/lib/commonjs/platform/createPlayerService.native.js +191 -114
  15. package/lib/commonjs/platform/createPlayerService.native.js.map +1 -1
  16. package/lib/commonjs/platform/createRecorderService.expo.js +248 -127
  17. package/lib/commonjs/platform/createRecorderService.expo.js.map +1 -1
  18. package/lib/commonjs/platform/createRecorderService.native.js +212 -129
  19. package/lib/commonjs/platform/createRecorderService.native.js.map +1 -1
  20. package/lib/commonjs/platform/types.js.map +1 -1
  21. package/lib/commonjs/utils/expoBackwardUtils.js +23 -0
  22. package/lib/commonjs/utils/expoBackwardUtils.js.map +1 -1
  23. package/lib/commonjs/utils/expoPermissionGranted.js.map +1 -1
  24. package/lib/commonjs/version.js +1 -1
  25. package/lib/commonjs/version.js.map +1 -1
  26. package/lib/module/components/ChannelInput/VoiceMessageInput.js +1 -1
  27. package/lib/module/components/ChannelInput/VoiceMessageInput.js.map +1 -1
  28. package/lib/module/components/ChannelInput/index.js +3 -26
  29. package/lib/module/components/ChannelInput/index.js.map +1 -1
  30. package/lib/module/hooks/useVoiceMessageInput.js +10 -2
  31. package/lib/module/hooks/useVoiceMessageInput.js.map +1 -1
  32. package/lib/module/platform/createFileService.native.js +1 -1
  33. package/lib/module/platform/createFileService.native.js.map +1 -1
  34. package/lib/module/platform/createMediaService.expo.js +82 -13
  35. package/lib/module/platform/createMediaService.expo.js.map +1 -1
  36. package/lib/module/platform/createPlayerService.expo.js +214 -113
  37. package/lib/module/platform/createPlayerService.expo.js.map +1 -1
  38. package/lib/module/platform/createPlayerService.native.js +191 -114
  39. package/lib/module/platform/createPlayerService.native.js.map +1 -1
  40. package/lib/module/platform/createRecorderService.expo.js +249 -128
  41. package/lib/module/platform/createRecorderService.expo.js.map +1 -1
  42. package/lib/module/platform/createRecorderService.native.js +212 -129
  43. package/lib/module/platform/createRecorderService.native.js.map +1 -1
  44. package/lib/module/platform/types.js.map +1 -1
  45. package/lib/module/utils/expoBackwardUtils.js +23 -0
  46. package/lib/module/utils/expoBackwardUtils.js.map +1 -1
  47. package/lib/module/utils/expoPermissionGranted.js.map +1 -1
  48. package/lib/module/version.js +1 -1
  49. package/lib/module/version.js.map +1 -1
  50. package/lib/typescript/src/containers/SendbirdUIKitContainer.d.ts +1 -1
  51. package/lib/typescript/src/platform/createMediaService.expo.d.ts +2 -2
  52. package/lib/typescript/src/platform/createPlayerService.expo.d.ts +2 -2
  53. package/lib/typescript/src/platform/createPlayerService.native.d.ts +5 -3
  54. package/lib/typescript/src/platform/createRecorderService.expo.d.ts +2 -2
  55. package/lib/typescript/src/platform/createRecorderService.native.d.ts +5 -3
  56. package/lib/typescript/src/platform/types.d.ts +4 -0
  57. package/lib/typescript/src/utils/expoBackwardUtils.d.ts +10 -0
  58. package/lib/typescript/src/utils/expoPermissionGranted.d.ts +1 -1
  59. package/lib/typescript/src/version.d.ts +1 -1
  60. package/package.json +29 -5
  61. package/src/components/ChannelInput/VoiceMessageInput.tsx +1 -1
  62. package/src/components/ChannelInput/index.tsx +6 -36
  63. package/src/hooks/useVoiceMessageInput.ts +7 -2
  64. package/src/platform/createFileService.native.ts +1 -1
  65. package/src/platform/createMediaService.expo.tsx +87 -9
  66. package/src/platform/createPlayerService.expo.tsx +242 -109
  67. package/src/platform/createPlayerService.native.tsx +237 -113
  68. package/src/platform/createRecorderService.expo.tsx +268 -107
  69. package/src/platform/createRecorderService.native.tsx +240 -118
  70. package/src/platform/types.ts +5 -0
  71. package/src/utils/expoBackwardUtils.ts +29 -0
  72. package/src/utils/expoPermissionGranted.ts +3 -1
  73. package/src/version.ts +1 -1
@@ -12,150 +12,233 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
12
12
  function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
13
13
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
14
14
  function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
15
- const createNativeRecorderService = ({
16
- audioRecorderModule,
17
- permissionModule
18
- }) => {
19
- const module = new audioRecorderModule.default();
20
- class VoiceRecorder {
21
- constructor() {
22
- _defineProperty(this, "uri", undefined);
23
- _defineProperty(this, "state", 'idle');
24
- _defineProperty(this, "options", {
25
- minDuration: _VoiceMessageConfig.default.DEFAULT.RECORDER.MIN_DURATION,
26
- maxDuration: _VoiceMessageConfig.default.DEFAULT.RECORDER.MAX_DURATION,
27
- extension: _VoiceMessageConfig.default.DEFAULT.RECORDER.EXTENSION
28
- });
29
- // NOTE: In Android, even when startRecorder() is awaited, if stop() is executed immediately afterward, an error occurs
30
- _defineProperty(this, "_recordStartedAt", 0);
31
- _defineProperty(this, "_getRecorderStopSafeBuffer", () => {
32
- const minWaitingTime = 500;
33
- const elapsedTime = Date.now() - this._recordStartedAt;
34
- if (elapsedTime > minWaitingTime) return 0;else return minWaitingTime - elapsedTime;
35
- });
36
- _defineProperty(this, "recordingSubscribers", new Set());
37
- _defineProperty(this, "stateSubscribers", new Set());
38
- _defineProperty(this, "audioSettings", {
39
- sampleRate: _VoiceMessageConfig.default.DEFAULT.RECORDER.SAMPLE_RATE,
40
- bitRate: _VoiceMessageConfig.default.DEFAULT.RECORDER.BIT_RATE,
41
- audioChannels: _VoiceMessageConfig.default.DEFAULT.RECORDER.CHANNELS
42
- // encoding: mpeg4_aac
15
+ class AudioRecorderPlayerAdapter {
16
+ constructor(audioRecorderModule) {
17
+ _defineProperty(this, "module", void 0);
18
+ _defineProperty(this, "audioOptions", void 0);
19
+ this.module = new audioRecorderModule.default();
20
+ this.audioOptions = _reactNative.Platform.select({
21
+ android: {
22
+ AudioEncodingBitRateAndroid: _VoiceMessageConfig.default.DEFAULT.RECORDER.BIT_RATE,
23
+ AudioChannelsAndroid: _VoiceMessageConfig.default.DEFAULT.RECORDER.CHANNELS,
24
+ AudioSamplingRateAndroid: _VoiceMessageConfig.default.DEFAULT.RECORDER.SAMPLE_RATE,
25
+ AudioEncoderAndroid: audioRecorderModule.AudioEncoderAndroidType.AAC,
26
+ OutputFormatAndroid: audioRecorderModule.OutputFormatAndroidType.MPEG_4,
27
+ AudioSourceAndroid: audioRecorderModule.AudioSourceAndroidType.VOICE_RECOGNITION
28
+ },
29
+ ios: {
30
+ AVEncoderBitRateKeyIOS: _VoiceMessageConfig.default.DEFAULT.RECORDER.BIT_RATE,
31
+ AVNumberOfChannelsKeyIOS: _VoiceMessageConfig.default.DEFAULT.RECORDER.CHANNELS,
32
+ AVSampleRateKeyIOS: _VoiceMessageConfig.default.DEFAULT.RECORDER.SAMPLE_RATE,
33
+ AVFormatIDKeyIOS: audioRecorderModule.AVEncodingOption.mp4,
34
+ // same with aac
35
+ AVEncoderAudioQualityKeyIOS: audioRecorderModule.AVEncoderAudioQualityIOSType.high
36
+ },
37
+ default: {}
38
+ });
39
+ }
40
+ async setSubscriptionDuration(duration) {
41
+ await this.module.setSubscriptionDuration(duration);
42
+ }
43
+ addRecordBackListener(callback) {
44
+ this.module.addRecordBackListener(callback);
45
+ }
46
+ convertRecordPath(uri) {
47
+ return _reactNative.Platform.OS === 'ios' ? uri.split('/').pop() || uri : uri;
48
+ }
49
+ async startRecorder(uri) {
50
+ await this.module.startRecorder(uri, this.audioOptions);
51
+ }
52
+ async stopRecorder() {
53
+ await this.module.stopRecorder();
54
+ }
55
+ }
56
+ class NitroSoundOrLegacyV4Adapter {
57
+ constructor(audioRecorderModule) {
58
+ _defineProperty(this, "module", void 0);
59
+ _defineProperty(this, "audioOptions", void 0);
60
+ this.module = audioRecorderModule.default;
61
+ this.audioOptions = _reactNative.Platform.select({
62
+ android: {
63
+ AudioEncodingBitRateAndroid: _VoiceMessageConfig.default.DEFAULT.RECORDER.BIT_RATE,
64
+ AudioChannelsAndroid: _VoiceMessageConfig.default.DEFAULT.RECORDER.CHANNELS,
65
+ AudioSamplingRateAndroid: _VoiceMessageConfig.default.DEFAULT.RECORDER.SAMPLE_RATE,
66
+ AudioEncoderAndroid: audioRecorderModule.AudioEncoderAndroidType.AAC,
67
+ OutputFormatAndroid: audioRecorderModule.OutputFormatAndroidType.MPEG_4,
68
+ AudioSourceAndroid: audioRecorderModule.AudioSourceAndroidType.VOICE_RECOGNITION
69
+ },
70
+ ios: {
71
+ AVEncoderBitRateKeyIOS: _VoiceMessageConfig.default.DEFAULT.RECORDER.BIT_RATE,
72
+ AVNumberOfChannelsKeyIOS: _VoiceMessageConfig.default.DEFAULT.RECORDER.CHANNELS,
73
+ AVSampleRateKeyIOS: _VoiceMessageConfig.default.DEFAULT.RECORDER.SAMPLE_RATE,
74
+ AVFormatIDKeyIOS: 'mp4',
75
+ // same with aac
76
+ AVEncoderAudioQualityKeyIOS: audioRecorderModule.AVEncoderAudioQualityIOSType.high
77
+ },
78
+ default: {}
79
+ });
80
+ }
81
+ setSubscriptionDuration(duration) {
82
+ try {
83
+ this.module.setSubscriptionDuration(duration);
84
+ } catch (error) {
85
+ _uikitUtils.Logger.warn('[RecorderService.Native] Failed to set subscription duration', error);
86
+ }
87
+ }
88
+ addRecordBackListener(callback) {
89
+ this.module.addRecordBackListener(callback);
90
+ }
91
+ convertRecordPath(uri) {
92
+ return uri;
93
+ }
94
+ async startRecorder(uri) {
95
+ await this.module.startRecorder(uri, this.audioOptions);
96
+ }
97
+ async stopRecorder() {
98
+ await this.module.stopRecorder();
99
+ }
100
+ }
101
+ class VoiceRecorder {
102
+ constructor(adapter, permissionModule) {
103
+ this.adapter = adapter;
104
+ this.permissionModule = permissionModule;
105
+ _defineProperty(this, "uri", undefined);
106
+ _defineProperty(this, "state", 'idle');
107
+ _defineProperty(this, "options", {
108
+ minDuration: _VoiceMessageConfig.default.DEFAULT.RECORDER.MIN_DURATION,
109
+ maxDuration: _VoiceMessageConfig.default.DEFAULT.RECORDER.MAX_DURATION,
110
+ extension: _VoiceMessageConfig.default.DEFAULT.RECORDER.EXTENSION
111
+ });
112
+ _defineProperty(this, "_recordStartedAt", 0);
113
+ _defineProperty(this, "_stopping", false);
114
+ _defineProperty(this, "recordingSubscribers", new Set());
115
+ _defineProperty(this, "stateSubscribers", new Set());
116
+ _defineProperty(this, "setState", state => {
117
+ this.state = state;
118
+ this.stateSubscribers.forEach(callback => {
119
+ callback(state);
43
120
  });
44
- _defineProperty(this, "audioOptions", _reactNative.Platform.select({
45
- android: {
46
- AudioEncodingBitRateAndroid: this.audioSettings.bitRate,
47
- AudioChannelsAndroid: this.audioSettings.audioChannels,
48
- AudioSamplingRateAndroid: this.audioSettings.sampleRate,
49
- AudioEncoderAndroid: audioRecorderModule.AudioEncoderAndroidType.AAC,
50
- OutputFormatAndroid: audioRecorderModule.OutputFormatAndroidType.MPEG_4,
51
- AudioSourceAndroid: audioRecorderModule.AudioSourceAndroidType.VOICE_RECOGNITION
52
- },
53
- ios: {
54
- AVEncoderBitRateKeyIOS: this.audioSettings.bitRate,
55
- AVNumberOfChannelsKeyIOS: this.audioSettings.audioChannels,
56
- AVSampleRateKeyIOS: this.audioSettings.sampleRate,
57
- AVFormatIDKeyIOS: audioRecorderModule.AVEncodingOption.mp4,
58
- // same with aac
59
- AVEncoderAudioQualityKeyIOS: audioRecorderModule.AVEncoderAudioQualityIOSType.high
60
- },
61
- default: {}
62
- }));
63
- _defineProperty(this, "setState", state => {
64
- this.state = state;
65
- this.stateSubscribers.forEach(callback => {
66
- callback(state);
67
- });
121
+ });
122
+ _defineProperty(this, "getRecorderStopSafeBuffer", () => {
123
+ const minWaitingTime = 500;
124
+ const elapsedTime = Date.now() - this._recordStartedAt;
125
+ if (elapsedTime > minWaitingTime) return 0;else return minWaitingTime - elapsedTime;
126
+ });
127
+ _defineProperty(this, "requestPermission", async () => {
128
+ const permission = _reactNative.Platform.select({
129
+ android: [this.permissionModule.PERMISSIONS.ANDROID.RECORD_AUDIO],
130
+ ios: [this.permissionModule.PERMISSIONS.IOS.MICROPHONE],
131
+ windows: [this.permissionModule.PERMISSIONS.WINDOWS.MICROPHONE],
132
+ default: undefined
68
133
  });
69
- _defineProperty(this, "requestPermission", async () => {
70
- const permission = _reactNative.Platform.select({
71
- android: [permissionModule.PERMISSIONS.ANDROID.RECORD_AUDIO],
72
- ios: [permissionModule.PERMISSIONS.IOS.MICROPHONE],
73
- windows: [permissionModule.PERMISSIONS.WINDOWS.MICROPHONE],
74
- default: undefined
75
- });
76
- if (_reactNative.Platform.OS === 'android' && _reactNative.Platform.Version <= 28) {
77
- permission === null || permission === void 0 || permission.push(permissionModule.PERMISSIONS.ANDROID.WRITE_EXTERNAL_STORAGE);
78
- }
79
- if (permission) {
80
- const status = await permissionModule.checkMultiple(permission);
81
- if ((0, _nativePermissionGranted.default)(status)) {
82
- return true;
83
- } else {
84
- const status = await permissionModule.requestMultiple(permission);
85
- return (0, _nativePermissionGranted.default)(status);
86
- }
87
- } else {
134
+ if (_reactNative.Platform.OS === 'android' && _reactNative.Platform.Version <= 28) {
135
+ permission === null || permission === void 0 || permission.push(this.permissionModule.PERMISSIONS.ANDROID.WRITE_EXTERNAL_STORAGE);
136
+ }
137
+ if (permission) {
138
+ const status = await this.permissionModule.checkMultiple(permission);
139
+ if ((0, _nativePermissionGranted.default)(status)) {
88
140
  return true;
141
+ } else {
142
+ const status = await this.permissionModule.requestMultiple(permission);
143
+ return (0, _nativePermissionGranted.default)(status);
89
144
  }
90
- });
91
- _defineProperty(this, "addRecordingListener", callback => {
92
- this.recordingSubscribers.add(callback);
93
- return () => {
94
- this.recordingSubscribers.delete(callback);
95
- };
96
- });
97
- _defineProperty(this, "addStateListener", callback => {
98
- this.stateSubscribers.add(callback);
99
- return () => {
100
- this.stateSubscribers.delete(callback);
101
- };
102
- });
103
- _defineProperty(this, "record", async uri => {
104
- if ((0, _uikitUtils.matchesOneOf)(this.state, ['idle', 'completed'])) {
105
- try {
106
- this.setState('preparing');
107
- await module.startRecorder(uri, {
108
- ...this.audioOptions
109
- });
110
- if (_reactNative.Platform.OS === 'android') {
111
- this._recordStartedAt = Date.now();
112
- }
113
- this.uri = uri;
114
- this.setState('recording');
115
- } catch (e) {
116
- this.setState('idle');
117
- throw e;
145
+ } else {
146
+ return true;
147
+ }
148
+ });
149
+ _defineProperty(this, "addRecordingListener", callback => {
150
+ this.recordingSubscribers.add(callback);
151
+ return () => {
152
+ this.recordingSubscribers.delete(callback);
153
+ };
154
+ });
155
+ _defineProperty(this, "addStateListener", callback => {
156
+ this.stateSubscribers.add(callback);
157
+ return () => {
158
+ this.stateSubscribers.delete(callback);
159
+ };
160
+ });
161
+ _defineProperty(this, "record", async uri => {
162
+ if ((0, _uikitUtils.matchesOneOf)(this.state, ['idle', 'completed'])) {
163
+ try {
164
+ this.setState('preparing');
165
+ await this.adapter.startRecorder(uri);
166
+ if (_reactNative.Platform.OS === 'android') {
167
+ this._recordStartedAt = Date.now();
118
168
  }
169
+ this.uri = uri;
170
+ this.setState('recording');
171
+ } catch (e) {
172
+ this.setState('idle');
173
+ throw e;
119
174
  }
120
- });
121
- _defineProperty(this, "stop", async () => {
122
- if ((0, _uikitUtils.matchesOneOf)(this.state, ['recording'])) {
175
+ }
176
+ });
177
+ _defineProperty(this, "stop", async () => {
178
+ if ((0, _uikitUtils.matchesOneOf)(this.state, ['recording']) && !this._stopping) {
179
+ this._stopping = true;
180
+ try {
123
181
  if (_reactNative.Platform.OS === 'android') {
124
- const buffer = this._getRecorderStopSafeBuffer();
182
+ const buffer = this.getRecorderStopSafeBuffer();
125
183
  if (buffer > 0) await (0, _uikitUtils.sleep)(buffer);
126
184
  }
127
- await module.stopRecorder();
185
+ await this.adapter.stopRecorder();
128
186
  this.setState('completed');
187
+ } catch (error) {
188
+ _uikitUtils.Logger.error('[RecorderService.Native] Failed to stop recorder', error);
189
+ throw error;
190
+ } finally {
191
+ this._stopping = false;
129
192
  }
130
- });
131
- _defineProperty(this, "reset", async () => {
132
- await this.stop();
133
- this.uri = undefined;
134
- this.recordingSubscribers.clear();
135
- this.setState('idle');
136
- });
137
- module.setSubscriptionDuration(0.1).catch(error => {
193
+ }
194
+ });
195
+ _defineProperty(this, "reset", async () => {
196
+ await this.stop();
197
+ this.uri = undefined;
198
+ this.recordingSubscribers.clear();
199
+ this.setState('idle');
200
+ });
201
+ _defineProperty(this, "convertRecordPath", uri => {
202
+ return this.adapter.convertRecordPath(uri);
203
+ });
204
+ this.initialize();
205
+ }
206
+ initialize() {
207
+ const setDurationResult = this.adapter.setSubscriptionDuration(0.1);
208
+ if (setDurationResult instanceof Promise) {
209
+ setDurationResult.catch(error => {
138
210
  _uikitUtils.Logger.warn('[RecorderService.Native] Failed to set subscription duration', error);
139
211
  });
140
- module.addRecordBackListener(data => {
141
- const completed = data.currentPosition >= this.options.maxDuration;
142
- if (completed) {
143
- this.stop().catch(error => {
144
- _uikitUtils.Logger.warn('[RecorderService.Native] Failed to stop in RecordBackListener', error);
145
- });
146
- }
147
- if (this.state === 'recording') {
148
- this.recordingSubscribers.forEach(callback => {
149
- callback({
150
- currentTime: data.currentPosition,
151
- completed
152
- });
153
- });
154
- }
155
- });
156
212
  }
213
+ this.adapter.addRecordBackListener(data => {
214
+ const completed = data.currentPosition >= this.options.maxDuration;
215
+ if (completed) {
216
+ this.stop().catch(error => {
217
+ _uikitUtils.Logger.warn('[RecorderService.Native] Failed to stop in RecordBackListener', error);
218
+ });
219
+ }
220
+ if (this.state === 'recording') {
221
+ this.recordingSubscribers.forEach(callback => {
222
+ callback({
223
+ currentTime: data.currentPosition,
224
+ completed
225
+ });
226
+ });
227
+ }
228
+ });
157
229
  }
158
- return new VoiceRecorder();
230
+ }
231
+ const createNativeRecorderService = modules => {
232
+ const adapter = isNitroSoundOrLegacyV4Module(modules.audioRecorderModule) ? new NitroSoundOrLegacyV4Adapter(modules.audioRecorderModule) : new AudioRecorderPlayerAdapter(modules.audioRecorderModule);
233
+ return new VoiceRecorder(adapter, modules.permissionModule);
159
234
  };
235
+ function isNitroSoundOrLegacyV4Module(module) {
236
+ const isNitroSound = 'createSound' in module && typeof module.createSound === 'function';
237
+ const isLegacyV4 = 'default' in module && 'getHybridObject' in module.default && typeof module.default.getHybridObject === 'function';
238
+ if (isLegacyV4) {
239
+ _uikitUtils.Logger.warn('react-native-audio-recorder-player is deprecated. Please use react-native-nitro-sound instead.');
240
+ }
241
+ return isNitroSound || isLegacyV4;
242
+ }
160
243
  var _default = exports.default = createNativeRecorderService;
161
244
  //# sourceMappingURL=createRecorderService.native.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["_reactNative","require","_uikitUtils","_VoiceMessageConfig","_interopRequireDefault","_nativePermissionGranted","e","__esModule","default","_defineProperty","r","t","_toPropertyKey","Object","defineProperty","value","enumerable","configurable","writable","i","_toPrimitive","Symbol","toPrimitive","call","TypeError","String","Number","createNativeRecorderService","audioRecorderModule","permissionModule","module","VoiceRecorder","constructor","undefined","minDuration","VoiceMessageConfig","DEFAULT","RECORDER","MIN_DURATION","maxDuration","MAX_DURATION","extension","EXTENSION","minWaitingTime","elapsedTime","Date","now","_recordStartedAt","Set","sampleRate","SAMPLE_RATE","bitRate","BIT_RATE","audioChannels","CHANNELS","Platform","select","android","AudioEncodingBitRateAndroid","audioSettings","AudioChannelsAndroid","AudioSamplingRateAndroid","AudioEncoderAndroid","AudioEncoderAndroidType","AAC","OutputFormatAndroid","OutputFormatAndroidType","MPEG_4","AudioSourceAndroid","AudioSourceAndroidType","VOICE_RECOGNITION","ios","AVEncoderBitRateKeyIOS","AVNumberOfChannelsKeyIOS","AVSampleRateKeyIOS","AVFormatIDKeyIOS","AVEncodingOption","mp4","AVEncoderAudioQualityKeyIOS","AVEncoderAudioQualityIOSType","high","state","stateSubscribers","forEach","callback","permission","PERMISSIONS","ANDROID","RECORD_AUDIO","IOS","MICROPHONE","windows","WINDOWS","OS","Version","push","WRITE_EXTERNAL_STORAGE","status","checkMultiple","nativePermissionGranted","requestMultiple","recordingSubscribers","add","delete","uri","matchesOneOf","setState","startRecorder","audioOptions","buffer","_getRecorderStopSafeBuffer","sleep","stopRecorder","stop","clear","setSubscriptionDuration","catch","error","Logger","warn","addRecordBackListener","data","completed","currentPosition","options","currentTime","_default","exports"],"sources":["createRecorderService.native.tsx"],"sourcesContent":["import { Platform } from 'react-native';\nimport * as RNAudioRecorder from 'react-native-audio-recorder-player';\nimport * as Permissions from 'react-native-permissions';\nimport { Permission } from 'react-native-permissions/src/types';\n\nimport { Logger, matchesOneOf, sleep } from '@sendbird/uikit-utils';\n\nimport VoiceMessageConfig from '../libs/VoiceMessageConfig';\nimport nativePermissionGranted from '../utils/nativePermissionGranted';\nimport type { RecorderServiceInterface, Unsubscribe } from './types';\n\ntype RecordingListener = Parameters<RecorderServiceInterface['addRecordingListener']>[number];\ntype StateListener = Parameters<RecorderServiceInterface['addStateListener']>[number];\ntype Modules = {\n audioRecorderModule: typeof RNAudioRecorder;\n permissionModule: typeof Permissions;\n};\nconst createNativeRecorderService = ({ audioRecorderModule, permissionModule }: Modules): RecorderServiceInterface => {\n const module = new audioRecorderModule.default();\n\n class VoiceRecorder implements RecorderServiceInterface {\n public uri: RecorderServiceInterface['uri'] = undefined;\n public state: RecorderServiceInterface['state'] = 'idle';\n public options: RecorderServiceInterface['options'] = {\n minDuration: VoiceMessageConfig.DEFAULT.RECORDER.MIN_DURATION,\n maxDuration: VoiceMessageConfig.DEFAULT.RECORDER.MAX_DURATION,\n extension: VoiceMessageConfig.DEFAULT.RECORDER.EXTENSION,\n };\n\n // NOTE: In Android, even when startRecorder() is awaited, if stop() is executed immediately afterward, an error occurs\n private _recordStartedAt = 0;\n private _getRecorderStopSafeBuffer = () => {\n const minWaitingTime = 500;\n const elapsedTime = Date.now() - this._recordStartedAt;\n if (elapsedTime > minWaitingTime) return 0;\n else return minWaitingTime - elapsedTime;\n };\n\n private readonly recordingSubscribers = new Set<RecordingListener>();\n private readonly stateSubscribers = new Set<StateListener>();\n private readonly audioSettings = {\n sampleRate: VoiceMessageConfig.DEFAULT.RECORDER.SAMPLE_RATE,\n bitRate: VoiceMessageConfig.DEFAULT.RECORDER.BIT_RATE,\n audioChannels: VoiceMessageConfig.DEFAULT.RECORDER.CHANNELS,\n // encoding: mpeg4_aac\n };\n private readonly audioOptions = Platform.select({\n android: {\n AudioEncodingBitRateAndroid: this.audioSettings.bitRate,\n AudioChannelsAndroid: this.audioSettings.audioChannels,\n AudioSamplingRateAndroid: this.audioSettings.sampleRate,\n AudioEncoderAndroid: audioRecorderModule.AudioEncoderAndroidType.AAC,\n OutputFormatAndroid: audioRecorderModule.OutputFormatAndroidType.MPEG_4,\n AudioSourceAndroid: audioRecorderModule.AudioSourceAndroidType.VOICE_RECOGNITION,\n },\n ios: {\n AVEncoderBitRateKeyIOS: this.audioSettings.bitRate,\n AVNumberOfChannelsKeyIOS: this.audioSettings.audioChannels,\n AVSampleRateKeyIOS: this.audioSettings.sampleRate,\n AVFormatIDKeyIOS: audioRecorderModule.AVEncodingOption.mp4, // same with aac\n AVEncoderAudioQualityKeyIOS: audioRecorderModule.AVEncoderAudioQualityIOSType.high,\n },\n default: {},\n });\n\n constructor() {\n module.setSubscriptionDuration(0.1).catch((error) => {\n Logger.warn('[RecorderService.Native] Failed to set subscription duration', error);\n });\n module.addRecordBackListener((data) => {\n const completed = data.currentPosition >= this.options.maxDuration;\n\n if (completed) {\n this.stop().catch((error) => {\n Logger.warn('[RecorderService.Native] Failed to stop in RecordBackListener', error);\n });\n }\n if (this.state === 'recording') {\n this.recordingSubscribers.forEach((callback) => {\n callback({ currentTime: data.currentPosition, completed });\n });\n }\n });\n }\n\n private setState = (state: RecorderServiceInterface['state']) => {\n this.state = state;\n this.stateSubscribers.forEach((callback) => {\n callback(state);\n });\n };\n\n public requestPermission = async (): Promise<boolean> => {\n const permission: Permission[] | undefined = Platform.select({\n android: [permissionModule.PERMISSIONS.ANDROID.RECORD_AUDIO],\n ios: [permissionModule.PERMISSIONS.IOS.MICROPHONE],\n windows: [permissionModule.PERMISSIONS.WINDOWS.MICROPHONE],\n default: undefined,\n });\n\n if (Platform.OS === 'android' && Platform.Version <= 28) {\n permission?.push(permissionModule.PERMISSIONS.ANDROID.WRITE_EXTERNAL_STORAGE);\n }\n\n if (permission) {\n const status = await permissionModule.checkMultiple(permission);\n if (nativePermissionGranted(status)) {\n return true;\n } else {\n const status = await permissionModule.requestMultiple(permission);\n return nativePermissionGranted(status);\n }\n } else {\n return true;\n }\n };\n\n public addRecordingListener = (callback: RecordingListener): Unsubscribe => {\n this.recordingSubscribers.add(callback);\n return () => {\n this.recordingSubscribers.delete(callback);\n };\n };\n\n public addStateListener = (callback: StateListener): Unsubscribe => {\n this.stateSubscribers.add(callback);\n return () => {\n this.stateSubscribers.delete(callback);\n };\n };\n\n public record = async (uri: string): Promise<void> => {\n if (matchesOneOf(this.state, ['idle', 'completed'])) {\n try {\n this.setState('preparing');\n await module.startRecorder(uri, {\n ...this.audioOptions,\n });\n\n if (Platform.OS === 'android') {\n this._recordStartedAt = Date.now();\n }\n\n this.uri = uri;\n this.setState('recording');\n } catch (e) {\n this.setState('idle');\n throw e;\n }\n }\n };\n\n public stop = async (): Promise<void> => {\n if (matchesOneOf(this.state, ['recording'])) {\n if (Platform.OS === 'android') {\n const buffer = this._getRecorderStopSafeBuffer();\n if (buffer > 0) await sleep(buffer);\n }\n\n await module.stopRecorder();\n this.setState('completed');\n }\n };\n\n public reset = async (): Promise<void> => {\n await this.stop();\n this.uri = undefined;\n this.recordingSubscribers.clear();\n this.setState('idle');\n };\n }\n\n return new VoiceRecorder();\n};\n\nexport default createNativeRecorderService;\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_reactNative","require","_uikitUtils","_VoiceMessageConfig","_interopRequireDefault","_nativePermissionGranted","e","__esModule","default","_defineProperty","r","t","_toPropertyKey","Object","defineProperty","value","enumerable","configurable","writable","i","_toPrimitive","Symbol","toPrimitive","call","TypeError","String","Number","AudioRecorderPlayerAdapter","constructor","audioRecorderModule","module","audioOptions","Platform","select","android","AudioEncodingBitRateAndroid","VoiceMessageConfig","DEFAULT","RECORDER","BIT_RATE","AudioChannelsAndroid","CHANNELS","AudioSamplingRateAndroid","SAMPLE_RATE","AudioEncoderAndroid","AudioEncoderAndroidType","AAC","OutputFormatAndroid","OutputFormatAndroidType","MPEG_4","AudioSourceAndroid","AudioSourceAndroidType","VOICE_RECOGNITION","ios","AVEncoderBitRateKeyIOS","AVNumberOfChannelsKeyIOS","AVSampleRateKeyIOS","AVFormatIDKeyIOS","AVEncodingOption","mp4","AVEncoderAudioQualityKeyIOS","AVEncoderAudioQualityIOSType","high","setSubscriptionDuration","duration","addRecordBackListener","callback","convertRecordPath","uri","OS","split","pop","startRecorder","stopRecorder","NitroSoundOrLegacyV4Adapter","error","Logger","warn","VoiceRecorder","adapter","permissionModule","undefined","minDuration","MIN_DURATION","maxDuration","MAX_DURATION","extension","EXTENSION","Set","state","stateSubscribers","forEach","minWaitingTime","elapsedTime","Date","now","_recordStartedAt","permission","PERMISSIONS","ANDROID","RECORD_AUDIO","IOS","MICROPHONE","windows","WINDOWS","Version","push","WRITE_EXTERNAL_STORAGE","status","checkMultiple","nativePermissionGranted","requestMultiple","recordingSubscribers","add","delete","matchesOneOf","setState","_stopping","buffer","getRecorderStopSafeBuffer","sleep","stop","clear","initialize","setDurationResult","Promise","catch","data","completed","currentPosition","options","currentTime","createNativeRecorderService","modules","isNitroSoundOrLegacyV4Module","isNitroSound","createSound","isLegacyV4","getHybridObject","_default","exports"],"sources":["createRecorderService.native.tsx"],"sourcesContent":["import { Platform } from 'react-native';\nimport type * as LegacyModule from 'react-native-audio-recorder-player';\nimport type * as NitroSoundOrLegacyV4Module from 'react-native-nitro-sound';\nimport * as Permissions from 'react-native-permissions';\nimport { Permission } from 'react-native-permissions/src/types';\n\nimport { Logger, matchesOneOf, sleep } from '@sendbird/uikit-utils';\n\nimport VoiceMessageConfig from '../libs/VoiceMessageConfig';\nimport nativePermissionGranted from '../utils/nativePermissionGranted';\nimport type { RecorderServiceInterface, Unsubscribe } from './types';\n\nexport type AudioRecorderModule = typeof LegacyModule | typeof NitroSoundOrLegacyV4Module;\n\ntype RecordingListener = Parameters<RecorderServiceInterface['addRecordingListener']>[number];\ntype StateListener = Parameters<RecorderServiceInterface['addStateListener']>[number];\ntype Modules = {\n audioRecorderModule: AudioRecorderModule;\n permissionModule: typeof Permissions;\n};\n\ninterface RecordBackData {\n currentPosition: number;\n duration?: number;\n}\n\ninterface RecorderModuleAdapter {\n setSubscriptionDuration(duration: number): Promise<void> | void;\n addRecordBackListener(callback: (data: RecordBackData) => void): void;\n convertRecordPath(uri: string): string;\n startRecorder(uri: string): Promise<void>;\n stopRecorder(): Promise<void>;\n}\n\nclass AudioRecorderPlayerAdapter implements RecorderModuleAdapter {\n private module: InstanceType<typeof LegacyModule.default>;\n private readonly audioOptions;\n\n constructor(audioRecorderModule: typeof LegacyModule) {\n this.module = new audioRecorderModule.default();\n\n this.audioOptions = Platform.select({\n android: {\n AudioEncodingBitRateAndroid: VoiceMessageConfig.DEFAULT.RECORDER.BIT_RATE,\n AudioChannelsAndroid: VoiceMessageConfig.DEFAULT.RECORDER.CHANNELS,\n AudioSamplingRateAndroid: VoiceMessageConfig.DEFAULT.RECORDER.SAMPLE_RATE,\n AudioEncoderAndroid: audioRecorderModule.AudioEncoderAndroidType.AAC,\n OutputFormatAndroid: audioRecorderModule.OutputFormatAndroidType.MPEG_4,\n AudioSourceAndroid: audioRecorderModule.AudioSourceAndroidType.VOICE_RECOGNITION,\n },\n ios: {\n AVEncoderBitRateKeyIOS: VoiceMessageConfig.DEFAULT.RECORDER.BIT_RATE,\n AVNumberOfChannelsKeyIOS: VoiceMessageConfig.DEFAULT.RECORDER.CHANNELS,\n AVSampleRateKeyIOS: VoiceMessageConfig.DEFAULT.RECORDER.SAMPLE_RATE,\n AVFormatIDKeyIOS: audioRecorderModule.AVEncodingOption.mp4, // same with aac\n AVEncoderAudioQualityKeyIOS: audioRecorderModule.AVEncoderAudioQualityIOSType.high,\n },\n default: {},\n });\n }\n\n async setSubscriptionDuration(duration: number): Promise<void> {\n await this.module.setSubscriptionDuration(duration);\n }\n\n addRecordBackListener(callback: (data: RecordBackData) => void): void {\n this.module.addRecordBackListener(callback);\n }\n\n convertRecordPath(uri: string): string {\n return Platform.OS === 'ios' ? uri.split('/').pop() || uri : uri;\n }\n\n async startRecorder(uri: string): Promise<void> {\n await this.module.startRecorder(uri, this.audioOptions as Parameters<typeof this.module.startRecorder>[1]);\n }\n\n async stopRecorder(): Promise<void> {\n await this.module.stopRecorder();\n }\n}\n\nclass NitroSoundOrLegacyV4Adapter implements RecorderModuleAdapter {\n private module;\n private readonly audioOptions;\n\n constructor(audioRecorderModule: typeof NitroSoundOrLegacyV4Module) {\n this.module = audioRecorderModule.default;\n this.audioOptions = Platform.select({\n android: {\n AudioEncodingBitRateAndroid: VoiceMessageConfig.DEFAULT.RECORDER.BIT_RATE,\n AudioChannelsAndroid: VoiceMessageConfig.DEFAULT.RECORDER.CHANNELS,\n AudioSamplingRateAndroid: VoiceMessageConfig.DEFAULT.RECORDER.SAMPLE_RATE,\n AudioEncoderAndroid: audioRecorderModule.AudioEncoderAndroidType.AAC,\n OutputFormatAndroid: audioRecorderModule.OutputFormatAndroidType.MPEG_4,\n AudioSourceAndroid: audioRecorderModule.AudioSourceAndroidType.VOICE_RECOGNITION,\n },\n ios: {\n AVEncoderBitRateKeyIOS: VoiceMessageConfig.DEFAULT.RECORDER.BIT_RATE,\n AVNumberOfChannelsKeyIOS: VoiceMessageConfig.DEFAULT.RECORDER.CHANNELS,\n AVSampleRateKeyIOS: VoiceMessageConfig.DEFAULT.RECORDER.SAMPLE_RATE,\n AVFormatIDKeyIOS: 'mp4', // same with aac\n AVEncoderAudioQualityKeyIOS: audioRecorderModule.AVEncoderAudioQualityIOSType.high,\n },\n default: {},\n });\n }\n\n setSubscriptionDuration(duration: number): void {\n try {\n this.module.setSubscriptionDuration(duration);\n } catch (error) {\n Logger.warn('[RecorderService.Native] Failed to set subscription duration', error);\n }\n }\n\n addRecordBackListener(callback: (data: RecordBackData) => void): void {\n this.module.addRecordBackListener(callback);\n }\n\n convertRecordPath(uri: string): string {\n return uri;\n }\n\n async startRecorder(uri: string): Promise<void> {\n await this.module.startRecorder(uri, this.audioOptions as Parameters<typeof this.module.startRecorder>[1]);\n }\n\n async stopRecorder(): Promise<void> {\n await this.module.stopRecorder();\n }\n}\n\nclass VoiceRecorder implements RecorderServiceInterface {\n public uri: RecorderServiceInterface['uri'] = undefined;\n public state: RecorderServiceInterface['state'] = 'idle';\n public options: RecorderServiceInterface['options'] = {\n minDuration: VoiceMessageConfig.DEFAULT.RECORDER.MIN_DURATION,\n maxDuration: VoiceMessageConfig.DEFAULT.RECORDER.MAX_DURATION,\n extension: VoiceMessageConfig.DEFAULT.RECORDER.EXTENSION,\n };\n\n private _recordStartedAt = 0;\n private _stopping = false;\n private readonly recordingSubscribers = new Set<RecordingListener>();\n private readonly stateSubscribers = new Set<StateListener>();\n\n constructor(private readonly adapter: RecorderModuleAdapter, private readonly permissionModule: typeof Permissions) {\n this.initialize();\n }\n\n private initialize(): void {\n const setDurationResult = this.adapter.setSubscriptionDuration(0.1);\n if (setDurationResult instanceof Promise) {\n setDurationResult.catch((error) => {\n Logger.warn('[RecorderService.Native] Failed to set subscription duration', error);\n });\n }\n\n this.adapter.addRecordBackListener((data) => {\n const completed = data.currentPosition >= this.options.maxDuration;\n\n if (completed) {\n this.stop().catch((error) => {\n Logger.warn('[RecorderService.Native] Failed to stop in RecordBackListener', error);\n });\n }\n if (this.state === 'recording') {\n this.recordingSubscribers.forEach((callback) => {\n callback({ currentTime: data.currentPosition, completed });\n });\n }\n });\n }\n\n private setState = (state: RecorderServiceInterface['state']): void => {\n this.state = state;\n this.stateSubscribers.forEach((callback) => {\n callback(state);\n });\n };\n\n private getRecorderStopSafeBuffer = (): number => {\n const minWaitingTime = 500;\n const elapsedTime = Date.now() - this._recordStartedAt;\n if (elapsedTime > minWaitingTime) return 0;\n else return minWaitingTime - elapsedTime;\n };\n\n public requestPermission = async (): Promise<boolean> => {\n const permission: Permission[] | undefined = Platform.select({\n android: [this.permissionModule.PERMISSIONS.ANDROID.RECORD_AUDIO],\n ios: [this.permissionModule.PERMISSIONS.IOS.MICROPHONE],\n windows: [this.permissionModule.PERMISSIONS.WINDOWS.MICROPHONE],\n default: undefined,\n });\n\n if (Platform.OS === 'android' && Platform.Version <= 28) {\n permission?.push(this.permissionModule.PERMISSIONS.ANDROID.WRITE_EXTERNAL_STORAGE);\n }\n\n if (permission) {\n const status = await this.permissionModule.checkMultiple(permission);\n if (nativePermissionGranted(status)) {\n return true;\n } else {\n const status = await this.permissionModule.requestMultiple(permission);\n return nativePermissionGranted(status);\n }\n } else {\n return true;\n }\n };\n\n public addRecordingListener = (callback: RecordingListener): Unsubscribe => {\n this.recordingSubscribers.add(callback);\n return () => {\n this.recordingSubscribers.delete(callback);\n };\n };\n\n public addStateListener = (callback: StateListener): Unsubscribe => {\n this.stateSubscribers.add(callback);\n return () => {\n this.stateSubscribers.delete(callback);\n };\n };\n\n public record = async (uri: string): Promise<void> => {\n if (matchesOneOf(this.state, ['idle', 'completed'])) {\n try {\n this.setState('preparing');\n await this.adapter.startRecorder(uri);\n\n if (Platform.OS === 'android') {\n this._recordStartedAt = Date.now();\n }\n\n this.uri = uri;\n this.setState('recording');\n } catch (e) {\n this.setState('idle');\n throw e;\n }\n }\n };\n\n public stop = async (): Promise<void> => {\n if (matchesOneOf(this.state, ['recording']) && !this._stopping) {\n this._stopping = true;\n try {\n if (Platform.OS === 'android') {\n const buffer = this.getRecorderStopSafeBuffer();\n if (buffer > 0) await sleep(buffer);\n }\n\n await this.adapter.stopRecorder();\n this.setState('completed');\n } catch (error) {\n Logger.error('[RecorderService.Native] Failed to stop recorder', error);\n throw error;\n } finally {\n this._stopping = false;\n }\n }\n };\n\n public reset = async (): Promise<void> => {\n await this.stop();\n this.uri = undefined;\n this.recordingSubscribers.clear();\n this.setState('idle');\n };\n\n public convertRecordPath = (uri: string): string => {\n return this.adapter.convertRecordPath(uri);\n };\n}\n\nconst createNativeRecorderService = (modules: Modules): RecorderServiceInterface => {\n const adapter = isNitroSoundOrLegacyV4Module(modules.audioRecorderModule)\n ? new NitroSoundOrLegacyV4Adapter(modules.audioRecorderModule)\n : new AudioRecorderPlayerAdapter(modules.audioRecorderModule as typeof LegacyModule);\n\n return new VoiceRecorder(adapter, modules.permissionModule);\n};\n\nfunction isNitroSoundOrLegacyV4Module(module: AudioRecorderModule): module is typeof NitroSoundOrLegacyV4Module {\n const isNitroSound = 'createSound' in module && typeof module.createSound === 'function';\n const isLegacyV4 =\n 'default' in module && 'getHybridObject' in module.default && typeof module.default.getHybridObject === 'function';\n if (isLegacyV4) {\n Logger.warn('react-native-audio-recorder-player is deprecated. Please use react-native-nitro-sound instead.');\n }\n return isNitroSound || isLegacyV4;\n}\n\nexport default createNativeRecorderService;\n"],"mappings":"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","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["types.ts"],"sourcesContent":["import type { ReactNode } from 'react';\n\nimport type SBUError from '../libs/SBUError';\n\nexport type Unsubscribe = () => void | undefined;\nexport type DownloadedPath = string;\nexport type FilePickerResponse = FileType | null;\n\n/**\n * We are following the file format of react-native FormData\n * @see https://github.com/facebook/react-native/blob/main/packages/react-native/Libraries/Network/FormData.js#L37-L41\n * */\nexport type FileType = { name: string; uri: string; size: number; type: string };\n\n// ---------- NotificationService ---------- //\nexport interface NotificationServiceInterface {\n hasPushPermission(): Promise<boolean>;\n requestPushPermission(): Promise<boolean>;\n\n getAPNSToken(): Promise<string | null>;\n getFCMToken(): Promise<string | null>;\n onTokenRefresh(handler: (token: string) => void): Unsubscribe;\n}\n\n// ---------- ClipboardService ---------- //\nexport interface ClipboardServiceInterface {\n setString(text: string): void;\n getString(): Promise<string>;\n}\n\n// ---------- FileService ---------- //\nexport interface FileServiceInterface extends FilePickerServiceInterface, FileSystemServiceInterface {}\n\nexport interface OpenResultListener {\n onOpenFailure?: (error: SBUError, originError?: unknown) => void;\n}\nexport interface OpenMediaLibraryOptions extends OpenResultListener {\n selectionLimit?: number;\n mediaType?: 'photo' | 'video' | 'all';\n}\nexport interface OpenCameraOptions extends OpenResultListener {\n cameraType?: 'front' | 'back';\n mediaType?: 'photo' | 'video' | 'all';\n}\nexport type OpenDocumentOptions = OpenResultListener;\nexport interface SaveOptions {\n fileUrl: string;\n fileName: string;\n fileType?: string | null;\n}\n\nexport interface FilePickerServiceInterface {\n openMediaLibrary(options?: OpenMediaLibraryOptions): Promise<null | FilePickerResponse[]>;\n openCamera(options?: OpenCameraOptions): Promise<FilePickerResponse>;\n openDocument(options?: OpenDocumentOptions): Promise<FilePickerResponse>;\n}\n\nexport interface FileSystemServiceInterface {\n // NOTE: On iOS, You can access the downloaded files by providing options below to info.plist\n // - Supports opening documents in place\n // - Application supports iTunes file sharing\n save(options?: SaveOptions): Promise<DownloadedPath | null>;\n createRecordFilePath(customExtension?: string): { recordFilePath: string; uri: string };\n}\n\n// ---------- MediaService ---------- //\nexport type VideoProps = {\n source: { uri: string } | number;\n resizeMode?: 'cover' | 'contain' | 'stretch';\n onLoad?: () => void;\n};\n\nexport type GetVideoThumbnailOptions = {\n url: string;\n timeMills?: number;\n quality?: number;\n};\nexport type GetVideoThumbnailResult = Promise<{ path: string } | null>;\n\nexport type CompressImageOptions = {\n /**\n * A uri of image file to compress\n * */\n uri: string;\n\n /**\n * A resize width, apply only to downscale\n * */\n maxWidth?: number;\n\n /**\n * A resize height, apply only to downscale\n * */\n maxHeight?: number;\n\n /**\n * A value in range 0.0 - 1.0 specifying compression level of the result image.\n * 1 means highest quality and 0 the lowest quality.\n * */\n compressionRate?: number;\n};\nexport type CompressImageResult = Promise<{ uri: string; size: number } | null>;\n\nexport interface MediaServiceInterface {\n VideoComponent<Props = {}>(props: VideoProps & Props): ReactNode;\n getVideoThumbnail(options: GetVideoThumbnailOptions): GetVideoThumbnailResult;\n compressImage(options: CompressImageOptions): CompressImageResult;\n}\n\n// ---------- PlayerService ---------- //\nexport interface PlayerServiceInterface {\n uri?: string;\n state: 'idle' | 'preparing' | 'playing' | 'paused' | 'stopped';\n\n /**\n * Check and request permission for the player.\n * */\n requestPermission(): Promise<boolean>;\n\n /**\n * Add a playback listener.\n * */\n addPlaybackListener(\n callback: (params: { currentTime: number; duration: number; stopped: boolean }) => void,\n ): Unsubscribe;\n\n /**\n * Add a state listener.\n * */\n addStateListener(callback: (state: PlayerServiceInterface['state']) => void): Unsubscribe;\n\n /**\n * State transition:\n * [idle, stopped] to [playing] - start from the beginning\n * [paused] to [playing] - resume\n * */\n play(uri: string): Promise<void>;\n\n /**\n * State transition:\n * [playing] to [paused]\n * */\n pause(): Promise<void>;\n\n /**\n * State transition:\n * [preparing, playing, paused] to [stop]\n * */\n stop(): Promise<void>;\n\n /**\n * State transition:\n * [*] to [idle]\n * */\n reset(): Promise<void>;\n\n /**\n * Seek time, only available when the state is [playing, paused].\n * */\n seek(time: number): Promise<void>;\n}\n\n// ---------- RecorderService ---------- //\nexport interface RecorderOptions {\n /**\n * Minimum recording duration (milliseconds).\n * */\n minDuration: number;\n\n /**\n * Maximum recording duration (milliseconds).\n * */\n maxDuration: number;\n\n /**\n * File extension for recorded audio file\n * */\n extension: string;\n}\n\nexport interface RecorderServiceInterface {\n uri?: string;\n options: RecorderOptions;\n state: 'idle' | 'preparing' | 'recording' | 'completed';\n\n /**\n * Check and request permission for the recorder.\n * */\n requestPermission(): Promise<boolean>;\n\n /**\n * Add recording listener.\n * */\n addRecordingListener(callback: (params: { currentTime: number; completed: boolean }) => void): Unsubscribe;\n\n /**\n * Add state listener.\n * */\n addStateListener(callback: (state: RecorderServiceInterface['state']) => void): Unsubscribe;\n\n /**\n * State transition:\n * [idle, completed] to [recording]\n * */\n record(uri?: string): Promise<void>;\n\n /**\n * State transition:\n * [recording] to [completed]\n * */\n stop(): Promise<void>;\n\n /**\n * State transition:\n * [*] to [idle]\n * */\n reset(): Promise<void>;\n}\n"],"mappings":"","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["types.ts"],"sourcesContent":["import type { ReactNode } from 'react';\n\nimport type SBUError from '../libs/SBUError';\n\nexport type Unsubscribe = () => void | undefined;\nexport type DownloadedPath = string;\nexport type FilePickerResponse = FileType | null;\n\n/**\n * We are following the file format of react-native FormData\n * @see https://github.com/facebook/react-native/blob/main/packages/react-native/Libraries/Network/FormData.js#L37-L41\n * */\nexport type FileType = { name: string; uri: string; size: number; type: string };\n\n// ---------- NotificationService ---------- //\nexport interface NotificationServiceInterface {\n hasPushPermission(): Promise<boolean>;\n requestPushPermission(): Promise<boolean>;\n\n getAPNSToken(): Promise<string | null>;\n getFCMToken(): Promise<string | null>;\n onTokenRefresh(handler: (token: string) => void): Unsubscribe;\n}\n\n// ---------- ClipboardService ---------- //\nexport interface ClipboardServiceInterface {\n setString(text: string): void;\n getString(): Promise<string>;\n}\n\n// ---------- FileService ---------- //\nexport interface FileServiceInterface extends FilePickerServiceInterface, FileSystemServiceInterface {}\n\nexport interface OpenResultListener {\n onOpenFailure?: (error: SBUError, originError?: unknown) => void;\n}\nexport interface OpenMediaLibraryOptions extends OpenResultListener {\n selectionLimit?: number;\n mediaType?: 'photo' | 'video' | 'all';\n}\nexport interface OpenCameraOptions extends OpenResultListener {\n cameraType?: 'front' | 'back';\n mediaType?: 'photo' | 'video' | 'all';\n}\nexport type OpenDocumentOptions = OpenResultListener;\nexport interface SaveOptions {\n fileUrl: string;\n fileName: string;\n fileType?: string | null;\n}\n\nexport interface FilePickerServiceInterface {\n openMediaLibrary(options?: OpenMediaLibraryOptions): Promise<null | FilePickerResponse[]>;\n openCamera(options?: OpenCameraOptions): Promise<FilePickerResponse>;\n openDocument(options?: OpenDocumentOptions): Promise<FilePickerResponse>;\n}\n\nexport interface FileSystemServiceInterface {\n // NOTE: On iOS, You can access the downloaded files by providing options below to info.plist\n // - Supports opening documents in place\n // - Application supports iTunes file sharing\n save(options?: SaveOptions): Promise<DownloadedPath | null>;\n createRecordFilePath(customExtension?: string): { recordFilePath: string; uri: string };\n}\n\n// ---------- MediaService ---------- //\nexport type VideoProps = {\n source: { uri: string } | number;\n resizeMode?: 'cover' | 'contain' | 'stretch';\n onLoad?: () => void;\n};\n\nexport type GetVideoThumbnailOptions = {\n url: string;\n timeMills?: number;\n quality?: number;\n};\nexport type GetVideoThumbnailResult = Promise<{ path: string } | null>;\n\nexport type CompressImageOptions = {\n /**\n * A uri of image file to compress\n * */\n uri: string;\n\n /**\n * A resize width, apply only to downscale\n * */\n maxWidth?: number;\n\n /**\n * A resize height, apply only to downscale\n * */\n maxHeight?: number;\n\n /**\n * A value in range 0.0 - 1.0 specifying compression level of the result image.\n * 1 means highest quality and 0 the lowest quality.\n * */\n compressionRate?: number;\n};\nexport type CompressImageResult = Promise<{ uri: string; size: number } | null>;\n\nexport interface MediaServiceInterface {\n VideoComponent<Props = {}>(props: VideoProps & Props): ReactNode;\n getVideoThumbnail(options: GetVideoThumbnailOptions): GetVideoThumbnailResult;\n compressImage(options: CompressImageOptions): CompressImageResult;\n}\n\n// ---------- PlayerService ---------- //\nexport interface PlayerServiceInterface {\n uri?: string;\n state: 'idle' | 'preparing' | 'playing' | 'paused' | 'stopped';\n\n /**\n * Check and request permission for the player.\n * */\n requestPermission(): Promise<boolean>;\n\n /**\n * Add a playback listener.\n * */\n addPlaybackListener(\n callback: (params: { currentTime: number; duration: number; stopped: boolean }) => void,\n ): Unsubscribe;\n\n /**\n * Add a state listener.\n * */\n addStateListener(callback: (state: PlayerServiceInterface['state']) => void): Unsubscribe;\n\n /**\n * State transition:\n * [idle, stopped] to [playing] - start from the beginning\n * [paused] to [playing] - resume\n * */\n play(uri: string): Promise<void>;\n\n /**\n * State transition:\n * [playing] to [paused]\n * */\n pause(): Promise<void>;\n\n /**\n * State transition:\n * [preparing, playing, paused] to [stop]\n * */\n stop(): Promise<void>;\n\n /**\n * State transition:\n * [*] to [idle]\n * */\n reset(): Promise<void>;\n\n /**\n * Seek time, only available when the state is [playing, paused].\n * */\n seek(time: number): Promise<void>;\n}\n\n// ---------- RecorderService ---------- //\nexport interface RecorderOptions {\n /**\n * Minimum recording duration (milliseconds).\n * */\n minDuration: number;\n\n /**\n * Maximum recording duration (milliseconds).\n * */\n maxDuration: number;\n\n /**\n * File extension for recorded audio file\n * */\n extension: string;\n}\n\nexport interface RecorderServiceInterface {\n uri?: string;\n options: RecorderOptions;\n state: 'idle' | 'preparing' | 'recording' | 'completed';\n\n /**\n * Check and request permission for the recorder.\n * */\n requestPermission(): Promise<boolean>;\n\n /**\n * Add recording listener.\n * */\n addRecordingListener(callback: (params: { currentTime: number; completed: boolean }) => void): Unsubscribe;\n\n /**\n * Add state listener.\n * */\n addStateListener(callback: (state: RecorderServiceInterface['state']) => void): Unsubscribe;\n\n /**\n * State transition:\n * [idle, completed] to [recording]\n * */\n record(uri?: string): Promise<void>;\n\n /**\n * State transition:\n * [recording] to [completed]\n * */\n stop(): Promise<void>;\n\n /**\n * State transition:\n * [*] to [idle]\n * */\n reset(): Promise<void>;\n\n /**\n * Get the record path processed for the specific platform and adapter.\n * */\n convertRecordPath(uri: string): string;\n}\n"],"mappings":"","ignoreList":[]}
@@ -79,6 +79,29 @@ const expoBackwardUtils = {
79
79
  }
80
80
  }
81
81
  },
82
+ expoAV: {
83
+ isLegacyAVModule(module) {
84
+ try {
85
+ return 'Video' in module && 'Audio' in module && typeof module.Video === 'function';
86
+ } catch {
87
+ return false;
88
+ }
89
+ },
90
+ isAudioModule(module) {
91
+ try {
92
+ return 'useAudioRecorder' in module && typeof module.useAudioRecorder === 'function';
93
+ } catch {
94
+ return false;
95
+ }
96
+ },
97
+ isVideoModule(module) {
98
+ try {
99
+ return 'VideoView' in module && 'useVideoPlayer' in module && typeof module.useVideoPlayer === 'function';
100
+ } catch {
101
+ return false;
102
+ }
103
+ }
104
+ },
82
105
  toFileSize(info) {
83
106
  if ('size' in info) {
84
107
  return info.size;
@@ -1 +1 @@
1
- {"version":3,"names":["_normalizeFile","_interopRequireDefault","require","e","__esModule","default","expoBackwardUtils","imagePicker","isCanceled","result","canceled","cancelled","toFilePickerResponses","fsModule","assets","promises","map","fileName","name","fileSize","size","type","uri","normalizeFile","Promise","all","fileInfo","getInfoAsync","response","toFileSize","documentPicker","mimeType","info","_default","exports"],"sources":["expoBackwardUtils.ts"],"sourcesContent":["import type * as ExpoDocumentPicker from 'expo-document-picker';\nimport type * as ExpoFs from 'expo-file-system';\nimport type * as ExpoImagePicker from 'expo-image-picker';\n\nimport type { FilePickerResponse } from '../platform/types';\nimport normalizeFile from './normalizeFile';\n\nconst expoBackwardUtils = {\n imagePicker: {\n isCanceled(result: ExpoImagePicker.ImagePickerResult) {\n // @ts-expect-error backward compatibility\n return result.canceled ?? result.cancelled;\n },\n async toFilePickerResponses(\n result: ExpoImagePicker.ImagePickerResult,\n fsModule: typeof ExpoFs,\n ): Promise<FilePickerResponse[]> {\n if (result.assets) {\n const assets = result.assets || [];\n const promises = assets.map(({ fileName: name, fileSize: size, type, uri }) =>\n normalizeFile({ uri, size, name, type }),\n );\n\n return Promise.all(promises);\n } else if ('uri' in result && typeof result.uri === 'string') {\n const fileInfo = await fsModule.getInfoAsync(result.uri);\n const response = await normalizeFile({ uri: result.uri, size: expoBackwardUtils.toFileSize(fileInfo) });\n return [response];\n } else {\n return [];\n }\n },\n },\n documentPicker: {\n isCanceled(result: ExpoDocumentPicker.DocumentPickerResult) {\n // @ts-expect-error backward compatibility\n return result.canceled ?? result.type === 'cancel';\n },\n async toFilePickerResponses(result: ExpoDocumentPicker.DocumentPickerResult): Promise<FilePickerResponse[]> {\n if (result.assets) {\n const assets = result.assets || [];\n const promises = assets.map(({ name, size, mimeType, uri }) =>\n normalizeFile({ uri, size, name, type: mimeType }),\n );\n\n return Promise.all(promises);\n } else if ('uri' in result && typeof result.uri === 'string') {\n // @ts-expect-error backward compatibility\n const { mimeType, uri, size, name } = result;\n const response = await normalizeFile({ uri, size, name, type: mimeType });\n\n return [response];\n } else {\n return [];\n }\n },\n },\n toFileSize(info: ExpoFs.FileInfo) {\n if ('size' in info) {\n return info.size;\n } else {\n return 0;\n }\n },\n};\n\nexport default expoBackwardUtils;\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_normalizeFile","_interopRequireDefault","require","e","__esModule","default","expoBackwardUtils","imagePicker","isCanceled","result","canceled","cancelled","toFilePickerResponses","fsModule","assets","promises","map","fileName","name","fileSize","size","type","uri","normalizeFile","Promise","all","fileInfo","getInfoAsync","response","toFileSize","documentPicker","mimeType","expoAV","isLegacyAVModule","module","Video","isAudioModule","useAudioRecorder","isVideoModule","useVideoPlayer","info","_default","exports"],"sources":["expoBackwardUtils.ts"],"sourcesContent":["import type * as ExpoAudio from 'expo-audio';\nimport type * as ExpoAV from 'expo-av';\nimport type * as ExpoDocumentPicker from 'expo-document-picker';\nimport type * as ExpoFs from 'expo-file-system';\nimport type * as ExpoImagePicker from 'expo-image-picker';\nimport type * as ExpoVideo from 'expo-video';\n\nimport type { FilePickerResponse } from '../platform/types';\nimport normalizeFile from './normalizeFile';\n\nconst expoBackwardUtils = {\n imagePicker: {\n isCanceled(result: ExpoImagePicker.ImagePickerResult) {\n // @ts-expect-error backward compatibility\n return result.canceled ?? result.cancelled;\n },\n async toFilePickerResponses(\n result: ExpoImagePicker.ImagePickerResult,\n fsModule: typeof ExpoFs,\n ): Promise<FilePickerResponse[]> {\n if (result.assets) {\n const assets = result.assets || [];\n const promises = assets.map(({ fileName: name, fileSize: size, type, uri }) =>\n normalizeFile({ uri, size, name, type }),\n );\n\n return Promise.all(promises);\n } else if ('uri' in result && typeof result.uri === 'string') {\n const fileInfo = await fsModule.getInfoAsync(result.uri);\n const response = await normalizeFile({ uri: result.uri, size: expoBackwardUtils.toFileSize(fileInfo) });\n return [response];\n } else {\n return [];\n }\n },\n },\n documentPicker: {\n isCanceled(result: ExpoDocumentPicker.DocumentPickerResult) {\n // @ts-expect-error backward compatibility\n return result.canceled ?? result.type === 'cancel';\n },\n async toFilePickerResponses(result: ExpoDocumentPicker.DocumentPickerResult): Promise<FilePickerResponse[]> {\n if (result.assets) {\n const assets = result.assets || [];\n const promises = assets.map(({ name, size, mimeType, uri }) =>\n normalizeFile({ uri, size, name, type: mimeType }),\n );\n\n return Promise.all(promises);\n } else if ('uri' in result && typeof result.uri === 'string') {\n // @ts-expect-error backward compatibility\n const { mimeType, uri, size, name } = result;\n const response = await normalizeFile({ uri, size, name, type: mimeType });\n\n return [response];\n } else {\n return [];\n }\n },\n },\n expoAV: {\n isLegacyAVModule(module: ExpoAudioModule | ExpoVideoModule): module is typeof ExpoAV {\n try {\n return 'Video' in module && 'Audio' in module && typeof module.Video === 'function';\n } catch {\n return false;\n }\n },\n isAudioModule(module: ExpoAudioModule): module is typeof ExpoAudio {\n try {\n return 'useAudioRecorder' in module && typeof module.useAudioRecorder === 'function';\n } catch {\n return false;\n }\n },\n isVideoModule(module: ExpoVideoModule): module is typeof ExpoVideo {\n try {\n return 'VideoView' in module && 'useVideoPlayer' in module && typeof module.useVideoPlayer === 'function';\n } catch {\n return false;\n }\n },\n },\n toFileSize(info: ExpoFs.FileInfo) {\n if ('size' in info) {\n return info.size;\n } else {\n return 0;\n }\n },\n};\n\nexport type ExpoAudioModule = typeof ExpoAV | typeof ExpoAudio;\nexport type ExpoVideoModule = typeof ExpoAV | typeof ExpoVideo;\n\nexport default expoBackwardUtils;\n"],"mappings":"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","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"names":["expoPermissionGranted","stats","limitedCallback","every","res","accessPrivileges","granted","status","_res$ios","ios","_default","exports","default"],"sources":["expoPermissionGranted.ts"],"sourcesContent":["import type { NotificationPermissionsStatus } from 'expo-notifications';\n\nexport interface ExpoPermissionResponse {\n canAskAgain: boolean;\n granted: boolean;\n status: 'denied' | 'granted' | 'undetermined';\n}\n\nexport interface ExpoMediaLibraryPermissionResponse extends ExpoPermissionResponse {\n accessPrivileges?: 'all' | 'limited' | 'none';\n}\nexport interface ExpoPushPermissionResponse extends ExpoPermissionResponse, NotificationPermissionsStatus {}\n\nconst expoPermissionGranted = (\n stats: Array<ExpoMediaLibraryPermissionResponse | ExpoPushPermissionResponse | ExpoPermissionResponse>,\n limitedCallback?: () => void,\n) => {\n return stats.every((res) => {\n if ('accessPrivileges' in res) {\n if (res.accessPrivileges === 'limited') limitedCallback?.();\n return (\n res.granted || res.status === 'granted' || res.accessPrivileges === 'all' || res.accessPrivileges === 'limited'\n );\n }\n if ('ios' in res) {\n // NOT_DETERMINED = 0,\n // DENIED = 1,\n // AUTHORIZED = 2,\n // PROVISIONAL = 3,\n // EPHEMERAL = 4,\n return (\n res.granted || res.status === 'granted' || (res.ios?.status && (res.ios.status === 2 || res.ios.status === 3))\n );\n }\n return res.granted || res.status === 'granted';\n });\n};\n\nexport default expoPermissionGranted;\n"],"mappings":";;;;;;AAaA,MAAMA,qBAAqB,GAAGA,CAC5BC,KAAsG,EACtGC,eAA4B,KACzB;EACH,OAAOD,KAAK,CAACE,KAAK,CAAEC,GAAG,IAAK;IAC1B,IAAI,kBAAkB,IAAIA,GAAG,EAAE;MAC7B,IAAIA,GAAG,CAACC,gBAAgB,KAAK,SAAS,EAAEH,eAAe,aAAfA,eAAe,eAAfA,eAAe,CAAG,CAAC;MAC3D,OACEE,GAAG,CAACE,OAAO,IAAIF,GAAG,CAACG,MAAM,KAAK,SAAS,IAAIH,GAAG,CAACC,gBAAgB,KAAK,KAAK,IAAID,GAAG,CAACC,gBAAgB,KAAK,SAAS;IAEnH;IACA,IAAI,KAAK,IAAID,GAAG,EAAE;MAAA,IAAAI,QAAA;MAChB;MACA;MACA;MACA;MACA;MACA,OACEJ,GAAG,CAACE,OAAO,IAAIF,GAAG,CAACG,MAAM,KAAK,SAAS,IAAK,EAAAC,QAAA,GAAAJ,GAAG,CAACK,GAAG,cAAAD,QAAA,uBAAPA,QAAA,CAASD,MAAM,MAAKH,GAAG,CAACK,GAAG,CAACF,MAAM,KAAK,CAAC,IAAIH,GAAG,CAACK,GAAG,CAACF,MAAM,KAAK,CAAC,CAAE;IAElH;IACA,OAAOH,GAAG,CAACE,OAAO,IAAIF,GAAG,CAACG,MAAM,KAAK,SAAS;EAChD,CAAC,CAAC;AACJ,CAAC;AAAC,IAAAG,QAAA,GAAAC,OAAA,CAAAC,OAAA,GAEaZ,qBAAqB","ignoreList":[]}
1
+ {"version":3,"names":["expoPermissionGranted","stats","limitedCallback","every","res","accessPrivileges","granted","status","_res$ios","ios","_default","exports","default"],"sources":["expoPermissionGranted.ts"],"sourcesContent":["import type { NotificationPermissionsStatus } from 'expo-notifications';\n\nexport interface ExpoPermissionResponse {\n canAskAgain: boolean;\n granted: boolean;\n status: 'denied' | 'granted' | 'undetermined';\n}\n\nexport interface ExpoMediaLibraryPermissionResponse extends ExpoPermissionResponse {\n accessPrivileges?: 'all' | 'limited' | 'none';\n}\nexport interface ExpoPushPermissionResponse\n extends Omit<ExpoPermissionResponse, 'status'>,\n NotificationPermissionsStatus {}\n\nconst expoPermissionGranted = (\n stats: Array<ExpoMediaLibraryPermissionResponse | ExpoPushPermissionResponse | ExpoPermissionResponse>,\n limitedCallback?: () => void,\n) => {\n return stats.every((res) => {\n if ('accessPrivileges' in res) {\n if (res.accessPrivileges === 'limited') limitedCallback?.();\n return (\n res.granted || res.status === 'granted' || res.accessPrivileges === 'all' || res.accessPrivileges === 'limited'\n );\n }\n if ('ios' in res) {\n // NOT_DETERMINED = 0,\n // DENIED = 1,\n // AUTHORIZED = 2,\n // PROVISIONAL = 3,\n // EPHEMERAL = 4,\n return (\n res.granted || res.status === 'granted' || (res.ios?.status && (res.ios.status === 2 || res.ios.status === 3))\n );\n }\n return res.granted || res.status === 'granted';\n });\n};\n\nexport default expoPermissionGranted;\n"],"mappings":";;;;;;AAeA,MAAMA,qBAAqB,GAAGA,CAC5BC,KAAsG,EACtGC,eAA4B,KACzB;EACH,OAAOD,KAAK,CAACE,KAAK,CAAEC,GAAG,IAAK;IAC1B,IAAI,kBAAkB,IAAIA,GAAG,EAAE;MAC7B,IAAIA,GAAG,CAACC,gBAAgB,KAAK,SAAS,EAAEH,eAAe,aAAfA,eAAe,eAAfA,eAAe,CAAG,CAAC;MAC3D,OACEE,GAAG,CAACE,OAAO,IAAIF,GAAG,CAACG,MAAM,KAAK,SAAS,IAAIH,GAAG,CAACC,gBAAgB,KAAK,KAAK,IAAID,GAAG,CAACC,gBAAgB,KAAK,SAAS;IAEnH;IACA,IAAI,KAAK,IAAID,GAAG,EAAE;MAAA,IAAAI,QAAA;MAChB;MACA;MACA;MACA;MACA;MACA,OACEJ,GAAG,CAACE,OAAO,IAAIF,GAAG,CAACG,MAAM,KAAK,SAAS,IAAK,EAAAC,QAAA,GAAAJ,GAAG,CAACK,GAAG,cAAAD,QAAA,uBAAPA,QAAA,CAASD,MAAM,MAAKH,GAAG,CAACK,GAAG,CAACF,MAAM,KAAK,CAAC,IAAIH,GAAG,CAACK,GAAG,CAACF,MAAM,KAAK,CAAC,CAAE;IAElH;IACA,OAAOH,GAAG,CAACE,OAAO,IAAIF,GAAG,CAACG,MAAM,KAAK,SAAS;EAChD,CAAC,CAAC;AACJ,CAAC;AAAC,IAAAG,QAAA,GAAAC,OAAA,CAAAC,OAAA,GAEaZ,qBAAqB","ignoreList":[]}
@@ -4,6 +4,6 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.default = void 0;
7
- const VERSION = '3.10.3';
7
+ const VERSION = '3.11.1';
8
8
  var _default = exports.default = VERSION;
9
9
  //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["VERSION","_default","exports","default"],"sources":["version.ts"],"sourcesContent":["const VERSION = '3.10.3';\nexport default VERSION;\n"],"mappings":";;;;;;AAAA,MAAMA,OAAO,GAAG,QAAQ;AAAC,IAAAC,QAAA,GAAAC,OAAA,CAAAC,OAAA,GACVH,OAAO","ignoreList":[]}
1
+ {"version":3,"names":["VERSION","_default","exports","default"],"sources":["version.ts"],"sourcesContent":["const VERSION = '3.11.1';\nexport default VERSION;\n"],"mappings":";;;;;;AAAA,MAAMA,OAAO,GAAG,QAAQ;AAAC,IAAAC,QAAA,GAAAC,OAAA,CAAAC,OAAA,GACVH,OAAO","ignoreList":[]}
@@ -61,7 +61,7 @@ const VoiceMessageInput = ({
61
61
  break;
62
62
  }
63
63
  } catch (error) {
64
- Logger.warn('Failed to run voice message action.', state);
64
+ Logger.warn('Failed to run voice message action.', state, error);
65
65
  }
66
66
  };
67
67
  const renderActionIcon = () => {