Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
138 changes: 70 additions & 68 deletions package/expo-package/src/optionalDependencies/getPhotos.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,75 +32,77 @@ type ReturnType = {
iOSLimited: boolean;
};

export const getPhotos = MediaLibrary
? async ({ after, first }): Promise<ReturnType> => {
try {
if (Platform.OS === 'android') {
console.warn(
'expo-media-library can be removed in favour of new google policy(https://support.google.com/googleplay/android-developer/answer/14115180?hl=en) if you do not have gallery as your core feature of the app.\nYou can replace it with expo-image-picker and uninstall it. Guide - https://getstream.io/chat/docs/sdk/react-native/guides/native-image-picker/.',
);
}
// NOTE:
// should always check first before requesting permission
// because always requesting permission will cause
// the app to go to background even if it was granted
const { accessPrivileges, status } = await MediaLibrary.getPermissionsAsync();
if (status !== 'granted') {
const { status: newStatus } = await MediaLibrary.requestPermissionsAsync();
if (newStatus !== 'granted') {
throw new Error('getPhotos Error');
}
}
const results = await MediaLibrary.getAssetsAsync({
after,
first,
mediaType: [MediaLibrary.MediaType.photo, MediaLibrary.MediaType.video],
sortBy: [MediaLibrary.SortBy.modificationTime],
});
const assetEntries = await Promise.all(
results.assets.map(async (asset) => {
const localUri = await getLocalAssetUri(asset.id);
const mimeType =
mime.getType(asset.filename || asset.uri) ||
(asset.mediaType === MediaLibrary.MediaType.video ? 'video/*' : 'image/*');
const originalUri = asset.uri;
const uri = localUri || originalUri;
// done this way to work around this issue: https://github.com/babel/babel/issues/18264
// until it gets fixed upstream
const getPhotosWithDependency = async ({ after, first }): Promise<ReturnType> => {
try {
if (Platform.OS === 'android') {
console.warn(
'expo-media-library can be removed in favour of new google policy(https://support.google.com/googleplay/android-developer/answer/14115180?hl=en) if you do not have gallery as your core feature of the app.\nYou can replace it with expo-image-picker and uninstall it. Guide - https://getstream.io/chat/docs/sdk/react-native/guides/native-image-picker/.',
);
}
// NOTE:
// should always check first before requesting permission
// because always requesting permission will cause
// the app to go to background even if it was granted
const { accessPrivileges, status } = await MediaLibrary.getPermissionsAsync();
if (status !== 'granted') {
const { status: newStatus } = await MediaLibrary.requestPermissionsAsync();
if (newStatus !== 'granted') {
throw new Error('getPhotos Error');
}
}
const results = await MediaLibrary.getAssetsAsync({
after,
first,
mediaType: [MediaLibrary.MediaType.photo, MediaLibrary.MediaType.video],
sortBy: [MediaLibrary.SortBy.modificationTime],
});
const assetEntries = await Promise.all(
results.assets.map(async (asset) => {
const localUri = await getLocalAssetUri(asset.id);
const mimeType =
mime.getType(asset.filename || asset.uri) ||
(asset.mediaType === MediaLibrary.MediaType.video ? 'video/*' : 'image/*');
const originalUri = asset.uri;
const uri = localUri || originalUri;

return {
asset,
isVideo: asset.mediaType === MediaLibrary.MediaType.video,
mimeType,
originalUri,
uri,
};
}),
);
const videoUris = assetEntries
.filter(({ isVideo, originalUri }) => isVideo && !!originalUri)
.map(({ originalUri }) => originalUri);
const videoThumbnailResults = await generateThumbnails(videoUris);
return {
asset,
isVideo: asset.mediaType === MediaLibrary.MediaType.video,
mimeType,
originalUri,
uri,
};
}),
);
const videoUris = assetEntries
.filter(({ isVideo, originalUri }) => isVideo && !!originalUri)
.map(({ originalUri }) => originalUri);
const videoThumbnailResults = await generateThumbnails(videoUris);

const assets = assetEntries.map(({ asset, isVideo, mimeType, originalUri, uri }) => {
const thumbnailResult =
isVideo && originalUri ? videoThumbnailResults[originalUri] : undefined;
const assets = assetEntries.map(({ asset, isVideo, mimeType, originalUri, uri }) => {
const thumbnailResult =
isVideo && originalUri ? videoThumbnailResults[originalUri] : undefined;

return {
duration: asset.duration * 1000,
height: asset.height,
name: asset.filename,
size: 0,
thumb_url: thumbnailResult?.uri || undefined,
type: mimeType,
uri,
width: asset.width,
};
});
return {
duration: asset.duration * 1000,
height: asset.height,
name: asset.filename,
size: 0,
thumb_url: thumbnailResult?.uri || undefined,
type: mimeType,
uri,
width: asset.width,
};
});

const hasNextPage = results.hasNextPage;
const endCursor = results.endCursor;
return { assets, endCursor, hasNextPage, iOSLimited: accessPrivileges === 'limited' };
} catch {
throw new Error('getPhotos Error');
}
}
: null;
const hasNextPage = results.hasNextPage;
const endCursor = results.endCursor;
return { assets, endCursor, hasNextPage, iOSLimited: accessPrivileges === 'limited' };
} catch {
throw new Error('getPhotos Error');
}
};

export const getPhotos = MediaLibrary ? getPhotosWithDependency : null;
128 changes: 65 additions & 63 deletions package/native-package/src/optionalDependencies/getPhotos.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,69 +72,71 @@ const verifyAndroidPermissions = async () => {
return true;
};

export const getPhotos = CameraRollDependency
? async ({ after, first }): Promise<ReturnType> => {
try {
if (Platform.OS === 'android') {
console.warn(
'@react-native-camera-roll/camera-roll can be removed in favour of new google policy(https://support.google.com/googleplay/android-developer/answer/14115180?hl=en) if you do not have gallery as your core feature of the app.\nYou can replace it with react-native-image-picker and uninstall it. Guide - https://getstream.io/chat/docs/sdk/react-native/guides/native-image-picker/.',
);
const granted = await verifyAndroidPermissions();
if (!granted) {
throw new Error('getPhotos Error');
}
}
const results = await CameraRollDependency.CameraRoll.getPhotos({
after,
assetType: 'All',
first,
include: ['fileSize', 'filename', 'imageSize', 'playableDuration'],
});
const assetEntries = await Promise.all(
results.edges.map(async (edge) => {
const originalUri = edge.node?.image?.uri;
const type =
(Platform.OS === 'ios'
? mime.getType(edge.node.image.filename as string) || edge.node.type
: edge.node.type) ||
mime.getType(edge.node.image.filename as string) ||
mime.getType(originalUri) ||
(edge.node.image.playableDuration ? 'video/*' : 'image/*');
const isImage = type.includes('image');

return {
edge,
isImage,
originalUri,
type,
uri: isImage && getLocalAssetUri ? await getLocalAssetUri(originalUri) : originalUri,
};
}),
);
const videoUris = assetEntries
.filter(({ isImage, originalUri }) => !isImage && !!originalUri)
.map(({ originalUri }) => originalUri);
const videoThumbnailResults = await generateThumbnails(videoUris);

const assets = assetEntries.map(({ edge, isImage, originalUri, type, uri }) => {
const thumbnailResult =
!isImage && originalUri ? videoThumbnailResults[originalUri] : undefined;

return {
...edge.node.image,
name: edge.node.image.filename as string,
duration: edge.node.image.playableDuration * 1000,
thumb_url: thumbnailResult?.uri || undefined,
size: edge.node.image.fileSize as number,
type,
uri,
};
});
const hasNextPage = results.page_info.has_next_page;
const endCursor = results.page_info.end_cursor;
return { assets, endCursor, hasNextPage, iOSLimited: !!results.limited };
} catch (_error) {
// done this way to work around this issue: https://github.com/babel/babel/issues/18264
// until it gets fixed upstream
const getPhotosWithDependency = async ({ after, first }): Promise<ReturnType> => {
try {
if (Platform.OS === 'android') {
console.warn(
'@react-native-camera-roll/camera-roll can be removed in favour of new google policy(https://support.google.com/googleplay/android-developer/answer/14115180?hl=en) if you do not have gallery as your core feature of the app.\nYou can replace it with react-native-image-picker and uninstall it. Guide - https://getstream.io/chat/docs/sdk/react-native/guides/native-image-picker/.',
);
const granted = await verifyAndroidPermissions();
if (!granted) {
throw new Error('getPhotos Error');
}
}
: null;
const results = await CameraRollDependency.CameraRoll.getPhotos({
after,
assetType: 'All',
first,
include: ['fileSize', 'filename', 'imageSize', 'playableDuration'],
});
const assetEntries = await Promise.all(
results.edges.map(async (edge) => {
const originalUri = edge.node?.image?.uri;
const type =
(Platform.OS === 'ios'
? mime.getType(edge.node.image.filename as string) || edge.node.type
: edge.node.type) ||
mime.getType(edge.node.image.filename as string) ||
mime.getType(originalUri) ||
(edge.node.image.playableDuration ? 'video/*' : 'image/*');
const isImage = type.includes('image');

return {
edge,
isImage,
originalUri,
type,
uri: isImage && getLocalAssetUri ? await getLocalAssetUri(originalUri) : originalUri,
};
}),
);
const videoUris = assetEntries
.filter(({ isImage, originalUri }) => !isImage && !!originalUri)
.map(({ originalUri }) => originalUri);
const videoThumbnailResults = await generateThumbnails(videoUris);

const assets = assetEntries.map(({ edge, isImage, originalUri, type, uri }) => {
const thumbnailResult =
!isImage && originalUri ? videoThumbnailResults[originalUri] : undefined;

return {
...edge.node.image,
name: edge.node.image.filename as string,
duration: edge.node.image.playableDuration * 1000,
thumb_url: thumbnailResult?.uri || undefined,
size: edge.node.image.fileSize as number,
type,
uri,
};
});
const hasNextPage = results.page_info.has_next_page;
const endCursor = results.page_info.end_cursor;
return { assets, endCursor, hasNextPage, iOSLimited: !!results.limited };
} catch (_error) {
throw new Error('getPhotos Error');
}
};

export const getPhotos = CameraRollDependency ? getPhotosWithDependency : null;
Loading