react-native-gesture-image-viewer 2.0.0-beta.2 → 2.0.0-beta.4
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 +13 -6
- package/lib/module/GestureViewer.js +5 -5
- package/lib/module/GestureViewer.js.map +1 -1
- package/lib/module/GestureViewerManager.js +5 -5
- package/lib/module/GestureViewerManager.js.map +1 -1
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/useGestureViewer.js +40 -63
- package/lib/module/useGestureViewer.js.map +1 -1
- package/lib/module/useGestureViewerController.js +39 -58
- package/lib/module/useGestureViewerController.js.map +1 -1
- package/lib/module/useGestureViewerState.js +78 -0
- package/lib/module/useGestureViewerState.js.map +1 -0
- package/lib/typescript/src/GestureViewer.d.ts +2 -2
- package/lib/typescript/src/GestureViewer.d.ts.map +1 -1
- package/lib/typescript/src/GestureViewerManager.d.ts +5 -8
- package/lib/typescript/src/GestureViewerManager.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +2 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +60 -57
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/lib/typescript/src/useGestureViewer.d.ts +1 -1
- package/lib/typescript/src/useGestureViewer.d.ts.map +1 -1
- package/lib/typescript/src/useGestureViewerController.d.ts +10 -21
- package/lib/typescript/src/useGestureViewerController.d.ts.map +1 -1
- package/lib/typescript/src/useGestureViewerState.d.ts +35 -0
- package/lib/typescript/src/useGestureViewerState.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/GestureViewer.tsx +7 -7
- package/src/GestureViewerManager.ts +9 -9
- package/src/index.tsx +2 -1
- package/src/types.ts +60 -59
- package/src/useGestureViewer.ts +41 -69
- package/src/useGestureViewerController.ts +43 -62
- package/src/useGestureViewerState.ts +85 -0
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { useEffect, useMemo, useRef
|
|
1
|
+
import { useEffect, useMemo, useRef } from 'react';
|
|
2
2
|
import type GestureViewerManager from './GestureViewerManager';
|
|
3
3
|
import { registry } from './GestureViewerRegistry';
|
|
4
|
-
import type { GestureViewerController
|
|
4
|
+
import type { GestureViewerController } from './types';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Hook to control the gesture viewer programmatically.
|
|
8
8
|
*
|
|
9
9
|
* @param id - Viewer instance identifier (default: 'default')
|
|
10
|
-
* @returns Methods
|
|
10
|
+
* @returns Methods for controlling the viewer
|
|
11
11
|
*
|
|
12
12
|
* **Available methods:**
|
|
13
13
|
* - `goToIndex(index: number)` - Navigate to specific index (0 to totalCount-1)
|
|
@@ -16,88 +16,69 @@ import type { GestureViewerController, GestureViewerControllerState } from './ty
|
|
|
16
16
|
* - `zoomIn(multiplier?: number)` - Zoom in (default: 0.25)
|
|
17
17
|
* - `zoomOut(multiplier?: number)` - Zoom out (default: 0.25)
|
|
18
18
|
* - `resetZoom(scale?: number)` - Reset zoom level (default: 1.0)
|
|
19
|
-
* - `rotate(angle?:
|
|
20
|
-
*
|
|
21
|
-
* **Available state:**
|
|
22
|
-
* - `currentIndex: number` - Current active index (read-only)
|
|
23
|
-
* - `totalCount: number` - Total number of items (read-only)
|
|
19
|
+
* - `rotate(angle?: RotationAngle, clockwise?: boolean)` - Rotate content (default: 90° clockwise)
|
|
24
20
|
*
|
|
25
21
|
* @example
|
|
26
22
|
* ```tsx
|
|
27
|
-
* const
|
|
23
|
+
* const controller = useGestureViewerController();
|
|
28
24
|
*
|
|
29
25
|
* // Navigate to specific index
|
|
30
|
-
* goToIndex(2);
|
|
26
|
+
* controller.goToIndex(2);
|
|
31
27
|
*
|
|
32
28
|
* // Go to next image
|
|
33
|
-
* goToNext();
|
|
29
|
+
* controller.goToNext();
|
|
34
30
|
*
|
|
35
31
|
* // Zoom in by 25%
|
|
36
|
-
* zoomIn();
|
|
32
|
+
* controller.zoomIn();
|
|
37
33
|
*
|
|
38
34
|
* // Zoom out by 50%
|
|
39
|
-
* zoomOut(0.5);
|
|
35
|
+
* controller.zoomOut(0.5);
|
|
40
36
|
*
|
|
41
37
|
* // Reset to original size
|
|
42
|
-
* resetZoom();
|
|
38
|
+
* controller.resetZoom();
|
|
43
39
|
*
|
|
44
40
|
* // Rotate 90 degrees clockwise
|
|
45
|
-
* rotate();
|
|
41
|
+
* controller.rotate();
|
|
46
42
|
*
|
|
47
43
|
* // Rotate 180 degrees
|
|
48
|
-
* rotate(180);
|
|
49
|
-
*
|
|
50
|
-
* // Check current state
|
|
51
|
-
* console.log(`Image ${currentIndex + 1} of ${totalCount}`);
|
|
52
|
-
*
|
|
53
|
-
* // Check navigation availability
|
|
54
|
-
* const canGoNext = currentIndex < totalCount - 1;
|
|
55
|
-
* const canGoPrevious = currentIndex > 0;
|
|
44
|
+
* controller.rotate(180);
|
|
56
45
|
* ```
|
|
57
46
|
*/
|
|
58
47
|
export const useGestureViewerController = (id = 'default'): GestureViewerController => {
|
|
59
|
-
const
|
|
60
|
-
currentIndex: 0,
|
|
61
|
-
totalCount: 0,
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
const [manager, setManager] = useState<GestureViewerManager | null>(null);
|
|
65
|
-
const unsubscribeRef = useRef<(() => void) | null>(null);
|
|
48
|
+
const managerRef = useRef<GestureViewerManager | null>(null);
|
|
66
49
|
|
|
67
50
|
useEffect(() => {
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
setManager(newManager);
|
|
51
|
+
const unsubscribe = registry.subscribeToManager(id, (manager) => {
|
|
52
|
+
managerRef.current = manager;
|
|
53
|
+
});
|
|
73
54
|
|
|
74
|
-
|
|
75
|
-
setState(newManager.getState());
|
|
76
|
-
unsubscribeRef.current = newManager.subscribe(setState);
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
setState({ currentIndex: 0, totalCount: 0 });
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
const unsubscribeFromRegistry = registry.subscribeToManager(id, handleManagerChange);
|
|
84
|
-
|
|
85
|
-
return () => {
|
|
86
|
-
unsubscribeFromRegistry();
|
|
87
|
-
unsubscribeRef.current?.();
|
|
88
|
-
};
|
|
55
|
+
return unsubscribe;
|
|
89
56
|
}, [id]);
|
|
90
57
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
58
|
+
return useMemo<GestureViewerController>(
|
|
59
|
+
() => ({
|
|
60
|
+
goToIndex: (index) => {
|
|
61
|
+
managerRef.current?.goToIndex(index);
|
|
62
|
+
},
|
|
63
|
+
goToPrevious: () => {
|
|
64
|
+
managerRef.current?.goToPrevious();
|
|
65
|
+
},
|
|
66
|
+
goToNext: () => {
|
|
67
|
+
managerRef.current?.goToNext();
|
|
68
|
+
},
|
|
69
|
+
zoomIn: (multiplier) => {
|
|
70
|
+
managerRef.current?.zoomIn(multiplier);
|
|
71
|
+
},
|
|
72
|
+
zoomOut: (multiplier) => {
|
|
73
|
+
managerRef.current?.zoomOut(multiplier);
|
|
74
|
+
},
|
|
75
|
+
resetZoom: (scale) => {
|
|
76
|
+
managerRef.current?.resetZoom(scale);
|
|
77
|
+
},
|
|
78
|
+
rotate: (angle, clockwise) => {
|
|
79
|
+
managerRef.current?.rotate(angle, clockwise);
|
|
80
|
+
},
|
|
81
|
+
}),
|
|
82
|
+
[],
|
|
83
|
+
);
|
|
103
84
|
};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { useCallback, useRef, useSyncExternalStore } from 'react';
|
|
2
|
+
import { registry } from './GestureViewerRegistry';
|
|
3
|
+
import type { GestureViewerState } from './types';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Hook to access the current state of the gesture viewer.
|
|
7
|
+
*
|
|
8
|
+
* @param id - Viewer instance identifier (default: 'default')
|
|
9
|
+
* @returns Current state of the viewer
|
|
10
|
+
*
|
|
11
|
+
* **Available state:**
|
|
12
|
+
* - `currentIndex: number` - Current active index (read-only)
|
|
13
|
+
* - `totalCount: number` - Total number of items (read-only)
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```tsx
|
|
17
|
+
* const { currentIndex, totalCount } = useGestureViewerState();
|
|
18
|
+
*
|
|
19
|
+
* // Display current position
|
|
20
|
+
* return (
|
|
21
|
+
* <Text>
|
|
22
|
+
* {currentIndex + 1} / {totalCount}
|
|
23
|
+
* </Text>
|
|
24
|
+
* );
|
|
25
|
+
*
|
|
26
|
+
* // React to index changes
|
|
27
|
+
* useEffect(() => {
|
|
28
|
+
* console.log(`Moved to image ${currentIndex + 1}`);
|
|
29
|
+
* trackPageView(currentIndex);
|
|
30
|
+
* }, [currentIndex]);
|
|
31
|
+
*
|
|
32
|
+
* // Check navigation availability
|
|
33
|
+
* const canGoNext = currentIndex < totalCount - 1;
|
|
34
|
+
* const canGoPrevious = currentIndex > 0;
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export const useGestureViewerState = (id = 'default'): GestureViewerState => {
|
|
38
|
+
const stateRef = useRef<GestureViewerState>({ currentIndex: 0, totalCount: 0 });
|
|
39
|
+
|
|
40
|
+
const updateState = useCallback((newState: GestureViewerState, onStoreChange: () => void) => {
|
|
41
|
+
if (
|
|
42
|
+
stateRef.current.currentIndex !== newState.currentIndex ||
|
|
43
|
+
stateRef.current.totalCount !== newState.totalCount
|
|
44
|
+
) {
|
|
45
|
+
stateRef.current = { ...newState };
|
|
46
|
+
onStoreChange();
|
|
47
|
+
}
|
|
48
|
+
}, []);
|
|
49
|
+
|
|
50
|
+
const subscribe = useCallback(
|
|
51
|
+
(onStoreChange: () => void) => {
|
|
52
|
+
let unsubscribeFromManager: (() => void) | null = null;
|
|
53
|
+
|
|
54
|
+
const unsubscribeFromRegistry = registry.subscribeToManager(id, (newManager) => {
|
|
55
|
+
unsubscribeFromManager?.();
|
|
56
|
+
unsubscribeFromManager = null;
|
|
57
|
+
|
|
58
|
+
if (newManager) {
|
|
59
|
+
unsubscribeFromManager = newManager.subscribe((newState) => {
|
|
60
|
+
updateState(newState, onStoreChange);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
updateState(newManager.getState(), onStoreChange);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
updateState({ currentIndex: 0, totalCount: 0 }, onStoreChange);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
return () => {
|
|
71
|
+
unsubscribeFromRegistry();
|
|
72
|
+
unsubscribeFromManager?.();
|
|
73
|
+
};
|
|
74
|
+
},
|
|
75
|
+
[id, updateState],
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
const getSnapshot = useCallback(() => {
|
|
79
|
+
return stateRef.current;
|
|
80
|
+
}, []);
|
|
81
|
+
|
|
82
|
+
const state = useSyncExternalStore(subscribe, getSnapshot);
|
|
83
|
+
|
|
84
|
+
return state;
|
|
85
|
+
};
|