1- import React , { useCallback , useEffect , useRef , useState } from 'react' ;
1+ import React , { useCallback , useEffect , useState } from 'react' ;
22import { Image , ImageStyle , StyleSheet , ViewStyle } from 'react-native' ;
33import { Gesture , GestureDetector } from 'react-native-gesture-handler' ;
44
@@ -11,24 +11,8 @@ import Animated, {
1111 withTiming ,
1212} from 'react-native-reanimated' ;
1313
14- import BottomSheet from '@gorhom/bottom-sheet' ;
15-
1614import { AnimatedGalleryImage } from './components/AnimatedGalleryImage' ;
1715import { AnimatedGalleryVideo } from './components/AnimatedGalleryVideo' ;
18- import {
19- ImageGalleryFooter ,
20- ImageGalleryFooterCustomComponentProps ,
21- } from './components/ImageGalleryFooter' ;
22- import {
23- ImageGalleryHeader ,
24- ImageGalleryHeaderCustomComponentProps ,
25- } from './components/ImageGalleryHeader' ;
26- import { ImageGalleryOverlay } from './components/ImageGalleryOverlay' ;
27- import { ImageGalleryGridImageComponents , ImageGrid } from './components/ImageGrid' ;
28- import {
29- ImageGalleryGridHandleCustomComponentProps ,
30- ImageGridHandle ,
31- } from './components/ImageGridHandle' ;
3216
3317import { useImageGalleryGestures } from './hooks/useImageGalleryGestures' ;
3418
@@ -43,9 +27,21 @@ import {
4327import { useTheme } from '../../contexts/themeContext/ThemeContext' ;
4428import { useStateStore } from '../../hooks' ;
4529import { useViewport } from '../../hooks/useViewport' ;
30+ import { IconProps } from '../../icons/utils/base' ;
4631import { ImageGalleryState } from '../../state-store/image-gallery-state-store' ;
4732import { FileTypes } from '../../types/types' ;
4833import { dismissKeyboard } from '../KeyboardCompatibleView/KeyboardControllerAvoidingView' ;
34+ import { BottomSheetModal } from '../UIComponents' ;
35+
36+ export type ImageGalleryActionHandler = ( ) => Promise < void > | void ;
37+
38+ export type ImageGalleryActionItem = {
39+ action : ImageGalleryActionHandler ;
40+ Icon : React . ComponentType < IconProps > ;
41+ id : 'showInChat' | 'save' | 'reply' | 'delete' | string ;
42+ label : string ;
43+ type : 'destructive' | 'standard' ;
44+ } ;
4945
5046const MARGIN = 32 ;
5147
@@ -60,68 +56,31 @@ export enum IsSwiping {
6056 FALSE ,
6157}
6258
63- export type ImageGalleryCustomComponents = {
64- /**
65- * Override props for following UI components, which are part of [image gallery](https://github.com/GetStream/stream-chat-react-native/wiki/Cookbook-v3.0#gallery-components).
66- *
67- * - [ImageGalleryFooter](#ImageGalleryFooter)
68- *
69- * - [ImageGrid](#ImageGrid)
70- *
71- * - [ImageGridHandle](#ImageGridHandle)
72- *
73- * - [ImageGalleryHeader](#ImageGalleryHeader)
74- *
75- * e.g.,
76- *
77- * ```js
78- * {
79- * footer: {
80- * ShareIcon: CustomShareIconComponent
81- * },
82- * grid: {
83- * avatarComponent: CustomAvatarComponent
84- * },
85- * gridHandle: {
86- * centerComponent: CustomCenterComponent
87- * },
88- * header: {
89- * CloseIcon: CustomCloseButtonComponent
90- * },
91- * }
92- * ```
93- * @overrideType object
94- */
95- imageGalleryCustomComponents ?: {
96- footer ?: ImageGalleryFooterCustomComponentProps ;
97- grid ?: ImageGalleryGridImageComponents ;
98- gridHandle ?: ImageGalleryGridHandleCustomComponentProps ;
99- header ?: ImageGalleryHeaderCustomComponentProps ;
100- } ;
101- } ;
102-
10359const imageGallerySelector = ( state : ImageGalleryState ) => ( {
10460 assets : state . assets ,
10561 currentIndex : state . currentIndex ,
10662} ) ;
10763
10864type ImageGalleryWithContextProps = Pick <
10965 ImageGalleryProviderProps ,
110- | 'imageGalleryCustomComponents'
111- | 'imageGalleryGridSnapPoints'
112- | 'imageGalleryGridHandleHeight'
11366 | 'numberOfImageGalleryGridColumns'
67+ | 'ImageGalleryHeader'
68+ | 'ImageGalleryFooter'
69+ | 'ImageGalleryVideoControls'
70+ | 'ImageGalleryGrid'
11471> &
11572 Pick < OverlayContextValue , 'overlayOpacity' > ;
11673
11774export const ImageGalleryWithContext = ( props : ImageGalleryWithContextProps ) => {
11875 const {
119- imageGalleryGridHandleHeight,
120- imageGalleryGridSnapPoints,
121- imageGalleryCustomComponents,
12276 numberOfImageGalleryGridColumns,
12377 overlayOpacity,
78+ ImageGalleryHeader,
79+ ImageGalleryFooter,
80+ ImageGalleryVideoControls,
81+ ImageGalleryGrid,
12482 } = props ;
83+ const [ isGridViewVisible , setIsGridViewVisible ] = useState ( false ) ;
12584 const {
12685 theme : {
12786 colors : { white_snow } ,
@@ -143,22 +102,6 @@ export const ImageGalleryWithContext = (props: ImageGalleryWithContextProps) =>
143102
144103 const halfScreenHeight = fullWindowHeight / 2 ;
145104 const quarterScreenHeight = fullWindowHeight / 4 ;
146- const snapPoints = React . useMemo (
147- ( ) => [ ( fullWindowHeight * 3 ) / 4 , fullWindowHeight - ( imageGalleryGridHandleHeight ?? 0 ) ] ,
148- // eslint-disable-next-line react-hooks/exhaustive-deps
149- [ ] ,
150- ) ;
151-
152- /**
153- * BottomSheetModal ref
154- */
155- const bottomSheetModalRef = useRef < BottomSheet > ( null ) ;
156-
157- /**
158- * BottomSheetModal state
159- */
160- const [ currentBottomSheetIndex , setCurrentBottomSheetIndex ] = useState ( 0 ) ;
161- const animatedBottomSheetIndex = useSharedValue ( 0 ) ;
162105
163106 /**
164107 * Fade animation for screen, it is always rendered with pointerEvents
@@ -322,30 +265,16 @@ export const ImageGalleryWithContext = (props: ImageGalleryWithContextProps) =>
322265 * Functions toclose BottomSheetModal with image grid
323266 */
324267 const closeGridView = ( ) => {
325- if ( bottomSheetModalRef . current ?. close ) {
326- bottomSheetModalRef . current . close ( ) ;
327- }
268+ setIsGridViewVisible ( false ) ;
328269 } ;
329270
330271 /**
331272 * Function to open BottomSheetModal with image grid
332273 */
333274 const openGridView = ( ) => {
334- if ( bottomSheetModalRef . current ?. snapToIndex ) {
335- bottomSheetModalRef . current . snapToIndex ( 0 ) ;
336- }
275+ setIsGridViewVisible ( true ) ;
337276 } ;
338277
339- const MemoizedImageGridHandle = useCallback (
340- ( ) => (
341- < ImageGridHandle
342- closeGridView = { closeGridView }
343- { ...imageGalleryCustomComponents ?. gridHandle }
344- />
345- ) ,
346- [ imageGalleryCustomComponents ?. gridHandle ] ,
347- ) ;
348-
349278 return (
350279 < Animated . View
351280 accessibilityLabel = 'Image Gallery'
@@ -403,42 +332,34 @@ export const ImageGalleryWithContext = (props: ImageGalleryWithContextProps) =>
403332 </ Animated . View >
404333 </ Animated . View >
405334 </ GestureDetector >
406- < ImageGalleryHeader
407- opacity = { headerFooterOpacity }
408- visible = { headerFooterVisible }
409- { ...imageGalleryCustomComponents ?. header }
410- />
411-
412- < ImageGalleryFooter
413- accessibilityLabel = { 'Image Gallery Footer' }
414- opacity = { headerFooterOpacity }
415- openGridView = { openGridView }
416- visible = { headerFooterVisible }
417- { ...imageGalleryCustomComponents ?. footer }
418- />
419-
420- < ImageGalleryOverlay
421- animatedBottomSheetIndex = { animatedBottomSheetIndex }
422- closeGridView = { closeGridView }
423- currentBottomSheetIndex = { currentBottomSheetIndex }
424- />
425- < BottomSheet
426- animatedIndex = { animatedBottomSheetIndex }
427- enablePanDownToClose = { true }
428- handleComponent = { MemoizedImageGridHandle }
429- // @ts -ignore
430- handleHeight = { imageGalleryGridHandleHeight }
431- index = { - 1 }
432- onChange = { ( index : number ) => setCurrentBottomSheetIndex ( index ) }
433- ref = { bottomSheetModalRef }
434- snapPoints = { imageGalleryGridSnapPoints || snapPoints }
435- >
436- < ImageGrid
437- closeGridView = { closeGridView }
438- numberOfImageGalleryGridColumns = { numberOfImageGalleryGridColumns }
439- { ...imageGalleryCustomComponents ?. grid }
335+ { ImageGalleryHeader ? (
336+ < ImageGalleryHeader opacity = { headerFooterOpacity } visible = { headerFooterVisible } />
337+ ) : null }
338+
339+ { ImageGalleryFooter ? (
340+ < ImageGalleryFooter
341+ accessibilityLabel = { 'Image Gallery Footer' }
342+ opacity = { headerFooterOpacity }
343+ openGridView = { openGridView }
344+ visible = { headerFooterVisible }
345+ ImageGalleryVideoControls = { ImageGalleryVideoControls }
440346 />
441- </ BottomSheet >
347+ ) : null }
348+
349+ < BottomSheetModal
350+ height = { 350 }
351+ onClose = { ( ) => {
352+ setIsGridViewVisible ( false ) ;
353+ } }
354+ visible = { isGridViewVisible }
355+ >
356+ { ImageGalleryGrid ? (
357+ < ImageGalleryGrid
358+ closeGridView = { closeGridView }
359+ numberOfImageGalleryGridColumns = { numberOfImageGalleryGridColumns }
360+ />
361+ ) : null }
362+ </ BottomSheetModal >
442363 </ Animated . View >
443364 ) ;
444365} ;
@@ -447,19 +368,21 @@ export type ImageGalleryProps = Partial<ImageGalleryWithContextProps>;
447368
448369export const ImageGallery = ( props : ImageGalleryProps ) => {
449370 const {
450- imageGalleryCustomComponents,
451- imageGalleryGridHandleHeight,
452- imageGalleryGridSnapPoints,
453371 numberOfImageGalleryGridColumns,
372+ ImageGalleryHeader,
373+ ImageGalleryFooter,
374+ ImageGalleryVideoControls,
375+ ImageGalleryGrid,
454376 } = useImageGalleryContext ( ) ;
455377 const { overlayOpacity } = useOverlayContext ( ) ;
456378 return (
457379 < ImageGalleryWithContext
458- imageGalleryCustomComponents = { imageGalleryCustomComponents }
459- imageGalleryGridHandleHeight = { imageGalleryGridHandleHeight }
460- imageGalleryGridSnapPoints = { imageGalleryGridSnapPoints }
461380 numberOfImageGalleryGridColumns = { numberOfImageGalleryGridColumns }
462381 overlayOpacity = { overlayOpacity }
382+ ImageGalleryHeader = { ImageGalleryHeader }
383+ ImageGalleryFooter = { ImageGalleryFooter }
384+ ImageGalleryVideoControls = { ImageGalleryVideoControls }
385+ ImageGalleryGrid = { ImageGalleryGrid }
463386 { ...props }
464387 />
465388 ) ;
0 commit comments