@sendbird/uikit-react-native
Version:
Sendbird UIKit for React Native: A feature-rich and customizable chat UI kit with messaging, channel management, and user authentication.
268 lines • 10.9 kB
JavaScript
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; }
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
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); }
import { Platform } from 'react-native';
import { Logger, getFileExtension, getFileExtensionFromMime, getFileExtensionFromUri, getFileType, normalizeFileName } from '@sendbird/uikit-utils';
import SBUError from '../libs/SBUError';
import nativePermissionGranted from '../utils/nativePermissionGranted';
import normalizeFile from '../utils/normalizeFile';
function getAndroidStoragePermissionsByAPILevel(permissionModule) {
if (Platform.OS !== 'android') return [];
if (Platform.Version > 32) {
return [permissionModule.PERMISSIONS.ANDROID.READ_MEDIA_AUDIO, permissionModule.PERMISSIONS.ANDROID.READ_MEDIA_IMAGES, permissionModule.PERMISSIONS.ANDROID.READ_MEDIA_VIDEO];
}
if (Platform.Version > 28) {
return [permissionModule.PERMISSIONS.ANDROID.READ_EXTERNAL_STORAGE];
}
return [permissionModule.PERMISSIONS.ANDROID.WRITE_EXTERNAL_STORAGE, permissionModule.PERMISSIONS.ANDROID.READ_EXTERNAL_STORAGE];
}
const createNativeFileService = _ref => {
let {
imagePickerModule,
documentPickerModule,
permissionModule,
mediaLibraryModule,
fsModule
} = _ref;
const cameraPermissions = Platform.select({
ios: [permissionModule.PERMISSIONS.IOS.CAMERA, permissionModule.PERMISSIONS.IOS.MICROPHONE],
android: [permissionModule.PERMISSIONS.ANDROID.CAMERA],
default: []
});
const mediaLibraryPermissions = Platform.select({
ios: [permissionModule.PERMISSIONS.IOS.PHOTO_LIBRARY, permissionModule.PERMISSIONS.IOS.PHOTO_LIBRARY_ADD_ONLY],
android: getAndroidStoragePermissionsByAPILevel(permissionModule),
default: []
});
class NativeFileService {
constructor() {
_defineProperty(this, "buildDownloadPath", async options => {
const dirname = Platform.select({
android: fsModule.Dirs.CacheDir,
default: fsModule.Dirs.DocumentDir
});
const context = {
dirname,
filename: options.fileName
};
const extension = getFileExtension(options.fileName) || getFileExtensionFromMime(options.fileType) || getFileExtension(options.fileUrl) || (await getFileExtensionFromUri(options.fileUrl));
if (extension) context.filename = normalizeFileName(context.filename, extension);
return {
path: `${context.dirname}/${context.filename}`,
...context
};
});
_defineProperty(this, "downloadFile", async options => {
const {
path,
filename
} = await this.buildDownloadPath(options);
await fsModule.FileSystem.fetch(options.fileUrl, {
path
});
return {
downloadedPath: path,
file: {
name: filename,
type: getFileType(getFileExtension(path))
}
};
});
}
async hasCameraPermission() {
const status = await permissionModule.checkMultiple(cameraPermissions);
return nativePermissionGranted(status);
}
async requestCameraPermission() {
const status = await permissionModule.requestMultiple(cameraPermissions);
return nativePermissionGranted(status);
}
async hasMediaLibraryPermission() {
const status = await permissionModule.checkMultiple(mediaLibraryPermissions);
return nativePermissionGranted(status);
}
async requestMediaLibraryPermission() {
const status = await permissionModule.requestMultiple(mediaLibraryPermissions);
return nativePermissionGranted(status);
}
async openCamera(options) {
var _response$assets;
const hasPermission = await this.hasCameraPermission();
if (!hasPermission) {
const granted = await this.requestCameraPermission();
if (!granted) {
var _options$onOpenFailur;
options === null || options === void 0 ? void 0 : (_options$onOpenFailur = options.onOpenFailure) === null || _options$onOpenFailur === void 0 ? void 0 : _options$onOpenFailur.call(options, SBUError.PERMISSIONS_DENIED);
return null;
}
}
const response = await imagePickerModule.launchCamera({
presentationStyle: 'fullScreen',
cameraType: (options === null || options === void 0 ? void 0 : options.cameraType) ?? 'back',
mediaType: (() => {
switch (options === null || options === void 0 ? void 0 : options.mediaType) {
case 'photo':
return 'photo';
case 'video':
return 'video';
case 'all':
return 'mixed';
default:
return 'photo';
}
})()
});
if (response.didCancel) return null;
if (response.errorCode === 'camera_unavailable') {
var _options$onOpenFailur2;
options === null || options === void 0 ? void 0 : (_options$onOpenFailur2 = options.onOpenFailure) === null || _options$onOpenFailur2 === void 0 ? void 0 : _options$onOpenFailur2.call(options, SBUError.DEVICE_UNAVAILABLE, new Error(response.errorMessage));
return null;
}
const {
fileName: name,
fileSize: size,
type,
uri
} = ((_response$assets = response.assets) === null || _response$assets === void 0 ? void 0 : _response$assets[0]) ?? {};
return normalizeFile({
uri,
size,
name,
type
});
}
async openMediaLibrary(options) {
/**
* NOTE: options.selectionLimit {@link https://github.com/react-native-image-picker/react-native-image-picker#options}
* We do not support 0 (any number of files)
**/
const selectionLimit = (options === null || options === void 0 ? void 0 : options.selectionLimit) || 1;
const hasPermission = await this.hasMediaLibraryPermission();
if (!hasPermission) {
const granted = await this.requestMediaLibraryPermission();
if (!granted) {
var _options$onOpenFailur3;
options === null || options === void 0 ? void 0 : (_options$onOpenFailur3 = options.onOpenFailure) === null || _options$onOpenFailur3 === void 0 ? void 0 : _options$onOpenFailur3.call(options, SBUError.PERMISSIONS_DENIED);
return null;
}
}
const response = await imagePickerModule.launchImageLibrary({
presentationStyle: 'fullScreen',
selectionLimit,
mediaType: (() => {
switch (options === null || options === void 0 ? void 0 : options.mediaType) {
case 'photo':
return 'photo';
case 'video':
return 'video';
case 'all':
return 'mixed';
default:
return 'photo';
}
})()
});
if (response.didCancel) return null;
if (response.errorCode === 'camera_unavailable') {
var _options$onOpenFailur4;
options === null || options === void 0 ? void 0 : (_options$onOpenFailur4 = options.onOpenFailure) === null || _options$onOpenFailur4 === void 0 ? void 0 : _options$onOpenFailur4.call(options, SBUError.DEVICE_UNAVAILABLE, new Error(response.errorMessage));
return null;
}
return Promise.all((response.assets || []).slice(0, selectionLimit).map(_ref2 => {
let {
fileName: name,
fileSize: size,
type,
uri
} = _ref2;
return normalizeFile({
uri,
size,
name,
type
});
}));
}
async openDocument(options) {
try {
const {
uri,
size,
name,
type
} = await documentPickerModule.pickSingle();
return normalizeFile({
uri,
size,
name,
type
});
} catch (e) {
if (!documentPickerModule.isCancel(e) && documentPickerModule.isInProgress(e)) {
var _options$onOpenFailur5;
options === null || options === void 0 ? void 0 : (_options$onOpenFailur5 = options.onOpenFailure) === null || _options$onOpenFailur5 === void 0 ? void 0 : _options$onOpenFailur5.call(options, SBUError.UNKNOWN, e);
}
return null;
}
}
async save(options) {
const hasPermission = await this.hasMediaLibraryPermission();
if (!hasPermission) {
const granted = await this.requestMediaLibraryPermission();
if (!granted) throw new Error('Permission not granted');
}
const {
downloadedPath,
file
} = await this.downloadFile(options);
if (Platform.OS === 'ios') {
if (file.type === 'image' || file.type === 'video') {
const mediaTypeMap = {
'image': 'photo',
'video': 'video'
};
const mediaType = mediaTypeMap[file.type];
await mediaLibraryModule.save(downloadedPath, {
type: mediaType
});
}
}
if (Platform.OS === 'android') {
const externalDirMap = {
'file': 'downloads',
'audio': 'audio',
'image': 'images',
'video': 'video'
};
const externalDir = externalDirMap[file.type];
await fsModule.FileSystem.cpExternal(downloadedPath, file.name, externalDir).catch(() => {
Logger.error('Failed to save file to external storage. Retry saving to downloads directory instead.');
return fsModule.FileSystem.cpExternal(downloadedPath, file.name, 'downloads');
});
}
return downloadedPath;
}
createRecordFilePath() {
let customExtension = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'm4a';
const filename = `record-${Date.now()}.${customExtension}`;
const path = `${fsModule.Dirs.CacheDir}/${filename}`;
return Platform.select({
ios: {
uri: path,
recordFilePath: filename
},
android: {
uri: path.startsWith('file://') ? path : 'file://' + path,
recordFilePath: path
},
default: {
uri: path,
recordFilePath: path
}
});
}
}
return new NativeFileService();
};
export default createNativeFileService;
//# sourceMappingURL=createFileService.native.js.map