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.
Files changed (35) hide show
  1. package/README.md +13 -6
  2. package/lib/module/GestureViewer.js +5 -5
  3. package/lib/module/GestureViewer.js.map +1 -1
  4. package/lib/module/GestureViewerManager.js +5 -5
  5. package/lib/module/GestureViewerManager.js.map +1 -1
  6. package/lib/module/index.js +1 -0
  7. package/lib/module/index.js.map +1 -1
  8. package/lib/module/useGestureViewer.js +40 -63
  9. package/lib/module/useGestureViewer.js.map +1 -1
  10. package/lib/module/useGestureViewerController.js +39 -58
  11. package/lib/module/useGestureViewerController.js.map +1 -1
  12. package/lib/module/useGestureViewerState.js +78 -0
  13. package/lib/module/useGestureViewerState.js.map +1 -0
  14. package/lib/typescript/src/GestureViewer.d.ts +2 -2
  15. package/lib/typescript/src/GestureViewer.d.ts.map +1 -1
  16. package/lib/typescript/src/GestureViewerManager.d.ts +5 -8
  17. package/lib/typescript/src/GestureViewerManager.d.ts.map +1 -1
  18. package/lib/typescript/src/index.d.ts +2 -1
  19. package/lib/typescript/src/index.d.ts.map +1 -1
  20. package/lib/typescript/src/types.d.ts +60 -57
  21. package/lib/typescript/src/types.d.ts.map +1 -1
  22. package/lib/typescript/src/useGestureViewer.d.ts +1 -1
  23. package/lib/typescript/src/useGestureViewer.d.ts.map +1 -1
  24. package/lib/typescript/src/useGestureViewerController.d.ts +10 -21
  25. package/lib/typescript/src/useGestureViewerController.d.ts.map +1 -1
  26. package/lib/typescript/src/useGestureViewerState.d.ts +35 -0
  27. package/lib/typescript/src/useGestureViewerState.d.ts.map +1 -0
  28. package/package.json +1 -1
  29. package/src/GestureViewer.tsx +7 -7
  30. package/src/GestureViewerManager.ts +9 -9
  31. package/src/index.tsx +2 -1
  32. package/src/types.ts +60 -59
  33. package/src/useGestureViewer.ts +41 -69
  34. package/src/useGestureViewerController.ts +43 -62
  35. package/src/useGestureViewerState.ts +85 -0
@@ -1,13 +1,13 @@
1
- import { useEffect, useMemo, useRef, useState } from 'react';
1
+ import { useEffect, useMemo, useRef } from 'react';
2
2
  import type GestureViewerManager from './GestureViewerManager';
3
3
  import { registry } from './GestureViewerRegistry';
4
- import type { GestureViewerController, GestureViewerControllerState } from './types';
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 and state for controlling the viewer
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?: 0|90|180|270|360, clockwise?: boolean)` - Rotate content (default: 90° clockwise)
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 { goToIndex, goToNext, goToPrevious, zoomIn, zoomOut, resetZoom, rotate, currentIndex, totalCount } = useGestureViewerController();
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 [state, setState] = useState<GestureViewerControllerState>({
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 handleManagerChange = (newManager: GestureViewerManager | null) => {
69
- unsubscribeRef.current?.();
70
- unsubscribeRef.current = null;
71
-
72
- setManager(newManager);
51
+ const unsubscribe = registry.subscribeToManager(id, (manager) => {
52
+ managerRef.current = manager;
53
+ });
73
54
 
74
- if (newManager) {
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
- const noopFunction = useMemo(() => () => {}, []);
92
-
93
- return {
94
- goToIndex: manager?.goToIndex || noopFunction,
95
- goToPrevious: manager?.goToPrevious || noopFunction,
96
- goToNext: manager?.goToNext || noopFunction,
97
- zoomIn: manager?.zoomIn || noopFunction,
98
- zoomOut: manager?.zoomOut || noopFunction,
99
- resetZoom: manager?.resetZoom || noopFunction,
100
- rotate: manager?.rotate || noopFunction,
101
- ...state,
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
+ };