react-native-gesture-image-viewer 2.4.0 → 3.0.0-beta.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.
Files changed (133) hide show
  1. package/README.md +5 -3
  2. package/lib/module/GestureViewer.js +88 -146
  3. package/lib/module/GestureViewer.js.map +1 -1
  4. package/lib/module/GestureViewerManager.js +49 -105
  5. package/lib/module/GestureViewerManager.js.map +1 -1
  6. package/lib/module/gestureViewerAnimation.js +18 -0
  7. package/lib/module/gestureViewerAnimation.js.map +1 -0
  8. package/lib/module/gestureViewerPaging.js +66 -0
  9. package/lib/module/gestureViewerPaging.js.map +1 -0
  10. package/lib/module/gestureViewerRenderWindow.js +29 -0
  11. package/lib/module/gestureViewerRenderWindow.js.map +1 -0
  12. package/lib/module/getWebContentProps.js +6 -0
  13. package/lib/module/getWebContentProps.js.map +1 -0
  14. package/lib/module/getWebContentProps.web.js +8 -0
  15. package/lib/module/getWebContentProps.web.js.map +1 -0
  16. package/lib/module/platformTapGestures.js +4 -0
  17. package/lib/module/platformTapGestures.js.map +1 -0
  18. package/lib/module/platformTapGestures.web.js +4 -0
  19. package/lib/module/platformTapGestures.web.js.map +1 -0
  20. package/lib/module/renderWindow.js +160 -0
  21. package/lib/module/renderWindow.js.map +1 -0
  22. package/lib/module/useGestureViewer.js +386 -206
  23. package/lib/module/useGestureViewer.js.map +1 -1
  24. package/lib/module/useGestureViewerController.js +3 -3
  25. package/lib/module/useGestureViewerController.js.map +1 -1
  26. package/lib/module/useGestureViewerManagerBridge.js +85 -0
  27. package/lib/module/useGestureViewerManagerBridge.js.map +1 -0
  28. package/lib/module/useGestureViewerPaging.js +147 -79
  29. package/lib/module/useGestureViewerPaging.js.map +1 -1
  30. package/lib/module/useWebClickHandler.js +7 -0
  31. package/lib/module/useWebClickHandler.js.map +1 -0
  32. package/lib/module/useWebClickHandler.web.js +85 -0
  33. package/lib/module/useWebClickHandler.web.js.map +1 -0
  34. package/lib/module/useWebSingleTapTimer.js +12 -0
  35. package/lib/module/useWebSingleTapTimer.js.map +1 -0
  36. package/lib/module/useWebSingleTapTimer.web.js +25 -0
  37. package/lib/module/useWebSingleTapTimer.web.js.map +1 -0
  38. package/lib/module/utils/index.js +0 -77
  39. package/lib/module/utils/index.js.map +1 -1
  40. package/lib/module/utils/tapZoom.js +4 -3
  41. package/lib/module/utils/tapZoom.js.map +1 -1
  42. package/lib/typescript/src/GestureViewer.d.ts +1 -1
  43. package/lib/typescript/src/GestureViewer.d.ts.map +1 -1
  44. package/lib/typescript/src/GestureViewerManager.d.ts +20 -20
  45. package/lib/typescript/src/GestureViewerManager.d.ts.map +1 -1
  46. package/lib/typescript/src/gestureViewerAnimation.d.ts +15 -0
  47. package/lib/typescript/src/gestureViewerAnimation.d.ts.map +1 -0
  48. package/lib/typescript/src/gestureViewerPaging.d.ts +13 -0
  49. package/lib/typescript/src/gestureViewerPaging.d.ts.map +1 -0
  50. package/lib/typescript/src/gestureViewerRenderWindow.d.ts +15 -0
  51. package/lib/typescript/src/gestureViewerRenderWindow.d.ts.map +1 -0
  52. package/lib/typescript/src/getWebContentProps.d.ts +3 -0
  53. package/lib/typescript/src/getWebContentProps.d.ts.map +1 -0
  54. package/lib/typescript/src/getWebContentProps.web.d.ts +5 -0
  55. package/lib/typescript/src/getWebContentProps.web.d.ts.map +1 -0
  56. package/lib/typescript/src/platformTapGestures.d.ts +2 -0
  57. package/lib/typescript/src/platformTapGestures.d.ts.map +1 -0
  58. package/lib/typescript/src/platformTapGestures.web.d.ts +2 -0
  59. package/lib/typescript/src/platformTapGestures.web.d.ts.map +1 -0
  60. package/lib/typescript/src/renderWindow.d.ts +44 -0
  61. package/lib/typescript/src/renderWindow.d.ts.map +1 -0
  62. package/lib/typescript/src/types.d.ts +36 -53
  63. package/lib/typescript/src/types.d.ts.map +1 -1
  64. package/lib/typescript/src/useGestureViewer.d.ts +9 -9
  65. package/lib/typescript/src/useGestureViewer.d.ts.map +1 -1
  66. package/lib/typescript/src/useGestureViewerController.d.ts +1 -1
  67. package/lib/typescript/src/useGestureViewerManagerBridge.d.ts +28 -0
  68. package/lib/typescript/src/useGestureViewerManagerBridge.d.ts.map +1 -0
  69. package/lib/typescript/src/useGestureViewerPaging.d.ts +31 -2
  70. package/lib/typescript/src/useGestureViewerPaging.d.ts.map +1 -1
  71. package/lib/typescript/src/useWebClickHandler.d.ts +35 -0
  72. package/lib/typescript/src/useWebClickHandler.d.ts.map +1 -0
  73. package/lib/typescript/src/useWebClickHandler.web.d.ts +36 -0
  74. package/lib/typescript/src/useWebClickHandler.web.d.ts.map +1 -0
  75. package/lib/typescript/src/useWebSingleTapTimer.d.ts +6 -0
  76. package/lib/typescript/src/useWebSingleTapTimer.d.ts.map +1 -0
  77. package/lib/typescript/src/useWebSingleTapTimer.web.d.ts +6 -0
  78. package/lib/typescript/src/useWebSingleTapTimer.web.d.ts.map +1 -0
  79. package/lib/typescript/src/utils/index.d.ts +0 -20
  80. package/lib/typescript/src/utils/index.d.ts.map +1 -1
  81. package/lib/typescript/src/utils/tapZoom.d.ts.map +1 -1
  82. package/package.json +1 -1
  83. package/src/GestureViewer.tsx +104 -206
  84. package/src/GestureViewerManager.ts +77 -122
  85. package/src/gestureViewerAnimation.ts +18 -0
  86. package/src/gestureViewerPaging.ts +116 -0
  87. package/src/gestureViewerRenderWindow.ts +56 -0
  88. package/src/getWebContentProps.ts +5 -0
  89. package/src/getWebContentProps.web.ts +5 -0
  90. package/src/platformTapGestures.ts +1 -0
  91. package/src/platformTapGestures.web.ts +1 -0
  92. package/src/renderWindow.ts +253 -0
  93. package/src/types.ts +34 -100
  94. package/src/useGestureViewer.ts +557 -271
  95. package/src/useGestureViewerController.ts +3 -3
  96. package/src/useGestureViewerManagerBridge.ts +118 -0
  97. package/src/useGestureViewerPaging.ts +277 -114
  98. package/src/useWebClickHandler.ts +44 -0
  99. package/src/useWebClickHandler.web.ts +146 -0
  100. package/src/useWebSingleTapTimer.ts +10 -0
  101. package/src/useWebSingleTapTimer.web.ts +30 -0
  102. package/src/utils/index.ts +0 -102
  103. package/src/utils/tapZoom.ts +4 -3
  104. package/lib/module/WebPagingFixStyle.js +0 -25
  105. package/lib/module/WebPagingFixStyle.js.map +0 -1
  106. package/lib/module/scheduleInitialScroll.js +0 -21
  107. package/lib/module/scheduleInitialScroll.js.map +0 -1
  108. package/lib/module/useGestureViewerPaging.types.js +0 -4
  109. package/lib/module/useGestureViewerPaging.types.js.map +0 -1
  110. package/lib/module/useGestureViewerPaging.web.js +0 -291
  111. package/lib/module/useGestureViewerPaging.web.js.map +0 -1
  112. package/lib/module/utils/FlashList.js +0 -9
  113. package/lib/module/utils/FlashList.js.map +0 -1
  114. package/lib/module/utils/webScroll.js +0 -70
  115. package/lib/module/utils/webScroll.js.map +0 -1
  116. package/lib/typescript/src/WebPagingFixStyle.d.ts +0 -6
  117. package/lib/typescript/src/WebPagingFixStyle.d.ts.map +0 -1
  118. package/lib/typescript/src/scheduleInitialScroll.d.ts +0 -3
  119. package/lib/typescript/src/scheduleInitialScroll.d.ts.map +0 -1
  120. package/lib/typescript/src/useGestureViewerPaging.types.d.ts +0 -42
  121. package/lib/typescript/src/useGestureViewerPaging.types.d.ts.map +0 -1
  122. package/lib/typescript/src/useGestureViewerPaging.web.d.ts +0 -3
  123. package/lib/typescript/src/useGestureViewerPaging.web.d.ts.map +0 -1
  124. package/lib/typescript/src/utils/FlashList.d.ts +0 -2
  125. package/lib/typescript/src/utils/FlashList.d.ts.map +0 -1
  126. package/lib/typescript/src/utils/webScroll.d.ts +0 -18
  127. package/lib/typescript/src/utils/webScroll.d.ts.map +0 -1
  128. package/src/WebPagingFixStyle.tsx +0 -25
  129. package/src/scheduleInitialScroll.ts +0 -36
  130. package/src/useGestureViewerPaging.types.ts +0 -42
  131. package/src/useGestureViewerPaging.web.ts +0 -453
  132. package/src/utils/FlashList.ts +0 -7
  133. package/src/utils/webScroll.ts +0 -96
@@ -0,0 +1,146 @@
1
+ import { useMemo } from 'react';
2
+ import type { SharedValue } from 'react-native-reanimated';
3
+
4
+ import type { ScheduleWebSingleTap } from './useWebSingleTapTimer';
5
+ import { applyTapZoomAtPoint } from './utils/tapZoom';
6
+
7
+ export type WebTapTarget<ItemT> = {
8
+ index: number;
9
+ item: ItemT;
10
+ };
11
+
12
+ export type WebClickEvent = {
13
+ clientX: number;
14
+ clientY: number;
15
+ currentTarget: {
16
+ getBoundingClientRect: () => {
17
+ left: number;
18
+ top: number;
19
+ };
20
+ };
21
+ detail: number;
22
+ };
23
+
24
+ export type WebClickHandler = (event: WebClickEvent) => void;
25
+
26
+ export type EmitSingleTap<ItemT> = (x: number, y: number, tapTarget?: WebTapTarget<ItemT>) => void;
27
+
28
+ export type WebClickHandlerConfig<ItemT> = {
29
+ clearPendingWebSingleTap: () => void;
30
+ emitSingleTap: EmitSingleTap<ItemT>;
31
+ enableDoubleTapZoom: boolean;
32
+ getCurrentTapTarget: () => WebTapTarget<ItemT> | null;
33
+ height: number;
34
+ isInteractionLocked: () => boolean;
35
+ maxZoomScale: number;
36
+ scale: SharedValue<number>;
37
+ scheduleWebSingleTap: ScheduleWebSingleTap;
38
+ translateX: SharedValue<number>;
39
+ translateY: SharedValue<number>;
40
+ width: number;
41
+ };
42
+
43
+ export function createWebClickHandler<ItemT>({
44
+ clearPendingWebSingleTap,
45
+ emitSingleTap,
46
+ enableDoubleTapZoom,
47
+ getCurrentTapTarget,
48
+ height,
49
+ isInteractionLocked,
50
+ maxZoomScale,
51
+ scale,
52
+ scheduleWebSingleTap,
53
+ translateX,
54
+ translateY,
55
+ width,
56
+ }: WebClickHandlerConfig<ItemT>): WebClickHandler {
57
+ return (event) => {
58
+ const rect = event.currentTarget.getBoundingClientRect();
59
+ const x = event.clientX - rect.left;
60
+ const y = event.clientY - rect.top;
61
+
62
+ if (isInteractionLocked()) {
63
+ clearPendingWebSingleTap();
64
+ return;
65
+ }
66
+
67
+ const tapTarget = getCurrentTapTarget();
68
+
69
+ if (!tapTarget) {
70
+ return;
71
+ }
72
+
73
+ if (!enableDoubleTapZoom) {
74
+ emitSingleTap(x, y, tapTarget);
75
+ return;
76
+ }
77
+
78
+ if (event.detail === 2) {
79
+ clearPendingWebSingleTap();
80
+ applyTapZoomAtPoint({
81
+ x,
82
+ y,
83
+ width,
84
+ height,
85
+ maxZoomScale,
86
+ scale,
87
+ translateX,
88
+ translateY,
89
+ });
90
+ return;
91
+ }
92
+
93
+ if (event.detail === 1) {
94
+ scheduleWebSingleTap(() => {
95
+ emitSingleTap(x, y, tapTarget);
96
+ });
97
+ }
98
+ };
99
+ }
100
+
101
+ export function useWebClickHandler<ItemT>({
102
+ clearPendingWebSingleTap,
103
+ emitSingleTap,
104
+ enableDoubleTapZoom,
105
+ getCurrentTapTarget,
106
+ height,
107
+ isInteractionLocked,
108
+ maxZoomScale,
109
+ scale,
110
+ scheduleWebSingleTap,
111
+ translateX,
112
+ translateY,
113
+ width,
114
+ }: WebClickHandlerConfig<ItemT>): WebClickHandler {
115
+ return useMemo(
116
+ () =>
117
+ createWebClickHandler({
118
+ clearPendingWebSingleTap,
119
+ emitSingleTap,
120
+ enableDoubleTapZoom,
121
+ getCurrentTapTarget,
122
+ height,
123
+ isInteractionLocked,
124
+ maxZoomScale,
125
+ scale,
126
+ scheduleWebSingleTap,
127
+ translateX,
128
+ translateY,
129
+ width,
130
+ }),
131
+ [
132
+ clearPendingWebSingleTap,
133
+ emitSingleTap,
134
+ enableDoubleTapZoom,
135
+ getCurrentTapTarget,
136
+ height,
137
+ isInteractionLocked,
138
+ maxZoomScale,
139
+ scale,
140
+ scheduleWebSingleTap,
141
+ translateX,
142
+ translateY,
143
+ width,
144
+ ],
145
+ );
146
+ }
@@ -0,0 +1,10 @@
1
+ import { useCallback } from 'react';
2
+
3
+ export type ScheduleWebSingleTap = (callback: () => void, delay?: number) => void;
4
+
5
+ export function useWebSingleTapTimer() {
6
+ const clearPendingWebSingleTap = useCallback(() => {}, []);
7
+ const scheduleWebSingleTap = useCallback<ScheduleWebSingleTap>(() => {}, []);
8
+
9
+ return { clearPendingWebSingleTap, scheduleWebSingleTap };
10
+ }
@@ -0,0 +1,30 @@
1
+ import { useCallback, useEffect, useRef } from 'react';
2
+
3
+ export type ScheduleWebSingleTap = (callback: () => void, delay?: number) => void;
4
+
5
+ export function useWebSingleTapTimer() {
6
+ const webSingleTapTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
7
+
8
+ const clearPendingWebSingleTap = useCallback(() => {
9
+ if (webSingleTapTimerRef.current) {
10
+ clearTimeout(webSingleTapTimerRef.current);
11
+ webSingleTapTimerRef.current = null;
12
+ }
13
+ }, []);
14
+
15
+ const scheduleWebSingleTap = useCallback<ScheduleWebSingleTap>(
16
+ (callback, delay = 250) => {
17
+ clearPendingWebSingleTap();
18
+
19
+ webSingleTapTimerRef.current = setTimeout(() => {
20
+ callback();
21
+ webSingleTapTimerRef.current = null;
22
+ }, delay);
23
+ },
24
+ [clearPendingWebSingleTap],
25
+ );
26
+
27
+ useEffect(() => clearPendingWebSingleTap, [clearPendingWebSingleTap]);
28
+
29
+ return { clearPendingWebSingleTap, scheduleWebSingleTap };
30
+ }
@@ -1,52 +1,3 @@
1
- import {
2
- FlatList as RNFlatList,
3
- ScrollView as RNScrollView,
4
- type PlatformOSType,
5
- } from 'react-native';
6
- import {
7
- FlatList as GestureFlatList,
8
- ScrollView as GestureScrollView,
9
- } from 'react-native-gesture-handler';
10
-
11
- import type { FlatListComponent, ScrollViewComponent } from '../types';
12
-
13
- import { FlashList } from './FlashList';
14
-
15
- export const isScrollViewLike = (
16
- component: React.ComponentType<any>,
17
- ): component is ScrollViewComponent =>
18
- component === RNScrollView || component === GestureScrollView;
19
-
20
- export const isFlatListLike = (
21
- component: React.ComponentType<any>,
22
- ): component is FlatListComponent<any> => {
23
- if (component === RNFlatList || component === GestureFlatList || isFlashListLike(component)) {
24
- return true;
25
- }
26
-
27
- return false;
28
- };
29
-
30
- export const isFlashListLike = (component: React.ComponentType<any>): boolean => {
31
- if (FlashList && component === FlashList) {
32
- return true;
33
- }
34
-
35
- return component?.displayName === 'FlashList' || component?.name === 'FlashList';
36
- };
37
-
38
- /**
39
- * iOS needs the extra Native gesture wrapper so the dismiss pan can resolve before the scrollable claims touches.
40
- * We intentionally skip Android because the same require-to-fail relation regressed horizontal paging there,
41
- * and we also avoid wrapping RNGH-provided scrollables to prevent double-applying Gesture.Native() to components that already participate in RNGH.
42
- */
43
- export const shouldUseNativeScrollGesture = (
44
- platformOS: PlatformOSType,
45
- component: React.ComponentType<any>,
46
- ): boolean => {
47
- return platformOS === 'ios' && component !== GestureScrollView && component !== GestureFlatList;
48
- };
49
-
50
1
  export const createBoundsConstraint =
51
2
  ({ width, height }: { width: number; height: number }) =>
52
3
  ({
@@ -75,56 +26,3 @@ export const createBoundsConstraint =
75
26
  translateY: Math.max(-maxTranslateY, Math.min(maxTranslateY, translateY)),
76
27
  };
77
28
  };
78
-
79
- export const createLoopData = <T>(dataRef: React.RefObject<T[]>, enableLoop: boolean): T[] => {
80
- const data = dataRef.current;
81
-
82
- if (!enableLoop || !data?.length || data.length <= 1) {
83
- return data;
84
- }
85
-
86
- const lastItem = data.at(-1);
87
- const firstItem = data[0];
88
-
89
- if (lastItem === undefined || firstItem === undefined) {
90
- return data;
91
- }
92
-
93
- return [lastItem, ...data, firstItem];
94
- };
95
-
96
- export const getLoopAdjustedIndex = (
97
- scrollIndex: number,
98
- originalDataLength: number,
99
- enableLoop: boolean,
100
- ): { realIndex: number; needsJump: boolean; jumpToIndex?: number } => {
101
- if (!enableLoop || originalDataLength <= 1) {
102
- return { needsJump: false, realIndex: scrollIndex };
103
- }
104
-
105
- if (scrollIndex === 0) {
106
- return {
107
- jumpToIndex: originalDataLength,
108
- needsJump: true,
109
- realIndex: originalDataLength - 1,
110
- };
111
- } else if (scrollIndex === originalDataLength + 1) {
112
- return {
113
- jumpToIndex: 1,
114
- needsJump: true,
115
- realIndex: 0,
116
- };
117
- }
118
-
119
- return { needsJump: false, realIndex: scrollIndex - 1 };
120
- };
121
-
122
- export const createScrollAction = (listRef: any, width: number) => ({
123
- scrollTo: (index: number, animated: boolean) => {
124
- if (listRef?.scrollToIndex) {
125
- listRef.scrollToIndex({ animated, index });
126
- } else if (listRef?.scrollTo) {
127
- listRef.scrollTo({ animated, x: index * width });
128
- }
129
- },
130
- });
@@ -35,10 +35,11 @@ export const applyTapZoomAtPoint = ({
35
35
  // NOTE 확대로 밀려난 거리만큼 반대로 이동해서 탭 지점을 제자리에 유지
36
36
  translateX.set(withTiming(-centerX * (nextScale - 1), timingConfig));
37
37
  translateY.set(withTiming(-centerY * (nextScale - 1), timingConfig));
38
- } else {
39
- translateX.set(withTiming(0, timingConfig));
40
- translateY.set(withTiming(0, timingConfig));
38
+ scale.set(withTiming(nextScale, timingConfig));
39
+ return;
41
40
  }
42
41
 
42
+ translateX.set(withTiming(0, timingConfig));
43
+ translateY.set(withTiming(0, timingConfig));
43
44
  scale.set(withTiming(nextScale, timingConfig));
44
45
  };
@@ -1,25 +0,0 @@
1
- "use strict";
2
-
3
- import { Platform } from 'react-native';
4
- import { isFlashListLike, isFlatListLike } from "./utils/index.js";
5
- import { jsx as _jsx } from "react/jsx-runtime";
6
- function WebPagingFixStyle({
7
- Component
8
- }) {
9
- if (Platform.OS !== 'web') {
10
- return null;
11
- }
12
- if (isFlashListLike(Component)) {
13
- return /*#__PURE__*/_jsx("style", {
14
- children: `[data-flash-list-paging-enabled-fix] > div {height: 100%;}`
15
- });
16
- }
17
- if (isFlatListLike(Component)) {
18
- return /*#__PURE__*/_jsx("style", {
19
- children: `[data-flat-list-paging-enabled-fix] > div > div > div {height: 100%;}`
20
- });
21
- }
22
- return null;
23
- }
24
- export default WebPagingFixStyle;
25
- //# sourceMappingURL=WebPagingFixStyle.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["Platform","isFlashListLike","isFlatListLike","jsx","_jsx","WebPagingFixStyle","Component","OS","children"],"sourceRoot":"../../src","sources":["WebPagingFixStyle.tsx"],"mappings":";;AAAA,SAASA,QAAQ,QAAQ,cAAc;AAEvC,SAASC,eAAe,EAAEC,cAAc,QAAQ,kBAAS;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAM1D,SAASC,iBAAiBA,CAAC;EAAEC;AAAkC,CAAC,EAAE;EAChE,IAAIN,QAAQ,CAACO,EAAE,KAAK,KAAK,EAAE;IACzB,OAAO,IAAI;EACb;EAEA,IAAIN,eAAe,CAACK,SAAS,CAAC,EAAE;IAC9B,oBAAOF,IAAA;MAAAI,QAAA,EAAQ;IAA4D,CAAQ,CAAC;EACtF;EAEA,IAAIN,cAAc,CAACI,SAAS,CAAC,EAAE;IAC7B,oBAAOF,IAAA;MAAAI,QAAA,EAAQ;IAAuE,CAAQ,CAAC;EACjG;EAEA,OAAO,IAAI;AACb;AAEA,eAAeH,iBAAiB","ignoreList":[]}
@@ -1,21 +0,0 @@
1
- "use strict";
2
-
3
- export const INITIAL_SCROLL_IDLE_TIMEOUT_MS = 100;
4
- export const scheduleInitialScroll = callback => {
5
- const idleGlobal = globalThis;
6
- const requestIdleCallback = idleGlobal.requestIdleCallback?.bind(idleGlobal);
7
- const cancelIdleCallback = idleGlobal.cancelIdleCallback?.bind(idleGlobal);
8
- if (requestIdleCallback && cancelIdleCallback) {
9
- const idleCallbackId = requestIdleCallback(callback, {
10
- timeout: INITIAL_SCROLL_IDLE_TIMEOUT_MS
11
- });
12
- return () => {
13
- cancelIdleCallback(idleCallbackId);
14
- };
15
- }
16
- const timeoutId = setTimeout(callback, 0);
17
- return () => {
18
- clearTimeout(timeoutId);
19
- };
20
- };
21
- //# sourceMappingURL=scheduleInitialScroll.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["INITIAL_SCROLL_IDLE_TIMEOUT_MS","scheduleInitialScroll","callback","idleGlobal","globalThis","requestIdleCallback","bind","cancelIdleCallback","idleCallbackId","timeout","timeoutId","setTimeout","clearTimeout"],"sourceRoot":"../../src","sources":["scheduleInitialScroll.ts"],"mappings":";;AAAA,OAAO,MAAMA,8BAA8B,GAAG,GAAG;AAejD,OAAO,MAAMC,qBAAqB,GAAIC,QAAoB,IAAmB;EAC3E,MAAMC,UAAU,GAAGC,UAAiC;EACpD,MAAMC,mBAAmB,GAAGF,UAAU,CAACE,mBAAmB,EAAEC,IAAI,CAACH,UAAU,CAAC;EAC5E,MAAMI,kBAAkB,GAAGJ,UAAU,CAACI,kBAAkB,EAAED,IAAI,CAACH,UAAU,CAAC;EAE1E,IAAIE,mBAAmB,IAAIE,kBAAkB,EAAE;IAC7C,MAAMC,cAAc,GAAGH,mBAAmB,CAACH,QAAQ,EAAE;MACnDO,OAAO,EAAET;IACX,CAAC,CAAC;IAEF,OAAO,MAAM;MACXO,kBAAkB,CAACC,cAAc,CAAC;IACpC,CAAC;EACH;EAEA,MAAME,SAAS,GAAGC,UAAU,CAACT,QAAQ,EAAE,CAAC,CAAC;EAEzC,OAAO,MAAM;IACXU,YAAY,CAACF,SAAS,CAAC;EACzB,CAAC;AACH,CAAC","ignoreList":[]}
@@ -1,4 +0,0 @@
1
- "use strict";
2
-
3
- export {};
4
- //# sourceMappingURL=useGestureViewerPaging.types.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":[],"sourceRoot":"../../src","sources":["useGestureViewerPaging.types.ts"],"mappings":"","ignoreList":[]}
@@ -1,291 +0,0 @@
1
- "use strict";
2
-
3
- import { useCallback, useEffect, useRef, useState } from 'react';
4
- import { applyTapZoomAtPoint } from "./utils/tapZoom.js";
5
- import { getWebAutoPlayTargetPhysicalIndex, getWebScrollPhysicalIndex, resolveWebScrollFinalState } from "./utils/webScroll.js";
6
- export function useGestureViewerPaging({
7
- adjustedInitialIndex,
8
- autoPlay,
9
- autoPlayInterval,
10
- currentIndex,
11
- dataLength,
12
- enableDoubleTapZoom,
13
- enableHorizontalSwipe,
14
- enableLoop,
15
- height,
16
- onSingleTap,
17
- isRotated,
18
- isZoomed,
19
- itemSpacing,
20
- manager,
21
- maxZoomScale,
22
- scale,
23
- scrollTo,
24
- syncCurrentIndex,
25
- syncPendingIndex,
26
- translateX,
27
- translateY,
28
- width
29
- }) {
30
- const [activeListIndex, setActiveListIndex] = useState(adjustedInitialIndex);
31
- const activeResetItemSpacing = adjustedInitialIndex > 0 ? itemSpacing : 0;
32
- const activeResetWidth = adjustedInitialIndex > 0 ? width : 0;
33
- const webSingleTapTimerRef = useRef(null);
34
- const webScrollRuntimeRef = useRef({
35
- actor: 'idle',
36
- isAutoplayPausedByUser: false,
37
- lastSettledPhysicalIndex: adjustedInitialIndex,
38
- latestOffsetX: adjustedInitialIndex * (width + itemSpacing),
39
- latestRawPhysicalIndex: adjustedInitialIndex,
40
- lastProgrammaticScrollVersion: 0,
41
- settleTimer: null,
42
- resumeAutoplayTimer: null
43
- });
44
- const clearWebSingleTapTimer = useCallback(() => {
45
- if (webSingleTapTimerRef.current) {
46
- clearTimeout(webSingleTapTimerRef.current);
47
- webSingleTapTimerRef.current = null;
48
- }
49
- }, []);
50
- const clearWebSettleTimer = useCallback(() => {
51
- const runtime = webScrollRuntimeRef.current;
52
- if (runtime.settleTimer) {
53
- clearTimeout(runtime.settleTimer);
54
- runtime.settleTimer = null;
55
- }
56
- }, []);
57
- const clearWebAutoplayResumeTimer = useCallback(() => {
58
- const runtime = webScrollRuntimeRef.current;
59
- if (runtime.resumeAutoplayTimer) {
60
- clearTimeout(runtime.resumeAutoplayTimer);
61
- runtime.resumeAutoplayTimer = null;
62
- }
63
- }, []);
64
- const scheduleWebAutoplayResume = useCallback(() => {
65
- const runtime = webScrollRuntimeRef.current;
66
- clearWebAutoplayResumeTimer();
67
- runtime.resumeAutoplayTimer = setTimeout(() => {
68
- runtime.isAutoplayPausedByUser = false;
69
- runtime.resumeAutoplayTimer = null;
70
- }, 800);
71
- }, [clearWebAutoplayResumeTimer]);
72
- const pauseWebAutoplayWithoutPagingInteraction = useCallback(() => {
73
- const runtime = webScrollRuntimeRef.current;
74
- runtime.isAutoplayPausedByUser = true;
75
- runtime.actor = 'idle';
76
- clearWebAutoplayResumeTimer();
77
- }, [clearWebAutoplayResumeTimer]);
78
- const beginWebUserInteraction = useCallback((force = false) => {
79
- const runtime = webScrollRuntimeRef.current;
80
- if (!force && runtime.actor === 'autoplay') {
81
- return;
82
- }
83
- runtime.actor = 'user';
84
- runtime.isAutoplayPausedByUser = true;
85
- clearWebAutoplayResumeTimer();
86
- }, [clearWebAutoplayResumeTimer]);
87
- const beginWebAutoplayScroll = useCallback(() => {
88
- const runtime = webScrollRuntimeRef.current;
89
- runtime.actor = 'autoplay';
90
- runtime.isAutoplayPausedByUser = false;
91
- runtime.lastProgrammaticScrollVersion = manager?.getProgrammaticScrollVersion() ?? 0;
92
- clearWebAutoplayResumeTimer();
93
- }, [clearWebAutoplayResumeTimer, manager]);
94
- const syncProgrammaticActorFromManager = useCallback(() => {
95
- const runtime = webScrollRuntimeRef.current;
96
- const nextVersion = manager?.getProgrammaticScrollVersion() ?? 0;
97
- if (nextVersion === runtime.lastProgrammaticScrollVersion) {
98
- return;
99
- }
100
- runtime.actor = 'autoplay';
101
- runtime.isAutoplayPausedByUser = false;
102
- runtime.lastProgrammaticScrollVersion = nextVersion;
103
- clearWebAutoplayResumeTimer();
104
- }, [clearWebAutoplayResumeTimer, manager]);
105
- const finalizeWebScroll = useCallback((offsetX, source = 'scroll') => {
106
- if (!enableHorizontalSwipe || dataLength <= 0) {
107
- return;
108
- }
109
- const runtime = webScrollRuntimeRef.current;
110
- const settledByActor = runtime.actor;
111
- clearWebSettleTimer();
112
- runtime.latestOffsetX = offsetX;
113
- const settledState = resolveWebScrollFinalState({
114
- dataLength,
115
- enableLoop,
116
- lastSettledPhysicalIndex: runtime.lastSettledPhysicalIndex,
117
- offsetX,
118
- pageWidth: width + itemSpacing
119
- });
120
- if (!settledState) {
121
- return;
122
- }
123
- const {
124
- logicalIndex,
125
- rawPhysicalIndex,
126
- settledPhysicalIndex
127
- } = settledState;
128
- if (source === 'scroll' && runtime.latestRawPhysicalIndex !== rawPhysicalIndex) {
129
- return;
130
- }
131
- if (rawPhysicalIndex !== settledPhysicalIndex) {
132
- const crossedLoopBoundary = enableLoop && dataLength > 1 && (rawPhysicalIndex === 0 || rawPhysicalIndex === dataLength + 1);
133
- scrollTo(settledPhysicalIndex, !crossedLoopBoundary);
134
- }
135
- runtime.lastSettledPhysicalIndex = settledPhysicalIndex;
136
- runtime.latestOffsetX = settledPhysicalIndex * (width + itemSpacing);
137
- runtime.actor = 'idle';
138
- manager?.cancelPendingLoopTransition();
139
- setActiveListIndex(settledPhysicalIndex);
140
- syncCurrentIndex(logicalIndex);
141
- if (settledByActor === 'user') {
142
- scheduleWebAutoplayResume();
143
- }
144
- }, [clearWebSettleTimer, dataLength, enableHorizontalSwipe, enableLoop, itemSpacing, manager, scheduleWebAutoplayResume, scrollTo, syncCurrentIndex, width]);
145
- const scheduleWebScrollSettle = useCallback(offsetX => {
146
- const runtime = webScrollRuntimeRef.current;
147
- runtime.latestOffsetX = offsetX;
148
- runtime.latestRawPhysicalIndex = getWebScrollPhysicalIndex(offsetX, width + itemSpacing);
149
- clearWebSettleTimer();
150
- runtime.settleTimer = setTimeout(() => {
151
- finalizeWebScroll(runtime.latestOffsetX, 'scroll');
152
- }, 180);
153
- }, [clearWebSettleTimer, finalizeWebScroll, itemSpacing, width]);
154
- useEffect(() => {
155
- const runtime = webScrollRuntimeRef.current;
156
- runtime.actor = 'idle';
157
- runtime.isAutoplayPausedByUser = false;
158
- runtime.lastSettledPhysicalIndex = adjustedInitialIndex;
159
- runtime.latestOffsetX = adjustedInitialIndex * (activeResetWidth + activeResetItemSpacing);
160
- runtime.latestRawPhysicalIndex = adjustedInitialIndex;
161
- runtime.lastProgrammaticScrollVersion = manager?.getProgrammaticScrollVersion() ?? 0;
162
- setActiveListIndex(adjustedInitialIndex);
163
- clearWebSettleTimer();
164
- clearWebAutoplayResumeTimer();
165
- }, [activeResetItemSpacing, activeResetWidth, adjustedInitialIndex, clearWebAutoplayResumeTimer, clearWebSettleTimer, dataLength, manager]);
166
- useEffect(() => {
167
- const runtime = webScrollRuntimeRef.current;
168
- runtime.actor = 'idle';
169
- runtime.isAutoplayPausedByUser = false;
170
- runtime.latestOffsetX = runtime.lastSettledPhysicalIndex * (width + itemSpacing);
171
- runtime.latestRawPhysicalIndex = runtime.lastSettledPhysicalIndex;
172
- runtime.lastProgrammaticScrollVersion = manager?.getProgrammaticScrollVersion() ?? 0;
173
- clearWebSettleTimer();
174
- clearWebAutoplayResumeTimer();
175
- }, [clearWebAutoplayResumeTimer, clearWebSettleTimer, itemSpacing, manager, width]);
176
- useEffect(() => {
177
- return () => {
178
- clearWebSingleTapTimer();
179
- clearWebSettleTimer();
180
- clearWebAutoplayResumeTimer();
181
- };
182
- }, [clearWebAutoplayResumeTimer, clearWebSettleTimer, clearWebSingleTapTimer]);
183
- useEffect(() => {
184
- if (!autoPlay || dataLength <= 1 || isZoomed || isRotated || !enableLoop && currentIndex === dataLength - 1) {
185
- return;
186
- }
187
- const intervalMs = Math.max(250, Math.floor(autoPlayInterval || 0));
188
- if (!Number.isFinite(intervalMs)) {
189
- return;
190
- }
191
- const interval = setInterval(() => {
192
- if (isZoomed || isRotated) {
193
- return;
194
- }
195
- const runtime = webScrollRuntimeRef.current;
196
- if (runtime.actor !== 'idle' || runtime.isAutoplayPausedByUser || runtime.settleTimer) {
197
- return;
198
- }
199
- const targetPhysicalIndex = getWebAutoPlayTargetPhysicalIndex({
200
- currentIndex,
201
- dataLength,
202
- enableLoop
203
- });
204
- if (targetPhysicalIndex === null) {
205
- return;
206
- }
207
- beginWebAutoplayScroll();
208
- runtime.latestOffsetX = targetPhysicalIndex * (width + itemSpacing);
209
- scrollTo(targetPhysicalIndex, true);
210
- scheduleWebScrollSettle(runtime.latestOffsetX);
211
- }, intervalMs);
212
- return () => clearInterval(interval);
213
- }, [autoPlay, autoPlayInterval, beginWebAutoplayScroll, currentIndex, dataLength, enableLoop, isRotated, isZoomed, itemSpacing, scheduleWebScrollSettle, scrollTo, width]);
214
- const onScroll = useCallback(event => {
215
- if (!enableHorizontalSwipe) {
216
- return;
217
- }
218
- const offsetX = event.nativeEvent.contentOffset.x;
219
- const runtime = webScrollRuntimeRef.current;
220
- const pendingState = resolveWebScrollFinalState({
221
- dataLength,
222
- enableLoop,
223
- lastSettledPhysicalIndex: runtime.lastSettledPhysicalIndex,
224
- offsetX,
225
- pageWidth: width + itemSpacing
226
- });
227
- if (pendingState) {
228
- syncPendingIndex(pendingState.logicalIndex);
229
- }
230
- syncProgrammaticActorFromManager();
231
- beginWebUserInteraction();
232
- scheduleWebScrollSettle(offsetX);
233
- }, [beginWebUserInteraction, dataLength, enableHorizontalSwipe, enableLoop, itemSpacing, scheduleWebScrollSettle, syncPendingIndex, syncProgrammaticActorFromManager, width]);
234
- const onMomentumScrollEnd = useCallback(event => {
235
- if (!enableHorizontalSwipe) {
236
- return;
237
- }
238
- finalizeWebScroll(event.nativeEvent.contentOffset.x, 'momentum');
239
- }, [enableHorizontalSwipe, finalizeWebScroll]);
240
- const onScrollBeginDrag = useCallback(() => {
241
- beginWebUserInteraction(true);
242
- clearWebSettleTimer();
243
- manager?.handleScrollBeginDrag();
244
- }, [beginWebUserInteraction, clearWebSettleTimer, manager]);
245
- const onWebClick = useCallback(event => {
246
- const detail = event.detail;
247
- const rect = event.currentTarget.getBoundingClientRect();
248
- const resolvedX = event.clientX - rect.left;
249
- const resolvedY = event.clientY - rect.top;
250
- if (!enableDoubleTapZoom) {
251
- if (!onSingleTap) {
252
- return;
253
- }
254
- clearWebSingleTapTimer();
255
- onSingleTap(resolvedX, resolvedY);
256
- return;
257
- }
258
- if (detail === 2) {
259
- clearWebSingleTapTimer();
260
- pauseWebAutoplayWithoutPagingInteraction();
261
- scheduleWebAutoplayResume();
262
- applyTapZoomAtPoint({
263
- x: resolvedX,
264
- y: resolvedY,
265
- width,
266
- height,
267
- maxZoomScale,
268
- scale,
269
- translateX,
270
- translateY
271
- });
272
- return;
273
- }
274
- if (detail !== 1 || !onSingleTap) {
275
- return;
276
- }
277
- clearWebSingleTapTimer();
278
- webSingleTapTimerRef.current = setTimeout(() => {
279
- onSingleTap(resolvedX, resolvedY);
280
- webSingleTapTimerRef.current = null;
281
- }, 250);
282
- }, [clearWebSingleTapTimer, enableDoubleTapZoom, height, maxZoomScale, onSingleTap, pauseWebAutoplayWithoutPagingInteraction, scale, scheduleWebAutoplayResume, translateX, translateY, width]);
283
- return {
284
- activeListIndex,
285
- onMomentumScrollEnd,
286
- onScroll,
287
- onScrollBeginDrag,
288
- onWebClick
289
- };
290
- }
291
- //# sourceMappingURL=useGestureViewerPaging.web.js.map