@sendbird/uikit-react-native 3.10.3 → 3.11.0
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/README.md +2 -2
- package/lib/commonjs/components/ChannelInput/VoiceMessageInput.js +1 -1
- package/lib/commonjs/components/ChannelInput/VoiceMessageInput.js.map +1 -1
- package/lib/commonjs/components/ChannelInput/index.js +2 -25
- package/lib/commonjs/components/ChannelInput/index.js.map +1 -1
- package/lib/commonjs/hooks/useVoiceMessageInput.js +10 -2
- package/lib/commonjs/hooks/useVoiceMessageInput.js.map +1 -1
- package/lib/commonjs/platform/createFileService.native.js +1 -1
- package/lib/commonjs/platform/createFileService.native.js.map +1 -1
- package/lib/commonjs/platform/createPlayerService.native.js +191 -114
- package/lib/commonjs/platform/createPlayerService.native.js.map +1 -1
- package/lib/commonjs/platform/createRecorderService.expo.js +3 -0
- package/lib/commonjs/platform/createRecorderService.expo.js.map +1 -1
- package/lib/commonjs/platform/createRecorderService.native.js +212 -129
- package/lib/commonjs/platform/createRecorderService.native.js.map +1 -1
- package/lib/commonjs/platform/types.js.map +1 -1
- package/lib/commonjs/version.js +1 -1
- package/lib/commonjs/version.js.map +1 -1
- package/lib/module/components/ChannelInput/VoiceMessageInput.js +1 -1
- package/lib/module/components/ChannelInput/VoiceMessageInput.js.map +1 -1
- package/lib/module/components/ChannelInput/index.js +3 -26
- package/lib/module/components/ChannelInput/index.js.map +1 -1
- package/lib/module/hooks/useVoiceMessageInput.js +10 -2
- package/lib/module/hooks/useVoiceMessageInput.js.map +1 -1
- package/lib/module/platform/createFileService.native.js +1 -1
- package/lib/module/platform/createFileService.native.js.map +1 -1
- package/lib/module/platform/createPlayerService.native.js +191 -114
- package/lib/module/platform/createPlayerService.native.js.map +1 -1
- package/lib/module/platform/createRecorderService.expo.js +3 -0
- package/lib/module/platform/createRecorderService.expo.js.map +1 -1
- package/lib/module/platform/createRecorderService.native.js +212 -129
- package/lib/module/platform/createRecorderService.native.js.map +1 -1
- package/lib/module/platform/types.js.map +1 -1
- package/lib/module/version.js +1 -1
- package/lib/module/version.js.map +1 -1
- package/lib/typescript/src/containers/SendbirdUIKitContainer.d.ts +1 -1
- package/lib/typescript/src/platform/createPlayerService.native.d.ts +5 -3
- package/lib/typescript/src/platform/createRecorderService.native.d.ts +5 -3
- package/lib/typescript/src/platform/types.d.ts +4 -0
- package/lib/typescript/src/version.d.ts +1 -1
- package/package.json +18 -5
- package/src/components/ChannelInput/VoiceMessageInput.tsx +1 -1
- package/src/components/ChannelInput/index.tsx +6 -36
- package/src/hooks/useVoiceMessageInput.ts +7 -2
- package/src/platform/createFileService.native.ts +1 -1
- package/src/platform/createPlayerService.native.tsx +237 -113
- package/src/platform/createRecorderService.expo.tsx +4 -0
- package/src/platform/createRecorderService.native.tsx +240 -118
- package/src/platform/types.ts +5 -0
- package/src/version.ts +1 -1
|
@@ -3,134 +3,211 @@ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol"
|
|
|
3
3
|
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); }
|
|
4
4
|
import { Platform } from 'react-native';
|
|
5
5
|
import { Logger, matchesOneOf, sleep } from '@sendbird/uikit-utils';
|
|
6
|
-
|
|
7
|
-
audioRecorderModule
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
6
|
+
class AudioRecorderPlayerAdapter {
|
|
7
|
+
constructor(audioRecorderModule) {
|
|
8
|
+
_defineProperty(this, "module", void 0);
|
|
9
|
+
this.module = new audioRecorderModule.default();
|
|
10
|
+
}
|
|
11
|
+
async setSubscriptionDuration(duration) {
|
|
12
|
+
await this.module.setSubscriptionDuration(duration);
|
|
13
|
+
}
|
|
14
|
+
addPlayBackListener(callback) {
|
|
15
|
+
this.module.addPlayBackListener(callback);
|
|
16
|
+
}
|
|
17
|
+
removePlayBackListener() {
|
|
18
|
+
this.module.removePlayBackListener();
|
|
19
|
+
}
|
|
20
|
+
async startPlayer(uri) {
|
|
21
|
+
await this.module.startPlayer(uri);
|
|
22
|
+
}
|
|
23
|
+
async pausePlayer() {
|
|
24
|
+
await this.module.pausePlayer();
|
|
25
|
+
}
|
|
26
|
+
async resumePlayer() {
|
|
27
|
+
await this.module.resumePlayer();
|
|
28
|
+
}
|
|
29
|
+
async stopPlayer() {
|
|
30
|
+
await this.module.stopPlayer();
|
|
31
|
+
}
|
|
32
|
+
async seekToPlayer(time) {
|
|
33
|
+
await this.module.seekToPlayer(time);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
class NitroSoundOrLegacyV4Adapter {
|
|
37
|
+
constructor(audioRecorderModule) {
|
|
38
|
+
_defineProperty(this, "module", void 0);
|
|
39
|
+
this.module = audioRecorderModule.default;
|
|
40
|
+
}
|
|
41
|
+
setSubscriptionDuration(duration) {
|
|
42
|
+
try {
|
|
43
|
+
this.module.setSubscriptionDuration(duration);
|
|
44
|
+
} catch (error) {
|
|
45
|
+
Logger.warn('[PlayerService.Native] Failed to set subscription duration', error);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
addPlayBackListener(callback) {
|
|
49
|
+
this.module.addPlayBackListener(callback);
|
|
50
|
+
}
|
|
51
|
+
removePlayBackListener() {
|
|
52
|
+
this.module.removePlayBackListener();
|
|
53
|
+
}
|
|
54
|
+
async startPlayer(uri) {
|
|
55
|
+
await this.module.startPlayer(uri);
|
|
56
|
+
}
|
|
57
|
+
async pausePlayer() {
|
|
58
|
+
await this.module.pausePlayer();
|
|
59
|
+
}
|
|
60
|
+
async resumePlayer() {
|
|
61
|
+
await this.module.resumePlayer();
|
|
62
|
+
}
|
|
63
|
+
async stopPlayer() {
|
|
64
|
+
await this.module.stopPlayer();
|
|
65
|
+
}
|
|
66
|
+
async seekToPlayer(time) {
|
|
67
|
+
await this.module.seekToPlayer(time);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
class VoicePlayer {
|
|
71
|
+
constructor(adapter, permissionModule) {
|
|
72
|
+
this.adapter = adapter;
|
|
73
|
+
this.permissionModule = permissionModule;
|
|
74
|
+
_defineProperty(this, "uri", void 0);
|
|
75
|
+
_defineProperty(this, "state", 'idle');
|
|
76
|
+
_defineProperty(this, "playbackSubscribers", new Set());
|
|
77
|
+
_defineProperty(this, "stateSubscribers", new Set());
|
|
78
|
+
_defineProperty(this, "setState", state => {
|
|
79
|
+
this.state = state;
|
|
80
|
+
this.stateSubscribers.forEach(callback => {
|
|
81
|
+
callback(state);
|
|
22
82
|
});
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
83
|
+
});
|
|
84
|
+
_defineProperty(this, "setListener", () => {
|
|
85
|
+
this.adapter.addPlayBackListener(async data => {
|
|
86
|
+
const stopped = data.currentPosition >= data.duration;
|
|
87
|
+
if (stopped) {
|
|
88
|
+
this.stop().catch(error => {
|
|
89
|
+
Logger.warn('[PlayerService.Native] Failed to stop in PlayBackListener', error);
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
if (this.state === 'playing') {
|
|
93
|
+
this.playbackSubscribers.forEach(callback => {
|
|
94
|
+
callback({
|
|
95
|
+
currentTime: data.currentPosition,
|
|
96
|
+
duration: data.duration,
|
|
97
|
+
stopped
|
|
38
98
|
});
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
_defineProperty(this, "removeListener", () => {
|
|
43
|
-
module.removePlayBackListener();
|
|
99
|
+
});
|
|
100
|
+
}
|
|
44
101
|
});
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
58
|
-
} else {
|
|
102
|
+
});
|
|
103
|
+
_defineProperty(this, "removeListener", () => {
|
|
104
|
+
this.adapter.removePlayBackListener();
|
|
105
|
+
});
|
|
106
|
+
_defineProperty(this, "requestPermission", async () => {
|
|
107
|
+
if (Platform.OS === 'android') {
|
|
108
|
+
if (Platform.Version > 32) return true;
|
|
109
|
+
const {
|
|
110
|
+
READ_EXTERNAL_STORAGE
|
|
111
|
+
} = this.permissionModule.PERMISSIONS.ANDROID;
|
|
112
|
+
const status = await this.permissionModule.check(READ_EXTERNAL_STORAGE);
|
|
113
|
+
if (status === 'granted') {
|
|
59
114
|
return true;
|
|
115
|
+
} else {
|
|
116
|
+
const status = await this.permissionModule.request(READ_EXTERNAL_STORAGE);
|
|
117
|
+
return status === 'granted';
|
|
60
118
|
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
119
|
+
} else {
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
_defineProperty(this, "addPlaybackListener", callback => {
|
|
124
|
+
this.playbackSubscribers.add(callback);
|
|
125
|
+
return () => {
|
|
126
|
+
this.playbackSubscribers.delete(callback);
|
|
127
|
+
};
|
|
128
|
+
});
|
|
129
|
+
_defineProperty(this, "addStateListener", callback => {
|
|
130
|
+
this.stateSubscribers.add(callback);
|
|
131
|
+
return () => {
|
|
132
|
+
this.stateSubscribers.delete(callback);
|
|
133
|
+
};
|
|
134
|
+
});
|
|
135
|
+
_defineProperty(this, "play", async uri => {
|
|
136
|
+
if (matchesOneOf(this.state, ['idle', 'stopped'])) {
|
|
137
|
+
try {
|
|
138
|
+
this.setState('preparing');
|
|
139
|
+
this.uri = uri;
|
|
140
|
+
this.setListener();
|
|
80
141
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
this.removeListener();
|
|
89
|
-
throw e;
|
|
90
|
-
}
|
|
91
|
-
} else if (matchesOneOf(this.state, ['paused']) && this.uri === uri) {
|
|
92
|
-
try {
|
|
93
|
-
this.setListener();
|
|
94
|
-
await module.resumePlayer();
|
|
95
|
-
this.setState('playing');
|
|
96
|
-
} catch (e) {
|
|
97
|
-
this.removeListener();
|
|
98
|
-
throw e;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
});
|
|
102
|
-
_defineProperty(this, "pause", async () => {
|
|
103
|
-
if (matchesOneOf(this.state, ['playing'])) {
|
|
104
|
-
await module.pausePlayer();
|
|
142
|
+
// FIXME: Workaround, `module.startPlayer()` caused a significant frame-drop and prevented the 'preparing' UI transition.
|
|
143
|
+
await sleep(0);
|
|
144
|
+
await this.adapter.startPlayer(uri);
|
|
145
|
+
this.setState('playing');
|
|
146
|
+
} catch (e) {
|
|
147
|
+
this.setState('idle');
|
|
148
|
+
this.uri = undefined;
|
|
105
149
|
this.removeListener();
|
|
106
|
-
|
|
150
|
+
throw e;
|
|
107
151
|
}
|
|
108
|
-
})
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
await
|
|
152
|
+
} else if (matchesOneOf(this.state, ['paused']) && this.uri === uri) {
|
|
153
|
+
try {
|
|
154
|
+
this.setListener();
|
|
155
|
+
await this.adapter.resumePlayer();
|
|
156
|
+
this.setState('playing');
|
|
157
|
+
} catch (e) {
|
|
112
158
|
this.removeListener();
|
|
113
|
-
|
|
159
|
+
throw e;
|
|
114
160
|
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
this.
|
|
120
|
-
this.
|
|
121
|
-
this.
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
_defineProperty(this, "pause", async () => {
|
|
164
|
+
if (matchesOneOf(this.state, ['playing'])) {
|
|
165
|
+
await this.adapter.pausePlayer();
|
|
166
|
+
this.removeListener();
|
|
167
|
+
this.setState('paused');
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
_defineProperty(this, "stop", async () => {
|
|
171
|
+
if (matchesOneOf(this.state, ['preparing', 'playing', 'paused'])) {
|
|
172
|
+
await this.adapter.stopPlayer();
|
|
173
|
+
this.removeListener();
|
|
174
|
+
this.setState('stopped');
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
_defineProperty(this, "reset", async () => {
|
|
178
|
+
await this.stop();
|
|
179
|
+
this.setState('idle');
|
|
180
|
+
this.uri = undefined;
|
|
181
|
+
this.playbackSubscribers.clear();
|
|
182
|
+
this.stateSubscribers.clear();
|
|
183
|
+
});
|
|
184
|
+
_defineProperty(this, "seek", async time => {
|
|
185
|
+
if (matchesOneOf(this.state, ['playing', 'paused'])) {
|
|
186
|
+
await this.adapter.seekToPlayer(time);
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
this.initialize();
|
|
190
|
+
}
|
|
191
|
+
initialize() {
|
|
192
|
+
const setDurationResult = this.adapter.setSubscriptionDuration(0.1);
|
|
193
|
+
if (setDurationResult instanceof Promise) {
|
|
194
|
+
setDurationResult.catch(error => {
|
|
129
195
|
Logger.warn('[PlayerService.Native] Failed to set subscription duration', error);
|
|
130
196
|
});
|
|
131
197
|
}
|
|
132
198
|
}
|
|
133
|
-
|
|
199
|
+
}
|
|
200
|
+
const createNativePlayerService = modules => {
|
|
201
|
+
const adapter = isNitroSoundOrLegacyV4Module(modules.audioRecorderModule) ? new NitroSoundOrLegacyV4Adapter(modules.audioRecorderModule) : new AudioRecorderPlayerAdapter(modules.audioRecorderModule);
|
|
202
|
+
return new VoicePlayer(adapter, modules.permissionModule);
|
|
134
203
|
};
|
|
204
|
+
function isNitroSoundOrLegacyV4Module(module) {
|
|
205
|
+
const isNitroSound = 'createSound' in module && typeof module.createSound === 'function';
|
|
206
|
+
const isLegacyV4 = 'default' in module && 'getHybridObject' in module.default && typeof module.default.getHybridObject === 'function';
|
|
207
|
+
if (isLegacyV4) {
|
|
208
|
+
Logger.warn('react-native-audio-recorder-player is deprecated. Please use react-native-nitro-sound instead.');
|
|
209
|
+
}
|
|
210
|
+
return isNitroSound || isLegacyV4;
|
|
211
|
+
}
|
|
135
212
|
export default createNativePlayerService;
|
|
136
213
|
//# sourceMappingURL=createPlayerService.native.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["Platform","Logger","matchesOneOf","sleep","createNativePlayerService","audioRecorderModule","permissionModule","module","default","VoicePlayer","constructor","_defineProperty","Set","state","stateSubscribers","forEach","callback","addPlayBackListener","data","stopped","currentPosition","duration","stop","catch","error","warn","playbackSubscribers","currentTime","removePlayBackListener","OS","Version","READ_EXTERNAL_STORAGE","PERMISSIONS","ANDROID","status","check","request","add","delete","uri","setState","setListener","startPlayer","e","undefined","removeListener","resumePlayer","pausePlayer","stopPlayer","clear","time","seekToPlayer","setSubscriptionDuration"],"sources":["createPlayerService.native.tsx"],"sourcesContent":["import { Platform } from 'react-native';\nimport type * as RNAudioRecorder from 'react-native-audio-recorder-player';\nimport * as Permissions from 'react-native-permissions';\n\nimport { Logger, matchesOneOf, sleep } from '@sendbird/uikit-utils';\n\nimport type { PlayerServiceInterface, Unsubscribe } from './types';\n\ntype Modules = {\n audioRecorderModule: typeof RNAudioRecorder;\n permissionModule: typeof Permissions;\n};\ntype PlaybackListener = Parameters<PlayerServiceInterface['addPlaybackListener']>[number];\ntype StateListener = Parameters<PlayerServiceInterface['addStateListener']>[number];\nconst createNativePlayerService = ({ audioRecorderModule, permissionModule }: Modules): PlayerServiceInterface => {\n const module = new audioRecorderModule.default();\n\n class VoicePlayer implements PlayerServiceInterface {\n uri?: string;\n state: PlayerServiceInterface['state'] = 'idle';\n\n private readonly playbackSubscribers = new Set<PlaybackListener>();\n private readonly stateSubscribers = new Set<StateListener>();\n\n constructor() {\n module.setSubscriptionDuration(0.1).catch((error) => {\n Logger.warn('[PlayerService.Native] Failed to set subscription duration', error);\n });\n }\n\n private setState = (state: PlayerServiceInterface['state']) => {\n this.state = state;\n this.stateSubscribers.forEach((callback) => {\n callback(state);\n });\n };\n\n private setListener = () => {\n module.addPlayBackListener(async (data) => {\n const stopped = data.currentPosition >= data.duration;\n\n if (stopped) {\n this.stop().catch((error) => {\n Logger.warn('[PlayerService.Native] Failed to stop in PlayBackListener', error);\n });\n }\n if (this.state === 'playing') {\n this.playbackSubscribers.forEach((callback) => {\n callback({ currentTime: data.currentPosition, duration: data.duration, stopped });\n });\n }\n });\n };\n\n private removeListener = () => {\n module.removePlayBackListener();\n };\n\n public requestPermission = async (): Promise<boolean> => {\n if (Platform.OS === 'android') {\n if (Platform.Version > 32) return true;\n\n const { READ_EXTERNAL_STORAGE } = permissionModule.PERMISSIONS.ANDROID;\n\n const status = await permissionModule.check(READ_EXTERNAL_STORAGE);\n if (status === 'granted') {\n return true;\n } else {\n const status = await permissionModule.request(READ_EXTERNAL_STORAGE);\n return status === 'granted';\n }\n } else {\n return true;\n }\n };\n\n public addPlaybackListener = (callback: PlaybackListener): Unsubscribe => {\n this.playbackSubscribers.add(callback);\n return () => {\n this.playbackSubscribers.delete(callback);\n };\n };\n\n public addStateListener = (callback: (state: PlayerServiceInterface['state']) => void): Unsubscribe => {\n this.stateSubscribers.add(callback);\n return () => {\n this.stateSubscribers.delete(callback);\n };\n };\n\n public play = async (uri: string): Promise<void> => {\n if (matchesOneOf(this.state, ['idle', 'stopped'])) {\n try {\n this.setState('preparing');\n this.uri = uri;\n this.setListener();\n\n // FIXME: Workaround, `module.startPlayer()` caused a significant frame-drop and prevented the 'preparing' UI transition.\n await sleep(0);\n await module.startPlayer(uri);\n\n this.setState('playing');\n } catch (e) {\n this.setState('idle');\n this.uri = undefined;\n this.removeListener();\n throw e;\n }\n } else if (matchesOneOf(this.state, ['paused']) && this.uri === uri) {\n try {\n this.setListener();\n await module.resumePlayer();\n this.setState('playing');\n } catch (e) {\n this.removeListener();\n throw e;\n }\n }\n };\n\n public pause = async (): Promise<void> => {\n if (matchesOneOf(this.state, ['playing'])) {\n await module.pausePlayer();\n this.removeListener();\n this.setState('paused');\n }\n };\n\n public stop = async (): Promise<void> => {\n if (matchesOneOf(this.state, ['preparing', 'playing', 'paused'])) {\n await module.stopPlayer();\n this.removeListener();\n this.setState('stopped');\n }\n };\n\n public reset = async (): Promise<void> => {\n await this.stop();\n this.setState('idle');\n this.uri = undefined;\n this.playbackSubscribers.clear();\n this.stateSubscribers.clear();\n };\n\n public seek = async (time: number): Promise<void> => {\n if (matchesOneOf(this.state, ['playing', 'paused'])) {\n await module.seekToPlayer(time);\n }\n };\n }\n\n return new VoicePlayer();\n};\n\nexport default createNativePlayerService;\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["Platform","Logger","matchesOneOf","sleep","AudioRecorderPlayerAdapter","constructor","audioRecorderModule","_defineProperty","module","default","setSubscriptionDuration","duration","addPlayBackListener","callback","removePlayBackListener","startPlayer","uri","pausePlayer","resumePlayer","stopPlayer","seekToPlayer","time","NitroSoundOrLegacyV4Adapter","error","warn","VoicePlayer","adapter","permissionModule","Set","state","stateSubscribers","forEach","data","stopped","currentPosition","stop","catch","playbackSubscribers","currentTime","OS","Version","READ_EXTERNAL_STORAGE","PERMISSIONS","ANDROID","status","check","request","add","delete","setState","setListener","e","undefined","removeListener","clear","initialize","setDurationResult","Promise","createNativePlayerService","modules","isNitroSoundOrLegacyV4Module","isNitroSound","createSound","isLegacyV4","getHybridObject"],"sources":["createPlayerService.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';\n\nimport { Logger, matchesOneOf, sleep } from '@sendbird/uikit-utils';\n\nimport { AudioRecorderModule } from './createRecorderService.native';\nimport type { PlayerServiceInterface, Unsubscribe } from './types';\n\nexport type AudioPlayerModule = typeof LegacyModule | typeof NitroSoundOrLegacyV4Module;\n\ntype Modules = {\n audioRecorderModule: AudioPlayerModule;\n permissionModule: typeof Permissions;\n};\ntype PlaybackListener = Parameters<PlayerServiceInterface['addPlaybackListener']>[number];\ntype StateListener = Parameters<PlayerServiceInterface['addStateListener']>[number];\n\ninterface PlayBackData {\n currentPosition: number;\n duration: number;\n}\n\ninterface PlayerModuleAdapter {\n setSubscriptionDuration(duration: number): Promise<void> | void;\n addPlayBackListener(callback: (data: PlayBackData) => void): void;\n removePlayBackListener(): void;\n startPlayer(uri: string): Promise<void>;\n pausePlayer(): Promise<void>;\n resumePlayer(): Promise<void>;\n stopPlayer(): Promise<void>;\n seekToPlayer(time: number): Promise<void>;\n}\n\nclass AudioRecorderPlayerAdapter implements PlayerModuleAdapter {\n private module: InstanceType<typeof LegacyModule.default>;\n\n constructor(audioRecorderModule: typeof LegacyModule) {\n this.module = new audioRecorderModule.default();\n }\n\n async setSubscriptionDuration(duration: number): Promise<void> {\n await this.module.setSubscriptionDuration(duration);\n }\n\n addPlayBackListener(callback: (data: PlayBackData) => void): void {\n this.module.addPlayBackListener(callback);\n }\n\n removePlayBackListener(): void {\n this.module.removePlayBackListener();\n }\n\n async startPlayer(uri: string): Promise<void> {\n await this.module.startPlayer(uri);\n }\n\n async pausePlayer(): Promise<void> {\n await this.module.pausePlayer();\n }\n\n async resumePlayer(): Promise<void> {\n await this.module.resumePlayer();\n }\n\n async stopPlayer(): Promise<void> {\n await this.module.stopPlayer();\n }\n\n async seekToPlayer(time: number): Promise<void> {\n await this.module.seekToPlayer(time);\n }\n}\n\nclass NitroSoundOrLegacyV4Adapter implements PlayerModuleAdapter {\n private module;\n\n constructor(audioRecorderModule: typeof NitroSoundOrLegacyV4Module) {\n this.module = audioRecorderModule.default;\n }\n\n setSubscriptionDuration(duration: number): void {\n try {\n this.module.setSubscriptionDuration(duration);\n } catch (error) {\n Logger.warn('[PlayerService.Native] Failed to set subscription duration', error);\n }\n }\n\n addPlayBackListener(callback: (data: PlayBackData) => void): void {\n this.module.addPlayBackListener(callback);\n }\n\n removePlayBackListener(): void {\n this.module.removePlayBackListener();\n }\n\n async startPlayer(uri: string): Promise<void> {\n await this.module.startPlayer(uri);\n }\n\n async pausePlayer(): Promise<void> {\n await this.module.pausePlayer();\n }\n\n async resumePlayer(): Promise<void> {\n await this.module.resumePlayer();\n }\n\n async stopPlayer(): Promise<void> {\n await this.module.stopPlayer();\n }\n\n async seekToPlayer(time: number): Promise<void> {\n await this.module.seekToPlayer(time);\n }\n}\n\nclass VoicePlayer implements PlayerServiceInterface {\n public uri?: string;\n public state: PlayerServiceInterface['state'] = 'idle';\n\n private readonly playbackSubscribers = new Set<PlaybackListener>();\n private readonly stateSubscribers = new Set<StateListener>();\n\n constructor(private readonly adapter: PlayerModuleAdapter, 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('[PlayerService.Native] Failed to set subscription duration', error);\n });\n }\n }\n\n private setState = (state: PlayerServiceInterface['state']) => {\n this.state = state;\n this.stateSubscribers.forEach((callback) => {\n callback(state);\n });\n };\n\n private setListener = () => {\n this.adapter.addPlayBackListener(async (data) => {\n const stopped = data.currentPosition >= data.duration;\n\n if (stopped) {\n this.stop().catch((error) => {\n Logger.warn('[PlayerService.Native] Failed to stop in PlayBackListener', error);\n });\n }\n if (this.state === 'playing') {\n this.playbackSubscribers.forEach((callback) => {\n callback({ currentTime: data.currentPosition, duration: data.duration, stopped });\n });\n }\n });\n };\n\n private removeListener = () => {\n this.adapter.removePlayBackListener();\n };\n\n public requestPermission = async (): Promise<boolean> => {\n if (Platform.OS === 'android') {\n if (Platform.Version > 32) return true;\n\n const { READ_EXTERNAL_STORAGE } = this.permissionModule.PERMISSIONS.ANDROID;\n\n const status = await this.permissionModule.check(READ_EXTERNAL_STORAGE);\n if (status === 'granted') {\n return true;\n } else {\n const status = await this.permissionModule.request(READ_EXTERNAL_STORAGE);\n return status === 'granted';\n }\n } else {\n return true;\n }\n };\n\n public addPlaybackListener = (callback: PlaybackListener): Unsubscribe => {\n this.playbackSubscribers.add(callback);\n return () => {\n this.playbackSubscribers.delete(callback);\n };\n };\n\n public addStateListener = (callback: (state: PlayerServiceInterface['state']) => void): Unsubscribe => {\n this.stateSubscribers.add(callback);\n return () => {\n this.stateSubscribers.delete(callback);\n };\n };\n\n public play = async (uri: string): Promise<void> => {\n if (matchesOneOf(this.state, ['idle', 'stopped'])) {\n try {\n this.setState('preparing');\n this.uri = uri;\n this.setListener();\n\n // FIXME: Workaround, `module.startPlayer()` caused a significant frame-drop and prevented the 'preparing' UI transition.\n await sleep(0);\n await this.adapter.startPlayer(uri);\n\n this.setState('playing');\n } catch (e) {\n this.setState('idle');\n this.uri = undefined;\n this.removeListener();\n throw e;\n }\n } else if (matchesOneOf(this.state, ['paused']) && this.uri === uri) {\n try {\n this.setListener();\n await this.adapter.resumePlayer();\n this.setState('playing');\n } catch (e) {\n this.removeListener();\n throw e;\n }\n }\n };\n\n public pause = async (): Promise<void> => {\n if (matchesOneOf(this.state, ['playing'])) {\n await this.adapter.pausePlayer();\n this.removeListener();\n this.setState('paused');\n }\n };\n\n public stop = async (): Promise<void> => {\n if (matchesOneOf(this.state, ['preparing', 'playing', 'paused'])) {\n await this.adapter.stopPlayer();\n this.removeListener();\n this.setState('stopped');\n }\n };\n\n public reset = async (): Promise<void> => {\n await this.stop();\n this.setState('idle');\n this.uri = undefined;\n this.playbackSubscribers.clear();\n this.stateSubscribers.clear();\n };\n\n public seek = async (time: number): Promise<void> => {\n if (matchesOneOf(this.state, ['playing', 'paused'])) {\n await this.adapter.seekToPlayer(time);\n }\n };\n}\n\nconst createNativePlayerService = (modules: Modules): PlayerServiceInterface => {\n const adapter = isNitroSoundOrLegacyV4Module(modules.audioRecorderModule)\n ? new NitroSoundOrLegacyV4Adapter(modules.audioRecorderModule)\n : new AudioRecorderPlayerAdapter(modules.audioRecorderModule as typeof LegacyModule);\n\n return new VoicePlayer(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 createNativePlayerService;\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["Platform","matchesOneOf","sleep","VoiceMessageConfig","expoPermissionGranted","createExpoRecorderService","avModule","VoiceRecorder","constructor","_defineProperty","undefined","minDuration","DEFAULT","RECORDER","MIN_DURATION","maxDuration","MAX_DURATION","extension","EXTENSION","minWaitingTime","elapsedTime","Date","now","_recordStartedAt","Audio","Recording","Set","sampleRate","SAMPLE_RATE","bitRate","BIT_RATE","numberOfChannels","CHANNELS","android","_audioSettings","options","audioEncoder","AndroidAudioEncoder","AAC","outputFormat","AndroidOutputFormat","MPEG_4","ios","IOSOutputFormat","MPEG4AAC","audioQuality","IOSAudioQuality","HIGH","web","setState","OS","setAudioModeAsync","allowsRecordingIOS","playsInSilentModeIOS","_recorder","_isDoneRecording","setProgressUpdateInterval","setOnRecordingStatusUpdate","status","completed","durationMillis","stop","isRecording","_recordingSubscribers","forEach","callback","currentTime","prepareToRecordAsync","_audioOptions","state","_stateSubscribers","getPermissionsAsync","requestPermissionsAsync","add","delete","prepare","startAsync","uri","getURI","e","buffer","_getRecorderStopSafeBuffer","stopAndUnloadAsync","clear"],"sources":["createRecorderService.expo.tsx"],"sourcesContent":["import * as ExpoAV from 'expo-av';\nimport type { RecordingOptions } from 'expo-av/build/Audio/Recording.types';\nimport { Platform } from 'react-native';\n\nimport { matchesOneOf, sleep } from '@sendbird/uikit-utils';\n\nimport VoiceMessageConfig from '../libs/VoiceMessageConfig';\nimport expoPermissionGranted from '../utils/expoPermissionGranted';\nimport type { RecorderServiceInterface, Unsubscribe } from './types';\n\ntype RecordingListener = Parameters<RecorderServiceInterface['addRecordingListener']>[number];\ntype StateListener = Parameters<RecorderServiceInterface['addStateListener']>[number];\ntype Modules = {\n avModule: typeof ExpoAV;\n};\nconst createExpoRecorderService = ({ avModule }: Modules): RecorderServiceInterface => {\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 _recorder = new avModule.Audio.Recording();\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 numberOfChannels: VoiceMessageConfig.DEFAULT.RECORDER.CHANNELS,\n // encoding: mpeg4_aac\n };\n private readonly _audioOptions: RecordingOptions = {\n android: {\n ...this._audioSettings,\n extension: `.${this.options.extension}`,\n audioEncoder: avModule.Audio.AndroidAudioEncoder.AAC,\n outputFormat: avModule.Audio.AndroidOutputFormat.MPEG_4,\n },\n ios: {\n ...this._audioSettings,\n extension: `.${this.options.extension}`,\n outputFormat: avModule.Audio.IOSOutputFormat.MPEG4AAC,\n audioQuality: avModule.Audio.IOSAudioQuality.HIGH,\n },\n web: {},\n };\n\n private prepare = async () => {\n this.setState('preparing');\n if (Platform.OS === 'ios') {\n await avModule.Audio.setAudioModeAsync({ allowsRecordingIOS: true, playsInSilentModeIOS: true });\n }\n\n if (this._recorder._isDoneRecording) {\n this._recorder = new avModule.Audio.Recording();\n }\n this._recorder.setProgressUpdateInterval(100);\n this._recorder.setOnRecordingStatusUpdate((status) => {\n const completed = status.durationMillis >= this.options.maxDuration;\n if (completed) this.stop();\n if (status.isRecording) {\n this._recordingSubscribers.forEach((callback) => {\n callback({ currentTime: status.durationMillis, completed: completed });\n });\n }\n });\n await this._recorder.prepareToRecordAsync(this._audioOptions);\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 status = await avModule.Audio.getPermissionsAsync();\n if (expoPermissionGranted([status])) {\n return true;\n } else {\n const status = await avModule.Audio.requestPermissionsAsync();\n return expoPermissionGranted([status]);\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 (): Promise<void> => {\n if (matchesOneOf(this.state, ['idle', 'completed'])) {\n try {\n await this.prepare();\n await this._recorder.startAsync();\n\n if (Platform.OS === 'android') {\n this._recordStartedAt = Date.now();\n }\n\n const uri = this._recorder.getURI();\n if (uri) 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 this._recorder.stopAndUnloadAsync();\n if (Platform.OS === 'ios') {\n await avModule.Audio.setAudioModeAsync({ allowsRecordingIOS: false, playsInSilentModeIOS: false });\n }\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._recorder = new avModule.Audio.Recording();\n this.setState('idle');\n };\n }\n\n return new VoiceRecorder();\n};\n\nexport default createExpoRecorderService;\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["Platform","matchesOneOf","sleep","VoiceMessageConfig","expoPermissionGranted","createExpoRecorderService","avModule","VoiceRecorder","constructor","_defineProperty","undefined","minDuration","DEFAULT","RECORDER","MIN_DURATION","maxDuration","MAX_DURATION","extension","EXTENSION","minWaitingTime","elapsedTime","Date","now","_recordStartedAt","Audio","Recording","Set","sampleRate","SAMPLE_RATE","bitRate","BIT_RATE","numberOfChannels","CHANNELS","android","_audioSettings","options","audioEncoder","AndroidAudioEncoder","AAC","outputFormat","AndroidOutputFormat","MPEG_4","ios","IOSOutputFormat","MPEG4AAC","audioQuality","IOSAudioQuality","HIGH","web","setState","OS","setAudioModeAsync","allowsRecordingIOS","playsInSilentModeIOS","_recorder","_isDoneRecording","setProgressUpdateInterval","setOnRecordingStatusUpdate","status","completed","durationMillis","stop","isRecording","_recordingSubscribers","forEach","callback","currentTime","prepareToRecordAsync","_audioOptions","state","_stateSubscribers","getPermissionsAsync","requestPermissionsAsync","add","delete","prepare","startAsync","uri","getURI","e","buffer","_getRecorderStopSafeBuffer","stopAndUnloadAsync","clear"],"sources":["createRecorderService.expo.tsx"],"sourcesContent":["import * as ExpoAV from 'expo-av';\nimport type { RecordingOptions } from 'expo-av/build/Audio/Recording.types';\nimport { Platform } from 'react-native';\n\nimport { matchesOneOf, sleep } from '@sendbird/uikit-utils';\n\nimport VoiceMessageConfig from '../libs/VoiceMessageConfig';\nimport expoPermissionGranted from '../utils/expoPermissionGranted';\nimport type { RecorderServiceInterface, Unsubscribe } from './types';\n\ntype RecordingListener = Parameters<RecorderServiceInterface['addRecordingListener']>[number];\ntype StateListener = Parameters<RecorderServiceInterface['addStateListener']>[number];\ntype Modules = {\n avModule: typeof ExpoAV;\n};\nconst createExpoRecorderService = ({ avModule }: Modules): RecorderServiceInterface => {\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 _recorder = new avModule.Audio.Recording();\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 numberOfChannels: VoiceMessageConfig.DEFAULT.RECORDER.CHANNELS,\n // encoding: mpeg4_aac\n };\n private readonly _audioOptions: RecordingOptions = {\n android: {\n ...this._audioSettings,\n extension: `.${this.options.extension}`,\n audioEncoder: avModule.Audio.AndroidAudioEncoder.AAC,\n outputFormat: avModule.Audio.AndroidOutputFormat.MPEG_4,\n },\n ios: {\n ...this._audioSettings,\n extension: `.${this.options.extension}`,\n outputFormat: avModule.Audio.IOSOutputFormat.MPEG4AAC,\n audioQuality: avModule.Audio.IOSAudioQuality.HIGH,\n },\n web: {},\n };\n\n private prepare = async () => {\n this.setState('preparing');\n if (Platform.OS === 'ios') {\n await avModule.Audio.setAudioModeAsync({ allowsRecordingIOS: true, playsInSilentModeIOS: true });\n }\n\n if (this._recorder._isDoneRecording) {\n this._recorder = new avModule.Audio.Recording();\n }\n this._recorder.setProgressUpdateInterval(100);\n this._recorder.setOnRecordingStatusUpdate((status) => {\n const completed = status.durationMillis >= this.options.maxDuration;\n if (completed) this.stop();\n if (status.isRecording) {\n this._recordingSubscribers.forEach((callback) => {\n callback({ currentTime: status.durationMillis, completed: completed });\n });\n }\n });\n await this._recorder.prepareToRecordAsync(this._audioOptions);\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 status = await avModule.Audio.getPermissionsAsync();\n if (expoPermissionGranted([status])) {\n return true;\n } else {\n const status = await avModule.Audio.requestPermissionsAsync();\n return expoPermissionGranted([status]);\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 (): Promise<void> => {\n if (matchesOneOf(this.state, ['idle', 'completed'])) {\n try {\n await this.prepare();\n await this._recorder.startAsync();\n\n if (Platform.OS === 'android') {\n this._recordStartedAt = Date.now();\n }\n\n const uri = this._recorder.getURI();\n if (uri) 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 this._recorder.stopAndUnloadAsync();\n if (Platform.OS === 'ios') {\n await avModule.Audio.setAudioModeAsync({ allowsRecordingIOS: false, playsInSilentModeIOS: false });\n }\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._recorder = new avModule.Audio.Recording();\n this.setState('idle');\n };\n\n public convertRecordPath = (uri: string): string => {\n return uri;\n };\n }\n\n return new VoiceRecorder();\n};\n\nexport default createExpoRecorderService;\n"],"mappings":"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","ignoreList":[]}
|