react-native-gesture-image-viewer 2.3.3 → 2.5.0
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.
- package/README.md +19 -5
- package/lib/module/GestureViewer.js +39 -15
- package/lib/module/GestureViewer.js.map +1 -1
- package/lib/module/GestureViewerManager.js +43 -14
- package/lib/module/GestureViewerManager.js.map +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/itemDimensions.js +86 -0
- package/lib/module/itemDimensions.js.map +1 -0
- package/lib/module/useGestureViewer.js +246 -28
- package/lib/module/useGestureViewer.js.map +1 -1
- package/lib/module/useGestureViewerPaging.js +17 -5
- package/lib/module/useGestureViewerPaging.js.map +1 -1
- package/lib/module/useGestureViewerPaging.web.js +31 -7
- package/lib/module/useGestureViewerPaging.web.js.map +1 -1
- package/lib/module/utils/index.js +43 -10
- package/lib/module/utils/index.js.map +1 -1
- package/lib/module/utils/tapZoom.js +51 -13
- package/lib/module/utils/tapZoom.js.map +1 -1
- package/lib/typescript/src/GestureViewer.d.ts.map +1 -1
- package/lib/typescript/src/GestureViewerManager.d.ts +16 -3
- package/lib/typescript/src/GestureViewerManager.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +1 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/itemDimensions.d.ts +26 -0
- package/lib/typescript/src/itemDimensions.d.ts.map +1 -0
- package/lib/typescript/src/types.d.ts +40 -1
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/lib/typescript/src/useGestureViewer.d.ts +4 -2
- package/lib/typescript/src/useGestureViewer.d.ts.map +1 -1
- package/lib/typescript/src/useGestureViewerPaging.d.ts +1 -1
- package/lib/typescript/src/useGestureViewerPaging.d.ts.map +1 -1
- package/lib/typescript/src/useGestureViewerPaging.types.d.ts +3 -0
- package/lib/typescript/src/useGestureViewerPaging.types.d.ts.map +1 -1
- package/lib/typescript/src/useGestureViewerPaging.web.d.ts +1 -1
- package/lib/typescript/src/useGestureViewerPaging.web.d.ts.map +1 -1
- package/lib/typescript/src/utils/index.d.ts +7 -3
- package/lib/typescript/src/utils/index.d.ts.map +1 -1
- package/lib/typescript/src/utils/tapZoom.d.ts +17 -1
- package/lib/typescript/src/utils/tapZoom.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/GestureViewer.tsx +64 -18
- package/src/GestureViewerManager.ts +58 -19
- package/src/index.tsx +5 -0
- package/src/itemDimensions.ts +162 -0
- package/src/types.ts +51 -1
- package/src/useGestureViewer.ts +381 -52
- package/src/useGestureViewerPaging.ts +21 -7
- package/src/useGestureViewerPaging.types.ts +3 -0
- package/src/useGestureViewerPaging.web.ts +46 -7
- package/src/utils/index.ts +86 -27
- package/src/utils/tapZoom.ts +66 -13
|
@@ -6,6 +6,8 @@ export type UseGestureViewerPagingArgs = {
|
|
|
6
6
|
adjustedInitialIndex: number;
|
|
7
7
|
autoPlay: boolean;
|
|
8
8
|
autoPlayInterval: number;
|
|
9
|
+
contentHeight: SharedValue<number>;
|
|
10
|
+
contentWidth: SharedValue<number>;
|
|
9
11
|
currentIndex: number;
|
|
10
12
|
dataLength: number;
|
|
11
13
|
enableDoubleTapZoom: boolean;
|
|
@@ -33,6 +35,7 @@ export type WebClickTarget = {
|
|
|
33
35
|
};
|
|
34
36
|
};
|
|
35
37
|
export type UseGestureViewerPagingResult = {
|
|
38
|
+
activeListIndex: number;
|
|
36
39
|
onMomentumScrollEnd?: ScrollViewProps['onMomentumScrollEnd'];
|
|
37
40
|
onScroll?: ScrollViewProps['onScroll'];
|
|
38
41
|
onScrollBeginDrag?: ScrollViewProps['onScrollBeginDrag'];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useGestureViewerPaging.types.d.ts","sourceRoot":"","sources":["../../../src/useGestureViewerPaging.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AACxC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE3D,OAAO,KAAK,oBAAoB,MAAM,wBAAwB,CAAC;AAE/D,MAAM,MAAM,0BAA0B,GAAG;IACvC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,QAAQ,EAAE,OAAO,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,mBAAmB,EAAE,OAAO,CAAC;IAC7B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACrC,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC3B,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;IACrD,gBAAgB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C,gBAAgB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C,UAAU,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAChC,UAAU,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAChC,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,qBAAqB,EAAE,MAAM;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;CAC5D,CAAC;AAEF,MAAM,MAAM,4BAA4B,GAAG;IACzC,mBAAmB,CAAC,EAAE,eAAe,CAAC,qBAAqB,CAAC,CAAC;IAC7D,QAAQ,CAAC,EAAE,eAAe,CAAC,UAAU,CAAC,CAAC;IACvC,iBAAiB,CAAC,EAAE,eAAe,CAAC,mBAAmB,CAAC,CAAC;IACzD,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,cAAc,CAAC,KAAK,IAAI,CAAC;CAC1D,CAAC"}
|
|
1
|
+
{"version":3,"file":"useGestureViewerPaging.types.d.ts","sourceRoot":"","sources":["../../../src/useGestureViewerPaging.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AACxC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE3D,OAAO,KAAK,oBAAoB,MAAM,wBAAwB,CAAC;AAE/D,MAAM,MAAM,0BAA0B,GAAG;IACvC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,QAAQ,EAAE,OAAO,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACnC,YAAY,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,mBAAmB,EAAE,OAAO,CAAC;IAC7B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACrC,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC3B,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;IACrD,gBAAgB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C,gBAAgB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C,UAAU,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAChC,UAAU,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAChC,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,qBAAqB,EAAE,MAAM;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;CAC5D,CAAC;AAEF,MAAM,MAAM,4BAA4B,GAAG;IACzC,eAAe,EAAE,MAAM,CAAC;IACxB,mBAAmB,CAAC,EAAE,eAAe,CAAC,qBAAqB,CAAC,CAAC;IAC7D,QAAQ,CAAC,EAAE,eAAe,CAAC,UAAU,CAAC,CAAC;IACvC,iBAAiB,CAAC,EAAE,eAAe,CAAC,mBAAmB,CAAC,CAAC;IACzD,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,cAAc,CAAC,KAAK,IAAI,CAAC;CAC1D,CAAC"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { UseGestureViewerPagingArgs, UseGestureViewerPagingResult } from './useGestureViewerPaging.types';
|
|
2
|
-
export declare function useGestureViewerPaging({ adjustedInitialIndex, autoPlay, autoPlayInterval, currentIndex, dataLength, enableDoubleTapZoom, enableHorizontalSwipe, enableLoop, height, onSingleTap, isRotated, isZoomed, itemSpacing, manager, maxZoomScale, scale, scrollTo, syncCurrentIndex, syncPendingIndex, translateX, translateY, width, }: UseGestureViewerPagingArgs): UseGestureViewerPagingResult;
|
|
2
|
+
export declare function useGestureViewerPaging({ adjustedInitialIndex, autoPlay, autoPlayInterval, contentHeight, contentWidth, currentIndex, dataLength, enableDoubleTapZoom, enableHorizontalSwipe, enableLoop, height, onSingleTap, isRotated, isZoomed, itemSpacing, manager, maxZoomScale, scale, scrollTo, syncCurrentIndex, syncPendingIndex, translateX, translateY, width, }: UseGestureViewerPagingArgs): UseGestureViewerPagingResult;
|
|
3
3
|
//# sourceMappingURL=useGestureViewerPaging.web.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useGestureViewerPaging.web.d.ts","sourceRoot":"","sources":["../../../src/useGestureViewerPaging.web.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,0BAA0B,EAC1B,4BAA4B,EAE7B,MAAM,gCAAgC,CAAC;AAqBxC,wBAAgB,sBAAsB,CAAC,EACrC,oBAAoB,EACpB,QAAQ,EACR,gBAAgB,EAChB,YAAY,EACZ,UAAU,EACV,mBAAmB,EACnB,qBAAqB,EACrB,UAAU,EACV,MAAM,EACN,WAAW,EACX,SAAS,EACT,QAAQ,EACR,WAAW,EACX,OAAO,EACP,YAAY,EACZ,KAAK,EACL,QAAQ,EACR,gBAAgB,EAChB,gBAAgB,EAChB,UAAU,EACV,UAAU,EACV,KAAK,GACN,EAAE,0BAA0B,GAAG,4BAA4B,
|
|
1
|
+
{"version":3,"file":"useGestureViewerPaging.web.d.ts","sourceRoot":"","sources":["../../../src/useGestureViewerPaging.web.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,0BAA0B,EAC1B,4BAA4B,EAE7B,MAAM,gCAAgC,CAAC;AAqBxC,wBAAgB,sBAAsB,CAAC,EACrC,oBAAoB,EACpB,QAAQ,EACR,gBAAgB,EAChB,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,mBAAmB,EACnB,qBAAqB,EACrB,UAAU,EACV,MAAM,EACN,WAAW,EACX,SAAS,EACT,QAAQ,EACR,WAAW,EACX,OAAO,EACP,YAAY,EACZ,KAAK,EACL,QAAQ,EACR,gBAAgB,EAChB,gBAAgB,EAChB,UAAU,EACV,UAAU,EACV,KAAK,GACN,EAAE,0BAA0B,GAAG,4BAA4B,CAma3D"}
|
|
@@ -9,10 +9,13 @@ export declare const isFlashListLike: (component: React.ComponentType<any>) => b
|
|
|
9
9
|
* and we also avoid wrapping RNGH-provided scrollables to prevent double-applying Gesture.Native() to components that already participate in RNGH.
|
|
10
10
|
*/
|
|
11
11
|
export declare const shouldUseNativeScrollGesture: (platformOS: PlatformOSType, component: React.ComponentType<any>) => boolean;
|
|
12
|
-
export declare const
|
|
12
|
+
export declare const clampIndex: (index: number | undefined, dataLength: number) => number;
|
|
13
|
+
export declare const resolveGeometrySyncTranslationMode: (previousIndex: number | null, nextIndex: number, scale: number) => "constrain" | "none" | "reset";
|
|
14
|
+
export declare const clampTranslationToBounds: ({ width, height, contentWidth, contentHeight, scale, translateX, translateY, }: {
|
|
13
15
|
width: number;
|
|
14
16
|
height: number;
|
|
15
|
-
|
|
17
|
+
contentWidth?: number;
|
|
18
|
+
contentHeight?: number;
|
|
16
19
|
translateX: number;
|
|
17
20
|
translateY: number;
|
|
18
21
|
scale: number;
|
|
@@ -20,7 +23,8 @@ export declare const createBoundsConstraint: ({ width, height }: {
|
|
|
20
23
|
translateX: number;
|
|
21
24
|
translateY: number;
|
|
22
25
|
};
|
|
23
|
-
export declare const createLoopData: <T>(
|
|
26
|
+
export declare const createLoopData: <T>(data: T[], enableLoop: boolean) => T[];
|
|
27
|
+
export declare const getLoopPhysicalIndex: (logicalIndex: number, dataLength: number, enableLoop: boolean) => number;
|
|
24
28
|
export declare const getLoopAdjustedIndex: (scrollIndex: number, originalDataLength: number, enableLoop: boolean) => {
|
|
25
29
|
realIndex: number;
|
|
26
30
|
needsJump: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,cAAc,CAAC;AAMtB,OAAO,KAAK,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAIvE,eAAO,MAAM,gBAAgB,GAC3B,WAAW,KAAK,CAAC,aAAa,CAAC,GAAG,CAAC,KAClC,SAAS,IAAI,mBAC+C,CAAC;AAEhE,eAAO,MAAM,cAAc,GACzB,WAAW,KAAK,CAAC,aAAa,CAAC,GAAG,CAAC,KAClC,SAAS,IAAI,iBAAiB,CAAC,GAAG,CAMpC,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,WAAW,KAAK,CAAC,aAAa,CAAC,GAAG,CAAC,KAAG,OAMrE,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,4BAA4B,GACvC,YAAY,cAAc,EAC1B,WAAW,KAAK,CAAC,aAAa,CAAC,GAAG,CAAC,KAClC,OAEF,CAAC;AAEF,eAAO,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,cAAc,CAAC;AAMtB,OAAO,KAAK,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAIvE,eAAO,MAAM,gBAAgB,GAC3B,WAAW,KAAK,CAAC,aAAa,CAAC,GAAG,CAAC,KAClC,SAAS,IAAI,mBAC+C,CAAC;AAEhE,eAAO,MAAM,cAAc,GACzB,WAAW,KAAK,CAAC,aAAa,CAAC,GAAG,CAAC,KAClC,SAAS,IAAI,iBAAiB,CAAC,GAAG,CAMpC,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,WAAW,KAAK,CAAC,aAAa,CAAC,GAAG,CAAC,KAAG,OAMrE,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,4BAA4B,GACvC,YAAY,cAAc,EAC1B,WAAW,KAAK,CAAC,aAAa,CAAC,GAAG,CAAC,KAClC,OAEF,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,OAAO,MAAM,GAAG,SAAS,EAAE,YAAY,MAAM,KAAG,MAY1E,CAAC;AAEF,eAAO,MAAM,kCAAkC,GAC7C,eAAe,MAAM,GAAG,IAAI,EAC5B,WAAW,MAAM,EACjB,OAAO,MAAM,KACZ,WAAW,GAAG,MAAM,GAAG,OAMzB,CAAC;AAoBF,eAAO,MAAM,wBAAwB,GAAI,gFAQtC;IACD,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;CACf;;;CAsBA,CAAC;AAEF,eAAO,MAAM,cAAc,GAAI,CAAC,EAAE,MAAM,CAAC,EAAE,EAAE,YAAY,OAAO,KAAG,CAAC,EAanE,CAAC;AAEF,eAAO,MAAM,oBAAoB,GAC/B,cAAc,MAAM,EACpB,YAAY,MAAM,EAClB,YAAY,OAAO,KAClB,MAA0E,CAAC;AAE9E,eAAO,MAAM,oBAAoB,GAC/B,aAAa,MAAM,EACnB,oBAAoB,MAAM,EAC1B,YAAY,OAAO,KAClB;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAoB/D,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,SAAS,GAAG,EAAE,OAAO,MAAM;sBAC1C,MAAM,YAAY,OAAO;CAO3C,CAAC"}
|
|
@@ -1,9 +1,25 @@
|
|
|
1
1
|
import type { SharedValue } from 'react-native-reanimated';
|
|
2
|
-
export declare const
|
|
2
|
+
export declare const getTapZoomTarget: ({ x, y, width, height, contentWidth, contentHeight, maxZoomScale, scale, }: {
|
|
3
3
|
x: number;
|
|
4
4
|
y: number;
|
|
5
5
|
width: number;
|
|
6
6
|
height: number;
|
|
7
|
+
contentWidth?: number;
|
|
8
|
+
contentHeight?: number;
|
|
9
|
+
maxZoomScale: number;
|
|
10
|
+
scale: number;
|
|
11
|
+
}) => {
|
|
12
|
+
scale: number;
|
|
13
|
+
translateX: number;
|
|
14
|
+
translateY: number;
|
|
15
|
+
};
|
|
16
|
+
export declare const applyTapZoomAtPoint: ({ x, y, width, height, contentWidth, contentHeight, maxZoomScale, scale, translateX, translateY, }: {
|
|
17
|
+
x: number;
|
|
18
|
+
y: number;
|
|
19
|
+
width: number;
|
|
20
|
+
height: number;
|
|
21
|
+
contentWidth?: number;
|
|
22
|
+
contentHeight?: number;
|
|
7
23
|
maxZoomScale: number;
|
|
8
24
|
scale: SharedValue<number>;
|
|
9
25
|
translateX: SharedValue<number>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tapZoom.d.ts","sourceRoot":"","sources":["../../../../src/utils/tapZoom.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"tapZoom.d.ts","sourceRoot":"","sources":["../../../../src/utils/tapZoom.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAK3D,eAAO,MAAM,gBAAgB,GAAI,4EAS9B;IACD,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;CACf;;;;CA2BA,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAAI,oGAWjC;IACD,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC3B,UAAU,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAChC,UAAU,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CACjC,SAsBA,CAAC"}
|
package/package.json
CHANGED
package/src/GestureViewer.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useCallback, useEffect, useMemo,
|
|
1
|
+
import { useCallback, useEffect, useMemo, type ReactElement } from 'react';
|
|
2
2
|
import {
|
|
3
3
|
Platform,
|
|
4
4
|
type ScrollViewProps,
|
|
@@ -10,10 +10,16 @@ import { Gesture, GestureDetector, GestureHandlerRootView } from 'react-native-g
|
|
|
10
10
|
import Animated from 'react-native-reanimated';
|
|
11
11
|
|
|
12
12
|
import { registry } from './GestureViewerRegistry';
|
|
13
|
-
import type {
|
|
13
|
+
import type {
|
|
14
|
+
GestureViewerItemDimensions,
|
|
15
|
+
GestureViewerProps,
|
|
16
|
+
GestureViewerRenderItemInfo,
|
|
17
|
+
} from './types';
|
|
14
18
|
import { useGestureViewer } from './useGestureViewer';
|
|
15
19
|
import {
|
|
20
|
+
clampIndex,
|
|
16
21
|
createLoopData,
|
|
22
|
+
getLoopPhysicalIndex,
|
|
17
23
|
isFlashListLike,
|
|
18
24
|
isFlatListLike,
|
|
19
25
|
isScrollViewLike,
|
|
@@ -21,6 +27,31 @@ import {
|
|
|
21
27
|
} from './utils';
|
|
22
28
|
import WebPagingFixStyle from './WebPagingFixStyle';
|
|
23
29
|
|
|
30
|
+
type GestureViewerItemCellProps<ItemT> = {
|
|
31
|
+
item: ItemT;
|
|
32
|
+
index: number;
|
|
33
|
+
isActive: boolean;
|
|
34
|
+
renderItem: (item: ItemT, index: number, info: GestureViewerRenderItemInfo) => ReactElement;
|
|
35
|
+
setItemDimensions: (index: number, item: ItemT, dimensions: GestureViewerItemDimensions) => void;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
function GestureViewerItemCell<ItemT>({
|
|
39
|
+
item,
|
|
40
|
+
index,
|
|
41
|
+
isActive,
|
|
42
|
+
renderItem,
|
|
43
|
+
setItemDimensions,
|
|
44
|
+
}: GestureViewerItemCellProps<ItemT>) {
|
|
45
|
+
const registerItemDimensions = (dimensions: GestureViewerItemDimensions) => {
|
|
46
|
+
setItemDimensions(index, item, dimensions);
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
return renderItem(item, index, {
|
|
50
|
+
isActive,
|
|
51
|
+
setItemDimensions: registerItemDimensions,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
24
55
|
export function GestureViewer<ItemT, LC>({
|
|
25
56
|
id = 'default',
|
|
26
57
|
data,
|
|
@@ -40,18 +71,20 @@ export function GestureViewer<ItemT, LC>({
|
|
|
40
71
|
}: GestureViewerProps<ItemT, LC>) {
|
|
41
72
|
const Component = ListComponent as React.ComponentType<any>;
|
|
42
73
|
|
|
43
|
-
const dataRef = useRef(data);
|
|
44
|
-
|
|
45
74
|
const { width: screenWidth, height: screenHeight } = useWindowDimensions();
|
|
46
75
|
|
|
47
76
|
const width = customWidth || screenWidth;
|
|
48
77
|
const height = customHeight || screenHeight;
|
|
78
|
+
const normalizedInitialIndex = clampIndex(initialIndex, data.length);
|
|
79
|
+
const initialListIndex = getLoopPhysicalIndex(normalizedInitialIndex, data.length, enableLoop);
|
|
49
80
|
|
|
50
|
-
const loopData = useMemo(() => createLoopData(
|
|
81
|
+
const loopData = useMemo(() => createLoopData(data, enableLoop), [data, enableLoop]);
|
|
51
82
|
|
|
52
83
|
const isScrollView = isScrollViewLike(Component);
|
|
84
|
+
const isFlashList = isFlashListLike(Component);
|
|
53
85
|
|
|
54
86
|
const {
|
|
87
|
+
activeListIndex,
|
|
55
88
|
listRef,
|
|
56
89
|
isZoomed,
|
|
57
90
|
isRotated,
|
|
@@ -66,12 +99,13 @@ export function GestureViewer<ItemT, LC>({
|
|
|
66
99
|
animatedStyle,
|
|
67
100
|
backdropStyle,
|
|
68
101
|
handleDismiss,
|
|
102
|
+
setItemDimensions,
|
|
69
103
|
} = useGestureViewer({
|
|
70
104
|
id,
|
|
71
105
|
data,
|
|
72
106
|
width,
|
|
73
107
|
height,
|
|
74
|
-
initialIndex,
|
|
108
|
+
initialIndex: normalizedInitialIndex,
|
|
75
109
|
itemSpacing,
|
|
76
110
|
enableLoop,
|
|
77
111
|
...props,
|
|
@@ -89,7 +123,9 @@ export function GestureViewer<ItemT, LC>({
|
|
|
89
123
|
);
|
|
90
124
|
|
|
91
125
|
const renderItem = useCallback(
|
|
92
|
-
({ item, index }: { item: ItemT; index: number }) => {
|
|
126
|
+
({ item, index, target }: { item: ItemT; index: number; target?: string }) => {
|
|
127
|
+
const isFlashListCell = !isFlashList || target === undefined || target === 'Cell';
|
|
128
|
+
|
|
93
129
|
return (
|
|
94
130
|
<View
|
|
95
131
|
key={isScrollView ? keyExtractor(item, index) : undefined}
|
|
@@ -102,11 +138,27 @@ export function GestureViewer<ItemT, LC>({
|
|
|
102
138
|
styles.item,
|
|
103
139
|
]}
|
|
104
140
|
>
|
|
105
|
-
|
|
141
|
+
<GestureViewerItemCell
|
|
142
|
+
index={index}
|
|
143
|
+
isActive={index === activeListIndex && isFlashListCell}
|
|
144
|
+
item={item}
|
|
145
|
+
renderItem={renderItemProp}
|
|
146
|
+
setItemDimensions={setItemDimensions}
|
|
147
|
+
/>
|
|
106
148
|
</View>
|
|
107
149
|
);
|
|
108
150
|
},
|
|
109
|
-
[
|
|
151
|
+
[
|
|
152
|
+
activeListIndex,
|
|
153
|
+
width,
|
|
154
|
+
itemSpacing,
|
|
155
|
+
renderItemProp,
|
|
156
|
+
keyExtractor,
|
|
157
|
+
isScrollView,
|
|
158
|
+
isFlashList,
|
|
159
|
+
height,
|
|
160
|
+
setItemDimensions,
|
|
161
|
+
],
|
|
110
162
|
);
|
|
111
163
|
|
|
112
164
|
const getItemLayout = useCallback(
|
|
@@ -122,10 +174,6 @@ export function GestureViewer<ItemT, LC>({
|
|
|
122
174
|
return Gesture.Race(dismissGesture, zoomGesture);
|
|
123
175
|
}, [zoomGesture, dismissGesture]);
|
|
124
176
|
|
|
125
|
-
useEffect(() => {
|
|
126
|
-
dataRef.current = data;
|
|
127
|
-
}, [data]);
|
|
128
|
-
|
|
129
177
|
useEffect(() => {
|
|
130
178
|
registry.createManager(id);
|
|
131
179
|
|
|
@@ -195,7 +243,7 @@ export function GestureViewer<ItemT, LC>({
|
|
|
195
243
|
onClick: onWebClick,
|
|
196
244
|
})}
|
|
197
245
|
{...(Platform.OS === 'web' &&
|
|
198
|
-
|
|
246
|
+
isFlashList && { dataSet: { 'flash-list-paging-enabled-fix': true } })}
|
|
199
247
|
>
|
|
200
248
|
{isScrollView
|
|
201
249
|
? maybeWrapWithNativeScrollGesture(
|
|
@@ -210,11 +258,9 @@ export function GestureViewer<ItemT, LC>({
|
|
|
210
258
|
{...commonProps}
|
|
211
259
|
data={loopData}
|
|
212
260
|
renderItem={renderItem}
|
|
213
|
-
initialScrollIndex={
|
|
214
|
-
enableLoop && data.length > 1 ? initialIndex + 1 : initialIndex
|
|
215
|
-
}
|
|
261
|
+
initialScrollIndex={initialListIndex}
|
|
216
262
|
keyExtractor={keyExtractor}
|
|
217
|
-
{...(
|
|
263
|
+
{...(isFlashList
|
|
218
264
|
? // NOTE - Deprecated estimatedItemSize for FlashList V2 (https://shopify.github.io/flash-list/docs/v2-changes#deprecated)
|
|
219
265
|
{ estimatedItemSize: width + itemSpacing }
|
|
220
266
|
: { windowSize: 3, maxToRenderPerBatch: 3, getItemLayout })}
|
|
@@ -6,12 +6,22 @@ import type {
|
|
|
6
6
|
GestureViewerEventType,
|
|
7
7
|
GestureViewerState,
|
|
8
8
|
} from './types';
|
|
9
|
-
import {
|
|
9
|
+
import { clampTranslationToBounds, createScrollAction } from './utils';
|
|
10
|
+
|
|
11
|
+
type ZoomSharedValuesOptions = {
|
|
12
|
+
scale: SharedValue<number>;
|
|
13
|
+
translateX: SharedValue<number>;
|
|
14
|
+
translateY: SharedValue<number>;
|
|
15
|
+
maxZoomScale: number;
|
|
16
|
+
contentWidth?: SharedValue<number>;
|
|
17
|
+
contentHeight?: SharedValue<number>;
|
|
18
|
+
};
|
|
10
19
|
|
|
11
20
|
class GestureViewerManager {
|
|
12
21
|
private currentIndex = 0;
|
|
13
22
|
private dataLength = 0;
|
|
14
|
-
private
|
|
23
|
+
private pagingStride = 0;
|
|
24
|
+
private viewportWidth = 0;
|
|
15
25
|
private height = 0;
|
|
16
26
|
private maxZoomScale = 2;
|
|
17
27
|
private enableHorizontalSwipe = true;
|
|
@@ -22,6 +32,8 @@ class GestureViewerManager {
|
|
|
22
32
|
private rotation: SharedValue<number> | null = null;
|
|
23
33
|
private translateX: SharedValue<number> | null = null;
|
|
24
34
|
private translateY: SharedValue<number> | null = null;
|
|
35
|
+
private contentWidth: SharedValue<number> | null = null;
|
|
36
|
+
private contentHeight: SharedValue<number> | null = null;
|
|
25
37
|
private resetTransformCallback: (() => void) | null = null;
|
|
26
38
|
|
|
27
39
|
private loopCallback: (() => void) | null = null;
|
|
@@ -105,8 +117,12 @@ class GestureViewerManager {
|
|
|
105
117
|
this.enableLoop = enabled;
|
|
106
118
|
}
|
|
107
119
|
|
|
108
|
-
|
|
109
|
-
this.
|
|
120
|
+
setPagingStride(pagingStride: number) {
|
|
121
|
+
this.pagingStride = pagingStride;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
setViewportWidth(width: number) {
|
|
125
|
+
this.viewportWidth = width;
|
|
110
126
|
}
|
|
111
127
|
|
|
112
128
|
setHeight(height: number) {
|
|
@@ -131,16 +147,20 @@ class GestureViewerManager {
|
|
|
131
147
|
}
|
|
132
148
|
}
|
|
133
149
|
|
|
134
|
-
setZoomSharedValues(
|
|
135
|
-
scale
|
|
136
|
-
translateX
|
|
137
|
-
translateY
|
|
138
|
-
maxZoomScale
|
|
139
|
-
|
|
150
|
+
setZoomSharedValues({
|
|
151
|
+
scale,
|
|
152
|
+
translateX,
|
|
153
|
+
translateY,
|
|
154
|
+
maxZoomScale,
|
|
155
|
+
contentWidth,
|
|
156
|
+
contentHeight,
|
|
157
|
+
}: ZoomSharedValuesOptions) {
|
|
140
158
|
this.scale = scale;
|
|
141
159
|
this.translateX = translateX;
|
|
142
160
|
this.translateY = translateY;
|
|
143
161
|
this.maxZoomScale = maxZoomScale;
|
|
162
|
+
this.contentWidth = contentWidth ?? null;
|
|
163
|
+
this.contentHeight = contentHeight ?? null;
|
|
144
164
|
}
|
|
145
165
|
|
|
146
166
|
setResetTransformCallback(callback: (() => void) | null) {
|
|
@@ -203,10 +223,7 @@ class GestureViewerManager {
|
|
|
203
223
|
|
|
204
224
|
this.scale.set(withTiming(nextScale));
|
|
205
225
|
|
|
206
|
-
const { translateX, translateY } =
|
|
207
|
-
width: this.width,
|
|
208
|
-
height: this.height,
|
|
209
|
-
})({
|
|
226
|
+
const { translateX, translateY } = this.constrainZoomTranslation({
|
|
210
227
|
translateX: this.translateX.get(),
|
|
211
228
|
translateY: this.translateY.get(),
|
|
212
229
|
scale: nextScale,
|
|
@@ -237,10 +254,7 @@ class GestureViewerManager {
|
|
|
237
254
|
return;
|
|
238
255
|
}
|
|
239
256
|
|
|
240
|
-
const { translateX, translateY } =
|
|
241
|
-
width: this.width,
|
|
242
|
-
height: this.height,
|
|
243
|
-
})({
|
|
257
|
+
const { translateX, translateY } = this.constrainZoomTranslation({
|
|
244
258
|
translateX: this.translateX.get(),
|
|
245
259
|
translateY: this.translateY.get(),
|
|
246
260
|
scale: nextScale,
|
|
@@ -273,7 +287,7 @@ class GestureViewerManager {
|
|
|
273
287
|
|
|
274
288
|
this.cancelPendingLoopTransition();
|
|
275
289
|
|
|
276
|
-
const { scrollTo } = createScrollAction(this.listRef, this.
|
|
290
|
+
const { scrollTo } = createScrollAction(this.listRef, this.pagingStride || this.viewportWidth);
|
|
277
291
|
|
|
278
292
|
if (this.enableLoop && this.dataLength > 1) {
|
|
279
293
|
if (index < 0) {
|
|
@@ -358,9 +372,14 @@ class GestureViewerManager {
|
|
|
358
372
|
this.currentIndex = 0;
|
|
359
373
|
this.dataLength = 0;
|
|
360
374
|
this.maxZoomScale = 2;
|
|
375
|
+
this.pagingStride = 0;
|
|
376
|
+
this.viewportWidth = 0;
|
|
377
|
+
this.height = 0;
|
|
361
378
|
this.scale = null;
|
|
362
379
|
this.translateX = null;
|
|
363
380
|
this.translateY = null;
|
|
381
|
+
this.contentWidth = null;
|
|
382
|
+
this.contentHeight = null;
|
|
364
383
|
this.rotation = null;
|
|
365
384
|
this.resetTransformCallback = null;
|
|
366
385
|
this.eventListeners.clear();
|
|
@@ -370,6 +389,26 @@ class GestureViewerManager {
|
|
|
370
389
|
this.currentIndex = targetIndex;
|
|
371
390
|
this.notifyListeners();
|
|
372
391
|
};
|
|
392
|
+
|
|
393
|
+
private constrainZoomTranslation = ({
|
|
394
|
+
scale,
|
|
395
|
+
translateX,
|
|
396
|
+
translateY,
|
|
397
|
+
}: {
|
|
398
|
+
scale: number;
|
|
399
|
+
translateX: number;
|
|
400
|
+
translateY: number;
|
|
401
|
+
}) => {
|
|
402
|
+
return clampTranslationToBounds({
|
|
403
|
+
contentHeight: this.contentHeight?.get(),
|
|
404
|
+
contentWidth: this.contentWidth?.get(),
|
|
405
|
+
height: this.height,
|
|
406
|
+
scale,
|
|
407
|
+
translateX,
|
|
408
|
+
translateY,
|
|
409
|
+
width: this.viewportWidth || this.pagingStride,
|
|
410
|
+
});
|
|
411
|
+
};
|
|
373
412
|
}
|
|
374
413
|
|
|
375
414
|
export default GestureViewerManager;
|
package/src/index.tsx
CHANGED
|
@@ -6,7 +6,12 @@ export type {
|
|
|
6
6
|
GestureViewerEventCallback,
|
|
7
7
|
GestureViewerEventData,
|
|
8
8
|
GestureViewerEventType,
|
|
9
|
+
GestureViewerItemDimensions,
|
|
10
|
+
GestureViewerItemDimensionsResolver,
|
|
11
|
+
GestureViewerItemKey,
|
|
12
|
+
GestureViewerItemKeyResolver,
|
|
9
13
|
GestureViewerProps,
|
|
14
|
+
GestureViewerRenderItemInfo,
|
|
10
15
|
GestureViewerState,
|
|
11
16
|
GestureViewerSingleTapEvent,
|
|
12
17
|
} from './types';
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
GestureViewerItemDimensions,
|
|
3
|
+
GestureViewerItemDimensionsResolver,
|
|
4
|
+
GestureViewerItemKey,
|
|
5
|
+
GestureViewerItemKeyResolver,
|
|
6
|
+
} from './types';
|
|
7
|
+
|
|
8
|
+
type ItemDimensionsRegistryEntry<ItemT> = Readonly<{
|
|
9
|
+
item: ItemT;
|
|
10
|
+
itemKey?: GestureViewerItemKey;
|
|
11
|
+
dimensions: GestureViewerItemDimensions;
|
|
12
|
+
}>;
|
|
13
|
+
|
|
14
|
+
export type ItemDimensionsRegistry<ItemT> = Map<number, ItemDimensionsRegistryEntry<ItemT>>;
|
|
15
|
+
|
|
16
|
+
export const isValidItemDimensions = (
|
|
17
|
+
dimensions: GestureViewerItemDimensions | null | undefined,
|
|
18
|
+
): dimensions is GestureViewerItemDimensions => {
|
|
19
|
+
return (
|
|
20
|
+
dimensions !== null &&
|
|
21
|
+
dimensions !== undefined &&
|
|
22
|
+
Number.isFinite(dimensions.width) &&
|
|
23
|
+
Number.isFinite(dimensions.height) &&
|
|
24
|
+
dimensions.width > 0 &&
|
|
25
|
+
dimensions.height > 0
|
|
26
|
+
);
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const resolveItemKey = <ItemT>(
|
|
30
|
+
getItemKey: GestureViewerItemKeyResolver<ItemT> | undefined,
|
|
31
|
+
item: ItemT,
|
|
32
|
+
index: number,
|
|
33
|
+
): GestureViewerItemKey | undefined => {
|
|
34
|
+
const itemKey = getItemKey?.(item, index);
|
|
35
|
+
|
|
36
|
+
if (typeof itemKey === 'string') {
|
|
37
|
+
return itemKey;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return typeof itemKey === 'number' && Number.isFinite(itemKey) ? itemKey : undefined;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const doesEntryMatchItem = <ItemT>(
|
|
44
|
+
entry: ItemDimensionsRegistryEntry<ItemT>,
|
|
45
|
+
item: ItemT,
|
|
46
|
+
itemKey: GestureViewerItemKey | undefined,
|
|
47
|
+
): boolean => {
|
|
48
|
+
if (itemKey !== undefined && entry.itemKey !== undefined) {
|
|
49
|
+
return entry.itemKey === itemKey;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return Object.is(entry.item, item);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export const pruneItemDimensionsRegistry = <ItemT>(
|
|
56
|
+
registry: ItemDimensionsRegistry<ItemT>,
|
|
57
|
+
dataLength: number,
|
|
58
|
+
): void => {
|
|
59
|
+
for (const index of registry.keys()) {
|
|
60
|
+
if (index < 0 || index >= dataLength) {
|
|
61
|
+
registry.delete(index);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export const resolveItemDimensions = <ItemT>({
|
|
67
|
+
registry,
|
|
68
|
+
data,
|
|
69
|
+
index,
|
|
70
|
+
getItemDimensions,
|
|
71
|
+
getItemKey,
|
|
72
|
+
}: {
|
|
73
|
+
registry: ItemDimensionsRegistry<ItemT>;
|
|
74
|
+
data: readonly ItemT[];
|
|
75
|
+
index: number;
|
|
76
|
+
getItemDimensions?: GestureViewerItemDimensionsResolver<ItemT>;
|
|
77
|
+
getItemKey?: GestureViewerItemKeyResolver<ItemT>;
|
|
78
|
+
}): GestureViewerItemDimensions | undefined => {
|
|
79
|
+
if (index < 0 || index >= data.length) {
|
|
80
|
+
return undefined;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// `as ItemT` restores the viewer's dense-list invariant, which TypeScript cannot infer from
|
|
84
|
+
// generic indexed access when `noUncheckedIndexedAccess` is enabled.
|
|
85
|
+
const item = data[index] as ItemT;
|
|
86
|
+
const registered = registry.get(index);
|
|
87
|
+
const itemKey = registered ? resolveItemKey(getItemKey, item, index) : undefined;
|
|
88
|
+
|
|
89
|
+
if (
|
|
90
|
+
registered &&
|
|
91
|
+
doesEntryMatchItem(registered, item, itemKey) &&
|
|
92
|
+
isValidItemDimensions(registered.dimensions)
|
|
93
|
+
) {
|
|
94
|
+
return registered.dimensions;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const resolved = getItemDimensions?.(item, index);
|
|
98
|
+
|
|
99
|
+
if (isValidItemDimensions(resolved)) {
|
|
100
|
+
return resolved;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return undefined;
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
export const registerItemDimensions = <ItemT>({
|
|
107
|
+
registry,
|
|
108
|
+
data,
|
|
109
|
+
index,
|
|
110
|
+
item,
|
|
111
|
+
dimensions,
|
|
112
|
+
getItemKey,
|
|
113
|
+
}: {
|
|
114
|
+
registry: ItemDimensionsRegistry<ItemT>;
|
|
115
|
+
data: readonly ItemT[];
|
|
116
|
+
index: number;
|
|
117
|
+
item: ItemT;
|
|
118
|
+
dimensions: GestureViewerItemDimensions;
|
|
119
|
+
getItemKey?: GestureViewerItemKeyResolver<ItemT>;
|
|
120
|
+
}): boolean => {
|
|
121
|
+
if (index < 0 || index >= data.length || !isValidItemDimensions(dimensions)) {
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// `as ItemT` restores the viewer's dense-list invariant, which TypeScript cannot infer from
|
|
126
|
+
// generic indexed access when `noUncheckedIndexedAccess` is enabled.
|
|
127
|
+
const currentItem = data[index] as ItemT;
|
|
128
|
+
const currentItemKey = resolveItemKey(getItemKey, currentItem, index);
|
|
129
|
+
const reportedItemKey = Object.is(currentItem, item)
|
|
130
|
+
? currentItemKey
|
|
131
|
+
: resolveItemKey(getItemKey, item, index);
|
|
132
|
+
const hasMatchingKey =
|
|
133
|
+
currentItemKey !== undefined &&
|
|
134
|
+
reportedItemKey !== undefined &&
|
|
135
|
+
currentItemKey === reportedItemKey;
|
|
136
|
+
|
|
137
|
+
if (!Object.is(currentItem, item) && !hasMatchingKey) {
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const registered = registry.get(index);
|
|
142
|
+
|
|
143
|
+
if (
|
|
144
|
+
registered &&
|
|
145
|
+
doesEntryMatchItem(registered, currentItem, currentItemKey) &&
|
|
146
|
+
registered.dimensions.width === dimensions.width &&
|
|
147
|
+
registered.dimensions.height === dimensions.height
|
|
148
|
+
) {
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
registry.set(index, {
|
|
153
|
+
item: currentItem,
|
|
154
|
+
itemKey: currentItemKey,
|
|
155
|
+
dimensions: {
|
|
156
|
+
height: dimensions.height,
|
|
157
|
+
width: dimensions.width,
|
|
158
|
+
},
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
return true;
|
|
162
|
+
};
|