1- import React , { useMemo } from 'react' ;
1+ import React , { useCallback , useMemo } from 'react' ;
22import { Pressable , StyleSheet , Text , View } from 'react-native' ;
33
44import type { Attachment , LocalMessage } from 'stream-chat' ;
@@ -34,8 +34,10 @@ import {
3434} from '../../contexts/overlayContext/OverlayContext' ;
3535import { useTheme } from '../../contexts/themeContext/ThemeContext' ;
3636
37+ import { useStateStore } from '../../hooks' ;
3738import { useLoadingImage } from '../../hooks/useLoadingImage' ;
3839import { isVideoPlayerAvailable } from '../../native' ;
40+ import { PendingAttachmentsLoadingState } from '../../state-store/pending-attachments-loading-state' ;
3941import { primitives } from '../../theme' ;
4042import { FileTypes } from '../../types/types' ;
4143import { getUrlWithoutParams } from '../../utils/utils' ;
@@ -60,7 +62,9 @@ export type GalleryPropsWithContext = Pick<ImageGalleryContextValue, 'imageGalle
6062 | 'ImageLoadingIndicator'
6163 | 'ImageLoadingFailedIndicator'
6264 | 'ImageReloadIndicator'
65+ | 'ImageUploadingIndicator'
6366 | 'myMessageTheme'
67+ | 'pendingAttachmentsLoadingStore'
6468 > &
6569 Pick < OverlayContextValue , 'setOverlay' > & {
6670 channelId : string | undefined ;
@@ -75,6 +79,7 @@ const GalleryWithContext = (props: GalleryPropsWithContext) => {
7579 ImageLoadingFailedIndicator,
7680 ImageLoadingIndicator,
7781 ImageReloadIndicator,
82+ ImageUploadingIndicator,
7883 images,
7984 message,
8085 onLongPress,
@@ -85,6 +90,7 @@ const GalleryWithContext = (props: GalleryPropsWithContext) => {
8590 videos,
8691 VideoThumbnail,
8792 messageHasOnlyOneImage = false ,
93+ pendingAttachmentsLoadingStore,
8894 } = props ;
8995
9096 const { resizableCDNHosts } = useChatConfigContext ( ) ;
@@ -195,6 +201,7 @@ const GalleryWithContext = (props: GalleryPropsWithContext) => {
195201 ImageLoadingFailedIndicator = { ImageLoadingFailedIndicator }
196202 ImageLoadingIndicator = { ImageLoadingIndicator }
197203 ImageReloadIndicator = { ImageReloadIndicator }
204+ ImageUploadingIndicator = { ImageUploadingIndicator }
198205 imagesAndVideos = { imagesAndVideos }
199206 invertedDirections = { invertedDirections || false }
200207 key = { rowIndex }
@@ -209,6 +216,7 @@ const GalleryWithContext = (props: GalleryPropsWithContext) => {
209216 setOverlay = { setOverlay }
210217 thumbnail = { thumbnail }
211218 VideoThumbnail = { VideoThumbnail }
219+ pendingAttachmentsLoadingStore = { pendingAttachmentsLoadingStore }
212220 />
213221 ) ;
214222 } ) }
@@ -236,6 +244,8 @@ type GalleryThumbnailProps = {
236244 | 'ImageLoadingIndicator'
237245 | 'ImageLoadingFailedIndicator'
238246 | 'ImageReloadIndicator'
247+ | 'ImageUploadingIndicator'
248+ | 'pendingAttachmentsLoadingStore'
239249> &
240250 Pick < ImageGalleryContextValue , 'imageGalleryStateStore' > &
241251 Pick < MessageContextValue , 'onLongPress' | 'onPress' | 'onPressIn' | 'preventPress' > &
@@ -249,6 +259,7 @@ const GalleryThumbnail = ({
249259 ImageLoadingFailedIndicator,
250260 ImageLoadingIndicator,
251261 ImageReloadIndicator,
262+ ImageUploadingIndicator,
252263 imagesAndVideos,
253264 invertedDirections,
254265 message,
@@ -262,6 +273,7 @@ const GalleryThumbnail = ({
262273 setOverlay,
263274 thumbnail,
264275 VideoThumbnail,
276+ pendingAttachmentsLoadingStore,
265277} : GalleryThumbnailProps ) => {
266278 const {
267279 theme : {
@@ -274,6 +286,18 @@ const GalleryThumbnail = ({
274286 const { t } = useTranslationContext ( ) ;
275287 const styles = useStyles ( ) ;
276288
289+ const attachmentId = `${ message . id } -${ thumbnail . url } ` ;
290+ const selector = useCallback (
291+ ( state : PendingAttachmentsLoadingState ) => ( {
292+ isPendingAttachmentLoading : state . pendingAttachmentsLoading [ attachmentId ] ?? false ,
293+ } ) ,
294+ [ attachmentId ] ,
295+ ) ;
296+ const { isPendingAttachmentLoading } = useStateStore (
297+ pendingAttachmentsLoadingStore . store ,
298+ selector ,
299+ ) ?? { isPendingAttachmentLoading : false } ;
300+
277301 const openImageViewer = ( ) => {
278302 if ( ! message ) {
279303 return ;
@@ -346,14 +370,17 @@ const GalleryThumbnail = ({
346370 < VideoThumbnail
347371 style = { [ styles . image , imageBorderRadius ?? borderRadius , image ] }
348372 thumb_url = { thumbnail . thumb_url }
373+ isPendingAttachmentLoading = { isPendingAttachmentLoading }
349374 />
350375 ) : (
351376 < GalleryImageThumbnail
352377 borderRadius = { imageBorderRadius ?? borderRadius }
353378 ImageLoadingFailedIndicator = { ImageLoadingFailedIndicator }
354379 ImageLoadingIndicator = { ImageLoadingIndicator }
355380 ImageReloadIndicator = { ImageReloadIndicator }
381+ ImageUploadingIndicator = { ImageUploadingIndicator }
356382 thumbnail = { thumbnail }
383+ isPendingAttachmentLoading = { isPendingAttachmentLoading }
357384 />
358385 ) }
359386 { colIndex === numOfColumns - 1 && rowIndex === numOfRows - 1 && imagesAndVideos . length > 4 ? (
@@ -381,14 +408,23 @@ const GalleryImageThumbnail = ({
381408 ImageLoadingIndicator,
382409 ImageReloadIndicator,
383410 thumbnail,
411+ isPendingAttachmentLoading,
412+ ImageUploadingIndicator,
384413} : Pick <
385414 GalleryThumbnailProps ,
386415 | 'ImageLoadingFailedIndicator'
387416 | 'ImageLoadingIndicator'
388417 | 'ImageReloadIndicator'
418+ | 'ImageUploadingIndicator'
389419 | 'thumbnail'
390420 | 'borderRadius'
391- > ) => {
421+ > & {
422+ /**
423+ * Whether the attachment is currently being uploaded.
424+ * This is used to show a loading indicator in the thumbnail.
425+ */
426+ isPendingAttachmentLoading : boolean ;
427+ } ) => {
392428 const {
393429 isLoadingImage,
394430 isLoadingImageError,
@@ -434,6 +470,11 @@ const GalleryImageThumbnail = ({
434470 < ImageLoadingIndicator style = { styles . imageLoadingIndicatorStyle } />
435471 </ View >
436472 ) }
473+ { isPendingAttachmentLoading && (
474+ < View style = { styles . imageLoadingIndicatorContainer } >
475+ < ImageUploadingIndicator style = { styles . imageLoadingIndicatorStyle } />
476+ </ View >
477+ ) }
437478 </ >
438479 ) }
439480 </ View >
@@ -513,6 +554,7 @@ export const Gallery = (props: GalleryProps) => {
513554 ImageLoadingFailedIndicator : PropImageLoadingFailedIndicator ,
514555 ImageLoadingIndicator : PropImageLoadingIndicator ,
515556 ImageReloadIndicator : PropImageReloadIndicator ,
557+ ImageUploadingIndicator : PropImageUploadingIndicator ,
516558 images : propImages ,
517559 message : propMessage ,
518560 myMessageTheme : propMyMessageTheme ,
@@ -524,6 +566,7 @@ export const Gallery = (props: GalleryProps) => {
524566 videos : propVideos ,
525567 VideoThumbnail : PropVideoThumbnail ,
526568 messageContentOrder : propMessageContentOrder ,
569+ pendingAttachmentsLoadingStore : propPendingAttachmentsLoadingStore ,
527570 } = props ;
528571
529572 const { imageGalleryStateStore } = useImageGalleryContext ( ) ;
@@ -543,8 +586,10 @@ export const Gallery = (props: GalleryProps) => {
543586 ImageLoadingFailedIndicator : ContextImageLoadingFailedIndicator ,
544587 ImageLoadingIndicator : ContextImageLoadingIndicator ,
545588 ImageReloadIndicator : ContextImageReloadIndicator ,
589+ ImageUploadingIndicator : ContextImageUploadingIndicator ,
546590 myMessageTheme : contextMyMessageTheme ,
547591 VideoThumbnail : ContextVideoThumnbnail ,
592+ pendingAttachmentsLoadingStore : contextPendingAttachmentsLoadingStore ,
548593 } = useMessagesContext ( ) ;
549594 const { setOverlay : contextSetOverlay } = useOverlayContext ( ) ;
550595
@@ -568,8 +613,11 @@ export const Gallery = (props: GalleryProps) => {
568613 PropImageLoadingFailedIndicator || ContextImageLoadingFailedIndicator ;
569614 const ImageLoadingIndicator = PropImageLoadingIndicator || ContextImageLoadingIndicator ;
570615 const ImageReloadIndicator = PropImageReloadIndicator || ContextImageReloadIndicator ;
616+ const ImageUploadingIndicator = PropImageUploadingIndicator || ContextImageUploadingIndicator ;
571617 const myMessageTheme = propMyMessageTheme || contextMyMessageTheme ;
572618 const messageContentOrder = propMessageContentOrder || contextMessageContentOrder ;
619+ const pendingAttachmentsLoadingStore =
620+ propPendingAttachmentsLoadingStore || contextPendingAttachmentsLoadingStore ;
573621
574622 const messageHasOnlyOneImage =
575623 messageContentOrder ?. length === 1 &&
@@ -586,6 +634,7 @@ export const Gallery = (props: GalleryProps) => {
586634 ImageLoadingFailedIndicator,
587635 ImageLoadingIndicator,
588636 ImageReloadIndicator,
637+ ImageUploadingIndicator,
589638 images,
590639 message,
591640 myMessageTheme,
@@ -598,6 +647,7 @@ export const Gallery = (props: GalleryProps) => {
598647 VideoThumbnail,
599648 messageHasOnlyOneImage,
600649 messageContentOrder,
650+ pendingAttachmentsLoadingStore,
601651 } }
602652 />
603653 ) ;
0 commit comments