stream-chat-react-native-core
Version:
The official React Native and Expo components for Stream Chat, a service for building chat applications
459 lines • 18.6 kB
JavaScript
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.Gallery = void 0;
var _react = _interopRequireWildcard(require("react"));
var _reactNative = require("react-native");
var _GalleryImage = require("./GalleryImage");
var _buildGallery = require("./utils/buildGallery/buildGallery");
var _getGalleryImageBorderRadius = require("./utils/getGalleryImageBorderRadius");
var _openUrlSafely = require("./utils/openUrlSafely");
var _useA11yLabel = require("../../a11y/hooks/useA11yLabel");
var _contexts = require("../../contexts");
var _ChatConfigContext = require("../../contexts/chatConfigContext/ChatConfigContext");
var _ComponentsContext = require("../../contexts/componentsContext/ComponentsContext");
var _ImageGalleryContext = require("../../contexts/imageGalleryContext/ImageGalleryContext");
var _MessageContext = require("../../contexts/messageContext/MessageContext");
var _MessagesContext = require("../../contexts/messagesContext/MessagesContext");
var _OverlayContext = require("../../contexts/overlayContext/OverlayContext");
var _ThemeContext = require("../../contexts/themeContext/ThemeContext");
var _native = require("../../native");
var _theme = require("../../theme");
var _types = require("../../types/types");
var _utils = require("../../utils/utils");
var _jsxRuntime = require("react/jsx-runtime");
var _jsxFileName = "/home/runner/work/stream-chat-react-native/stream-chat-react-native/package/src/components/Attachment/Gallery.tsx";
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
var GalleryWithContext = props => {
var additionalPressableProps = props.additionalPressableProps,
alignment = props.alignment,
imageGalleryStateStore = props.imageGalleryStateStore,
images = props.images,
message = props.message,
onLongPress = props.onLongPress,
onPress = props.onPress,
onPressIn = props.onPressIn,
preventPress = props.preventPress,
setOverlay = props.setOverlay,
videos = props.videos,
_props$messageHasOnly = props.messageHasOnlyOneMedia,
messageHasOnlyOneMedia = _props$messageHasOnly === void 0 ? false : _props$messageHasOnly;
var _useChatConfigContext = (0, _ChatConfigContext.useChatConfigContext)(),
resizableCDNHosts = _useChatConfigContext.resizableCDNHosts;
var _useTheme = (0, _ThemeContext.useTheme)(),
_useTheme$theme$messa = _useTheme.theme.messageItemView.gallery,
galleryContainer = _useTheme$theme$messa.galleryContainer,
galleryItemColumn = _useTheme$theme$messa.galleryItemColumn,
gridHeight = _useTheme$theme$messa.gridHeight,
gridWidth = _useTheme$theme$messa.gridWidth,
maxHeight = _useTheme$theme$messa.maxHeight,
maxWidth = _useTheme$theme$messa.maxWidth,
minHeight = _useTheme$theme$messa.minHeight,
minWidth = _useTheme$theme$messa.minWidth;
var styles = useStyles();
var sizeConfig = {
gridHeight,
gridWidth,
maxHeight,
maxWidth,
minHeight,
minWidth
};
var imagesAndVideos = [...(images || []), ...(videos || [])];
var imagesAndVideosValue = `${images == null ? void 0 : images.length}${videos == null ? void 0 : videos.length}${images == null ? void 0 : images.map(i => `${i.image_url}${i.thumb_url}`).join('')}${videos == null ? void 0 : videos.map(i => `${i.image_url}${i.thumb_url}`).join('')}`;
var _useMemo = (0, _react.useMemo)(() => (0, _buildGallery.buildGallery)({
images: imagesAndVideos,
resizableCDNHosts,
sizeConfig
}), [imagesAndVideosValue]),
height = _useMemo.height,
invertedDirections = _useMemo.invertedDirections,
thumbnailGrid = _useMemo.thumbnailGrid,
width = _useMemo.width;
if (!(imagesAndVideos != null && imagesAndVideos.length)) {
return null;
}
var numOfColumns = thumbnailGrid.length;
return (0, _jsxRuntime.jsx)(_reactNative.View, {
style: [styles.container, {
flexDirection: invertedDirections ? 'column' : 'row',
alignSelf: alignment === 'right' ? 'flex-end' : 'flex-start'
}, imagesAndVideos.length !== 1 ? {
width: gridWidth,
height: gridHeight
} : {
minHeight: height,
minWidth: width
}, galleryContainer],
testID: "gallery-container",
children: thumbnailGrid.map((rows, colIndex) => {
var numOfRows = rows.length;
return (0, _jsxRuntime.jsx)(_reactNative.View, {
style: [styles.galleryItemColumn, {
flexDirection: invertedDirections ? 'row' : 'column'
}, galleryItemColumn],
testID: `gallery-${invertedDirections ? 'row' : 'column'}-${colIndex}`,
children: rows.map((thumbnail, rowIndex) => {
var borderRadius = (0, _getGalleryImageBorderRadius.getGalleryImageBorderRadius)({
colIndex,
height,
invertedDirections,
numOfColumns,
numOfRows,
rowIndex,
sizeConfig,
width,
messageHasOnlyOneMedia
});
if (!message) {
return null;
}
return (0, _jsxRuntime.jsx)(GalleryThumbnail, {
additionalPressableProps: additionalPressableProps,
borderRadius: borderRadius,
colIndex: colIndex,
imageGalleryStateStore: imageGalleryStateStore,
imagesAndVideos: imagesAndVideos,
invertedDirections: invertedDirections || false,
message: message,
numOfColumns: numOfColumns,
numOfRows: numOfRows,
onLongPress: onLongPress,
onPress: onPress,
onPressIn: onPressIn,
preventPress: preventPress,
rowIndex: rowIndex,
setOverlay: setOverlay,
thumbnail: thumbnail
}, rowIndex);
})
}, `gallery-${invertedDirections ? 'row' : 'column'}-${colIndex}`);
})
});
};
var GalleryThumbnail = ({
additionalPressableProps,
borderRadius,
colIndex,
imageGalleryStateStore,
imagesAndVideos,
invertedDirections,
message,
numOfColumns,
numOfRows,
onLongPress,
onPress,
onPressIn,
preventPress,
rowIndex,
setOverlay,
thumbnail
}) => {
var _useComponentsContext = (0, _ComponentsContext.useComponentsContext)(),
VideoThumbnail = _useComponentsContext.VideoThumbnail;
var _useTheme2 = (0, _ThemeContext.useTheme)(),
_useTheme2$theme = _useTheme2.theme,
_useTheme2$theme$mess = _useTheme2$theme.messageItemView.gallery,
image = _useTheme2$theme$mess.image,
imageBorderRadius = _useTheme2$theme$mess.imageBorderRadius,
imageContainer = _useTheme2$theme$mess.imageContainer,
moreImagesContainer = _useTheme2$theme$mess.moreImagesContainer,
moreImagesText = _useTheme2$theme$mess.moreImagesText,
semantics = _useTheme2$theme.semantics;
var _useTranslationContex = (0, _contexts.useTranslationContext)(),
t = _useTranslationContex.t;
var styles = useStyles();
var isVideo = thumbnail.type === _types.FileTypes.Video;
var thumbnailAccessibilityLabel = (0, _useA11yLabel.useA11yLabel)(isVideo ? 'a11y/Gallery Video' : 'a11y/Gallery Image');
var thumbnailAccessibilityHint = (0, _useA11yLabel.useA11yLabel)('a11y/Double tap to open');
var thumbnailRef = (0, _react.useRef)(null);
var openImageViewer = () => {
if (!message) {
return;
}
imageGalleryStateStore.openImageGallery({
messages: [message],
requesterNode: (0, _reactNative.findNodeHandle)(thumbnailRef.current),
selectedAttachmentUrl: thumbnail.url
});
setOverlay('gallery');
};
var defaultOnPress = () => {
if (thumbnail.url) {
if (thumbnail.type === _types.FileTypes.Video && !(0, _native.isVideoPlayerAvailable)()) {
(0, _openUrlSafely.openUrlSafely)(thumbnail.url);
} else {
openImageViewer();
}
}
};
return (0, _jsxRuntime.jsxs)(_reactNative.Pressable, {
accessibilityHint: thumbnailAccessibilityHint,
accessibilityLabel: thumbnailAccessibilityLabel,
accessibilityRole: "button",
disabled: preventPress,
ref: thumbnailRef,
onLongPress: event => {
if (onLongPress) {
onLongPress({
additionalInfo: {
thumbnail
},
emitter: 'gallery',
event
});
}
},
onPress: event => {
if (onPress) {
onPress({
additionalInfo: {
thumbnail
},
defaultHandler: defaultOnPress,
emitter: 'gallery',
event
});
}
},
onPressIn: event => {
if (onPressIn) {
onPressIn({
additionalInfo: {
thumbnail
},
defaultHandler: defaultOnPress,
emitter: 'gallery',
event
});
}
},
style: [styles.imageContainer, {
flex: thumbnail.flex
}, imageContainer],
testID: `gallery-${invertedDirections ? 'row' : 'column'}-${colIndex}-item-${rowIndex}`,
...additionalPressableProps,
children: [thumbnail.type === _types.FileTypes.Video ? (0, _jsxRuntime.jsx)(VideoThumbnail, {
localId: thumbnail.localId,
style: [styles.image, imageBorderRadius != null ? imageBorderRadius : borderRadius, image],
thumb_url: thumbnail.thumb_url
}) : (0, _jsxRuntime.jsx)(GalleryImageThumbnail, {
borderRadius: imageBorderRadius != null ? imageBorderRadius : borderRadius,
thumbnail: thumbnail
}), colIndex === numOfColumns - 1 && rowIndex === numOfRows - 1 && imagesAndVideos.length > 4 ? (0, _jsxRuntime.jsx)(_reactNative.View, {
style: [_reactNative.StyleSheet.absoluteFill, styles.moreImagesContainer, {
backgroundColor: semantics.backgroundCoreOverlayDark
}, borderRadius, moreImagesContainer],
children: (0, _jsxRuntime.jsx)(_reactNative.Text, {
style: [styles.moreImagesText, moreImagesText],
children: String(t('+{{count}}', {
count: imagesAndVideos.length - 4
}))
})
}) : null]
}, `gallery-item-${colIndex}/${rowIndex}`);
};
var GalleryImageThumbnail = ({
borderRadius,
thumbnail
}) => {
var _useTheme3 = (0, _ThemeContext.useTheme)(),
gallery = _useTheme3.theme.messageItemView.gallery;
var styles = useStyles();
return (0, _jsxRuntime.jsx)(_GalleryImage.LoadableGalleryImage, {
containerStyle: [styles.image, borderRadius],
imageStyle: gallery.image,
localId: thumbnail.localId,
resizeMode: thumbnail.resizeMode,
uri: thumbnail.url
});
};
var areEqual = (prevProps, nextProps) => {
var prevAlignment = prevProps.alignment,
prevImages = prevProps.images,
prevMessage = prevProps.message,
prevMyMessageTheme = prevProps.myMessageTheme,
prevVideos = prevProps.videos;
var nextAlignment = nextProps.alignment,
nextImages = nextProps.images,
nextMessage = nextProps.message,
nextMyMessageTheme = nextProps.myMessageTheme,
nextVideos = nextProps.videos;
var alignmentEqual = prevAlignment === nextAlignment;
if (!alignmentEqual) {
return false;
}
var messageEqual = (prevMessage == null ? void 0 : prevMessage.id) === (nextMessage == null ? void 0 : nextMessage.id) && `${prevMessage == null ? void 0 : prevMessage.updated_at}` === `${nextMessage == null ? void 0 : nextMessage.updated_at}`;
if (!messageEqual) {
return false;
}
var imagesEqual = prevImages.length === nextImages.length && prevImages.every((image, index) => (0, _utils.getUrlWithoutParams)(image.image_url) === (0, _utils.getUrlWithoutParams)(nextImages[index].image_url) && (0, _utils.getUrlWithoutParams)(image.thumb_url) === (0, _utils.getUrlWithoutParams)(nextImages[index].thumb_url));
if (!imagesEqual) {
return false;
}
var videosEqual = prevVideos.length === nextVideos.length && prevVideos.every((image, index) => (0, _utils.getUrlWithoutParams)(image.image_url) === (0, _utils.getUrlWithoutParams)(nextVideos[index].image_url) && (0, _utils.getUrlWithoutParams)(image.thumb_url) === (0, _utils.getUrlWithoutParams)(nextVideos[index].thumb_url));
if (!videosEqual) {
return false;
}
var messageThemeEqual = JSON.stringify(prevMyMessageTheme) === JSON.stringify(nextMyMessageTheme);
if (!messageThemeEqual) {
return false;
}
return true;
};
var MemoizedGallery = _react.default.memo(GalleryWithContext, areEqual);
var Gallery = props => {
var _ref, _ref2;
var propAlignment = props.alignment,
propAdditionalPressableProps = props.additionalPressableProps,
propImages = props.images,
propMessage = props.message,
propMyMessageTheme = props.myMessageTheme,
propOnLongPress = props.onLongPress,
propOnPress = props.onPress,
propOnPressIn = props.onPressIn,
propPreventPress = props.preventPress,
propSetOverlay = props.setOverlay,
propVideos = props.videos,
propMessageContentOrder = props.messageContentOrder;
var _useImageGalleryConte = (0, _ImageGalleryContext.useImageGalleryContext)(),
imageGalleryStateStore = _useImageGalleryConte.imageGalleryStateStore;
var _useMessageContext = (0, _MessageContext.useMessageContext)(),
contextAlignment = _useMessageContext.alignment,
contextImages = _useMessageContext.images,
contextMessage = _useMessageContext.message,
contextOnLongPress = _useMessageContext.onLongPress,
contextOnPress = _useMessageContext.onPress,
contextOnPressIn = _useMessageContext.onPressIn,
contextPreventPress = _useMessageContext.preventPress,
contextVideos = _useMessageContext.videos,
contextMessageContentOrder = _useMessageContext.messageContentOrder;
var _useMessagesContext = (0, _MessagesContext.useMessagesContext)(),
contextAdditionalPressableProps = _useMessagesContext.additionalPressableProps,
contextMyMessageTheme = _useMessagesContext.myMessageTheme;
var _useOverlayContext = (0, _OverlayContext.useOverlayContext)(),
contextSetOverlay = _useOverlayContext.setOverlay;
var images = (_ref = propImages != null ? propImages : contextImages) != null ? _ref : [];
var videos = (_ref2 = propVideos != null ? propVideos : contextVideos) != null ? _ref2 : [];
var imagesAndVideos = [...images, ...videos];
var message = propMessage || contextMessage;
var alignment = propAlignment || contextAlignment;
if (!images.length && !videos.length) {
return null;
}
var additionalPressableProps = propAdditionalPressableProps || contextAdditionalPressableProps;
var onLongPress = propOnLongPress || contextOnLongPress;
var onPressIn = propOnPressIn || contextOnPressIn;
var onPress = propOnPress || contextOnPress;
var preventPress = typeof propPreventPress === 'boolean' ? propPreventPress : contextPreventPress;
var setOverlay = propSetOverlay || contextSetOverlay;
var myMessageTheme = propMyMessageTheme || contextMyMessageTheme;
var messageContentOrder = propMessageContentOrder || contextMessageContentOrder;
var messageHasOnlyOneMedia = (messageContentOrder == null ? void 0 : messageContentOrder.length) === 1 && (messageContentOrder == null ? void 0 : messageContentOrder.includes('gallery')) && imagesAndVideos.length === 1;
return (0, _jsxRuntime.jsx)(MemoizedGallery, {
additionalPressableProps,
alignment,
channelId: message == null ? void 0 : message.cid,
imageGalleryStateStore,
images,
message,
myMessageTheme,
onLongPress,
onPress,
onPressIn,
preventPress,
setOverlay,
videos,
messageHasOnlyOneMedia,
messageContentOrder
});
};
exports.Gallery = Gallery;
var useStyles = () => {
var _useTheme4 = (0, _ThemeContext.useTheme)(),
semantics = _useTheme4.theme.semantics;
var _useMessageContext2 = (0, _MessageContext.useMessageContext)(),
isMyMessage = _useMessageContext2.isMyMessage;
return (0, _react.useMemo)(() => {
return _reactNative.StyleSheet.create({
errorTextSize: {
fontSize: _theme.primitives.typographyFontSizeXs,
lineHeight: _theme.primitives.typographyLineHeightTight,
fontWeight: _theme.primitives.typographyFontWeightRegular,
color: semantics.accentError
},
galleryItemColumn: {
gap: _theme.primitives.spacingXxs,
flex: 1
},
container: {
flexDirection: 'row',
gap: _theme.primitives.spacingXxs
},
imageContainer: {},
image: {
flex: 1,
backgroundColor: isMyMessage ? semantics.chatBgAttachmentOutgoing : semantics.chatBgAttachmentIncoming,
overflow: 'hidden'
},
imageLoadingErrorIndicatorStyle: {
bottom: 0,
left: 0,
position: 'absolute',
right: 0,
top: 0,
alignItems: 'center',
justifyContent: 'center'
},
imageLoadingIndicatorContainer: {
height: '100%',
justifyContent: 'center',
position: 'absolute',
width: '100%'
},
imageLoadingIndicatorStyle: {
alignItems: 'center',
justifyContent: 'center',
position: 'absolute'
},
imageReloadContainerStyle: {
bottom: 0,
left: 0,
position: 'absolute',
right: 0,
top: 0,
alignItems: 'center',
justifyContent: 'center'
},
moreImagesContainer: {
alignItems: 'center',
justifyContent: 'center'
},
moreImagesText: {
color: semantics.textOnAccent,
fontSize: _theme.primitives.typographyFontSize2xl,
lineHeight: _theme.primitives.typographyLineHeightRelaxed,
fontWeight: _theme.primitives.typographyFontWeightSemiBold
},
imageLoadingErrorContainer: {
bottom: 0,
left: 0,
position: 'absolute',
right: 0,
top: 0,
alignItems: 'center',
justifyContent: 'center'
},
imageLoadingErrorWrapper: {
bottom: 0,
left: 0,
position: 'absolute',
right: 0,
top: 0,
overflow: 'hidden'
}
});
}, [semantics, isMyMessage]);
};
Gallery.displayName = 'Gallery{messageItemView{gallery}}';
//# sourceMappingURL=Gallery.js.map