@sendbird/uikit-react-native 3.7.3 → 3.7.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (143) hide show
  1. package/README.md +5 -4
  2. package/lib/commonjs/components/ChannelInput/SendInput.js +2 -1
  3. package/lib/commonjs/components/ChannelInput/SendInput.js.map +1 -1
  4. package/lib/commonjs/components/ChannelInput/VoiceMessageInput.js +33 -23
  5. package/lib/commonjs/components/ChannelInput/VoiceMessageInput.js.map +1 -1
  6. package/lib/commonjs/components/ChannelInput/index.js +11 -5
  7. package/lib/commonjs/components/ChannelInput/index.js.map +1 -1
  8. package/lib/commonjs/components/ChannelMessageList/index.js +6 -1
  9. package/lib/commonjs/components/ChannelMessageList/index.js.map +1 -1
  10. package/lib/commonjs/components/ChannelThreadMessageList/index.js +6 -1
  11. package/lib/commonjs/components/ChannelThreadMessageList/index.js.map +1 -1
  12. package/lib/commonjs/components/FileViewer/FileViewerContent.js +1 -1
  13. package/lib/commonjs/components/FileViewer/FileViewerContent.js.map +1 -1
  14. package/lib/commonjs/components/FileViewer/FileViewerFooter.js +1 -0
  15. package/lib/commonjs/components/FileViewer/FileViewerFooter.js.map +1 -1
  16. package/lib/commonjs/components/FileViewer/FileViewerHeader.js +1 -0
  17. package/lib/commonjs/components/FileViewer/FileViewerHeader.js.map +1 -1
  18. package/lib/commonjs/components/GroupChannelMessageRenderer/index.js +1 -1
  19. package/lib/commonjs/components/GroupChannelMessageRenderer/index.js.map +1 -1
  20. package/lib/commonjs/components/ReactionAddons/BottomSheetReactionAddon.js +9 -3
  21. package/lib/commonjs/components/ReactionAddons/BottomSheetReactionAddon.js.map +1 -1
  22. package/lib/commonjs/components/ReactionBottomSheets/ReactionListBottomSheet.js +9 -3
  23. package/lib/commonjs/components/ReactionBottomSheets/ReactionListBottomSheet.js.map +1 -1
  24. package/lib/commonjs/components/ThreadParentMessageRenderer/index.js +1 -1
  25. package/lib/commonjs/components/ThreadParentMessageRenderer/index.js.map +1 -1
  26. package/lib/commonjs/containers/SendbirdUIKitContainer.js +0 -1
  27. package/lib/commonjs/containers/SendbirdUIKitContainer.js.map +1 -1
  28. package/lib/commonjs/contexts/PlatformServiceCtx.js +2 -1
  29. package/lib/commonjs/contexts/PlatformServiceCtx.js.map +1 -1
  30. package/lib/commonjs/contexts/SBUHandlersCtx.js.map +1 -1
  31. package/lib/commonjs/domain/groupChannel/component/GroupChannelMessageList.js +17 -3
  32. package/lib/commonjs/domain/groupChannel/component/GroupChannelMessageList.js.map +1 -1
  33. package/lib/commonjs/domain/groupChannelSettings/component/GroupChannelSettingsMenu.js +8 -4
  34. package/lib/commonjs/domain/groupChannelSettings/component/GroupChannelSettingsMenu.js.map +1 -1
  35. package/lib/commonjs/domain/groupChannelThread/component/GroupChannelThreadMessageList.js +16 -2
  36. package/lib/commonjs/domain/groupChannelThread/component/GroupChannelThreadMessageList.js.map +1 -1
  37. package/lib/commonjs/domain/groupChannelThread/component/GroupChannelThreadParentMessageInfo.js +8 -3
  38. package/lib/commonjs/domain/groupChannelThread/component/GroupChannelThreadParentMessageInfo.js.map +1 -1
  39. package/lib/commonjs/fragments/createGroupChannelFragment.js +3 -2
  40. package/lib/commonjs/fragments/createGroupChannelFragment.js.map +1 -1
  41. package/lib/commonjs/fragments/createGroupChannelThreadFragment.js +3 -2
  42. package/lib/commonjs/fragments/createGroupChannelThreadFragment.js.map +1 -1
  43. package/lib/commonjs/hooks/useConnection.js +2 -2
  44. package/lib/commonjs/hooks/useConnection.js.map +1 -1
  45. package/lib/commonjs/hooks/usePushTokenRegistration.js +24 -6
  46. package/lib/commonjs/hooks/usePushTokenRegistration.js.map +1 -1
  47. package/lib/commonjs/platform/createFileService.native.js +2 -2
  48. package/lib/commonjs/platform/createFileService.native.js.map +1 -1
  49. package/lib/commonjs/platform/createPlayerService.expo.js +8 -2
  50. package/lib/commonjs/platform/createPlayerService.expo.js.map +1 -1
  51. package/lib/commonjs/platform/createPlayerService.native.js +12 -7
  52. package/lib/commonjs/platform/createPlayerService.native.js.map +1 -1
  53. package/lib/commonjs/platform/createRecorderService.native.js +8 -2
  54. package/lib/commonjs/platform/createRecorderService.native.js.map +1 -1
  55. package/lib/commonjs/version.js +1 -1
  56. package/lib/commonjs/version.js.map +1 -1
  57. package/lib/module/components/ChannelInput/SendInput.js +2 -1
  58. package/lib/module/components/ChannelInput/SendInput.js.map +1 -1
  59. package/lib/module/components/ChannelInput/VoiceMessageInput.js +34 -24
  60. package/lib/module/components/ChannelInput/VoiceMessageInput.js.map +1 -1
  61. package/lib/module/components/ChannelInput/index.js +12 -6
  62. package/lib/module/components/ChannelInput/index.js.map +1 -1
  63. package/lib/module/components/ChannelMessageList/index.js +6 -1
  64. package/lib/module/components/ChannelMessageList/index.js.map +1 -1
  65. package/lib/module/components/ChannelThreadMessageList/index.js +6 -1
  66. package/lib/module/components/ChannelThreadMessageList/index.js.map +1 -1
  67. package/lib/module/components/FileViewer/FileViewerContent.js +1 -1
  68. package/lib/module/components/FileViewer/FileViewerContent.js.map +1 -1
  69. package/lib/module/components/FileViewer/FileViewerFooter.js +1 -0
  70. package/lib/module/components/FileViewer/FileViewerFooter.js.map +1 -1
  71. package/lib/module/components/FileViewer/FileViewerHeader.js +1 -0
  72. package/lib/module/components/FileViewer/FileViewerHeader.js.map +1 -1
  73. package/lib/module/components/GroupChannelMessageRenderer/index.js +1 -1
  74. package/lib/module/components/GroupChannelMessageRenderer/index.js.map +1 -1
  75. package/lib/module/components/ReactionAddons/BottomSheetReactionAddon.js +10 -4
  76. package/lib/module/components/ReactionAddons/BottomSheetReactionAddon.js.map +1 -1
  77. package/lib/module/components/ReactionBottomSheets/ReactionListBottomSheet.js +9 -3
  78. package/lib/module/components/ReactionBottomSheets/ReactionListBottomSheet.js.map +1 -1
  79. package/lib/module/components/ThreadParentMessageRenderer/index.js +1 -1
  80. package/lib/module/components/ThreadParentMessageRenderer/index.js.map +1 -1
  81. package/lib/module/containers/SendbirdUIKitContainer.js +0 -1
  82. package/lib/module/containers/SendbirdUIKitContainer.js.map +1 -1
  83. package/lib/module/contexts/PlatformServiceCtx.js +2 -1
  84. package/lib/module/contexts/PlatformServiceCtx.js.map +1 -1
  85. package/lib/module/contexts/SBUHandlersCtx.js.map +1 -1
  86. package/lib/module/domain/groupChannel/component/GroupChannelMessageList.js +17 -3
  87. package/lib/module/domain/groupChannel/component/GroupChannelMessageList.js.map +1 -1
  88. package/lib/module/domain/groupChannelSettings/component/GroupChannelSettingsMenu.js +8 -4
  89. package/lib/module/domain/groupChannelSettings/component/GroupChannelSettingsMenu.js.map +1 -1
  90. package/lib/module/domain/groupChannelThread/component/GroupChannelThreadMessageList.js +16 -2
  91. package/lib/module/domain/groupChannelThread/component/GroupChannelThreadMessageList.js.map +1 -1
  92. package/lib/module/domain/groupChannelThread/component/GroupChannelThreadParentMessageInfo.js +8 -3
  93. package/lib/module/domain/groupChannelThread/component/GroupChannelThreadParentMessageInfo.js.map +1 -1
  94. package/lib/module/fragments/createGroupChannelFragment.js +3 -2
  95. package/lib/module/fragments/createGroupChannelFragment.js.map +1 -1
  96. package/lib/module/fragments/createGroupChannelThreadFragment.js +3 -2
  97. package/lib/module/fragments/createGroupChannelThreadFragment.js.map +1 -1
  98. package/lib/module/hooks/useConnection.js +2 -2
  99. package/lib/module/hooks/useConnection.js.map +1 -1
  100. package/lib/module/hooks/usePushTokenRegistration.js +24 -6
  101. package/lib/module/hooks/usePushTokenRegistration.js.map +1 -1
  102. package/lib/module/platform/createFileService.native.js +2 -2
  103. package/lib/module/platform/createFileService.native.js.map +1 -1
  104. package/lib/module/platform/createPlayerService.expo.js +9 -3
  105. package/lib/module/platform/createPlayerService.expo.js.map +1 -1
  106. package/lib/module/platform/createPlayerService.native.js +13 -8
  107. package/lib/module/platform/createPlayerService.native.js.map +1 -1
  108. package/lib/module/platform/createRecorderService.native.js +9 -3
  109. package/lib/module/platform/createRecorderService.native.js.map +1 -1
  110. package/lib/module/version.js +1 -1
  111. package/lib/module/version.js.map +1 -1
  112. package/lib/typescript/src/containers/SendbirdUIKitContainer.d.ts +1 -1
  113. package/lib/typescript/src/contexts/SBUHandlersCtx.d.ts +1 -1
  114. package/lib/typescript/src/version.d.ts +1 -1
  115. package/package.json +6 -6
  116. package/src/components/ChannelInput/SendInput.tsx +2 -1
  117. package/src/components/ChannelInput/VoiceMessageInput.tsx +40 -24
  118. package/src/components/ChannelInput/index.tsx +16 -6
  119. package/src/components/ChannelMessageList/index.tsx +5 -1
  120. package/src/components/ChannelThreadMessageList/index.tsx +5 -1
  121. package/src/components/FileViewer/FileViewerContent.tsx +1 -1
  122. package/src/components/FileViewer/FileViewerFooter.tsx +1 -0
  123. package/src/components/FileViewer/FileViewerHeader.tsx +1 -0
  124. package/src/components/GroupChannelMessageRenderer/index.tsx +1 -1
  125. package/src/components/ReactionAddons/BottomSheetReactionAddon.tsx +13 -5
  126. package/src/components/ReactionBottomSheets/ReactionListBottomSheet.tsx +11 -4
  127. package/src/components/ThreadParentMessageRenderer/index.tsx +1 -1
  128. package/src/containers/SendbirdUIKitContainer.tsx +0 -1
  129. package/src/contexts/PlatformServiceCtx.tsx +2 -1
  130. package/src/contexts/SBUHandlersCtx.tsx +1 -1
  131. package/src/domain/groupChannel/component/GroupChannelMessageList.tsx +19 -3
  132. package/src/domain/groupChannelSettings/component/GroupChannelSettingsMenu.tsx +8 -4
  133. package/src/domain/groupChannelThread/component/GroupChannelThreadMessageList.tsx +17 -2
  134. package/src/domain/groupChannelThread/component/GroupChannelThreadParentMessageInfo.tsx +7 -3
  135. package/src/fragments/createGroupChannelFragment.tsx +3 -2
  136. package/src/fragments/createGroupChannelThreadFragment.tsx +3 -2
  137. package/src/hooks/useConnection.ts +8 -2
  138. package/src/hooks/usePushTokenRegistration.ts +24 -6
  139. package/src/platform/createFileService.native.ts +2 -6
  140. package/src/platform/createPlayerService.expo.tsx +9 -3
  141. package/src/platform/createPlayerService.native.tsx +15 -8
  142. package/src/platform/createRecorderService.native.tsx +9 -3
  143. package/src/version.ts +1 -1
@@ -1 +1 @@
1
- {"version":3,"names":["Platform","Logger","getFileExtension","getFileExtensionFromMime","getFileExtensionFromUri","getFileType","normalizeFileName","SBUError","nativePermissionGranted","normalizeFile","getAndroidStoragePermissionsByAPILevel","permissionModule","OS","Version","PERMISSIONS","ANDROID","READ_MEDIA_AUDIO","READ_MEDIA_IMAGES","READ_MEDIA_VIDEO","READ_EXTERNAL_STORAGE","WRITE_EXTERNAL_STORAGE","createNativeFileService","_ref","imagePickerModule","documentPickerModule","mediaLibraryModule","fsModule","cameraPermissions","select","ios","IOS","CAMERA","MICROPHONE","android","default","mediaLibraryPermissions","PHOTO_LIBRARY","PHOTO_LIBRARY_ADD_ONLY","NativeFileService","constructor","_defineProperty","options","dirname","Dirs","CacheDir","DocumentDir","context","filename","fileName","extension","fileType","fileUrl","path","buildDownloadPath","FileSystem","fetch","downloadedPath","file","name","type","hasCameraPermission","status","checkMultiple","requestCameraPermission","requestMultiple","hasMediaLibraryPermission","requestMediaLibraryPermission","openCamera","_response$assets","hasPermission","granted","_options$onOpenFailur","onOpenFailure","call","PERMISSIONS_DENIED","response","launchCamera","presentationStyle","cameraType","mediaType","didCancel","errorCode","_options$onOpenFailur2","DEVICE_UNAVAILABLE","Error","errorMessage","fileSize","size","uri","assets","openMediaLibrary","selectionLimit","_options$onOpenFailur3","launchImageLibrary","_options$onOpenFailur4","Promise","all","slice","map","_ref2","openDocument","pickSingle","e","isCancel","isInProgress","_options$onOpenFailur5","UNKNOWN","save","downloadFile","mediaTypeMap","externalDirMap","externalDir","cpExternal","catch","error","createRecordFilePath","customExtension","arguments","length","undefined","Date","now","recordFilePath","startsWith"],"sources":["createFileService.native.ts"],"sourcesContent":["import type { CameraRoll } from '@react-native-camera-roll/camera-roll';\nimport { Platform } from 'react-native';\nimport type * as DocumentPicker from 'react-native-document-picker';\nimport type * as FileAccess from 'react-native-file-access';\nimport type * as ImagePicker from 'react-native-image-picker';\nimport type * as Permissions from 'react-native-permissions';\nimport type { Permission } from 'react-native-permissions';\n\nimport {\n Logger,\n getFileExtension,\n getFileExtensionFromMime,\n getFileExtensionFromUri,\n getFileType,\n normalizeFileName,\n} from '@sendbird/uikit-utils';\n\nimport SBUError from '../libs/SBUError';\nimport nativePermissionGranted from '../utils/nativePermissionGranted';\nimport normalizeFile from '../utils/normalizeFile';\nimport type {\n FilePickerResponse,\n FileServiceInterface,\n OpenCameraOptions,\n OpenDocumentOptions,\n OpenMediaLibraryOptions,\n SaveOptions,\n} from './types';\n\nfunction getAndroidStoragePermissionsByAPILevel(permissionModule: typeof Permissions): Permission[] {\n if (Platform.OS !== 'android') return [];\n\n if (Platform.Version > 32) {\n return [\n permissionModule.PERMISSIONS.ANDROID.READ_MEDIA_AUDIO,\n permissionModule.PERMISSIONS.ANDROID.READ_MEDIA_IMAGES,\n permissionModule.PERMISSIONS.ANDROID.READ_MEDIA_VIDEO,\n ];\n }\n\n if (Platform.Version > 28) {\n return [permissionModule.PERMISSIONS.ANDROID.READ_EXTERNAL_STORAGE];\n }\n\n return [\n permissionModule.PERMISSIONS.ANDROID.WRITE_EXTERNAL_STORAGE,\n permissionModule.PERMISSIONS.ANDROID.READ_EXTERNAL_STORAGE,\n ];\n}\n\nconst createNativeFileService = ({\n imagePickerModule,\n documentPickerModule,\n permissionModule,\n mediaLibraryModule,\n fsModule,\n}: {\n imagePickerModule: typeof ImagePicker;\n documentPickerModule: typeof DocumentPicker;\n permissionModule: typeof Permissions;\n mediaLibraryModule: typeof CameraRoll;\n fsModule: typeof FileAccess;\n}): FileServiceInterface => {\n const cameraPermissions: Permission[] = Platform.select({\n ios: [permissionModule.PERMISSIONS.IOS.CAMERA, permissionModule.PERMISSIONS.IOS.MICROPHONE],\n android: [permissionModule.PERMISSIONS.ANDROID.CAMERA],\n default: [],\n });\n const mediaLibraryPermissions: Permission[] = Platform.select({\n ios: [permissionModule.PERMISSIONS.IOS.PHOTO_LIBRARY, permissionModule.PERMISSIONS.IOS.PHOTO_LIBRARY_ADD_ONLY],\n android: getAndroidStoragePermissionsByAPILevel(permissionModule),\n default: [],\n });\n\n class NativeFileService implements FileServiceInterface {\n async hasCameraPermission(): Promise<boolean> {\n const status = await permissionModule.checkMultiple(cameraPermissions);\n return nativePermissionGranted(status);\n }\n async requestCameraPermission(): Promise<boolean> {\n const status = await permissionModule.requestMultiple(cameraPermissions);\n return nativePermissionGranted(status);\n }\n async hasMediaLibraryPermission(): Promise<boolean> {\n const status = await permissionModule.checkMultiple(mediaLibraryPermissions);\n return nativePermissionGranted(status);\n }\n async requestMediaLibraryPermission(): Promise<boolean> {\n const status = await permissionModule.requestMultiple(mediaLibraryPermissions);\n return nativePermissionGranted(status);\n }\n\n async openCamera(options?: OpenCameraOptions): Promise<FilePickerResponse> {\n const hasPermission = await this.hasCameraPermission();\n if (!hasPermission) {\n const granted = await this.requestCameraPermission();\n if (!granted) {\n options?.onOpenFailure?.(SBUError.PERMISSIONS_DENIED);\n return null;\n }\n }\n\n const response = await imagePickerModule.launchCamera({\n presentationStyle: 'fullScreen',\n cameraType: options?.cameraType ?? 'back',\n mediaType: (() => {\n switch (options?.mediaType) {\n case 'photo':\n return 'photo';\n case 'video':\n return 'video';\n case 'all':\n return 'mixed';\n default:\n return 'photo';\n }\n })(),\n });\n if (response.didCancel) return null;\n if (response.errorCode === 'camera_unavailable') {\n options?.onOpenFailure?.(SBUError.DEVICE_UNAVAILABLE, new Error(response.errorMessage));\n return null;\n }\n\n const { fileName: name, fileSize: size, type, uri } = response.assets?.[0] ?? {};\n return normalizeFile({ uri, size, name, type });\n }\n async openMediaLibrary(options?: OpenMediaLibraryOptions): Promise<FilePickerResponse[] | null> {\n /**\n * NOTE: options.selectionLimit {@link https://github.com/react-native-image-picker/react-native-image-picker#options}\n * We do not support 0 (any number of files)\n **/\n const selectionLimit = options?.selectionLimit || 1;\n const hasPermission = await this.hasMediaLibraryPermission();\n if (!hasPermission) {\n const granted = await this.requestMediaLibraryPermission();\n if (!granted) {\n options?.onOpenFailure?.(SBUError.PERMISSIONS_DENIED);\n return null;\n }\n }\n\n const response = await imagePickerModule.launchImageLibrary({\n presentationStyle: 'fullScreen',\n selectionLimit,\n mediaType: (() => {\n switch (options?.mediaType) {\n case 'photo':\n return 'photo';\n case 'video':\n return 'video';\n case 'all':\n return 'mixed';\n default:\n return 'photo';\n }\n })(),\n });\n if (response.didCancel) return null;\n if (response.errorCode === 'camera_unavailable') {\n options?.onOpenFailure?.(SBUError.DEVICE_UNAVAILABLE, new Error(response.errorMessage));\n return null;\n }\n\n return Promise.all(\n (response.assets || [])\n .slice(0, selectionLimit)\n .map(({ fileName: name, fileSize: size, type, uri }) => normalizeFile({ uri, size, name, type })),\n );\n }\n async openDocument(options?: OpenDocumentOptions): Promise<FilePickerResponse> {\n try {\n const { uri, size, name, type } = await documentPickerModule.pickSingle();\n return normalizeFile({ uri, size, name, type });\n } catch (e) {\n if (!documentPickerModule.isCancel(e) && documentPickerModule.isInProgress(e)) {\n options?.onOpenFailure?.(SBUError.UNKNOWN, e);\n }\n return null;\n }\n }\n async save(options: SaveOptions): Promise<string> {\n const hasPermission = await this.hasMediaLibraryPermission();\n if (!hasPermission) {\n const granted = await this.requestMediaLibraryPermission();\n if (!granted) throw new Error('Permission not granted');\n }\n\n const { downloadedPath, file } = await this.downloadFile(options);\n\n if (Platform.OS === 'ios') {\n if (file.type === 'image' || file.type === 'video') {\n const mediaTypeMap = { 'image': 'photo', 'video': 'video' } as const;\n const mediaType = mediaTypeMap[file.type];\n await mediaLibraryModule.save(downloadedPath, { type: mediaType });\n }\n }\n\n if (Platform.OS === 'android') {\n const externalDirMap = { 'file': 'downloads', 'audio': 'audio', 'image': 'images', 'video': 'video' } as const;\n const externalDir = externalDirMap[file.type];\n await fsModule.FileSystem.cpExternal(downloadedPath, file.name, externalDir).catch(() => {\n Logger.error('Failed to save file to external storage. Retry saving to downloads directory instead.');\n return fsModule.FileSystem.cpExternal(downloadedPath, file.name, 'downloads');\n });\n }\n\n return downloadedPath;\n }\n\n private buildDownloadPath = async (options: SaveOptions) => {\n const dirname = Platform.select({ android: fsModule.Dirs.CacheDir, default: fsModule.Dirs.DocumentDir });\n const context = { dirname, filename: options.fileName };\n const extension =\n getFileExtension(options.fileName) ||\n getFileExtensionFromMime(options.fileType) ||\n getFileExtension(options.fileUrl) ||\n (await getFileExtensionFromUri(options.fileUrl));\n\n if (extension) context.filename = normalizeFileName(context.filename, extension);\n\n return { path: `${context.dirname}/${context.filename}`, ...context };\n };\n\n private downloadFile = async (options: SaveOptions) => {\n const { path, filename } = await this.buildDownloadPath(options);\n await fsModule.FileSystem.fetch(options.fileUrl, { path });\n return {\n downloadedPath: path,\n file: {\n name: filename,\n type: getFileType(getFileExtension(path)),\n } as const,\n };\n };\n\n createRecordFilePath(customExtension = 'm4a'): { recordFilePath: string; uri: string } {\n const filename = `record-${Date.now()}.${customExtension}`;\n const path = `${fsModule.Dirs.CacheDir}/${filename}`;\n return Platform.select({\n ios: {\n uri: path,\n recordFilePath: filename,\n },\n android: {\n uri: path.startsWith('file://') ? path : 'file://' + path,\n recordFilePath: path,\n },\n default: {\n uri: path,\n recordFilePath: path,\n },\n });\n }\n }\n\n return new NativeFileService();\n};\n\nexport default createNativeFileService;\n"],"mappings":"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"}
1
+ {"version":3,"names":["Platform","Logger","getFileExtension","getFileExtensionFromMime","getFileExtensionFromUri","getFileType","normalizeFileName","SBUError","nativePermissionGranted","normalizeFile","getAndroidStoragePermissionsByAPILevel","permissionModule","OS","Version","PERMISSIONS","ANDROID","READ_EXTERNAL_STORAGE","WRITE_EXTERNAL_STORAGE","createNativeFileService","_ref","imagePickerModule","documentPickerModule","mediaLibraryModule","fsModule","cameraPermissions","select","ios","IOS","CAMERA","MICROPHONE","android","default","mediaLibraryPermissions","PHOTO_LIBRARY","PHOTO_LIBRARY_ADD_ONLY","NativeFileService","constructor","_defineProperty","options","dirname","Dirs","CacheDir","DocumentDir","context","filename","fileName","extension","fileType","fileUrl","path","buildDownloadPath","FileSystem","fetch","downloadedPath","file","name","type","hasCameraPermission","status","checkMultiple","requestCameraPermission","requestMultiple","hasMediaLibraryPermission","requestMediaLibraryPermission","openCamera","_response$assets","hasPermission","granted","_options$onOpenFailur","onOpenFailure","call","PERMISSIONS_DENIED","response","launchCamera","presentationStyle","cameraType","mediaType","didCancel","errorCode","_options$onOpenFailur2","DEVICE_UNAVAILABLE","Error","errorMessage","fileSize","size","uri","assets","openMediaLibrary","selectionLimit","_options$onOpenFailur3","launchImageLibrary","_options$onOpenFailur4","Promise","all","slice","map","_ref2","openDocument","pickSingle","e","isCancel","isInProgress","_options$onOpenFailur5","UNKNOWN","save","downloadFile","mediaTypeMap","externalDirMap","externalDir","cpExternal","catch","error","createRecordFilePath","customExtension","arguments","length","undefined","Date","now","recordFilePath","startsWith"],"sources":["createFileService.native.ts"],"sourcesContent":["import type { CameraRoll } from '@react-native-camera-roll/camera-roll';\nimport { Platform } from 'react-native';\nimport type * as DocumentPicker from 'react-native-document-picker';\nimport type * as FileAccess from 'react-native-file-access';\nimport type * as ImagePicker from 'react-native-image-picker';\nimport type * as Permissions from 'react-native-permissions';\nimport type { Permission } from 'react-native-permissions';\n\nimport {\n Logger,\n getFileExtension,\n getFileExtensionFromMime,\n getFileExtensionFromUri,\n getFileType,\n normalizeFileName,\n} from '@sendbird/uikit-utils';\n\nimport SBUError from '../libs/SBUError';\nimport nativePermissionGranted from '../utils/nativePermissionGranted';\nimport normalizeFile from '../utils/normalizeFile';\nimport type {\n FilePickerResponse,\n FileServiceInterface,\n OpenCameraOptions,\n OpenDocumentOptions,\n OpenMediaLibraryOptions,\n SaveOptions,\n} from './types';\n\nfunction getAndroidStoragePermissionsByAPILevel(permissionModule: typeof Permissions): Permission[] {\n if (Platform.OS !== 'android') return [];\n\n if (Platform.Version > 32) {\n return [];\n }\n\n if (Platform.Version > 28) {\n return [permissionModule.PERMISSIONS.ANDROID.READ_EXTERNAL_STORAGE];\n }\n\n return [\n permissionModule.PERMISSIONS.ANDROID.WRITE_EXTERNAL_STORAGE,\n permissionModule.PERMISSIONS.ANDROID.READ_EXTERNAL_STORAGE,\n ];\n}\n\nconst createNativeFileService = ({\n imagePickerModule,\n documentPickerModule,\n permissionModule,\n mediaLibraryModule,\n fsModule,\n}: {\n imagePickerModule: typeof ImagePicker;\n documentPickerModule: typeof DocumentPicker;\n permissionModule: typeof Permissions;\n mediaLibraryModule: typeof CameraRoll;\n fsModule: typeof FileAccess;\n}): FileServiceInterface => {\n const cameraPermissions: Permission[] = Platform.select({\n ios: [permissionModule.PERMISSIONS.IOS.CAMERA, permissionModule.PERMISSIONS.IOS.MICROPHONE],\n android: [],\n default: [],\n });\n const mediaLibraryPermissions: Permission[] = Platform.select({\n ios: [permissionModule.PERMISSIONS.IOS.PHOTO_LIBRARY, permissionModule.PERMISSIONS.IOS.PHOTO_LIBRARY_ADD_ONLY],\n android: getAndroidStoragePermissionsByAPILevel(permissionModule),\n default: [],\n });\n\n class NativeFileService implements FileServiceInterface {\n async hasCameraPermission(): Promise<boolean> {\n const status = await permissionModule.checkMultiple(cameraPermissions);\n return nativePermissionGranted(status);\n }\n async requestCameraPermission(): Promise<boolean> {\n const status = await permissionModule.requestMultiple(cameraPermissions);\n return nativePermissionGranted(status);\n }\n async hasMediaLibraryPermission(): Promise<boolean> {\n const status = await permissionModule.checkMultiple(mediaLibraryPermissions);\n return nativePermissionGranted(status);\n }\n async requestMediaLibraryPermission(): Promise<boolean> {\n const status = await permissionModule.requestMultiple(mediaLibraryPermissions);\n return nativePermissionGranted(status);\n }\n\n async openCamera(options?: OpenCameraOptions): Promise<FilePickerResponse> {\n const hasPermission = await this.hasCameraPermission();\n if (!hasPermission) {\n const granted = await this.requestCameraPermission();\n if (!granted) {\n options?.onOpenFailure?.(SBUError.PERMISSIONS_DENIED);\n return null;\n }\n }\n\n const response = await imagePickerModule.launchCamera({\n presentationStyle: 'fullScreen',\n cameraType: options?.cameraType ?? 'back',\n mediaType: (() => {\n switch (options?.mediaType) {\n case 'photo':\n return 'photo';\n case 'video':\n return 'video';\n case 'all':\n return 'mixed';\n default:\n return 'photo';\n }\n })(),\n });\n if (response.didCancel) return null;\n if (response.errorCode === 'camera_unavailable') {\n options?.onOpenFailure?.(SBUError.DEVICE_UNAVAILABLE, new Error(response.errorMessage));\n return null;\n }\n\n const { fileName: name, fileSize: size, type, uri } = response.assets?.[0] ?? {};\n return normalizeFile({ uri, size, name, type });\n }\n async openMediaLibrary(options?: OpenMediaLibraryOptions): Promise<FilePickerResponse[] | null> {\n /**\n * NOTE: options.selectionLimit {@link https://github.com/react-native-image-picker/react-native-image-picker#options}\n * We do not support 0 (any number of files)\n **/\n const selectionLimit = options?.selectionLimit || 1;\n const hasPermission = await this.hasMediaLibraryPermission();\n if (!hasPermission) {\n const granted = await this.requestMediaLibraryPermission();\n if (!granted) {\n options?.onOpenFailure?.(SBUError.PERMISSIONS_DENIED);\n return null;\n }\n }\n\n const response = await imagePickerModule.launchImageLibrary({\n presentationStyle: 'fullScreen',\n selectionLimit,\n mediaType: (() => {\n switch (options?.mediaType) {\n case 'photo':\n return 'photo';\n case 'video':\n return 'video';\n case 'all':\n return 'mixed';\n default:\n return 'photo';\n }\n })(),\n });\n if (response.didCancel) return null;\n if (response.errorCode === 'camera_unavailable') {\n options?.onOpenFailure?.(SBUError.DEVICE_UNAVAILABLE, new Error(response.errorMessage));\n return null;\n }\n\n return Promise.all(\n (response.assets || [])\n .slice(0, selectionLimit)\n .map(({ fileName: name, fileSize: size, type, uri }) => normalizeFile({ uri, size, name, type })),\n );\n }\n async openDocument(options?: OpenDocumentOptions): Promise<FilePickerResponse> {\n try {\n const { uri, size, name, type } = await documentPickerModule.pickSingle();\n return normalizeFile({ uri, size, name, type });\n } catch (e) {\n if (!documentPickerModule.isCancel(e) && documentPickerModule.isInProgress(e)) {\n options?.onOpenFailure?.(SBUError.UNKNOWN, e);\n }\n return null;\n }\n }\n async save(options: SaveOptions): Promise<string> {\n const hasPermission = await this.hasMediaLibraryPermission();\n if (!hasPermission) {\n const granted = await this.requestMediaLibraryPermission();\n if (!granted) throw new Error('Permission not granted');\n }\n\n const { downloadedPath, file } = await this.downloadFile(options);\n\n if (Platform.OS === 'ios') {\n if (file.type === 'image' || file.type === 'video') {\n const mediaTypeMap = { 'image': 'photo', 'video': 'video' } as const;\n const mediaType = mediaTypeMap[file.type];\n await mediaLibraryModule.save(downloadedPath, { type: mediaType });\n }\n }\n\n if (Platform.OS === 'android') {\n const externalDirMap = { 'file': 'downloads', 'audio': 'audio', 'image': 'images', 'video': 'video' } as const;\n const externalDir = externalDirMap[file.type];\n await fsModule.FileSystem.cpExternal(downloadedPath, file.name, externalDir).catch(() => {\n Logger.error('Failed to save file to external storage. Retry saving to downloads directory instead.');\n return fsModule.FileSystem.cpExternal(downloadedPath, file.name, 'downloads');\n });\n }\n\n return downloadedPath;\n }\n\n private buildDownloadPath = async (options: SaveOptions) => {\n const dirname = Platform.select({ android: fsModule.Dirs.CacheDir, default: fsModule.Dirs.DocumentDir });\n const context = { dirname, filename: options.fileName };\n const extension =\n getFileExtension(options.fileName) ||\n getFileExtensionFromMime(options.fileType) ||\n getFileExtension(options.fileUrl) ||\n (await getFileExtensionFromUri(options.fileUrl));\n\n if (extension) context.filename = normalizeFileName(context.filename, extension);\n\n return { path: `${context.dirname}/${context.filename}`, ...context };\n };\n\n private downloadFile = async (options: SaveOptions) => {\n const { path, filename } = await this.buildDownloadPath(options);\n await fsModule.FileSystem.fetch(options.fileUrl, { path });\n return {\n downloadedPath: path,\n file: {\n name: filename,\n type: getFileType(getFileExtension(path)),\n } as const,\n };\n };\n\n createRecordFilePath(customExtension = 'm4a'): { recordFilePath: string; uri: string } {\n const filename = `record-${Date.now()}.${customExtension}`;\n const path = `${fsModule.Dirs.CacheDir}/${filename}`;\n return Platform.select({\n ios: {\n uri: path,\n recordFilePath: filename,\n },\n android: {\n uri: path.startsWith('file://') ? path : 'file://' + path,\n recordFilePath: path,\n },\n default: {\n uri: path,\n recordFilePath: path,\n },\n });\n }\n }\n\n return new NativeFileService();\n};\n\nexport default createNativeFileService;\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
2
2
  function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
3
3
  function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
4
- import { matchesOneOf } from '@sendbird/uikit-utils';
4
+ import { Logger, matchesOneOf } from '@sendbird/uikit-utils';
5
5
  import expoPermissionGranted from '../utils/expoPermissionGranted';
6
6
  const createExpoPlayerService = _ref => {
7
7
  let {
@@ -21,10 +21,16 @@ const createExpoPlayerService = _ref => {
21
21
  });
22
22
  });
23
23
  _defineProperty(this, "setListener", () => {
24
- sound.setProgressUpdateIntervalAsync(100);
24
+ sound.setProgressUpdateIntervalAsync(100).catch(error => {
25
+ Logger.warn('[PlayerService.Expo] Failed to set progress update interval', error);
26
+ });
25
27
  sound.setOnPlaybackStatusUpdate(status => {
26
28
  if (status.isLoaded) {
27
- if (status.didJustFinish) this.stop();
29
+ if (status.didJustFinish) {
30
+ this.stop().catch(error => {
31
+ Logger.warn('[PlayerService.Expo] Failed to stop in OnPlaybackStatusUpdate', error);
32
+ });
33
+ }
28
34
  if (status.isPlaying) {
29
35
  this.playbackSubscribers.forEach(callback => {
30
36
  callback({
@@ -1 +1 @@
1
- {"version":3,"names":["matchesOneOf","expoPermissionGranted","createExpoPlayerService","_ref","avModule","sound","Audio","Sound","VoicePlayer","constructor","_defineProperty","Set","state","stateSubscribers","forEach","callback","setProgressUpdateIntervalAsync","setOnPlaybackStatusUpdate","status","isLoaded","didJustFinish","stop","isPlaying","playbackSubscribers","currentTime","positionMillis","duration","durationMillis","stopped","getPermissionsAsync","requestPermissionsAsync","add","delete","uri","setState","loadAsync","shouldPlay","prepare","setListener","playAsync","e","undefined","removeListener","pauseAsync","stopAsync","unloadAsync","clear","time","playFromPositionAsync"],"sources":["createPlayerService.expo.tsx"],"sourcesContent":["import type * as ExpoAV from 'expo-av';\n\nimport { matchesOneOf } from '@sendbird/uikit-utils';\n\nimport expoPermissionGranted from '../utils/expoPermissionGranted';\nimport type { PlayerServiceInterface, Unsubscribe } from './types';\n\ntype Modules = {\n avModule: typeof ExpoAV;\n};\ntype PlaybackListener = Parameters<PlayerServiceInterface['addPlaybackListener']>[number];\ntype StateListener = Parameters<PlayerServiceInterface['addStateListener']>[number];\nconst createExpoPlayerService = ({ avModule }: Modules): PlayerServiceInterface => {\n const sound = new avModule.Audio.Sound();\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 private setState = (state: PlayerServiceInterface['state']) => {\n this.state = state;\n this.stateSubscribers.forEach((callback) => {\n callback(state);\n });\n };\n\n private setListener = () => {\n sound.setProgressUpdateIntervalAsync(100);\n sound.setOnPlaybackStatusUpdate((status) => {\n if (status.isLoaded) {\n if (status.didJustFinish) this.stop();\n if (status.isPlaying) {\n this.playbackSubscribers.forEach((callback) => {\n callback({\n currentTime: status.positionMillis,\n duration: status.durationMillis ?? 0,\n stopped: status.didJustFinish,\n });\n });\n }\n }\n });\n };\n\n private removeListener = () => {\n sound.setOnPlaybackStatusUpdate(null);\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 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 private prepare = async (uri: string) => {\n this.setState('preparing');\n await sound.loadAsync({ uri }, { shouldPlay: false }, true);\n this.uri = uri;\n };\n\n public play = async (uri: string): Promise<void> => {\n if (matchesOneOf(this.state, ['idle', 'stopped'])) {\n try {\n await this.prepare(uri);\n this.setListener();\n await sound.playAsync();\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 sound.playAsync();\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 sound.pauseAsync();\n this.removeListener();\n this.setState('paused');\n }\n };\n\n public stop = async (): Promise<void> => {\n if (matchesOneOf(this.state, ['playing', 'paused'])) {\n await sound.stopAsync();\n await sound.unloadAsync();\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 sound.playFromPositionAsync(time);\n }\n };\n }\n\n return new VoicePlayer();\n};\n\nexport default createExpoPlayerService;\n"],"mappings":"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"}
1
+ {"version":3,"names":["Logger","matchesOneOf","expoPermissionGranted","createExpoPlayerService","_ref","avModule","sound","Audio","Sound","VoicePlayer","constructor","_defineProperty","Set","state","stateSubscribers","forEach","callback","setProgressUpdateIntervalAsync","catch","error","warn","setOnPlaybackStatusUpdate","status","isLoaded","didJustFinish","stop","isPlaying","playbackSubscribers","currentTime","positionMillis","duration","durationMillis","stopped","getPermissionsAsync","requestPermissionsAsync","add","delete","uri","setState","loadAsync","shouldPlay","prepare","setListener","playAsync","e","undefined","removeListener","pauseAsync","stopAsync","unloadAsync","clear","time","playFromPositionAsync"],"sources":["createPlayerService.expo.tsx"],"sourcesContent":["import type * as ExpoAV from 'expo-av';\n\nimport { Logger, matchesOneOf } from '@sendbird/uikit-utils';\n\nimport expoPermissionGranted from '../utils/expoPermissionGranted';\nimport type { PlayerServiceInterface, Unsubscribe } from './types';\n\ntype Modules = {\n avModule: typeof ExpoAV;\n};\ntype PlaybackListener = Parameters<PlayerServiceInterface['addPlaybackListener']>[number];\ntype StateListener = Parameters<PlayerServiceInterface['addStateListener']>[number];\nconst createExpoPlayerService = ({ avModule }: Modules): PlayerServiceInterface => {\n const sound = new avModule.Audio.Sound();\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 private setState = (state: PlayerServiceInterface['state']) => {\n this.state = state;\n this.stateSubscribers.forEach((callback) => {\n callback(state);\n });\n };\n\n private setListener = () => {\n sound.setProgressUpdateIntervalAsync(100).catch((error) => {\n Logger.warn('[PlayerService.Expo] Failed to set progress update interval', error);\n });\n sound.setOnPlaybackStatusUpdate((status) => {\n if (status.isLoaded) {\n if (status.didJustFinish) {\n this.stop().catch((error) => {\n Logger.warn('[PlayerService.Expo] Failed to stop in OnPlaybackStatusUpdate', error);\n });\n }\n if (status.isPlaying) {\n this.playbackSubscribers.forEach((callback) => {\n callback({\n currentTime: status.positionMillis,\n duration: status.durationMillis ?? 0,\n stopped: status.didJustFinish,\n });\n });\n }\n }\n });\n };\n\n private removeListener = () => {\n sound.setOnPlaybackStatusUpdate(null);\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 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 private prepare = async (uri: string) => {\n this.setState('preparing');\n await sound.loadAsync({ uri }, { shouldPlay: false }, true);\n this.uri = uri;\n };\n\n public play = async (uri: string): Promise<void> => {\n if (matchesOneOf(this.state, ['idle', 'stopped'])) {\n try {\n await this.prepare(uri);\n this.setListener();\n await sound.playAsync();\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 sound.playAsync();\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 sound.pauseAsync();\n this.removeListener();\n this.setState('paused');\n }\n };\n\n public stop = async (): Promise<void> => {\n if (matchesOneOf(this.state, ['playing', 'paused'])) {\n await sound.stopAsync();\n await sound.unloadAsync();\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 sound.playFromPositionAsync(time);\n }\n };\n }\n\n return new VoicePlayer();\n};\n\nexport default createExpoPlayerService;\n"],"mappings":"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"}
@@ -2,7 +2,7 @@ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key i
2
2
  function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
3
3
  function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
4
4
  import { Platform } from 'react-native';
5
- import { matchesOneOf, sleep } from '@sendbird/uikit-utils';
5
+ import { Logger, matchesOneOf, sleep } from '@sendbird/uikit-utils';
6
6
  const createNativePlayerService = _ref => {
7
7
  let {
8
8
  audioRecorderModule,
@@ -22,9 +22,13 @@ const createNativePlayerService = _ref => {
22
22
  });
23
23
  });
24
24
  _defineProperty(this, "setListener", () => {
25
- module.addPlayBackListener(data => {
25
+ module.addPlayBackListener(async data => {
26
26
  const stopped = data.currentPosition >= data.duration;
27
- if (stopped) this.stop();
27
+ if (stopped) {
28
+ this.stop().catch(error => {
29
+ Logger.warn('[PlayerService.Native] Failed to stop in PlayBackListener', error);
30
+ });
31
+ }
28
32
  if (this.state === 'playing') {
29
33
  this.playbackSubscribers.forEach(callback => {
30
34
  callback({
@@ -41,16 +45,15 @@ const createNativePlayerService = _ref => {
41
45
  });
42
46
  _defineProperty(this, "requestPermission", async () => {
43
47
  if (Platform.OS === 'android') {
48
+ if (Platform.Version > 32) return true;
44
49
  const {
45
- READ_MEDIA_AUDIO,
46
50
  READ_EXTERNAL_STORAGE
47
51
  } = permissionModule.PERMISSIONS.ANDROID;
48
- const permission = Platform.Version > 32 ? READ_MEDIA_AUDIO : READ_EXTERNAL_STORAGE;
49
- const status = await permissionModule.check(permission);
52
+ const status = await permissionModule.check(READ_EXTERNAL_STORAGE);
50
53
  if (status === 'granted') {
51
54
  return true;
52
55
  } else {
53
- const status = await permissionModule.request(permission);
56
+ const status = await permissionModule.request(READ_EXTERNAL_STORAGE);
54
57
  return status === 'granted';
55
58
  }
56
59
  } else {
@@ -123,7 +126,9 @@ const createNativePlayerService = _ref => {
123
126
  await module.seekToPlayer(time);
124
127
  }
125
128
  });
126
- module.setSubscriptionDuration(0.1);
129
+ module.setSubscriptionDuration(0.1).catch(error => {
130
+ Logger.warn('[PlayerService.Native] Failed to set subscription duration', error);
131
+ });
127
132
  }
128
133
  }
129
134
  return new VoicePlayer();
@@ -1 +1 @@
1
- {"version":3,"names":["Platform","matchesOneOf","sleep","createNativePlayerService","_ref","audioRecorderModule","permissionModule","module","default","VoicePlayer","constructor","_defineProperty","Set","state","stateSubscribers","forEach","callback","addPlayBackListener","data","stopped","currentPosition","duration","stop","playbackSubscribers","currentTime","removePlayBackListener","OS","READ_MEDIA_AUDIO","READ_EXTERNAL_STORAGE","PERMISSIONS","ANDROID","permission","Version","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 { 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);\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((data) => {\n const stopped = data.currentPosition >= data.duration;\n\n if (stopped) this.stop();\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 const { READ_MEDIA_AUDIO, READ_EXTERNAL_STORAGE } = permissionModule.PERMISSIONS.ANDROID;\n const permission = Platform.Version > 32 ? READ_MEDIA_AUDIO : READ_EXTERNAL_STORAGE;\n\n const status = await permissionModule.check(permission);\n if (status === 'granted') {\n return true;\n } else {\n const status = await permissionModule.request(permission);\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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"}
1
+ {"version":3,"names":["Platform","Logger","matchesOneOf","sleep","createNativePlayerService","_ref","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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"}
@@ -2,7 +2,7 @@ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key i
2
2
  function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
3
3
  function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
4
4
  import { Platform } from 'react-native';
5
- import { matchesOneOf, sleep } from '@sendbird/uikit-utils';
5
+ import { Logger, matchesOneOf, sleep } from '@sendbird/uikit-utils';
6
6
  import VoiceMessageConfig from '../libs/VoiceMessageConfig';
7
7
  import nativePermissionGranted from '../utils/nativePermissionGranted';
8
8
  const createNativeRecorderService = _ref => {
@@ -128,10 +128,16 @@ const createNativeRecorderService = _ref => {
128
128
  this.recordingSubscribers.clear();
129
129
  this.setState('idle');
130
130
  });
131
- module.setSubscriptionDuration(0.1);
131
+ module.setSubscriptionDuration(0.1).catch(error => {
132
+ Logger.warn('[RecorderService.Native] Failed to set subscription duration', error);
133
+ });
132
134
  module.addRecordBackListener(data => {
133
135
  const completed = data.currentPosition >= this.options.maxDuration;
134
- if (completed) this.stop();
136
+ if (completed) {
137
+ this.stop().catch(error => {
138
+ Logger.warn('[RecorderService.Native] Failed to stop in RecordBackListener', error);
139
+ });
140
+ }
135
141
  if (this.state === 'recording') {
136
142
  this.recordingSubscribers.forEach(callback => {
137
143
  callback({
@@ -1 +1 @@
1
- {"version":3,"names":["Platform","matchesOneOf","sleep","VoiceMessageConfig","nativePermissionGranted","createNativeRecorderService","_ref","audioRecorderModule","permissionModule","module","default","VoiceRecorder","constructor","_defineProperty","undefined","minDuration","DEFAULT","RECORDER","MIN_DURATION","maxDuration","MAX_DURATION","extension","EXTENSION","minWaitingTime","elapsedTime","Date","now","_recordStartedAt","Set","sampleRate","SAMPLE_RATE","bitRate","BIT_RATE","audioChannels","CHANNELS","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","requestMultiple","recordingSubscribers","add","delete","uri","setState","startRecorder","audioOptions","e","buffer","_getRecorderStopSafeBuffer","stopRecorder","stop","clear","setSubscriptionDuration","addRecordBackListener","data","completed","currentPosition","options","currentTime"],"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 { 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);\n module.addRecordBackListener((data) => {\n const completed = data.currentPosition >= this.options.maxDuration;\n\n if (completed) this.stop();\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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"}
1
+ {"version":3,"names":["Platform","Logger","matchesOneOf","sleep","VoiceMessageConfig","nativePermissionGranted","createNativeRecorderService","_ref","audioRecorderModule","permissionModule","module","default","VoiceRecorder","constructor","_defineProperty","undefined","minDuration","DEFAULT","RECORDER","MIN_DURATION","maxDuration","MAX_DURATION","extension","EXTENSION","minWaitingTime","elapsedTime","Date","now","_recordStartedAt","Set","sampleRate","SAMPLE_RATE","bitRate","BIT_RATE","audioChannels","CHANNELS","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","requestMultiple","recordingSubscribers","add","delete","uri","setState","startRecorder","audioOptions","e","buffer","_getRecorderStopSafeBuffer","stopRecorder","stop","clear","setSubscriptionDuration","catch","error","warn","addRecordBackListener","data","completed","currentPosition","options","currentTime"],"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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"}
@@ -1,3 +1,3 @@
1
- const VERSION = '3.7.3';
1
+ const VERSION = '3.7.5';
2
2
  export default VERSION;
3
3
  //# sourceMappingURL=version.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["VERSION"],"sources":["version.ts"],"sourcesContent":["const VERSION = '3.7.3';\nexport default VERSION;\n"],"mappings":"AAAA,MAAMA,OAAO,GAAG,OAAO;AACvB,eAAeA,OAAO"}
1
+ {"version":3,"names":["VERSION"],"sources":["version.ts"],"sourcesContent":["const VERSION = '3.7.5';\nexport default VERSION;\n"],"mappings":"AAAA,MAAMA,OAAO,GAAG,OAAO;AACvB,eAAeA,OAAO"}
@@ -14,7 +14,7 @@ import type { StringSet } from '../localization/StringSet.type';
14
14
  import type { ClipboardServiceInterface, FileServiceInterface, MediaServiceInterface, NotificationServiceInterface, PlayerServiceInterface, RecorderServiceInterface } from '../platform/types';
15
15
  import { ErrorBoundaryProps, LocalCacheStorage } from '../types';
16
16
  export declare const SendbirdUIKit: Readonly<{
17
- VERSION: "3.7.3";
17
+ VERSION: "3.7.5";
18
18
  PLATFORM: string;
19
19
  DEFAULT: {
20
20
  AUTO_PUSH_TOKEN_REGISTRATION: boolean;
@@ -12,7 +12,7 @@ export interface SBUHandlers {
12
12
  * Note that this function is also called redundantly
13
13
  * when `onPressMediaMessage` handler is triggered by clicking on media messages containing images, videos, or audio.
14
14
  */
15
- onOpenFileURL: (url: string) => void;
15
+ onOpenFileURL?: (url: string) => void;
16
16
  }
17
17
  type Props = React.PropsWithChildren<SBUHandlers>;
18
18
  export type SBUHandlersContextType = SBUHandlers;
@@ -1,2 +1,2 @@
1
- declare const VERSION = "3.7.3";
1
+ declare const VERSION = "3.7.5";
2
2
  export default VERSION;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sendbird/uikit-react-native",
3
- "version": "3.7.3",
3
+ "version": "3.7.5",
4
4
  "description": "Sendbird UIKit for React Native: A feature-rich and customizable chat UI kit with messaging, channel management, and user authentication.",
5
5
  "keywords": [
6
6
  "sendbird",
@@ -60,10 +60,10 @@
60
60
  },
61
61
  "dependencies": {
62
62
  "@openspacelabs/react-native-zoomable-view": "^2.1.5",
63
- "@sendbird/uikit-chat-hooks": "3.7.3",
64
- "@sendbird/uikit-react-native-foundation": "3.7.3",
63
+ "@sendbird/uikit-chat-hooks": "3.7.5",
64
+ "@sendbird/uikit-react-native-foundation": "3.7.5",
65
65
  "@sendbird/uikit-tools": "0.0.1-alpha.77",
66
- "@sendbird/uikit-utils": "3.7.3"
66
+ "@sendbird/uikit-utils": "3.7.5"
67
67
  },
68
68
  "devDependencies": {
69
69
  "@bam.tech/react-native-image-resizer": "^3.0.4",
@@ -109,7 +109,7 @@
109
109
  "@react-native-clipboard/clipboard": ">=1.8.5",
110
110
  "@react-native-community/netinfo": ">=9.3.0",
111
111
  "@react-native-firebase/messaging": ">=14.4.0",
112
- "@sendbird/chat": "^4.12.9",
112
+ "@sendbird/chat": "^4.13.3",
113
113
  "@sendbird/react-native-scrollview-enhancer": "*",
114
114
  "date-fns": ">=2.28.0",
115
115
  "expo-av": ">=12.0.4",
@@ -208,5 +208,5 @@
208
208
  ]
209
209
  ]
210
210
  },
211
- "gitHead": "c6efa80d5e1859100d6cb02c239f0a2c45eec860"
211
+ "gitHead": "5ab71ecbed6948f2e26797d3b566369580386b53"
212
212
  }
@@ -216,7 +216,8 @@ const SendInput = forwardRef<RNTextInput, SendInputProps>(function SendInput(
216
216
  onClose={onClose}
217
217
  onDismiss={() => {
218
218
  onDismiss();
219
- Promise.allSettled([playerService.reset(), recorderService.reset()]);
219
+ playerService.reset().catch(() => {});
220
+ recorderService.reset().catch(() => {});
220
221
  }}
221
222
  backgroundStyle={{ justifyContent: 'flex-end' }}
222
223
  visible={voiceMessageInputVisible}
@@ -10,7 +10,7 @@ import {
10
10
  createStyleSheet,
11
11
  useUIKitTheme,
12
12
  } from '@sendbird/uikit-react-native-foundation';
13
- import { conditionChaining, millsToMMSS } from '@sendbird/uikit-utils';
13
+ import { Logger, conditionChaining, millsToMMSS } from '@sendbird/uikit-utils';
14
14
 
15
15
  import { useLocalization } from '../../hooks/useContext';
16
16
  import useVoiceMessageInput from '../../hooks/useVoiceMessageInput';
@@ -32,34 +32,50 @@ const VoiceMessageInput = ({ onClose, onSend }: VoiceMessageInputProps) => {
32
32
  const uiColors = colors.ui.voiceMessageInput.default[state.status !== 'idle' ? 'active' : 'inactive'];
33
33
 
34
34
  const onPressCancel = async () => {
35
- actions.cancel();
36
- onClose();
35
+ await actions
36
+ .cancel()
37
+ .catch((error) => {
38
+ Logger.warn('Failed to cancel voice message input', error);
39
+ })
40
+ .finally(() => {
41
+ onClose();
42
+ });
37
43
  };
38
44
 
39
45
  const onPressSend = async () => {
40
- actions.send();
41
- onClose();
46
+ await actions
47
+ .send()
48
+ .catch((error) => {
49
+ Logger.warn('Failed to send voice message', error);
50
+ })
51
+ .finally(() => {
52
+ onClose();
53
+ });
42
54
  };
43
55
 
44
- const onPressVoiceMessageAction = () => {
45
- switch (state.status) {
46
- case 'idle':
47
- actions.startRecording();
48
- break;
49
- case 'recording':
50
- if (lessThanMinimumDuration) {
51
- actions.cancel();
52
- } else {
53
- actions.stopRecording();
54
- }
55
- break;
56
- case 'recording_completed':
57
- case 'playing_paused':
58
- actions.playPlayer();
59
- break;
60
- case 'playing':
61
- actions.pausePlayer();
62
- break;
56
+ const onPressVoiceMessageAction = async () => {
57
+ try {
58
+ switch (state.status) {
59
+ case 'idle':
60
+ await actions.startRecording();
61
+ break;
62
+ case 'recording':
63
+ if (lessThanMinimumDuration) {
64
+ await actions.cancel();
65
+ } else {
66
+ await actions.stopRecording();
67
+ }
68
+ break;
69
+ case 'recording_completed':
70
+ case 'playing_paused':
71
+ await actions.playPlayer();
72
+ break;
73
+ case 'playing':
74
+ await actions.pausePlayer();
75
+ break;
76
+ }
77
+ } catch (error) {
78
+ Logger.warn('Failed to run voice message action.', state);
63
79
  }
64
80
  };
65
81
  const renderActionIcon = () => {
@@ -4,6 +4,7 @@ import { useSafeAreaInsets } from 'react-native-safe-area-context';
4
4
 
5
5
  import { createStyleSheet, useUIKitTheme } from '@sendbird/uikit-react-native-foundation';
6
6
  import {
7
+ Logger,
7
8
  SendbirdBaseChannel,
8
9
  SendbirdBaseMessage,
9
10
  SendbirdFileMessage,
@@ -187,12 +188,21 @@ const ChannelInput = (props: ChannelInputProps) => {
187
188
  };
188
189
 
189
190
  const useTypingTrigger = (text: string, channel: SendbirdBaseChannel) => {
190
- if (channel.isGroupChannel()) {
191
- useEffect(() => {
192
- if (text.length === 0) channel.endTyping();
193
- else channel.startTyping();
194
- }, [text]);
195
- }
191
+ useEffect(
192
+ () => {
193
+ function triggerTyping() {
194
+ if (channel.isGroupChannel()) {
195
+ const action = () => (text.length === 0 ? channel.endTyping() : channel.startTyping());
196
+ action().catch((error) => {
197
+ Logger.debug('ChannelInput: Failed to trigger typing', error);
198
+ });
199
+ }
200
+ }
201
+
202
+ triggerTyping();
203
+ },
204
+ channel.isGroupChannel() ? [text] : [],
205
+ );
196
206
  };
197
207
 
198
208
  const useTextClearOnDisabled = (setText: (val: string) => void, chatDisabled: boolean) => {
@@ -37,6 +37,7 @@ import {
37
37
  useSendbirdChat,
38
38
  useUserProfile,
39
39
  } from '../../hooks/useContext';
40
+ import SBUUtils from '../../libs/SBUUtils';
40
41
  import ChatFlatList from '../ChatFlatList';
41
42
  import { ReactionAddons } from '../ReactionAddons';
42
43
 
@@ -271,8 +272,11 @@ const useCreateMessagePressActions = <T extends SendbirdGroupChannel | SendbirdO
271
272
  const fileType = getFileType(message.type || getFileExtension(message.name));
272
273
  if (['image', 'video', 'audio'].includes(fileType)) {
273
274
  onPressMediaMessage?.(message, () => onDeleteMessage(message), getAvailableUriFromFileMessage(message));
275
+ handlers.onOpenFileURL?.(message.url);
276
+ } else {
277
+ const openFile = handlers.onOpenFileURL ?? SBUUtils.openURL;
278
+ openFile(message.url);
274
279
  }
275
- handlers.onOpenFileURL(message.url);
276
280
  }
277
281
  };
278
282