stream-chat-react-native-core
Version:
The official React Native and Expo components for Stream Chat, a service for building chat applications
102 lines (92 loc) • 2.92 kB
text/typescript
import type { Attachment } from 'stream-chat';
import { buildThumbnailGrid } from './buildThumbnailGrid';
import type { GallerySizeAndThumbnailGrid, GallerySizeConfig } from './types';
import { ChatConfigContextValue } from '../../../../contexts/chatConfigContext/ChatConfigContext';
import { getAspectRatio } from '../getAspectRatio';
/** function to move item to the front of the array */
function moveToFront<T>(array: T[], item: T): T[] {
const index = array.indexOf(item);
if (index === -1) {
return array;
}
const newArray = [...array];
newArray.splice(index, 1);
newArray.unshift(item);
return newArray;
}
export function buildGalleryOfThreeImages({
images,
resizableCDNHosts,
sizeConfig,
}: Pick<ChatConfigContextValue, 'resizableCDNHosts'> & {
images: Attachment[];
sizeConfig: GallerySizeConfig;
}): GallerySizeAndThumbnailGrid {
// Find the most ladscape and most portrait image.
const { landscapeImage, landscapeImageAspectRatio, portraitImage, portraitImageAspectRatio } =
images.reduce(
(acc, image) => {
const aspectRatio = getAspectRatio(image);
const o = { ...acc };
// Following nested if conditions can be combined, but have been kept
// separate intentionally for the sake of readability.
if (aspectRatio > 1) {
if (!o.landscapeImage || aspectRatio > o.landscapeImageAspectRatio) {
o.landscapeImage = image;
o.landscapeImageAspectRatio = aspectRatio;
}
} else {
if (!o.portraitImage || aspectRatio < o.portraitImageAspectRatio) {
o.portraitImage = image;
o.portraitImageAspectRatio = aspectRatio;
}
}
return o;
},
{
landscapeImageAspectRatio: 1,
portraitImageAspectRatio: 1,
} as {
landscapeImage: Attachment;
landscapeImageAspectRatio: number;
portraitImage: Attachment;
portraitImageAspectRatio: number;
},
);
// Check weather landscape image gets preference or portrait, by comparing aspect ratio.
if (landscapeImageAspectRatio > 1 / portraitImageAspectRatio) {
/**
* -----------
* | |
* | |
* |---------|
* | | |
* | | |
* -----------
*/
return buildThumbnailGrid({
grid: [[1], [1, 1]],
images: landscapeImage ? moveToFront(images, landscapeImage) : images,
invertedDirections: true,
resizableCDNHosts,
sizeConfig,
});
} else {
/**
* -----------
* | | |
* | | |
* | |----|
* | | |
* | | |
* -----------
*/
return buildThumbnailGrid({
grid: [[1], [1, 1]],
images: portraitImage ? moveToFront(images, portraitImage) : images,
invertedDirections: false,
resizableCDNHosts,
sizeConfig,
});
}
}