@yogiswara/honcho-editor-ui 2.5.9 → 2.6.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 (50) hide show
  1. package/dist/components/editor/HBulkPreset.js +12 -2
  2. package/dist/hooks/demo/HonchoEditorBulkDemo.d.ts +3 -0
  3. package/dist/hooks/demo/HonchoEditorBulkDemo.js +228 -0
  4. package/dist/hooks/demo/HonchoEditorSingleCleanDemo.d.ts +3 -0
  5. package/dist/hooks/demo/HonchoEditorSingleCleanDemo.js +354 -0
  6. package/dist/hooks/demo/index.d.ts +2 -0
  7. package/dist/hooks/demo/index.js +2 -0
  8. package/dist/hooks/editor/type.d.ts +71 -0
  9. package/dist/hooks/editor/useHonchoEditorBulk.d.ts +12 -12
  10. package/dist/hooks/editor/useHonchoEditorBulk.js +155 -42
  11. package/dist/hooks/editor/useHonchoEditorSingle.d.ts +43 -0
  12. package/dist/hooks/editor/useHonchoEditorSingle.js +158 -0
  13. package/dist/hooks/useAdjustmentHistory.d.ts +9 -5
  14. package/dist/hooks/useAdjustmentHistory.js +187 -31
  15. package/dist/hooks/useAdjustmentHistoryBatch.d.ts +18 -1
  16. package/dist/hooks/useAdjustmentHistoryBatch.js +627 -201
  17. package/dist/hooks/useGallerySwipe.d.ts +1 -1
  18. package/dist/hooks/usePaging.d.ts +89 -0
  19. package/dist/hooks/usePaging.js +211 -0
  20. package/dist/hooks/usePreset.d.ts +1 -1
  21. package/dist/hooks/usePreset.js +35 -35
  22. package/dist/index.d.ts +4 -3
  23. package/dist/index.js +3 -1
  24. package/dist/lib/context/EditorContext.d.ts +10 -0
  25. package/dist/lib/context/EditorContext.js +4 -2
  26. package/dist/lib/hooks/useEditorHeadless.d.ts +18 -2
  27. package/dist/lib/hooks/useEditorHeadless.js +142 -63
  28. package/dist/utils/adjustment.d.ts +2 -1
  29. package/dist/utils/adjustment.js +16 -0
  30. package/dist/utils/imageLoader.d.ts +11 -0
  31. package/dist/utils/imageLoader.js +53 -0
  32. package/package.json +1 -1
  33. package/dist/components/editor/GalleryAlbum/SimplifiedAlbumGallery.d.ts +0 -17
  34. package/dist/components/editor/GalleryAlbum/SimplifiedAlbumGallery.js +0 -14
  35. package/dist/components/editor/GalleryAlbum/SimplifiedImageItem.d.ts +0 -8
  36. package/dist/components/editor/GalleryAlbum/SimplifiedImageItem.js +0 -30
  37. package/dist/components/editor/HImageEditorPage.d.ts +0 -1
  38. package/dist/components/editor/HImageEditorPage.js +0 -187
  39. package/dist/hooks/__tests__/useGallerySwipe.test.d.ts +0 -0
  40. package/dist/hooks/__tests__/useGallerySwipe.test.js +0 -619
  41. package/dist/hooks/editor/useHonchoEditor.d.ts +0 -203
  42. package/dist/hooks/editor/useHonchoEditor.js +0 -716
  43. package/dist/hooks/useAdjustmentHistory.demo.d.ts +0 -8
  44. package/dist/hooks/useAdjustmentHistory.demo.js +0 -106
  45. package/dist/hooks/useAdjustmentHistory.example.d.ts +0 -38
  46. package/dist/hooks/useAdjustmentHistory.example.js +0 -182
  47. package/dist/hooks/useAdjustmentHistory.syncDemo.d.ts +0 -8
  48. package/dist/hooks/useAdjustmentHistory.syncDemo.js +0 -180
  49. package/dist/hooks/useGallerySwipe.example.d.ts +0 -24
  50. package/dist/hooks/useGallerySwipe.example.js +0 -184
@@ -1,6 +1,8 @@
1
1
  'use client';
2
- import { useState, useCallback, useEffect, useMemo } from 'react';
2
+ import { useState, useCallback, useEffect, useMemo, useRef } from 'react';
3
3
  import { useAdjustmentHistoryBatch } from '../useAdjustmentHistoryBatch';
4
+ import { usePaging } from "../usePaging";
5
+ import { usePreset } from "../usePreset";
4
6
  // Helper function to map the API response to the format our UI component needs
5
7
  const mapGalleryToPhotoData = (gallery, selectedIds) => {
6
8
  return {
@@ -38,36 +40,152 @@ function mapColorAdjustmentToAdjustmentState(adj) {
38
40
  sharpnessScore: adj.sharpness || 0,
39
41
  };
40
42
  }
43
+ // Helper function to convert Preset to AdjustmentState
44
+ const presetToAdjustmentState = (preset) => {
45
+ return {
46
+ tempScore: preset.temperature || 0,
47
+ tintScore: preset.tint || 0,
48
+ vibranceScore: preset.vibrance || 0,
49
+ saturationScore: preset.saturation || 0,
50
+ exposureScore: preset.exposure || 0,
51
+ highlightsScore: preset.highlights || 0,
52
+ shadowsScore: preset.shadows || 0,
53
+ whitesScore: preset.whites || 0,
54
+ blacksScore: preset.blacks || 0,
55
+ contrastScore: preset.contrast || 0,
56
+ clarityScore: preset.clarity || 0,
57
+ sharpnessScore: preset.sharpness || 0,
58
+ };
59
+ };
60
+ // Helper function to compare adjustment states
61
+ const adjustmentsMatch = (a, b) => {
62
+ const keys = [
63
+ 'tempScore', 'tintScore', 'vibranceScore', 'saturationScore',
64
+ 'exposureScore', 'highlightsScore', 'shadowsScore', 'whitesScore',
65
+ 'blacksScore', 'contrastScore', 'clarityScore', 'sharpnessScore'
66
+ ];
67
+ return keys.every(key => (a[key] || 0) === (b[key] || 0));
68
+ };
41
69
  export function useHonchoEditorBulk(controller, eventID, firebaseUid) {
42
- const { currentBatch, selectedIds, actions: batchActions } = useAdjustmentHistoryBatch();
43
- // State for Bulk Editing
44
- const [imageCollection, setImageCollection] = useState([]);
45
- const [isLoading, setIsLoading] = useState(true);
46
- const [error, setError] = useState(null);
47
- const [page, setPage] = useState(1);
48
- const [isFetchingMore, setIsFetchingMore] = useState(false);
49
- const [hasMore, setHasMore] = useState(true);
50
- const [selectedBulkPreset, setSelectedBulkPreset] = useState('preset1');
70
+ const { currentBatch, selectedIds, actions: batchActions, historyInfo } = useAdjustmentHistoryBatch({
71
+ controller,
72
+ firebaseUid,
73
+ eventId: eventID,
74
+ devWarnings: true
75
+ });
76
+ const { images, info, actions } = usePaging(controller, firebaseUid, eventID, {
77
+ autoLoad: true,
78
+ autoReset: false // Prevent auto-reset to avoid loops
79
+ });
80
+ // Preset management
81
+ const { presets, actions: presetActions } = usePreset(controller, firebaseUid, {
82
+ autoLoad: true,
83
+ devWarnings: true
84
+ });
85
+ // Track which images have been synced to prevent loops
86
+ const lastSyncedImageIds = useRef(new Set());
87
+ // State for Bulk Editing
88
+ const [selectedBulkPreset, setSelectedBulkPreset] = useState('');
89
+ // Calculate active preset based on selected images' adjustments
90
+ const activePreset = useMemo(() => {
91
+ if (selectedIds.length === 0) {
92
+ return null;
93
+ }
94
+ // Get adjustments for all selected images
95
+ const selectedAdjustments = selectedIds.map(imageId => {
96
+ return currentBatch.allImages[imageId] || {
97
+ tempScore: 0, tintScore: 0, vibranceScore: 0, saturationScore: 0,
98
+ exposureScore: 0, highlightsScore: 0, shadowsScore: 0, whitesScore: 0,
99
+ blacksScore: 0, contrastScore: 0, clarityScore: 0, sharpnessScore: 0,
100
+ };
101
+ });
102
+ // Check if all selected images have the same adjustments
103
+ const firstAdjustment = selectedAdjustments[0];
104
+ const allSameAdjustments = selectedAdjustments.every(adj => adjustmentsMatch(adj, firstAdjustment));
105
+ if (!allSameAdjustments) {
106
+ // Selected images have different adjustments
107
+ return null;
108
+ }
109
+ // Find preset that matches the common adjustment state
110
+ const matchingPreset = presets.find(preset => {
111
+ const presetAdjustments = presetToAdjustmentState(preset);
112
+ return adjustmentsMatch(presetAdjustments, firstAdjustment);
113
+ });
114
+ return matchingPreset || null;
115
+ }, [selectedIds, currentBatch.allImages, presets]);
116
+ // Update selectedBulkPreset when activePreset changes
117
+ useEffect(() => {
118
+ setSelectedBulkPreset(activePreset?.id || '');
119
+ }, [activePreset]);
120
+ // Use loading states from usePaging instead of local state
121
+ const isLoading = info.isLoading;
122
+ const error = info.error;
123
+ const hasMore = info.hasMore;
51
124
  const imageData = useMemo(() => {
52
- return imageCollection.map(item => {
53
- console.log("item FROM USEHONCHOBULK: ", item);
54
- return mapGalleryToPhotoData(item, selectedIds);
55
- }).map(item => {
56
- const adjustment = currentBatch.allImages[item.key];
57
- console.log("adjustment FROM USEHONCHOBULK: ", adjustment);
58
- return adjustment ? { ...item, ...adjustment } : item;
125
+ console.debug("imageData recalculating with:", {
126
+ imagesLength: images.length,
127
+ selectedIds,
128
+ currentBatch_allImages: currentBatch.allImages,
129
+ currentBatch_allImages_keys: Object.keys(currentBatch.allImages)
59
130
  });
60
- }, [imageCollection, selectedIds, currentBatch.allImages]);
131
+ const res = images.map(item => {
132
+ const basePhoto = mapGalleryToPhotoData(item, selectedIds);
133
+ const batchAdjustment = currentBatch.allImages[item.id];
134
+ console.debug(`Processing image ${item.id}:`, {
135
+ basePhoto,
136
+ batchAdjustment,
137
+ hasBatchAdjustment: !!batchAdjustment
138
+ });
139
+ // Merge batch adjustments over backend adjustments
140
+ return batchAdjustment ? { ...basePhoto, ...batchAdjustment } : basePhoto;
141
+ });
142
+ console.debug("imageData result:", res);
143
+ return res;
144
+ }, [images, selectedIds, currentBatch.allImages]);
145
+ // Store the latest batchActions.syncAdjustment in a ref to avoid dependency issues
146
+ const syncAdjustmentRef = useRef(batchActions.syncAdjustment);
147
+ syncAdjustmentRef.current = batchActions.syncAdjustment;
148
+ // Safe sync: Only sync new images to prevent infinite loops
149
+ useEffect(() => {
150
+ if (images.length === 0)
151
+ return;
152
+ // Check if we have new images that haven't been synced
153
+ const currentImageIds = new Set(images.map(img => img.id));
154
+ const hasNewImages = images.some(img => !lastSyncedImageIds.current.has(img.id));
155
+ if (hasNewImages) {
156
+ console.log('[useHonchoEditorBulk] Syncing new images to batch:', images.length);
157
+ syncAdjustmentRef.current(images.map(mapToImageAdjustmentConfig));
158
+ lastSyncedImageIds.current = currentImageIds;
159
+ }
160
+ }, [images]); // Only depend on images, not batchActions
61
161
  const handleBackCallbackBulk = useCallback(() => {
62
162
  const lastSelectedId = selectedIds.length > 0 ? selectedIds[selectedIds.length - 1] : "";
63
163
  controller.handleBack(firebaseUid, lastSelectedId);
64
164
  }, [controller, firebaseUid, selectedIds]);
65
- const handleSelectBulkPreset = (event) => setSelectedBulkPreset(event.target.value);
165
+ const handleSelectBulkPreset = useCallback((event) => {
166
+ const presetId = event.target.value;
167
+ setSelectedBulkPreset(presetId);
168
+ if (presetId && selectedIds.length > 0) {
169
+ // Find the preset
170
+ const preset = presets.find(p => p.id === presetId);
171
+ if (preset) {
172
+ // Convert preset to adjustment state
173
+ const presetAdjustments = presetToAdjustmentState(preset);
174
+ // Apply preset directly to all selected images using the clean action
175
+ batchActions.adjustSelectedWithPreset(presetAdjustments);
176
+ }
177
+ }
178
+ }, [presets, selectedIds, batchActions]);
66
179
  // This factory creates functions that adjust a value for all selected images
67
180
  const createRelativeAdjuster = useCallback((key, amount) => () => {
68
- console.debug("createRelativeAdjuster", key, amount);
181
+ console.debug("createRelativeAdjuster called:", { key, amount, selectedIds });
182
+ console.debug("currentBatch.allImages before:", currentBatch.allImages);
69
183
  batchActions.adjustSelected({ [key]: amount });
70
- }, [batchActions]);
184
+ // Debug after a short delay to see if the state changed
185
+ setTimeout(() => {
186
+ console.debug("currentBatch.allImages after:", currentBatch.allImages);
187
+ }, 100);
188
+ }, [batchActions, selectedIds, currentBatch.allImages]);
71
189
  const handleBulkTempDecreaseMax = createRelativeAdjuster('tempScore', -20);
72
190
  const handleBulkTempDecrease = createRelativeAdjuster('tempScore', -5);
73
191
  const handleBulkTempIncrease = createRelativeAdjuster('tempScore', 5);
@@ -148,26 +266,8 @@ export function useHonchoEditorBulk(controller, eventID, firebaseUid) {
148
266
  // loadImages(page + 1);
149
267
  // }
150
268
  // }, [isFetchingMore, hasMore, page, loadImages]);
151
- useEffect(() => {
152
- if (eventID && firebaseUid) {
153
- setIsLoading(true);
154
- setError(null);
155
- controller.getImageList(firebaseUid, eventID, 2)
156
- .then(response => {
157
- // TODO need do pagination for this one
158
- batchActions.syncAdjustment(response.gallery.map(mapToImageAdjustmentConfig));
159
- setImageCollection(response.gallery);
160
- })
161
- .catch(err => {
162
- console.error("Failed to fetch image list:", err);
163
- setError("Could not load images.");
164
- })
165
- .finally(() => {
166
- setIsLoading(false);
167
- });
168
- console.log("Image data FROM USEHONCHOBULK: ", imageData);
169
- }
170
- }, [eventID, firebaseUid, controller]);
269
+ // Note: Image loading is now handled by usePaging hook
270
+ // The sync logic above handles syncing loaded images to batch state
171
271
  // useEffect(() => {
172
272
  // if (eventID && firebaseUid) {
173
273
  // setImageCollection([]); // reset when event changes
@@ -184,9 +284,17 @@ export function useHonchoEditorBulk(controller, eventID, firebaseUid) {
184
284
  // loadMoreImages,
185
285
  // Gallery Handlers
186
286
  handleBackCallbackBulk,
287
+ // Preset functionality
288
+ presets,
187
289
  selectedBulkPreset,
188
- handleToggleImageSelection: batchActions.toggleSelection,
290
+ activePreset,
189
291
  handleSelectBulkPreset,
292
+ // Preset creation handlers
293
+ handleOpenPresetModal: () => { }, // TODO: Implement preset modal for bulk editing
294
+ presetActions, // Expose preset actions for create/rename/delete
295
+ handleToggleImageSelection: batchActions.toggleSelection,
296
+ handleLoadMore: actions.loadMore,
297
+ handleRefresh: actions.refresh,
190
298
  // Adjustment
191
299
  handleBulkTempDecreaseMax,
192
300
  handleBulkTempDecrease,
@@ -238,5 +346,10 @@ export function useHonchoEditorBulk(controller, eventID, firebaseUid) {
238
346
  handleBulkSharpnessDecrease,
239
347
  handleBulkSharpnessIncrease,
240
348
  handleBulkSharpnessIncreaseMax,
349
+ // History actions
350
+ handleUndo: batchActions.undo,
351
+ handleRedo: batchActions.redo,
352
+ handleReset: batchActions.reset,
353
+ historyInfo,
241
354
  };
242
355
  }
@@ -0,0 +1,43 @@
1
+ import { Controller, AdjustmentState, Preset } from './type';
2
+ import { Gallery } from './type';
3
+ import { AdjustmentValues } from '../../lib/editor/honcho-editor';
4
+ export interface UseHonchoEditorSingleOptions {
5
+ controller: Controller;
6
+ initImageId: string;
7
+ firebaseUid: string;
8
+ }
9
+ export interface UseHonchoEditorSingleState {
10
+ currentImageData: Gallery | null;
11
+ isGalleryLoading: boolean;
12
+ galleryError: string | null;
13
+ currentAdjustments: AdjustmentState;
14
+ isBatchMode: boolean;
15
+ canUndo: boolean;
16
+ canRedo: boolean;
17
+ isNextAvailable: boolean;
18
+ isPrevAvailable: boolean;
19
+ presets: Preset[];
20
+ activePreset: Preset | null;
21
+ presetsLoading: boolean;
22
+ presetsError: string | null;
23
+ }
24
+ export interface UseHonchoEditorSingleActions {
25
+ navigateNext: () => void;
26
+ navigatePrev: () => void;
27
+ updateAdjustment: (field: keyof AdjustmentState, value: number) => void;
28
+ setBatchMode: (enabled: boolean) => void;
29
+ startBatchMode: () => void;
30
+ endBatchMode: () => void;
31
+ undo: () => void;
32
+ redo: () => void;
33
+ reset: () => void;
34
+ loadPresets: () => Promise<void>;
35
+ applyPreset: (preset: Preset) => void;
36
+ createPreset: (name: string) => Promise<Preset | null>;
37
+ deletePreset: (presetId: string) => Promise<void>;
38
+ getEditorAdjustments: () => AdjustmentValues;
39
+ }
40
+ export declare function useHonchoEditorSingle({ controller, initImageId, firebaseUid }: UseHonchoEditorSingleOptions): {
41
+ state: UseHonchoEditorSingleState;
42
+ actions: UseHonchoEditorSingleActions;
43
+ };
@@ -0,0 +1,158 @@
1
+ 'use client';
2
+ import { useCallback, useMemo } from 'react';
3
+ import { useAdjustmentHistory } from '../useAdjustmentHistory';
4
+ import { useGallerySwipe } from '../useGallerySwipe';
5
+ import { usePreset } from '../usePreset';
6
+ // Default adjustment values
7
+ const initialAdjustments = {
8
+ tempScore: 0, tintScore: 0, vibranceScore: 0, saturationScore: 0,
9
+ exposureScore: 0, highlightsScore: 0, shadowsScore: 0, whitesScore: 0,
10
+ blacksScore: 0, contrastScore: 0, clarityScore: 0, sharpnessScore: 0,
11
+ };
12
+ export function useHonchoEditorSingle({ controller, initImageId, firebaseUid }) {
13
+ // Memoize parameters to prevent unnecessary re-renders
14
+ const memoizedController = useMemo(() => controller, [controller]);
15
+ const memoizedInitImageId = useMemo(() => initImageId, [initImageId]);
16
+ const memoizedFirebaseUid = useMemo(() => firebaseUid, [firebaseUid]);
17
+ // Initialize business logic hooks only
18
+ const adjustmentHistory = useAdjustmentHistory(initialAdjustments, memoizedController, memoizedFirebaseUid, memoizedInitImageId);
19
+ const gallerySwipe = useGallerySwipe(memoizedFirebaseUid, memoizedInitImageId, memoizedController);
20
+ const presetHook = usePreset(memoizedController, memoizedFirebaseUid, { autoLoad: true });
21
+ // Find active preset based on current adjustments
22
+ const activePreset = presetHook.actions.findByAdjustments(adjustmentHistory.currentState);
23
+ // Actions - pure business logic, no editor interaction - wrapped in useCallback to prevent re-renders
24
+ const navigateNext = useCallback(() => {
25
+ if (gallerySwipe.isNextAvailable) {
26
+ gallerySwipe.onSwipeNext();
27
+ }
28
+ }, [gallerySwipe.isNextAvailable, gallerySwipe.onSwipeNext]);
29
+ const navigatePrev = useCallback(() => {
30
+ if (gallerySwipe.isPrevAvailable) {
31
+ gallerySwipe.onSwipePrev();
32
+ }
33
+ }, [gallerySwipe.isPrevAvailable, gallerySwipe.onSwipePrev]);
34
+ const updateAdjustment = useCallback((field, value) => {
35
+ const newState = {
36
+ ...adjustmentHistory.currentState,
37
+ [field]: value
38
+ };
39
+ adjustmentHistory.actions.pushState(newState);
40
+ }, [adjustmentHistory.currentState, adjustmentHistory.actions.pushState]);
41
+ const setBatchMode = useCallback((enabled) => {
42
+ adjustmentHistory.config.setBatchMode(enabled);
43
+ }, [adjustmentHistory.config.setBatchMode]);
44
+ const startBatchMode = useCallback(() => {
45
+ adjustmentHistory.config.setBatchMode(true);
46
+ }, [adjustmentHistory.config.setBatchMode]);
47
+ const endBatchMode = useCallback(() => {
48
+ adjustmentHistory.config.setBatchMode(false);
49
+ }, [adjustmentHistory.config.setBatchMode]);
50
+ const undo = useCallback(() => {
51
+ adjustmentHistory.actions.undo();
52
+ }, [adjustmentHistory.actions.undo]);
53
+ const redo = useCallback(() => {
54
+ adjustmentHistory.actions.redo();
55
+ }, [adjustmentHistory.actions.redo]);
56
+ const reset = useCallback(async () => {
57
+ // Reset means setting all adjustments to 0 and adding it as new history entry
58
+ // This allows users to undo the reset operation
59
+ // Reset acts like normal adjustment - each reset creates a new history entry
60
+ console.log('Resetting adjustments to 0 - adding to history and sending to backend');
61
+ // First add reset to history (this creates local history entry)
62
+ adjustmentHistory.actions.pushState(initialAdjustments);
63
+ // Then sync to backend
64
+ await adjustmentHistory.config.syncToBackend();
65
+ }, [adjustmentHistory.actions.pushState, adjustmentHistory.config.syncToBackend]);
66
+ const loadPresets = useCallback(async () => {
67
+ await presetHook.actions.load();
68
+ }, [presetHook.actions.load]);
69
+ const applyPreset = useCallback(async (preset) => {
70
+ console.log('Applying preset:', preset.name, '- saving to backend history');
71
+ const adjustmentState = {
72
+ tempScore: preset.temperature,
73
+ tintScore: preset.tint,
74
+ vibranceScore: preset.vibrance,
75
+ saturationScore: preset.saturation,
76
+ exposureScore: preset.exposure,
77
+ highlightsScore: preset.highlights,
78
+ shadowsScore: preset.shadows,
79
+ whitesScore: preset.whites,
80
+ blacksScore: preset.blacks,
81
+ contrastScore: preset.contrast,
82
+ clarityScore: preset.clarity,
83
+ sharpnessScore: preset.sharpness,
84
+ };
85
+ // Apply preset directly and add to history
86
+ adjustmentHistory.actions.pushState(adjustmentState);
87
+ // Then sync to backend
88
+ await adjustmentHistory.config.syncToBackend();
89
+ }, [adjustmentHistory.actions.pushState, adjustmentHistory.config.syncToBackend]);
90
+ const createPreset = useCallback(async (name) => {
91
+ return await presetHook.actions.create(name, adjustmentHistory.currentState);
92
+ }, [presetHook.actions.create, adjustmentHistory.currentState]);
93
+ const deletePreset = useCallback(async (presetId) => {
94
+ await presetHook.actions.delete(presetId);
95
+ }, [presetHook.actions.delete]);
96
+ const getEditorAdjustments = useCallback(() => {
97
+ const adjustments = adjustmentHistory.currentState;
98
+ return {
99
+ temperature: adjustments.tempScore,
100
+ tint: adjustments.tintScore,
101
+ vibrance: adjustments.vibranceScore / 100,
102
+ saturation: adjustments.saturationScore / 100,
103
+ exposure: (adjustments.exposureScore / 100) * 3,
104
+ highlights: adjustments.highlightsScore / 100,
105
+ shadows: adjustments.shadowsScore / 100,
106
+ whites: adjustments.whitesScore / 100,
107
+ blacks: adjustments.blacksScore / 100,
108
+ contrast: adjustments.contrastScore / 100,
109
+ clarity: adjustments.clarityScore / 100,
110
+ sharpness: adjustments.sharpnessScore / 100,
111
+ };
112
+ }, [adjustmentHistory.currentState]);
113
+ const actions = {
114
+ // Navigation
115
+ navigateNext,
116
+ navigatePrev,
117
+ // Adjustments
118
+ updateAdjustment,
119
+ setBatchMode,
120
+ startBatchMode,
121
+ endBatchMode,
122
+ // History
123
+ undo,
124
+ redo,
125
+ reset,
126
+ // Presets
127
+ loadPresets,
128
+ applyPreset,
129
+ createPreset,
130
+ deletePreset,
131
+ // Adjustment conversion for editor
132
+ getEditorAdjustments
133
+ };
134
+ // State - pure business state, no editor state
135
+ const state = {
136
+ // Image state
137
+ currentImageData: gallerySwipe.currentImageData,
138
+ isGalleryLoading: gallerySwipe.isLoading,
139
+ galleryError: gallerySwipe.error,
140
+ // Adjustment state
141
+ currentAdjustments: adjustmentHistory.currentState,
142
+ isBatchMode: adjustmentHistory.historyInfo.isBatchMode,
143
+ canUndo: adjustmentHistory.historyInfo.canUndo,
144
+ canRedo: adjustmentHistory.historyInfo.canRedo,
145
+ // Navigation state
146
+ isNextAvailable: gallerySwipe.isNextAvailable,
147
+ isPrevAvailable: gallerySwipe.isPrevAvailable,
148
+ // Preset state
149
+ presets: presetHook.presets,
150
+ activePreset: activePreset || null,
151
+ presetsLoading: presetHook.info.isLoading,
152
+ presetsError: presetHook.info.error,
153
+ };
154
+ return {
155
+ state,
156
+ actions
157
+ };
158
+ }
@@ -1,8 +1,8 @@
1
- import { AdjustmentState } from './editor/useHonchoEditor';
1
+ import { AdjustmentState, Controller } from './editor/type';
2
2
  /**
3
3
  * Configuration options for the adjustment history hook
4
4
  */
5
- interface HistoryOptions {
5
+ export interface HistoryOptions {
6
6
  /** Maximum number of history entries to keep. Use 'unlimited' for no limit */
7
7
  maxSize?: number | 'unlimited';
8
8
  /** Whether to enable batch mode for grouping multiple changes */
@@ -57,9 +57,11 @@ export interface HistoryConfig {
57
57
  /** Set maximum history size */
58
58
  setMaxSize: (size: number | 'unlimited') => void;
59
59
  /** Enable or disable batch mode */
60
- setBatchMode: (enabled: boolean) => void;
60
+ setBatchMode: (enabled: boolean) => Promise<void>;
61
61
  /** Get current memory usage estimate */
62
62
  getMemoryUsage: () => number;
63
+ /** Force sync current state to backend */
64
+ syncToBackend: () => Promise<void>;
63
65
  }
64
66
  /**
65
67
  * Return type for the useAdjustmentHistory hook
@@ -86,8 +88,10 @@ export interface UseAdjustmentHistoryReturn {
86
88
  * - Automatic AdjustmentState comparison
87
89
  *
88
90
  * @param initialState - The initial AdjustmentState value
91
+ * @param controller - Controller for backend operations (optional)
92
+ * @param firebaseUid - Firebase UID for backend operations (optional)
93
+ * @param currentImageId - Current image ID for backend operations (optional)
89
94
  * @param options - Configuration options for history behavior
90
95
  * @returns Object with current state, history info, actions, and config
91
96
  */
92
- export declare function useAdjustmentHistory(initialState: AdjustmentState, options?: HistoryOptions): UseAdjustmentHistoryReturn;
93
- export {};
97
+ export declare function useAdjustmentHistory(initialState: AdjustmentState, controller?: Controller, firebaseUid?: string, currentImageId?: string, options?: HistoryOptions): UseAdjustmentHistoryReturn;