expo-simple-gallery 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"ExpoSimpleGalleryModal.d.ts","sourceRoot":"","sources":["../src/ExpoSimpleGalleryModal.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EACV,iBAAiB,EAElB,MAAM,gCAAgC,CAAC;AAKxC,wBAAgB,YAAY,CAAC,EAC3B,OAAO,EACP,IAAI,EACJ,YAAgB,EAChB,OAAO,EACP,gBAAgB,EAAE,gBAAgB,EAClC,YAAY,EACZ,KAAK,EACL,eAAe,GAChB,EAAE,iBAAiB,+BA2DnB"}
1
+ {"version":3,"file":"ExpoSimpleGalleryModal.d.ts","sourceRoot":"","sources":["../src/ExpoSimpleGalleryModal.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAsB,MAAM,gCAAgC,CAAC;AAK5F,wBAAgB,YAAY,CAAC,EAC3B,OAAO,EACP,IAAI,EACJ,YAAgB,EAChB,OAAO,EACP,gBAAgB,EAAE,gBAAgB,EAClC,YAAY,EACZ,KAAK,EACL,eAAe,GAChB,EAAE,iBAAiB,+BAmDnB"}
@@ -1,7 +1,7 @@
1
- import { requireNativeView } from 'expo';
1
+ import { requireNativeViewManager } from 'expo-modules-core';
2
2
  import { useCallback, useMemo, useState } from 'react';
3
- import { Modal, StyleSheet, View, } from 'react-native';
4
- const GalleryViewer = requireNativeView('GalleryImageViewer');
3
+ import { Modal, StyleSheet, View } from 'react-native';
4
+ const GalleryViewer = requireNativeViewManager('GalleryImageViewer');
5
5
  export function GalleryModal({ visible, uris, initialIndex = 0, onClose, overlayComponent: OverlayComponent, selectedUris, style, toggleSelection, }) {
6
6
  const [currentIndex, setCurrentIndex] = useState(initialIndex);
7
7
  const [currentUri, setCurrentUri] = useState(uris[initialIndex] || '');
@@ -1 +1 @@
1
- {"version":3,"file":"ExpoSimpleGalleryModal.js","sourceRoot":"","sources":["../src/ExpoSimpleGalleryModal.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AACzC,OAAO,EAAsB,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC3E,OAAO,EACL,KAAK,EAEL,UAAU,EACV,IAAI,GACL,MAAM,cAAc,CAAC;AAOtB,MAAM,aAAa,GACjB,iBAAiB,CAAC,oBAAoB,CAAC,CAAC;AAE1C,MAAM,UAAU,YAAY,CAAC,EAC3B,OAAO,EACP,IAAI,EACJ,YAAY,GAAG,CAAC,EAChB,OAAO,EACP,gBAAgB,EAAE,gBAAgB,EAClC,YAAY,EACZ,KAAK,EACL,eAAe,GACG;IAClB,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAC,YAAY,CAAC,CAAC;IAC/D,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC;IACvE,MAAM,QAAQ,GAAG,OAAO,CACtB,GAAG,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC,EAClC,CAAC,YAAY,EAAE,UAAU,CAAC,CAC3B,CAAC;IAEF,MAAM,gBAAgB,GAAG,WAAW,CAClC,CAAC,KAA2D,EAAE,EAAE;QAC9D,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC,WAAW,CAAC;QACzC,eAAe,CAAC,KAAK,CAAC,CAAC;QACvB,aAAa,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC,EACD,EAAE,CACH,CAAC;IAEF,MAAM,oBAAoB,GAAG,WAAW,CACtC,CAAC,KAAwC,EAAE,EAAE;QAC3C,OAAO,CAAC,KAAK,CAAC,CAAC;IACjB,CAAC,EACD,CAAC,OAAO,CAAC,CACV,CAAC;IAEF,MAAM,qBAAqB,GAAG,WAAW,CACvC,CAAC,QAAkB,EAAE,EAAE;QACrB,eAAe,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IACxC,CAAC,EACD,CAAC,UAAU,EAAE,eAAe,CAAC,CAC9B,CAAC;IAEF,OAAO,CACL,CAAC,KAAK,CACJ,OAAO,CAAC,CAAC,OAAO,CAAC,CACjB,WAAW,CAAC,CAAC,IAAI,CAAC,CAClB,aAAa,CAAC,MAAM,CACpB,cAAc,CAAC,CAAC,OAAO,CAAC,CAExB;MAAA,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,CACrC;QAAA,CAAC,aAAa,CACZ,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CACrB,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,YAAY,EAAE,CAAC,CAC9C,YAAY,CAAC,CAAC,gBAAgB,CAAC,CAC/B,gBAAgB,CAAC,CAAC,oBAAoB,CAAC,EAGzC;;QAAA,CAAC,gBAAgB,IAAI,CACnB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,aAAa,CAAC,UAAU,CAC5D;YAAA,CAAC,gBAAgB,CACf,KAAK,CAAC,CAAC,YAAY,CAAC,CACpB,GAAG,CAAC,CAAC,UAAU,CAAC,CAChB,QAAQ,CAAC,CAAC,QAAQ,CAAC,CACnB,eAAe,CAAC,CAAC,qBAAqB,CAAC,EAE3C;UAAA,EAAE,IAAI,CAAC,CACR,CACH;MAAA,EAAE,IAAI,CACR;IAAA,EAAE,KAAK,CAAC,CACT,CAAC;AACJ,CAAC;AAED,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC;IAC/B,SAAS,EAAE;QACT,IAAI,EAAE,CAAC;QACP,eAAe,EAAE,OAAO;KACzB;IACD,MAAM,EAAE;QACN,IAAI,EAAE,CAAC;KACR;IACD,gBAAgB,EAAE;QAChB,QAAQ,EAAE,UAAU;QACpB,GAAG,EAAE,CAAC;QACN,IAAI,EAAE,CAAC;QACP,KAAK,EAAE,CAAC;QACR,MAAM,EAAE,CAAC;KACV;CACF,CAAC,CAAC","sourcesContent":["import { requireNativeView } from 'expo';\nimport { type ComponentType, useCallback, useMemo, useState } from 'react';\nimport {\n Modal,\n type NativeSyntheticEvent,\n StyleSheet,\n View,\n} from 'react-native';\nimport type { GalleryItem } from './ExpoSimpleGallery.types';\nimport type {\n GalleryModalProps,\n GalleryViewerProps,\n} from './ExpoSimpleGalleryModal.types';\n\nconst GalleryViewer: ComponentType<GalleryViewerProps> =\n requireNativeView('GalleryImageViewer');\n\nexport function GalleryModal({\n visible,\n uris,\n initialIndex = 0,\n onClose,\n overlayComponent: OverlayComponent,\n selectedUris,\n style,\n toggleSelection,\n}: GalleryModalProps) {\n const [currentIndex, setCurrentIndex] = useState(initialIndex);\n const [currentUri, setCurrentUri] = useState(uris[initialIndex] || '');\n const selected = useMemo(\n () => selectedUris.has(currentUri),\n [selectedUris, currentUri]\n );\n\n const handlePageChange = useCallback(\n (event: NativeSyntheticEvent<{ index: number; uri: string }>) => {\n const { index, uri } = event.nativeEvent;\n setCurrentIndex(index);\n setCurrentUri(uri);\n },\n []\n );\n\n const handleDismissAttempt = useCallback(\n (event: NativeSyntheticEvent<GalleryItem>) => {\n onClose(event);\n },\n [onClose]\n );\n\n const handleSelectionToggle = useCallback(\n (selected?: boolean) => {\n toggleSelection(currentUri, selected);\n },\n [currentUri, toggleSelection]\n );\n\n return (\n <Modal\n visible={visible}\n transparent={true}\n animationType=\"fade\"\n onRequestClose={onClose}\n >\n <View style={[styles.container, style]}>\n <GalleryViewer\n style={styles.viewer}\n imageData={{ uris, startIndex: initialIndex }}\n onPageChange={handlePageChange}\n onDismissAttempt={handleDismissAttempt}\n />\n\n {OverlayComponent && (\n <View style={styles.overlayContainer} pointerEvents=\"box-none\">\n <OverlayComponent\n index={currentIndex}\n uri={currentUri}\n selected={selected}\n toggleSelection={handleSelectionToggle}\n />\n </View>\n )}\n </View>\n </Modal>\n );\n}\n\nconst styles = StyleSheet.create({\n container: {\n flex: 1,\n backgroundColor: 'black',\n },\n viewer: {\n flex: 1,\n },\n overlayContainer: {\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n },\n});\n"]}
1
+ {"version":3,"file":"ExpoSimpleGalleryModal.js","sourceRoot":"","sources":["../src/ExpoSimpleGalleryModal.tsx"],"names":[],"mappings":"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","sourcesContent":["import { requireNativeViewManager } from 'expo-modules-core';\nimport { type ComponentType, useCallback, useMemo, useState } from 'react';\nimport { Modal, type NativeSyntheticEvent, StyleSheet, View } from 'react-native';\nimport type { GalleryItem } from './ExpoSimpleGallery.types';\nimport type { GalleryModalProps, GalleryViewerProps } from './ExpoSimpleGalleryModal.types';\n\nconst GalleryViewer: ComponentType<GalleryViewerProps> =\n requireNativeViewManager('GalleryImageViewer');\n\nexport function GalleryModal({\n visible,\n uris,\n initialIndex = 0,\n onClose,\n overlayComponent: OverlayComponent,\n selectedUris,\n style,\n toggleSelection,\n}: GalleryModalProps) {\n const [currentIndex, setCurrentIndex] = useState(initialIndex);\n const [currentUri, setCurrentUri] = useState(uris[initialIndex] || '');\n const selected = useMemo(() => selectedUris.has(currentUri), [selectedUris, currentUri]);\n\n const handlePageChange = useCallback(\n (event: NativeSyntheticEvent<{ index: number; uri: string }>) => {\n const { index, uri } = event.nativeEvent;\n setCurrentIndex(index);\n setCurrentUri(uri);\n },\n []\n );\n\n const handleDismissAttempt = useCallback(\n (event: NativeSyntheticEvent<GalleryItem>) => {\n onClose(event);\n },\n [onClose]\n );\n\n const handleSelectionToggle = useCallback(\n (selected?: boolean) => {\n toggleSelection(currentUri, selected);\n },\n [currentUri, toggleSelection]\n );\n\n return (\n <Modal visible={visible} transparent={true} animationType=\"fade\" onRequestClose={onClose}>\n <View style={[styles.container, style]}>\n <GalleryViewer\n style={styles.viewer}\n imageData={{ uris, startIndex: initialIndex }}\n onPageChange={handlePageChange}\n onDismissAttempt={handleDismissAttempt}\n />\n\n {OverlayComponent && (\n <View style={styles.overlayContainer} pointerEvents=\"box-none\">\n <OverlayComponent\n index={currentIndex}\n uri={currentUri}\n selected={selected}\n toggleSelection={handleSelectionToggle}\n />\n </View>\n )}\n </View>\n </Modal>\n );\n}\n\nconst styles = StyleSheet.create({\n container: {\n flex: 1,\n backgroundColor: 'black',\n },\n viewer: {\n flex: 1,\n },\n overlayContainer: {\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n },\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"ExpoSimpleGalleryView.d.ts","sourceRoot":"","sources":["../src/ExpoSimpleGalleryView.tsx"],"names":[],"mappings":"AACA,OAAO,EAIL,KAAK,aAAa,EAOnB,MAAM,OAAO,CAAC;AAOf,OAAO,EACL,KAAK,wBAAwB,EAM7B,KAAK,QAAQ,EACd,MAAM,2BAA2B,CAAC;;;;;;;;;;;;;;;;;;;;AAanC,wBA8QE"}
1
+ {"version":3,"file":"ExpoSimpleGalleryView.d.ts","sourceRoot":"","sources":["../src/ExpoSimpleGalleryView.tsx"],"names":[],"mappings":"AACA,OAAO,EAIL,KAAK,aAAa,EAOnB,MAAM,OAAO,CAAC;AAOf,OAAO,EACL,KAAK,wBAAwB,EAM7B,KAAK,QAAQ,EACd,MAAM,2BAA2B,CAAC;;;;;;;;;;;;;;;;;;;;AAanC,wBA+PE"}
@@ -1,11 +1,11 @@
1
- import { requireNativeView } from 'expo';
1
+ import { requireNativeViewManager } from 'expo-modules-core';
2
2
  import { forwardRef, memo, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState, } from 'react';
3
3
  import { processColor, useWindowDimensions, } from 'react-native';
4
4
  import { isNestedArray, isNotNullOrUndefined, } from './ExpoSimpleGallery.types';
5
5
  import { GalleryModal } from './ExpoSimpleGalleryModal';
6
6
  import { MemoizedSectionHeader } from './components/MemoizedSectionHeader';
7
7
  import { MemoizedThumbnailOverlayComponent } from './components/MemoizedThumbnailOverlayComponent';
8
- const NativeView = requireNativeView('ExpoSimpleGallery');
8
+ const NativeView = requireNativeViewManager('ExpoSimpleGallery');
9
9
  const NativeViewMemoized = memo(NativeView);
10
10
  const OVERLAYS_BUFFER = 10;
11
11
  export default forwardRef(function ExpoSimpleGalleryView({ thumbnailOverlayComponent: ThumbnailOverlayComponent, fullscreenViewOverlayComponent: FullscreenOverlayComponent = () => null, sectionHeaderComponent: SectionHeaderComponent, sectionHeaderStyle, assets, thumbnailStyle, onSelectionChange, onOverlayPreloadRequested, onSectionHeadersVisible, debugLabels = false, onThumbnailPress, fullscreenViewOverlayStyle, onPreviewMenuOptionSelected, contextMenuOptions, initiallySelected, ...props }, forwardedRef) {
@@ -78,10 +78,13 @@ export default forwardRef(function ExpoSimpleGalleryView({ thumbnailOverlayCompo
78
78
  onThumbnailPress?.(event);
79
79
  }, [onThumbnailPress, openImageViewer]);
80
80
  const handleModalClose = useCallback((event) => {
81
- internalRef.current?.centerOnIndex(event.nativeEvent.index);
81
+ const index = event.nativeEvent.index;
82
82
  setModalVisible(false);
83
+ internalRef.current?.centerOnIndex(index);
83
84
  }, []);
84
- const thumbnailOverlays = useMemo(() => assets.flat().map((uri, index) => ThumbnailOverlayComponent ? (<MemoizedThumbnailOverlayComponent key={uri} OverlayComponent={ThumbnailOverlayComponent} uri={uri} index={index} width={thumbnailWidth} height={thumbnailHeight} selected={selectedUris.has(uri)} debugLabels={debugLabels} isNull={!(index >= visibleRangeMin - OVERLAYS_BUFFER &&
85
+ const thumbnailOverlays = useMemo(() => assets.flat().map((uri, index) => ThumbnailOverlayComponent ? (<MemoizedThumbnailOverlayComponent
86
+ // biome-ignore lint/suspicious/noArrayIndexKey: we need to force re-render on order change
87
+ key={`${uri}-${index}`} OverlayComponent={ThumbnailOverlayComponent} uri={uri} index={index} width={thumbnailWidth} height={thumbnailHeight} selected={selectedUris.has(uri)} debugLabels={debugLabels} isNull={!(index >= visibleRangeMin - OVERLAYS_BUFFER &&
85
88
  index <= visibleRangeMax + OVERLAYS_BUFFER)}/>) : null), [
86
89
  assets,
87
90
  ThumbnailOverlayComponent,
@@ -126,7 +129,9 @@ export default forwardRef(function ExpoSimpleGalleryView({ thumbnailOverlayCompo
126
129
  internalRef.current?.setSelected([...newSet]);
127
130
  }, [selectedUris]);
128
131
  return (<>
129
- <NativeViewMemoized {...props} thumbnailStyle={thumbnailStyleProcessed} sectionHeaderStyle={sectionHeaderStyle} assets={assets} onSelectionChange={handleSelectionChange} onOverlayPreloadRequested={handleOverlayPreloadRequest} onSectionHeadersVisible={handleSectionHeadersVisible} onThumbnailPress={handleThumbnailPress} onPreviewMenuOptionSelected={handlePreviewMenuOptionSelected} contextMenuOptions={contextMenuOptions} onLayout={() => {
132
+ <NativeViewMemoized
133
+ // key={assets.length}
134
+ {...props} thumbnailStyle={thumbnailStyleProcessed} sectionHeaderStyle={sectionHeaderStyle} assets={assets} onSelectionChange={handleSelectionChange} onOverlayPreloadRequested={handleOverlayPreloadRequest} onSectionHeadersVisible={handleSectionHeadersVisible} onThumbnailPress={handleThumbnailPress} onPreviewMenuOptionSelected={handlePreviewMenuOptionSelected} contextMenuOptions={contextMenuOptions} onLayout={() => {
130
135
  if (initiallySelected) {
131
136
  internalRef.current?.setSelected(initiallySelected?.filter(isNotNullOrUndefined));
132
137
  }
@@ -161,8 +166,7 @@ function useThumbnailDimensions({ thumbnailStyle, contentContainerStyle, columns
161
166
  contentContainerStyle?.paddingHorizontal ??
162
167
  contentContainerStyle?.padding ??
163
168
  0;
164
- const padding = Number.parseFloat(paddingLeft) +
165
- Number.parseFloat(paddingRight);
169
+ const padding = Number.parseFloat(paddingLeft) + Number.parseFloat(paddingRight);
166
170
  const thumbnailWidth = (width - padding - (columnsCount - 1) * thumbnailsSpacing) / columnsCount;
167
171
  const thumbnailHeight = thumbnailWidth / thumbnailAspectRatio;
168
172
  return { thumbnailWidth, thumbnailHeight };
@@ -1 +1 @@
1
- {"version":3,"file":"ExpoSimpleGalleryView.js","sourceRoot":"","sources":["../src/ExpoSimpleGalleryView.tsx"],"names":[],"mappings":"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","sourcesContent":["import { requireNativeView } from 'expo';\nimport {\n type ComponentType,\n forwardRef,\n memo,\n type RefAttributes,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport {\n type ColorValue,\n type NativeSyntheticEvent,\n processColor,\n useWindowDimensions,\n} from 'react-native';\nimport {\n type ExpoSimpleGalleryMethods,\n type ExpoSimpleGalleryViewProps,\n type GalleryItem,\n isNestedArray,\n isNotNullOrUndefined,\n type OnPreviewMenuOptionSelectedPayload,\n type UIAction,\n} from './ExpoSimpleGallery.types';\nimport { GalleryModal } from './ExpoSimpleGalleryModal';\nimport { MemoizedSectionHeader } from './components/MemoizedSectionHeader';\nimport { MemoizedThumbnailOverlayComponent } from './components/MemoizedThumbnailOverlayComponent';\n\nconst NativeView: ComponentType<\n ExpoSimpleGalleryViewProps & RefAttributes<ExpoSimpleGalleryMethods>\n> = requireNativeView('ExpoSimpleGallery');\n\nconst NativeViewMemoized = memo(NativeView);\n\nconst OVERLAYS_BUFFER = 10;\n\nexport default forwardRef<ExpoSimpleGalleryMethods, ExpoSimpleGalleryViewProps>(\n function ExpoSimpleGalleryView(\n {\n thumbnailOverlayComponent: ThumbnailOverlayComponent,\n fullscreenViewOverlayComponent: FullscreenOverlayComponent = () => null,\n sectionHeaderComponent: SectionHeaderComponent,\n sectionHeaderStyle,\n assets,\n thumbnailStyle,\n onSelectionChange,\n onOverlayPreloadRequested,\n onSectionHeadersVisible,\n debugLabels = false,\n onThumbnailPress,\n fullscreenViewOverlayStyle,\n onPreviewMenuOptionSelected,\n contextMenuOptions,\n initiallySelected,\n ...props\n }: ExpoSimpleGalleryViewProps,\n forwardedRef\n ) {\n const { width } = useWindowDimensions();\n const { thumbnailWidth, thumbnailHeight, thumbnailStyleProcessed } =\n useThumbnailDimensions({\n thumbnailStyle,\n contentContainerStyle: props.contentContainerStyle,\n columnsCount: props.columnsCount,\n });\n\n const openImageViewer = useCallback((index: number) => {\n setInitialIndex(index);\n setModalVisible(true);\n }, []);\n\n const thumbnailPressActionRef = useRef(props.thumbnailPressAction);\n useEffect(() => {\n thumbnailPressActionRef.current = props.thumbnailPressAction;\n }, [props.thumbnailPressAction]);\n\n const internalRef = useRef<ExpoSimpleGalleryMethods>(null);\n useImperativeHandle(forwardedRef, () => ({\n centerOnIndex: async (index: number) => {\n internalRef.current?.centerOnIndex(index);\n },\n setSelected: async (uris: string[]) => {\n internalRef.current?.setSelected(uris);\n },\n setThumbnailPressAction: async (\n action: ExpoSimpleGalleryViewProps['thumbnailPressAction']\n ) => {\n thumbnailPressActionRef.current = action;\n internalRef.current?.setThumbnailPressAction(action);\n },\n setThumbnailLongPressAction: async (\n action: ExpoSimpleGalleryViewProps['thumbnailLongPressAction']\n ) => {\n internalRef.current?.setThumbnailLongPressAction(action);\n },\n setThumbnailPanAction: async (\n action: ExpoSimpleGalleryViewProps['thumbnailPanAction']\n ) => {\n internalRef.current?.setThumbnailPanAction(action);\n },\n setContextMenuOptions: async (options: UIAction[]) => {\n internalRef.current?.setContextMenuOptions(options);\n },\n openImageViewer,\n closeImageViewer: () => {\n setModalVisible(false);\n },\n }));\n\n const [modalVisible, setModalVisible] = useState(false);\n const [initialIndex, setInitialIndex] = useState(0);\n\n const [selectedUris, setSelectedUris] = useState<Set<string>>(new Set());\n\n const [visibleRange, setVisibleRange] = useState<[number, number]>([0, 0]);\n const visibleRangeMin = useMemo(() => visibleRange[0], [visibleRange]);\n const visibleRangeMax = useMemo(() => visibleRange[1], [visibleRange]);\n\n const [visibleHeaders, setVisibleHeaders] = useState<number[]>([0]);\n const visibleHeadersRangeMin = useMemo(\n () => Math.min(...visibleHeaders),\n [visibleHeaders]\n );\n const visibleHeadersRangeMax = useMemo(\n () => Math.max(...visibleHeaders),\n [visibleHeaders]\n );\n\n const handleSelectionChange = useCallback(\n (event: NativeSyntheticEvent<{ selected: string[] }>) => {\n setSelectedUris(new Set(event.nativeEvent.selected));\n onSelectionChange?.(event);\n },\n [onSelectionChange]\n );\n\n const handleOverlayPreloadRequest = useCallback(\n (event: NativeSyntheticEvent<{ range: [number, number] }>) => {\n const [start, end] = event.nativeEvent.range;\n setVisibleRange([start, end]);\n onOverlayPreloadRequested?.(event);\n },\n [onOverlayPreloadRequested]\n );\n\n const handleSectionHeadersVisible = useCallback(\n (event: NativeSyntheticEvent<{ sections: number[] }>) => {\n setVisibleHeaders(event.nativeEvent.sections);\n onSectionHeadersVisible?.(event);\n },\n [onSectionHeadersVisible]\n );\n\n const handleThumbnailPress = useCallback(\n (event: NativeSyntheticEvent<GalleryItem>) => {\n if (thumbnailPressActionRef.current === 'open') {\n openImageViewer(event.nativeEvent.index);\n }\n onThumbnailPress?.(event);\n },\n [onThumbnailPress, openImageViewer]\n );\n\n const handleModalClose = useCallback(\n (event: NativeSyntheticEvent<GalleryItem>) => {\n internalRef.current?.centerOnIndex(event.nativeEvent.index);\n setModalVisible(false);\n },\n []\n );\n\n const thumbnailOverlays = useMemo(\n () =>\n assets.flat().map((uri, index) =>\n ThumbnailOverlayComponent ? (\n <MemoizedThumbnailOverlayComponent\n key={uri}\n OverlayComponent={ThumbnailOverlayComponent}\n uri={uri}\n index={index}\n width={thumbnailWidth}\n height={thumbnailHeight}\n selected={selectedUris.has(uri)}\n debugLabels={debugLabels}\n isNull={\n !(\n index >= visibleRangeMin - OVERLAYS_BUFFER &&\n index <= visibleRangeMax + OVERLAYS_BUFFER\n )\n }\n // isNull={false}\n />\n ) : null\n ),\n [\n assets,\n ThumbnailOverlayComponent,\n thumbnailWidth,\n thumbnailHeight,\n selectedUris,\n visibleRangeMin,\n visibleRangeMax,\n debugLabels,\n ]\n );\n\n const sectionHeaders = useMemo(() => {\n if (!SectionHeaderComponent || !isNestedArray(assets)) return null;\n return assets.map((group, index) => (\n <MemoizedSectionHeader\n key={JSON.stringify(group)}\n SectionHeader={SectionHeaderComponent}\n index={index}\n width={width}\n height={Number.parseFloat(\n (sectionHeaderStyle?.height ?? 0).toString()\n )}\n debugLabels={debugLabels}\n isNull={\n !(\n index >= visibleHeadersRangeMin - OVERLAYS_BUFFER &&\n index <= visibleHeadersRangeMax + OVERLAYS_BUFFER\n )\n }\n />\n ));\n }, [\n SectionHeaderComponent,\n assets,\n sectionHeaderStyle?.height,\n debugLabels,\n width,\n visibleHeadersRangeMin,\n visibleHeadersRangeMax,\n ]);\n\n const children = useMemo(\n () => [sectionHeaders, thumbnailOverlays],\n [sectionHeaders, thumbnailOverlays]\n );\n\n const handlePreviewMenuOptionSelected = useCallback(\n (event: NativeSyntheticEvent<OnPreviewMenuOptionSelectedPayload>) => {\n const action =\n contextMenuOptions?.[event.nativeEvent.optionIndex]?.action;\n action?.({\n uri: event.nativeEvent.uri,\n index: event.nativeEvent.index,\n });\n },\n [contextMenuOptions]\n );\n\n const handleToggleSelection = useCallback(\n (uri: string, selected?: boolean) => {\n const shouldSetSelected =\n selected === undefined ? !selectedUris.has(uri) : selected;\n const newSet = new Set(selectedUris);\n if (shouldSetSelected) {\n newSet.add(uri);\n } else {\n newSet.delete(uri);\n }\n internalRef.current?.setSelected([...newSet]);\n },\n [selectedUris]\n );\n\n return (\n <>\n <NativeViewMemoized\n {...props}\n thumbnailStyle={thumbnailStyleProcessed}\n sectionHeaderStyle={sectionHeaderStyle}\n assets={assets}\n onSelectionChange={handleSelectionChange}\n onOverlayPreloadRequested={handleOverlayPreloadRequest}\n onSectionHeadersVisible={handleSectionHeadersVisible}\n onThumbnailPress={handleThumbnailPress}\n onPreviewMenuOptionSelected={handlePreviewMenuOptionSelected}\n contextMenuOptions={contextMenuOptions}\n onLayout={() => {\n if (initiallySelected) {\n internalRef.current?.setSelected(\n initiallySelected?.filter(isNotNullOrUndefined)\n );\n }\n }}\n ref={internalRef}\n >\n {/* @ts-expect-error type of children is intentionally set to never | undefined */}\n {children}\n </NativeViewMemoized>\n <GalleryModal\n visible={modalVisible}\n uris={assets.flat()}\n initialIndex={initialIndex}\n onClose={handleModalClose}\n selectedUris={selectedUris}\n overlayComponent={FullscreenOverlayComponent}\n style={fullscreenViewOverlayStyle}\n toggleSelection={handleToggleSelection}\n />\n </>\n );\n }\n);\n\nfunction useThumbnailDimensions({\n thumbnailStyle,\n contentContainerStyle,\n columnsCount = 2,\n}: {\n thumbnailStyle: ExpoSimpleGalleryViewProps['thumbnailStyle'];\n contentContainerStyle: ExpoSimpleGalleryViewProps['contentContainerStyle'];\n columnsCount?: number;\n}) {\n const { width } = useWindowDimensions();\n const thumbnailStyleProcessed = useMemo(() => {\n if (!thumbnailStyle?.borderColor) return thumbnailStyle;\n const { borderColor } = thumbnailStyle;\n return {\n ...thumbnailStyle,\n borderColor: (processColor(borderColor) as ColorValue) ?? undefined,\n };\n }, [thumbnailStyle]);\n const { thumbnailWidth, thumbnailHeight } = useMemo(() => {\n const thumbnailAspectRatio =\n Number.parseFloat(\n (thumbnailStyleProcessed?.aspectRatio as string) ?? ''\n ) || 1;\n\n const thumbnailsSpacing = contentContainerStyle?.gap\n ? Number.parseInt(contentContainerStyle?.gap.toString())\n : 0;\n const paddingLeft =\n contentContainerStyle?.paddingLeft ??\n contentContainerStyle?.paddingHorizontal ??\n contentContainerStyle?.padding ??\n 0;\n const paddingRight =\n contentContainerStyle?.paddingRight ??\n contentContainerStyle?.paddingHorizontal ??\n contentContainerStyle?.padding ??\n 0;\n const padding =\n Number.parseFloat(paddingLeft as string) +\n Number.parseFloat(paddingRight as string);\n const thumbnailWidth =\n (width - padding - (columnsCount - 1) * thumbnailsSpacing) / columnsCount;\n const thumbnailHeight = thumbnailWidth / thumbnailAspectRatio;\n return { thumbnailWidth, thumbnailHeight };\n }, [width, thumbnailStyleProcessed, columnsCount, contentContainerStyle]);\n return { thumbnailWidth, thumbnailHeight, thumbnailStyleProcessed };\n}\n"]}
1
+ {"version":3,"file":"ExpoSimpleGalleryView.js","sourceRoot":"","sources":["../src/ExpoSimpleGalleryView.tsx"],"names":[],"mappings":"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","sourcesContent":["import { requireNativeViewManager } from 'expo-modules-core';\nimport {\n type ComponentType,\n forwardRef,\n memo,\n type RefAttributes,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport {\n type ColorValue,\n type NativeSyntheticEvent,\n processColor,\n useWindowDimensions,\n} from 'react-native';\nimport {\n type ExpoSimpleGalleryMethods,\n type ExpoSimpleGalleryViewProps,\n type GalleryItem,\n isNestedArray,\n isNotNullOrUndefined,\n type OnPreviewMenuOptionSelectedPayload,\n type UIAction,\n} from './ExpoSimpleGallery.types';\nimport { GalleryModal } from './ExpoSimpleGalleryModal';\nimport { MemoizedSectionHeader } from './components/MemoizedSectionHeader';\nimport { MemoizedThumbnailOverlayComponent } from './components/MemoizedThumbnailOverlayComponent';\n\nconst NativeView: ComponentType<\n ExpoSimpleGalleryViewProps & RefAttributes<ExpoSimpleGalleryMethods>\n> = requireNativeViewManager('ExpoSimpleGallery');\n\nconst NativeViewMemoized = memo(NativeView);\n\nconst OVERLAYS_BUFFER = 10;\n\nexport default forwardRef<ExpoSimpleGalleryMethods, ExpoSimpleGalleryViewProps>(\n function ExpoSimpleGalleryView(\n {\n thumbnailOverlayComponent: ThumbnailOverlayComponent,\n fullscreenViewOverlayComponent: FullscreenOverlayComponent = () => null,\n sectionHeaderComponent: SectionHeaderComponent,\n sectionHeaderStyle,\n assets,\n thumbnailStyle,\n onSelectionChange,\n onOverlayPreloadRequested,\n onSectionHeadersVisible,\n debugLabels = false,\n onThumbnailPress,\n fullscreenViewOverlayStyle,\n onPreviewMenuOptionSelected,\n contextMenuOptions,\n initiallySelected,\n ...props\n }: ExpoSimpleGalleryViewProps,\n forwardedRef\n ) {\n const { width } = useWindowDimensions();\n const { thumbnailWidth, thumbnailHeight, thumbnailStyleProcessed } = useThumbnailDimensions({\n thumbnailStyle,\n contentContainerStyle: props.contentContainerStyle,\n columnsCount: props.columnsCount,\n });\n\n const openImageViewer = useCallback((index: number) => {\n setInitialIndex(index);\n setModalVisible(true);\n }, []);\n\n const thumbnailPressActionRef = useRef(props.thumbnailPressAction);\n useEffect(() => {\n thumbnailPressActionRef.current = props.thumbnailPressAction;\n }, [props.thumbnailPressAction]);\n\n const internalRef = useRef<ExpoSimpleGalleryMethods>(null);\n useImperativeHandle(forwardedRef, () => ({\n centerOnIndex: async (index: number) => {\n internalRef.current?.centerOnIndex(index);\n },\n setSelected: async (uris: string[]) => {\n internalRef.current?.setSelected(uris);\n },\n setThumbnailPressAction: async (\n action: ExpoSimpleGalleryViewProps['thumbnailPressAction']\n ) => {\n thumbnailPressActionRef.current = action;\n internalRef.current?.setThumbnailPressAction(action);\n },\n setThumbnailLongPressAction: async (\n action: ExpoSimpleGalleryViewProps['thumbnailLongPressAction']\n ) => {\n internalRef.current?.setThumbnailLongPressAction(action);\n },\n setThumbnailPanAction: async (action: ExpoSimpleGalleryViewProps['thumbnailPanAction']) => {\n internalRef.current?.setThumbnailPanAction(action);\n },\n setContextMenuOptions: async (options: UIAction[]) => {\n internalRef.current?.setContextMenuOptions(options);\n },\n openImageViewer,\n closeImageViewer: () => {\n setModalVisible(false);\n },\n }));\n\n const [modalVisible, setModalVisible] = useState(false);\n const [initialIndex, setInitialIndex] = useState(0);\n\n const [selectedUris, setSelectedUris] = useState<Set<string>>(new Set());\n\n const [visibleRange, setVisibleRange] = useState<[number, number]>([0, 0]);\n const visibleRangeMin = useMemo(() => visibleRange[0], [visibleRange]);\n const visibleRangeMax = useMemo(() => visibleRange[1], [visibleRange]);\n\n const [visibleHeaders, setVisibleHeaders] = useState<number[]>([0]);\n const visibleHeadersRangeMin = useMemo(() => Math.min(...visibleHeaders), [visibleHeaders]);\n const visibleHeadersRangeMax = useMemo(() => Math.max(...visibleHeaders), [visibleHeaders]);\n\n const handleSelectionChange = useCallback(\n (event: NativeSyntheticEvent<{ selected: string[] }>) => {\n setSelectedUris(new Set(event.nativeEvent.selected));\n onSelectionChange?.(event);\n },\n [onSelectionChange]\n );\n\n const handleOverlayPreloadRequest = useCallback(\n (event: NativeSyntheticEvent<{ range: [number, number] }>) => {\n const [start, end] = event.nativeEvent.range;\n setVisibleRange([start, end]);\n onOverlayPreloadRequested?.(event);\n },\n [onOverlayPreloadRequested]\n );\n\n const handleSectionHeadersVisible = useCallback(\n (event: NativeSyntheticEvent<{ sections: number[] }>) => {\n setVisibleHeaders(event.nativeEvent.sections);\n onSectionHeadersVisible?.(event);\n },\n [onSectionHeadersVisible]\n );\n\n const handleThumbnailPress = useCallback(\n (event: NativeSyntheticEvent<GalleryItem>) => {\n if (thumbnailPressActionRef.current === 'open') {\n openImageViewer(event.nativeEvent.index);\n }\n onThumbnailPress?.(event);\n },\n [onThumbnailPress, openImageViewer]\n );\n\n const handleModalClose = useCallback((event: NativeSyntheticEvent<GalleryItem>) => {\n const index = event.nativeEvent.index;\n setModalVisible(false);\n internalRef.current?.centerOnIndex(index);\n }, []);\n\n const thumbnailOverlays = useMemo(\n () =>\n assets.flat().map((uri, index) =>\n ThumbnailOverlayComponent ? (\n <MemoizedThumbnailOverlayComponent\n // biome-ignore lint/suspicious/noArrayIndexKey: we need to force re-render on order change\n key={`${uri}-${index}`}\n OverlayComponent={ThumbnailOverlayComponent}\n uri={uri}\n index={index}\n width={thumbnailWidth}\n height={thumbnailHeight}\n selected={selectedUris.has(uri)}\n debugLabels={debugLabels}\n isNull={\n !(\n index >= visibleRangeMin - OVERLAYS_BUFFER &&\n index <= visibleRangeMax + OVERLAYS_BUFFER\n )\n }\n // isNull={false}\n />\n ) : null\n ),\n [\n assets,\n ThumbnailOverlayComponent,\n thumbnailWidth,\n thumbnailHeight,\n selectedUris,\n visibleRangeMin,\n visibleRangeMax,\n debugLabels,\n ]\n );\n\n const sectionHeaders = useMemo(() => {\n if (!SectionHeaderComponent || !isNestedArray(assets)) return null;\n return assets.map((group, index) => (\n <MemoizedSectionHeader\n key={JSON.stringify(group)}\n SectionHeader={SectionHeaderComponent}\n index={index}\n width={width}\n height={Number.parseFloat((sectionHeaderStyle?.height ?? 0).toString())}\n debugLabels={debugLabels}\n isNull={\n !(\n index >= visibleHeadersRangeMin - OVERLAYS_BUFFER &&\n index <= visibleHeadersRangeMax + OVERLAYS_BUFFER\n )\n }\n />\n ));\n }, [\n SectionHeaderComponent,\n assets,\n sectionHeaderStyle?.height,\n debugLabels,\n width,\n visibleHeadersRangeMin,\n visibleHeadersRangeMax,\n ]);\n\n const children = useMemo(\n () => [sectionHeaders, thumbnailOverlays],\n [sectionHeaders, thumbnailOverlays]\n );\n\n const handlePreviewMenuOptionSelected = useCallback(\n (event: NativeSyntheticEvent<OnPreviewMenuOptionSelectedPayload>) => {\n const action = contextMenuOptions?.[event.nativeEvent.optionIndex]?.action;\n action?.({\n uri: event.nativeEvent.uri,\n index: event.nativeEvent.index,\n });\n },\n [contextMenuOptions]\n );\n\n const handleToggleSelection = useCallback(\n (uri: string, selected?: boolean) => {\n const shouldSetSelected = selected === undefined ? !selectedUris.has(uri) : selected;\n const newSet = new Set(selectedUris);\n if (shouldSetSelected) {\n newSet.add(uri);\n } else {\n newSet.delete(uri);\n }\n internalRef.current?.setSelected([...newSet]);\n },\n [selectedUris]\n );\n\n return (\n <>\n <NativeViewMemoized\n // key={assets.length}\n {...props}\n thumbnailStyle={thumbnailStyleProcessed}\n sectionHeaderStyle={sectionHeaderStyle}\n assets={assets}\n onSelectionChange={handleSelectionChange}\n onOverlayPreloadRequested={handleOverlayPreloadRequest}\n onSectionHeadersVisible={handleSectionHeadersVisible}\n onThumbnailPress={handleThumbnailPress}\n onPreviewMenuOptionSelected={handlePreviewMenuOptionSelected}\n contextMenuOptions={contextMenuOptions}\n onLayout={() => {\n if (initiallySelected) {\n internalRef.current?.setSelected(initiallySelected?.filter(isNotNullOrUndefined));\n }\n }}\n ref={internalRef}\n >\n {/* @ts-expect-error type of children is intentionally set to never | undefined */}\n {children}\n </NativeViewMemoized>\n <GalleryModal\n visible={modalVisible}\n uris={assets.flat()}\n initialIndex={initialIndex}\n onClose={handleModalClose}\n selectedUris={selectedUris}\n overlayComponent={FullscreenOverlayComponent}\n style={fullscreenViewOverlayStyle}\n toggleSelection={handleToggleSelection}\n />\n </>\n );\n }\n);\n\nfunction useThumbnailDimensions({\n thumbnailStyle,\n contentContainerStyle,\n columnsCount = 2,\n}: {\n thumbnailStyle: ExpoSimpleGalleryViewProps['thumbnailStyle'];\n contentContainerStyle: ExpoSimpleGalleryViewProps['contentContainerStyle'];\n columnsCount?: number;\n}) {\n const { width } = useWindowDimensions();\n const thumbnailStyleProcessed = useMemo(() => {\n if (!thumbnailStyle?.borderColor) return thumbnailStyle;\n const { borderColor } = thumbnailStyle;\n return {\n ...thumbnailStyle,\n borderColor: (processColor(borderColor) as ColorValue) ?? undefined,\n };\n }, [thumbnailStyle]);\n const { thumbnailWidth, thumbnailHeight } = useMemo(() => {\n const thumbnailAspectRatio =\n Number.parseFloat((thumbnailStyleProcessed?.aspectRatio as string) ?? '') || 1;\n\n const thumbnailsSpacing = contentContainerStyle?.gap\n ? Number.parseInt(contentContainerStyle?.gap.toString())\n : 0;\n const paddingLeft =\n contentContainerStyle?.paddingLeft ??\n contentContainerStyle?.paddingHorizontal ??\n contentContainerStyle?.padding ??\n 0;\n const paddingRight =\n contentContainerStyle?.paddingRight ??\n contentContainerStyle?.paddingHorizontal ??\n contentContainerStyle?.padding ??\n 0;\n const padding =\n Number.parseFloat(paddingLeft as string) + Number.parseFloat(paddingRight as string);\n const thumbnailWidth =\n (width - padding - (columnsCount - 1) * thumbnailsSpacing) / columnsCount;\n const thumbnailHeight = thumbnailWidth / thumbnailAspectRatio;\n return { thumbnailWidth, thumbnailHeight };\n }, [width, thumbnailStyleProcessed, columnsCount, contentContainerStyle]);\n return { thumbnailWidth, thumbnailHeight, thumbnailStyleProcessed };\n}\n"]}
@@ -61,7 +61,6 @@ public class ExpoSimpleGalleryModule: Module {
61
61
  }
62
62
 
63
63
  AsyncFunction("centerOnIndex") { (view: ExpoSimpleGalleryView, index: Int) in
64
- print("AsyncFunction(centerOnIndex)")
65
64
  view.galleryView?.centerOnIndex(index)
66
65
  }.runOnQueue(.main)
67
66
 
@@ -40,38 +40,41 @@ final class ExpoSimpleGalleryView: ExpoView, ContextMenuActionsDelegate {
40
40
  }
41
41
 
42
42
  override func mountChildComponentView(_ childComponentView: UIView, index: Int) {
43
- DispatchQueue.main.async { [weak self] in
44
- guard let self else { return }
45
- guard childComponentView.superview == nil else { return }
46
- guard let label = childComponentView.accessibilityLabel else {
47
- self.callSuperMountChildComponentView(childComponentView, index: index)
43
+ // DispatchQueue.main.async { [weak self] in
44
+ // guard let self else { return }
45
+ guard childComponentView.superview == nil else { return }
46
+ guard let label = childComponentView.accessibilityLabel else {
47
+ self.callSuperMountChildComponentView(childComponentView, index: index)
48
+ return
49
+ }
50
+
51
+ if label.starts(with: "GalleryViewOverlay_") {
52
+ guard let id = Int(label.replacingOccurrences(of: "GalleryViewOverlay_", with: "")) else {
48
53
  return
49
54
  }
55
+ let component = ReactMountingComponent(view: childComponentView, index: index)
56
+ self.overlays["thumbnail"]?[id] = component
50
57
 
51
- if label.starts(with: "GalleryViewOverlay_") {
52
- guard let id = Int(label.replacingOccurrences(of: "GalleryViewOverlay_", with: "")) else { return }
53
- let component = ReactMountingComponent(view: childComponentView, index: index)
54
- self.overlays["thumbnail"]?[id] = component
58
+ if let cell = self.galleryView?.cell(withIndex: id) {
59
+ self.mount(to: cell, overlay: component)
60
+ }
61
+ } else if label.starts(with: "SectionHeaderOverlay_") {
62
+ guard let sectionId = Int(label.replacingOccurrences(of: "SectionHeaderOverlay_", with: ""))
63
+ else { return }
64
+ let component = ReactMountingComponent(view: childComponentView, index: index)
65
+ self.overlays["sectionHeader"]?[sectionId] = component
55
66
 
56
- if let cell = self.galleryView?.cell(withIndex: id) {
57
- self.mount(to: cell, overlay: component)
58
- }
59
- } else if label.starts(with: "SectionHeaderOverlay_") {
60
- guard let sectionId = Int(label.replacingOccurrences(of: "SectionHeaderOverlay_", with: "")) else { return }
61
- let component = ReactMountingComponent(view: childComponentView, index: index)
62
- self.overlays["sectionHeader"]?[sectionId] = component
63
-
64
- if let galleryView = self.galleryView, galleryView.isGroupedLayout {
65
- let indexPath = IndexPath(item: 0, section: sectionId)
66
- if let headerView = galleryView.supplementaryView(
67
- forElementKind: UICollectionView.elementKindSectionHeader,
68
- at: indexPath) as? GallerySectionHeaderView
69
- {
70
- self.mount(to: headerView, overlay: component)
71
- }
67
+ if let galleryView = self.galleryView, galleryView.isGroupedLayout {
68
+ let indexPath = IndexPath(item: 0, section: sectionId)
69
+ if let headerView = galleryView.supplementaryView(
70
+ forElementKind: UICollectionView.elementKindSectionHeader,
71
+ at: indexPath) as? GallerySectionHeaderView
72
+ {
73
+ self.mount(to: headerView, overlay: component)
72
74
  }
73
75
  }
74
76
  }
77
+ // }
75
78
  }
76
79
 
77
80
  override func unmountChildComponentView(_ childComponentView: UIView, index: Int) {
@@ -80,10 +83,13 @@ final class ExpoSimpleGalleryView: ExpoView, ContextMenuActionsDelegate {
80
83
  guard let label = childComponentView.accessibilityLabel else { return }
81
84
 
82
85
  if label.starts(with: "GalleryViewOverlay_") {
83
- guard let id = Int(label.replacingOccurrences(of: "GalleryViewOverlay_", with: "")) else { return }
86
+ guard let id = Int(label.replacingOccurrences(of: "GalleryViewOverlay_", with: "")) else {
87
+ return
88
+ }
84
89
  overlays["thumbnail"]?[id] = nil
85
90
  } else if label.starts(with: "SectionHeaderOverlay_") {
86
- guard let sectionId = Int(label.replacingOccurrences(of: "SectionHeaderOverlay_", with: "")) else { return }
91
+ guard let sectionId = Int(label.replacingOccurrences(of: "SectionHeaderOverlay_", with: ""))
92
+ else { return }
87
93
  overlays["sectionHeader"]?[sectionId] = nil
88
94
  }
89
95
  }
@@ -151,14 +157,29 @@ extension ExpoSimpleGalleryView: OverlayMountingDelegate {
151
157
  }
152
158
 
153
159
  func mount<T: OverlayContainer>(to container: T, overlay: ReactMountingComponent) {
154
- DispatchQueue.main.async { [weak self] in
155
- guard overlay.view.superview == nil else { return }
156
- guard self?.getMountedOverlayComponent(for: container)?.view != overlay.view else { return }
157
- // TODO: fix remounting after props (uris list) update
158
- container.overlayContainer.mountChildComponentView(overlay.view, index: overlay.index)
159
- // container.overlayContainer.addSubview(overlay.view)
160
- overlay.view.didMoveToSuperview()
160
+ // DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { [weak self] in
161
+ // guard let self else { return }
162
+
163
+ // if overlay.view.superview == container.overlayContainer {
164
+ // // Already mounted, no need to remount
165
+ // return
166
+ // } else
167
+
168
+ if overlay.view.superview != nil {
169
+ // If the overlay is already mounted somewhere else, unmount it first
170
+ self.unmount(overlay: overlay)
171
+ }
172
+
173
+ // guard overlay.view.superview == nil else { return }
174
+ if self.getMountedOverlayComponent(for: container) != nil {
175
+ self.unmount(from: container)
161
176
  }
177
+ // guard self.getMountedOverlayComponent(for: container)?.view != overlay.view else { return }
178
+ // TODO: fix remounting after props (uris list) update
179
+ // container.overlayContainer.mountChildComponentView(overlay.view, index: overlay.index)
180
+ container.overlayContainer.addSubview(overlay.view)
181
+ overlay.view.didMoveToSuperview()
182
+ // }
162
183
  }
163
184
 
164
185
  func unmount<T: OverlayContainer>(from container: T) {
@@ -169,10 +190,16 @@ extension ExpoSimpleGalleryView: OverlayMountingDelegate {
169
190
  }
170
191
 
171
192
  func unmount(overlay: ReactMountingComponent) {
193
+ guard overlay.view.superview != nil else { return }
194
+ print("Unmounting overlay: \(overlay.view.accessibilityLabel ?? "unknown")")
195
+ print("Overlay index: \(overlay.index)")
196
+ print("Overlay parent: \(String(describing: overlay.view.superview))")
197
+ overlay.view.willMove(toSuperview: nil)
172
198
  overlay.view.removeFromSuperview()
173
199
  }
174
200
 
175
- func getMountedOverlayComponent<T: OverlayContainer>(for container: T) -> ReactMountingComponent? {
201
+ func getMountedOverlayComponent<T: OverlayContainer>(for container: T) -> ReactMountingComponent?
202
+ {
176
203
  let (index, view) =
177
204
  container.overlayContainer.subviews.enumerated().first(where: { $0.element is ExpoView }) ?? (
178
205
  0, nil
@@ -46,14 +46,18 @@ extension GalleryGridView {
46
46
 
47
47
  reloadData()
48
48
 
49
- if !uris.isEmpty {
50
- let visibleItems = indexPathsForVisibleItems.map { $0.item }
51
- if let minItem = visibleItems.min(), let maxItem = visibleItems.max() {
52
- let range = (minItem, maxItem)
53
- overlayPreloadingDelegate?.galleryGrid(self, prefetchOverlaysFor: range)
54
- } else {
55
- let initialRange = (0, min(uris.count - 1, 30))
56
- overlayPreloadingDelegate?.galleryGrid(self, prefetchOverlaysFor: initialRange)
49
+ DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { [weak self] in
50
+ guard let self = self else { return }
51
+
52
+ if !uris.isEmpty {
53
+ let visibleItems = self.indexPathsForVisibleItems.map { $0.item }
54
+ if let minItem = visibleItems.min(), let maxItem = visibleItems.max() {
55
+ let range = (minItem, maxItem)
56
+ self.overlayPreloadingDelegate?.galleryGrid(self, prefetchOverlaysFor: range)
57
+ } else {
58
+ let initialRange = (0, min(uris.count - 1, 30))
59
+ self.overlayPreloadingDelegate?.galleryGrid(self, prefetchOverlaysFor: initialRange)
60
+ }
57
61
  }
58
62
  }
59
63
  }
@@ -68,21 +72,25 @@ extension GalleryGridView {
68
72
 
69
73
  reloadData()
70
74
 
71
- if !uris.isEmpty {
72
- let visibleIndexPaths = indexPathsForVisibleItems
73
- let flatIndices = visibleIndexPaths.compactMap { indexPath -> Int? in
74
- // Find the corresponding flat index for this indexPath
75
- sectionData.firstIndex { dict in
76
- dict["sectionIndex"] == indexPath.section && dict["itemIndex"] == indexPath.item
75
+ DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { [weak self] in
76
+ guard let self = self else { return }
77
+
78
+ if !uris.isEmpty {
79
+ let visibleIndexPaths = self.indexPathsForVisibleItems
80
+ let flatIndices = visibleIndexPaths.compactMap { indexPath -> Int? in
81
+ // Find the corresponding flat index for this indexPath
82
+ sectionData.firstIndex { dict in
83
+ dict["sectionIndex"] == indexPath.section && dict["itemIndex"] == indexPath.item
84
+ }
77
85
  }
78
- }
79
86
 
80
- if let minItem = flatIndices.min(), let maxItem = flatIndices.max() {
81
- let range = (minItem, maxItem)
82
- overlayPreloadingDelegate?.galleryGrid(self, prefetchOverlaysFor: range)
83
- } else {
84
- let initialRange = (0, min(uris.count - 1, 30))
85
- overlayPreloadingDelegate?.galleryGrid(self, prefetchOverlaysFor: initialRange)
87
+ if let minItem = flatIndices.min(), let maxItem = flatIndices.max() {
88
+ let range = (minItem, maxItem)
89
+ self.overlayPreloadingDelegate?.galleryGrid(self, prefetchOverlaysFor: range)
90
+ } else {
91
+ let initialRange = (0, min(uris.count - 1, 30))
92
+ self.overlayPreloadingDelegate?.galleryGrid(self, prefetchOverlaysFor: initialRange)
93
+ }
86
94
  }
87
95
  }
88
96
  }
@@ -16,9 +16,9 @@ final class GalleryGridView: UICollectionView {
16
16
  weak var overlayMountingDelegate: OverlayMountingDelegate?
17
17
  weak var gestureEventDelegate: GestureEventDelegate?
18
18
  weak var contextMenuActionsDelegate: ContextMenuActionsDelegate?
19
-
19
+
20
20
  var contextMenuOptions: (Int, String) -> [UIAction] = { _, _ in [] }
21
-
21
+
22
22
  var selectedAssets = Set<String>()
23
23
  var lastVisitedIndexPath: IndexPath?
24
24
  var firstVisitedCellWasSelected = false
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-simple-gallery",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "Image gallery view",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -14,12 +14,7 @@
14
14
  "expo-module": "expo-module",
15
15
  "open:ios": "xed example/ios"
16
16
  },
17
- "keywords": [
18
- "react-native",
19
- "expo",
20
- "expo-simple-gallery",
21
- "ExpoSimpleGallery"
22
- ],
17
+ "keywords": ["react-native", "expo", "expo-simple-gallery", "ExpoSimpleGallery"],
23
18
  "repository": "https://github.com/sincerely-manny/expo-simple-gallery",
24
19
  "bugs": {
25
20
  "url": "https://github.com/sincerely-manny/expo-simple-gallery/issues"
@@ -29,11 +24,11 @@
29
24
  "homepage": "https://github.com/sincerely-manny/expo-simple-gallery#readme",
30
25
  "devDependencies": {
31
26
  "@biomejs/biome": "^1.9.4",
32
- "@types/react": "~18.3.12",
33
- "expo": "~52.0.0",
27
+ "@types/react": "19.0.0",
28
+ "expo": "~53.0.0",
34
29
  "expo-module-scripts": "^4.0.3",
35
- "react-native": "0.76.0",
36
- "typescript": "^5.7.3"
30
+ "react-native": "0.79.2",
31
+ "typescript": "^5.8.0"
37
32
  },
38
33
  "peerDependencies": {
39
34
  "expo": "*",
@@ -1,19 +1,11 @@
1
- import { requireNativeView } from 'expo';
1
+ import { requireNativeViewManager } from 'expo-modules-core';
2
2
  import { type ComponentType, useCallback, useMemo, useState } from 'react';
3
- import {
4
- Modal,
5
- type NativeSyntheticEvent,
6
- StyleSheet,
7
- View,
8
- } from 'react-native';
3
+ import { Modal, type NativeSyntheticEvent, StyleSheet, View } from 'react-native';
9
4
  import type { GalleryItem } from './ExpoSimpleGallery.types';
10
- import type {
11
- GalleryModalProps,
12
- GalleryViewerProps,
13
- } from './ExpoSimpleGalleryModal.types';
5
+ import type { GalleryModalProps, GalleryViewerProps } from './ExpoSimpleGalleryModal.types';
14
6
 
15
7
  const GalleryViewer: ComponentType<GalleryViewerProps> =
16
- requireNativeView('GalleryImageViewer');
8
+ requireNativeViewManager('GalleryImageViewer');
17
9
 
18
10
  export function GalleryModal({
19
11
  visible,
@@ -27,10 +19,7 @@ export function GalleryModal({
27
19
  }: GalleryModalProps) {
28
20
  const [currentIndex, setCurrentIndex] = useState(initialIndex);
29
21
  const [currentUri, setCurrentUri] = useState(uris[initialIndex] || '');
30
- const selected = useMemo(
31
- () => selectedUris.has(currentUri),
32
- [selectedUris, currentUri]
33
- );
22
+ const selected = useMemo(() => selectedUris.has(currentUri), [selectedUris, currentUri]);
34
23
 
35
24
  const handlePageChange = useCallback(
36
25
  (event: NativeSyntheticEvent<{ index: number; uri: string }>) => {
@@ -56,12 +45,7 @@ export function GalleryModal({
56
45
  );
57
46
 
58
47
  return (
59
- <Modal
60
- visible={visible}
61
- transparent={true}
62
- animationType="fade"
63
- onRequestClose={onClose}
64
- >
48
+ <Modal visible={visible} transparent={true} animationType="fade" onRequestClose={onClose}>
65
49
  <View style={[styles.container, style]}>
66
50
  <GalleryViewer
67
51
  style={styles.viewer}
@@ -1,4 +1,4 @@
1
- import { requireNativeView } from 'expo';
1
+ import { requireNativeViewManager } from 'expo-modules-core';
2
2
  import {
3
3
  type ComponentType,
4
4
  forwardRef,
@@ -32,7 +32,7 @@ import { MemoizedThumbnailOverlayComponent } from './components/MemoizedThumbnai
32
32
 
33
33
  const NativeView: ComponentType<
34
34
  ExpoSimpleGalleryViewProps & RefAttributes<ExpoSimpleGalleryMethods>
35
- > = requireNativeView('ExpoSimpleGallery');
35
+ > = requireNativeViewManager('ExpoSimpleGallery');
36
36
 
37
37
  const NativeViewMemoized = memo(NativeView);
38
38
 
@@ -61,12 +61,11 @@ export default forwardRef<ExpoSimpleGalleryMethods, ExpoSimpleGalleryViewProps>(
61
61
  forwardedRef
62
62
  ) {
63
63
  const { width } = useWindowDimensions();
64
- const { thumbnailWidth, thumbnailHeight, thumbnailStyleProcessed } =
65
- useThumbnailDimensions({
66
- thumbnailStyle,
67
- contentContainerStyle: props.contentContainerStyle,
68
- columnsCount: props.columnsCount,
69
- });
64
+ const { thumbnailWidth, thumbnailHeight, thumbnailStyleProcessed } = useThumbnailDimensions({
65
+ thumbnailStyle,
66
+ contentContainerStyle: props.contentContainerStyle,
67
+ columnsCount: props.columnsCount,
68
+ });
70
69
 
71
70
  const openImageViewer = useCallback((index: number) => {
72
71
  setInitialIndex(index);
@@ -97,9 +96,7 @@ export default forwardRef<ExpoSimpleGalleryMethods, ExpoSimpleGalleryViewProps>(
97
96
  ) => {
98
97
  internalRef.current?.setThumbnailLongPressAction(action);
99
98
  },
100
- setThumbnailPanAction: async (
101
- action: ExpoSimpleGalleryViewProps['thumbnailPanAction']
102
- ) => {
99
+ setThumbnailPanAction: async (action: ExpoSimpleGalleryViewProps['thumbnailPanAction']) => {
103
100
  internalRef.current?.setThumbnailPanAction(action);
104
101
  },
105
102
  setContextMenuOptions: async (options: UIAction[]) => {
@@ -121,14 +118,8 @@ export default forwardRef<ExpoSimpleGalleryMethods, ExpoSimpleGalleryViewProps>(
121
118
  const visibleRangeMax = useMemo(() => visibleRange[1], [visibleRange]);
122
119
 
123
120
  const [visibleHeaders, setVisibleHeaders] = useState<number[]>([0]);
124
- const visibleHeadersRangeMin = useMemo(
125
- () => Math.min(...visibleHeaders),
126
- [visibleHeaders]
127
- );
128
- const visibleHeadersRangeMax = useMemo(
129
- () => Math.max(...visibleHeaders),
130
- [visibleHeaders]
131
- );
121
+ const visibleHeadersRangeMin = useMemo(() => Math.min(...visibleHeaders), [visibleHeaders]);
122
+ const visibleHeadersRangeMax = useMemo(() => Math.max(...visibleHeaders), [visibleHeaders]);
132
123
 
133
124
  const handleSelectionChange = useCallback(
134
125
  (event: NativeSyntheticEvent<{ selected: string[] }>) => {
@@ -165,20 +156,19 @@ export default forwardRef<ExpoSimpleGalleryMethods, ExpoSimpleGalleryViewProps>(
165
156
  [onThumbnailPress, openImageViewer]
166
157
  );
167
158
 
168
- const handleModalClose = useCallback(
169
- (event: NativeSyntheticEvent<GalleryItem>) => {
170
- internalRef.current?.centerOnIndex(event.nativeEvent.index);
171
- setModalVisible(false);
172
- },
173
- []
174
- );
159
+ const handleModalClose = useCallback((event: NativeSyntheticEvent<GalleryItem>) => {
160
+ const index = event.nativeEvent.index;
161
+ setModalVisible(false);
162
+ internalRef.current?.centerOnIndex(index);
163
+ }, []);
175
164
 
176
165
  const thumbnailOverlays = useMemo(
177
166
  () =>
178
167
  assets.flat().map((uri, index) =>
179
168
  ThumbnailOverlayComponent ? (
180
169
  <MemoizedThumbnailOverlayComponent
181
- key={uri}
170
+ // biome-ignore lint/suspicious/noArrayIndexKey: we need to force re-render on order change
171
+ key={`${uri}-${index}`}
182
172
  OverlayComponent={ThumbnailOverlayComponent}
183
173
  uri={uri}
184
174
  index={index}
@@ -216,9 +206,7 @@ export default forwardRef<ExpoSimpleGalleryMethods, ExpoSimpleGalleryViewProps>(
216
206
  SectionHeader={SectionHeaderComponent}
217
207
  index={index}
218
208
  width={width}
219
- height={Number.parseFloat(
220
- (sectionHeaderStyle?.height ?? 0).toString()
221
- )}
209
+ height={Number.parseFloat((sectionHeaderStyle?.height ?? 0).toString())}
222
210
  debugLabels={debugLabels}
223
211
  isNull={
224
212
  !(
@@ -245,8 +233,7 @@ export default forwardRef<ExpoSimpleGalleryMethods, ExpoSimpleGalleryViewProps>(
245
233
 
246
234
  const handlePreviewMenuOptionSelected = useCallback(
247
235
  (event: NativeSyntheticEvent<OnPreviewMenuOptionSelectedPayload>) => {
248
- const action =
249
- contextMenuOptions?.[event.nativeEvent.optionIndex]?.action;
236
+ const action = contextMenuOptions?.[event.nativeEvent.optionIndex]?.action;
250
237
  action?.({
251
238
  uri: event.nativeEvent.uri,
252
239
  index: event.nativeEvent.index,
@@ -257,8 +244,7 @@ export default forwardRef<ExpoSimpleGalleryMethods, ExpoSimpleGalleryViewProps>(
257
244
 
258
245
  const handleToggleSelection = useCallback(
259
246
  (uri: string, selected?: boolean) => {
260
- const shouldSetSelected =
261
- selected === undefined ? !selectedUris.has(uri) : selected;
247
+ const shouldSetSelected = selected === undefined ? !selectedUris.has(uri) : selected;
262
248
  const newSet = new Set(selectedUris);
263
249
  if (shouldSetSelected) {
264
250
  newSet.add(uri);
@@ -273,6 +259,7 @@ export default forwardRef<ExpoSimpleGalleryMethods, ExpoSimpleGalleryViewProps>(
273
259
  return (
274
260
  <>
275
261
  <NativeViewMemoized
262
+ // key={assets.length}
276
263
  {...props}
277
264
  thumbnailStyle={thumbnailStyleProcessed}
278
265
  sectionHeaderStyle={sectionHeaderStyle}
@@ -285,9 +272,7 @@ export default forwardRef<ExpoSimpleGalleryMethods, ExpoSimpleGalleryViewProps>(
285
272
  contextMenuOptions={contextMenuOptions}
286
273
  onLayout={() => {
287
274
  if (initiallySelected) {
288
- internalRef.current?.setSelected(
289
- initiallySelected?.filter(isNotNullOrUndefined)
290
- );
275
+ internalRef.current?.setSelected(initiallySelected?.filter(isNotNullOrUndefined));
291
276
  }
292
277
  }}
293
278
  ref={internalRef}
@@ -330,9 +315,7 @@ function useThumbnailDimensions({
330
315
  }, [thumbnailStyle]);
331
316
  const { thumbnailWidth, thumbnailHeight } = useMemo(() => {
332
317
  const thumbnailAspectRatio =
333
- Number.parseFloat(
334
- (thumbnailStyleProcessed?.aspectRatio as string) ?? ''
335
- ) || 1;
318
+ Number.parseFloat((thumbnailStyleProcessed?.aspectRatio as string) ?? '') || 1;
336
319
 
337
320
  const thumbnailsSpacing = contentContainerStyle?.gap
338
321
  ? Number.parseInt(contentContainerStyle?.gap.toString())
@@ -348,8 +331,7 @@ function useThumbnailDimensions({
348
331
  contentContainerStyle?.padding ??
349
332
  0;
350
333
  const padding =
351
- Number.parseFloat(paddingLeft as string) +
352
- Number.parseFloat(paddingRight as string);
334
+ Number.parseFloat(paddingLeft as string) + Number.parseFloat(paddingRight as string);
353
335
  const thumbnailWidth =
354
336
  (width - padding - (columnsCount - 1) * thumbnailsSpacing) / columnsCount;
355
337
  const thumbnailHeight = thumbnailWidth / thumbnailAspectRatio;