UNPKG

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
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