stream-chat-react-native-core
Version:
The official React Native and Expo components for Stream Chat, a service for building chat applications
99 lines (81 loc) • 2.38 kB
text/typescript
import type { Attachment } from 'stream-chat';
import { buildThumbnail } from './buildThumbnail';
import type { GallerySizeAndThumbnailGrid, GallerySizeConfig } from './types';
import { ChatConfigContextValue } from '../../../../contexts/chatConfigContext/ChatConfigContext';
import { getAspectRatio } from '../getAspectRatio';
/**
* Bound a number to a range.
* @param number The number to bound.
* @param min The minimum value.
* @param max The maximum value.
*
* @returns The bounded number.
*/
function clamp(number: number, min: number, max: number) {
return Math.min(Math.max(number, min), max);
}
function getContainerSize({
image,
sizeConfig,
}: {
image: Attachment;
sizeConfig: GallerySizeConfig;
}) {
const { original_height: height, original_width: width } = image;
const { gridHeight, gridWidth, maxHeight, maxWidth, minHeight, minWidth } = sizeConfig;
if (!height || !width) {
return { height: gridHeight, width: gridWidth };
}
const aspectRatio = getAspectRatio(image);
if (aspectRatio <= 1) {
const containerHeight = clamp(height, minHeight, maxHeight);
const containerWidth = clamp(containerHeight * aspectRatio, minWidth, maxWidth);
if (containerWidth === maxWidth) {
return {
height: clamp(containerWidth / aspectRatio, minHeight, maxHeight),
width: containerWidth,
};
}
return {
height: containerHeight,
width: containerWidth,
};
}
const containerWidth = clamp(width, minWidth, maxWidth);
const containerHeight = clamp(containerWidth / aspectRatio, minHeight, maxHeight);
if (containerHeight === maxHeight) {
return {
height: containerHeight,
width: clamp(containerHeight * aspectRatio, minHeight, maxHeight),
};
}
return {
height: containerHeight,
width: containerWidth,
};
}
export function buildGalleryOfSingleImage({
image,
resizableCDNHosts,
sizeConfig,
}: Pick<ChatConfigContextValue, 'resizableCDNHosts'> & {
image: Attachment;
sizeConfig: GallerySizeConfig;
}): GallerySizeAndThumbnailGrid {
const container = getContainerSize({
image,
sizeConfig,
});
const thumbnail = buildThumbnail({
image,
resizableCDNHosts,
flex: 1,
resizeMode: 'cover',
...container,
});
const column = [thumbnail];
return {
...container,
thumbnailGrid: [column],
};
}