@yogiswara/honcho-editor-ui 2.7.15 → 2.7.17
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/dist/components/editor/HHeaderEditor.d.ts +2 -0
- package/dist/components/editor/HHeaderEditor.js +1 -1
- package/dist/components/editor/HImageEditorMobile.d.ts +2 -0
- package/dist/components/editor/HTabColorAdjustmentMobile.d.ts +4 -2
- package/dist/components/editor/HTabColorAdjustmentMobile.js +3 -11
- package/dist/hooks/useAdjustmentHistory.d.ts +2 -4
- package/dist/hooks/useAdjustmentHistory.js +74 -67
- package/dist/lib/hooks/useEditorHeadless.js +1 -1
- package/package.json +1 -1
|
@@ -22,7 +22,7 @@ export default function HHeaderEditor(props) {
|
|
|
22
22
|
transform: 'scale(0.92)',
|
|
23
23
|
},
|
|
24
24
|
transition: 'transform 0.1s ease-in-out',
|
|
25
|
-
}, children: _jsx(CardMedia, { title: "back", src: "svg/Back.svg", component: "img" }) }) }), _jsxs(Stack, { direction: "row", justifyContent: "flex-end", alignItems: "center", sx: { pt: "20px", pb: "12px" }, spacing: 0.1, children: [_jsx(Button, { variant: "text", onClick: props.onSelectButton, sx: { color: colors.outlineVariant }, children: props.valueSelect }), _jsx(IconButton, { "aria-label": "undo", onClick: props.onUndo, sx: { color: colors.outlineVariant }, children: _jsx(CardMedia, { component: "img", image: "/v1/svg/undo-editor.svg" }) }), _jsx(IconButton, { "aria-label": "redo", onClick: props.onRedo, sx: { color: colors.outlineVariant }, children: _jsx(CardMedia, { component: "img", image: "/v1/svg/redo-editor.svg" }) }), _jsx(IconButton, { "aria-label": "option", onClick: props.onMenuClick, "aria-controls": open ? 'options-menu' : undefined, "aria-haspopup": "true", "aria-expanded": open ? 'true' : undefined, children: _jsx(CardMedia, { component: "img", image: "/v1/svg/dots-editor.svg" }) }), _jsxs(Menu, { id: "options-menu", anchorEl: props.anchorEl, open: open, onClose: props.onMenuClose, transformOrigin: { horizontal: 'right', vertical: 'top' }, anchorOrigin: { horizontal: 'right', vertical: 'bottom' }, slotProps: {
|
|
25
|
+
}, children: _jsx(CardMedia, { title: "back", src: "svg/Back.svg", component: "img" }) }) }), _jsxs(Stack, { direction: "row", justifyContent: "flex-end", alignItems: "center", sx: { pt: "20px", pb: "12px" }, spacing: 0.1, children: [_jsx(Button, { variant: "text", onClick: props.onSelectButton, sx: { color: colors.outlineVariant }, children: props.valueSelect }), _jsx(IconButton, { "aria-label": "undo", onClick: props.onUndo, sx: { color: colors.outlineVariant, opacity: props.canUndo ? 1 : 0.5 }, disabled: !props.canUndo, children: _jsx(CardMedia, { component: "img", image: "/v1/svg/undo-editor.svg" }) }), _jsx(IconButton, { "aria-label": "redo", onClick: props.onRedo, sx: { color: colors.outlineVariant, opacity: props.canRedo ? 1 : 0.5 }, disabled: !props.canRedo, children: _jsx(CardMedia, { component: "img", image: "/v1/svg/redo-editor.svg" }) }), _jsx(IconButton, { "aria-label": "option", onClick: props.onMenuClick, "aria-controls": open ? 'options-menu' : undefined, "aria-haspopup": "true", "aria-expanded": open ? 'true' : undefined, children: _jsx(CardMedia, { component: "img", image: "/v1/svg/dots-editor.svg" }) }), _jsxs(Menu, { id: "options-menu", anchorEl: props.anchorEl, open: open, onClose: props.onMenuClose, transformOrigin: { horizontal: 'right', vertical: 'top' }, anchorOrigin: { horizontal: 'right', vertical: 'bottom' }, slotProps: {
|
|
26
26
|
paper: {
|
|
27
27
|
sx: {
|
|
28
28
|
backgroundColor: colors.onBackground,
|
|
@@ -10,6 +10,8 @@ interface Props {
|
|
|
10
10
|
activeSubPanel: string;
|
|
11
11
|
setActivePanel: (tab: string) => void;
|
|
12
12
|
setActiveSubPanel: (subTab: string) => void;
|
|
13
|
+
activeTab: string;
|
|
14
|
+
innerRef?: React.Ref<HTMLDivElement>;
|
|
13
15
|
panelRef: React.RefObject<HTMLDivElement>;
|
|
14
16
|
contentRef: React.RefObject<HTMLDivElement | null>;
|
|
15
17
|
panelHeight: number;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import React from "react";
|
|
1
2
|
import { AdjustmentState } from '../../hooks/editor/type';
|
|
2
3
|
interface Props {
|
|
3
|
-
|
|
4
|
+
activeTab: string;
|
|
5
|
+
innerRef?: React.Ref<HTMLDivElement>;
|
|
4
6
|
tempScore: number;
|
|
5
7
|
tintScore: number;
|
|
6
8
|
vibranceScore: number;
|
|
@@ -29,5 +31,5 @@ interface Props {
|
|
|
29
31
|
onDragStart: () => void;
|
|
30
32
|
onDragEnd: () => void;
|
|
31
33
|
}
|
|
32
|
-
export default function HTabColorAdjustmentMobile(props: Props): import("react/jsx-runtime").JSX.Element
|
|
34
|
+
export default function HTabColorAdjustmentMobile(props: Props): import("react/jsx-runtime").JSX.Element;
|
|
33
35
|
export {};
|
|
@@ -1,16 +1,8 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import HSliderColorMobile from "./HSliderColorMobile";
|
|
3
3
|
import HSliderLightMobile from "./HSliderLightMobile";
|
|
4
4
|
import HSliderDetailsMobile from "./HSliderDetailsMobile";
|
|
5
|
+
import { Box } from "@mui/material";
|
|
5
6
|
export default function HTabColorAdjustmentMobile(props) {
|
|
6
|
-
|
|
7
|
-
case 'color':
|
|
8
|
-
return (_jsx(HSliderColorMobile, { tempScore: props.tempScore, tintScore: props.tintScore, onTempChange: props.onTempChange, onTintChange: props.onTintChange, vibranceScore: props.vibranceScore, onVibranceChange: props.onVibranceChange, saturationScore: props.saturationScore, onSaturationChange: props.onSaturationChange, isBatchMode: props.isBatchMode, onDragStart: props.onDragStart, onDragEnd: props.onDragEnd }));
|
|
9
|
-
case 'light':
|
|
10
|
-
return (_jsx(HSliderLightMobile, { contrastScore: props.contrastScore, exposureScore: props.exposureScore, highlightsScore: props.highlightsScore, shadowScore: props.shadowScore, whiteScore: props.whiteScore, blackScore: props.blackScore, onExposureChange: props.onExposureChange, onContrastChange: props.onContrastChange, onHighlightsChange: props.onHighlightsChange, onShadowsChange: props.onShadowsChange, onWhitesChange: props.onWhitesChange, onBlacksChange: props.onBlacksChange, isBatchMode: props.isBatchMode, onDragStart: props.onDragStart, onDragEnd: props.onDragEnd }));
|
|
11
|
-
case 'details':
|
|
12
|
-
return (_jsx(HSliderDetailsMobile, { clarityScore: props.clarityScore, sharpnessScore: props.sharpnessScore, onClarityChange: props.onClarityChange, onSharpnessChange: props.onSharpnessChange, isBatchMode: props.isBatchMode, onDragStart: props.onDragStart, onDragEnd: props.onDragEnd }));
|
|
13
|
-
default:
|
|
14
|
-
return null;
|
|
15
|
-
}
|
|
7
|
+
return (_jsxs(Box, { ref: props.innerRef, children: [props.activeTab === "light" && _jsx(HSliderLightMobile, { ...props }), props.activeTab === "color" && _jsx(HSliderColorMobile, { ...props }), props.activeTab === "details" && _jsx(HSliderDetailsMobile, { ...props })] }));
|
|
16
8
|
}
|
|
@@ -37,8 +37,6 @@ export interface HistoryActions {
|
|
|
37
37
|
undo: () => void;
|
|
38
38
|
/** Redo to next adjustment state */
|
|
39
39
|
redo: () => void;
|
|
40
|
-
/** Reset history with new initial adjustment state */
|
|
41
|
-
reset: (newInitialState: AdjustmentState) => void;
|
|
42
40
|
/** Jump to specific index in history */
|
|
43
41
|
jumpToIndex: (index: number) => void;
|
|
44
42
|
/** Clear all history and start fresh */
|
|
@@ -47,8 +45,6 @@ export interface HistoryActions {
|
|
|
47
45
|
getHistory: () => AdjustmentState[];
|
|
48
46
|
/** Trim history to specified size, keeping most recent entries */
|
|
49
47
|
trimHistory: (keepLast: number) => void;
|
|
50
|
-
/** Replace entire history with new list of adjustment states */
|
|
51
|
-
syncHistory: (newHistory: AdjustmentState[], targetIndex?: number) => void;
|
|
52
48
|
/** Sync history from backend using getEditorHistory */
|
|
53
49
|
syncFromBackend: () => Promise<void>;
|
|
54
50
|
}
|
|
@@ -69,6 +65,8 @@ export interface HistoryConfig {
|
|
|
69
65
|
export interface UseAdjustmentHistoryReturn {
|
|
70
66
|
/** Current adjustment state value */
|
|
71
67
|
currentState: AdjustmentState;
|
|
68
|
+
/** Current index in history */
|
|
69
|
+
currentIndex: number;
|
|
72
70
|
/** Information about history state */
|
|
73
71
|
historyInfo: HistoryInfo;
|
|
74
72
|
/** Available history actions */
|
|
@@ -99,8 +99,9 @@ export function useAdjustmentHistory(initialState, controller, firebaseUid, curr
|
|
|
99
99
|
]);
|
|
100
100
|
// Core state management
|
|
101
101
|
const [history, setHistory] = useState([{ state: initialState, taskId: `initial_${Date.now()}` }]);
|
|
102
|
-
const [currentIndex, setCurrentIndex] = useState(0);
|
|
103
102
|
const [currentState, setCurrentState] = useState(initialState);
|
|
103
|
+
const currentIndexRef = useRef(0);
|
|
104
|
+
const currentStateRef = useRef(initialState);
|
|
104
105
|
// Batch mode state - ref to avoid triggering effects
|
|
105
106
|
const batchModeRef = useRef(internalOptions.enableBatching);
|
|
106
107
|
const batchStartIndexRef = useRef(null);
|
|
@@ -109,6 +110,8 @@ export function useAdjustmentHistory(initialState, controller, firebaseUid, curr
|
|
|
109
110
|
// Configuration refs - prevent re-renders when config changes
|
|
110
111
|
const maxSizeRef = useRef(internalOptions.maxSize);
|
|
111
112
|
const devWarningsRef = useRef(internalOptions.devWarnings);
|
|
113
|
+
// Computed current index for return value (defined early for dependencies)
|
|
114
|
+
const currentIndex = currentIndexRef.current;
|
|
112
115
|
// Performance monitoring
|
|
113
116
|
const performanceRef = useRef({
|
|
114
117
|
lastHistorySize: 1,
|
|
@@ -162,10 +165,9 @@ export function useAdjustmentHistory(initialState, controller, firebaseUid, curr
|
|
|
162
165
|
const startIndex = Math.max(0, prevHistory.length - size);
|
|
163
166
|
const trimmedHistory = prevHistory.slice(startIndex);
|
|
164
167
|
// Adjust current index to maintain relative position
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
});
|
|
168
|
+
const prevIndex = currentIndexRef.current;
|
|
169
|
+
const adjustedIndex = prevIndex - startIndex;
|
|
170
|
+
currentIndexRef.current = Math.max(0, Math.min(adjustedIndex, trimmedHistory.length - 1));
|
|
169
171
|
return trimmedHistory;
|
|
170
172
|
});
|
|
171
173
|
}, []);
|
|
@@ -181,6 +183,7 @@ export function useAdjustmentHistory(initialState, controller, firebaseUid, curr
|
|
|
181
183
|
// Push new state to history
|
|
182
184
|
const pushState = useCallback((newState) => {
|
|
183
185
|
// Always update currentState immediately for smooth UI
|
|
186
|
+
currentStateRef.current = newState;
|
|
184
187
|
setCurrentState(newState);
|
|
185
188
|
if (batchModeRef.current) {
|
|
186
189
|
// In batch mode: Don't update history yet, just update UI state
|
|
@@ -189,22 +192,24 @@ export function useAdjustmentHistory(initialState, controller, firebaseUid, curr
|
|
|
189
192
|
return;
|
|
190
193
|
}
|
|
191
194
|
// Normal mode: Update history immediately
|
|
195
|
+
console.log(`[useAdjustmentHistory] Pushing new state to history:`, newState);
|
|
192
196
|
setHistory(prevHistory => {
|
|
193
|
-
const truncatedHistory = prevHistory.slice(0,
|
|
197
|
+
const truncatedHistory = prevHistory.slice(0, currentIndexRef.current + 1);
|
|
194
198
|
// const taskId = `task_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
195
199
|
// we put the taskId empty to check this state no need to save it
|
|
196
200
|
const newHistory = [...truncatedHistory, { state: newState, taskId: "" }];
|
|
197
|
-
|
|
201
|
+
currentIndexRef.current = newHistory.length - 1;
|
|
198
202
|
return newHistory;
|
|
199
203
|
});
|
|
200
|
-
}, [
|
|
204
|
+
}, []);
|
|
201
205
|
// Undo to previous state
|
|
202
206
|
const undo = useCallback(async () => {
|
|
203
|
-
if (
|
|
204
|
-
const newIndex =
|
|
207
|
+
if (currentIndexRef.current > 0) {
|
|
208
|
+
const newIndex = currentIndexRef.current - 1;
|
|
205
209
|
const historyEntry = history[newIndex];
|
|
206
210
|
const newState = historyEntry.state;
|
|
207
|
-
|
|
211
|
+
currentIndexRef.current = newIndex;
|
|
212
|
+
currentStateRef.current = newState;
|
|
208
213
|
setCurrentState(newState);
|
|
209
214
|
console.log(`[useAdjustmentHistory] Undoing to index ${newIndex}:`, newState);
|
|
210
215
|
// Call controller to set history index in backend if taskId exists
|
|
@@ -228,14 +233,15 @@ export function useAdjustmentHistory(initialState, controller, firebaseUid, curr
|
|
|
228
233
|
batchStartStateRef.current = null;
|
|
229
234
|
}
|
|
230
235
|
}
|
|
231
|
-
}, [
|
|
236
|
+
}, [history, internalOptions]);
|
|
232
237
|
// Redo to next state
|
|
233
238
|
const redo = useCallback(async () => {
|
|
234
|
-
if (
|
|
235
|
-
const newIndex =
|
|
239
|
+
if (currentIndexRef.current < history.length - 1) {
|
|
240
|
+
const newIndex = currentIndexRef.current + 1;
|
|
236
241
|
const historyEntry = history[newIndex];
|
|
237
242
|
const newState = historyEntry.state;
|
|
238
|
-
|
|
243
|
+
currentIndexRef.current = newIndex;
|
|
244
|
+
currentStateRef.current = newState;
|
|
239
245
|
setCurrentState(newState);
|
|
240
246
|
console.log(`[useAdjustmentHistory] Redoing to index ${newIndex}:`, newState);
|
|
241
247
|
// Call controller to set history index in backend if taskId exists
|
|
@@ -253,22 +259,24 @@ export function useAdjustmentHistory(initialState, controller, firebaseUid, curr
|
|
|
253
259
|
console.warn('🔄 Redo: No taskId available for setting history index', historyEntry.taskId, internalOptions.firebaseUid, internalOptions.currentImageId);
|
|
254
260
|
}
|
|
255
261
|
}
|
|
256
|
-
}, [
|
|
262
|
+
}, [history, internalOptions]);
|
|
257
263
|
// Reset history with new initial state
|
|
258
|
-
const reset = useCallback((newInitialState) => {
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
264
|
+
// const reset = useCallback((newInitialState: AdjustmentState) => {
|
|
265
|
+
// console.log("Reset called setHistory");
|
|
266
|
+
// setHistory([{ state: newInitialState, taskId: `reset_${Date.now()}` }]);
|
|
267
|
+
// currentIndexRef.current = 0;
|
|
268
|
+
// currentStateRef.current = newInitialState;
|
|
269
|
+
// batchModeRef.current = internalOptions.enableBatching;
|
|
270
|
+
// batchStartIndexRef.current = null;
|
|
271
|
+
// batchStartStateRef.current = null;
|
|
272
|
+
// }, [internalOptions.enableBatching]);
|
|
266
273
|
// Jump to specific index in history
|
|
267
274
|
const jumpToIndex = useCallback((index) => {
|
|
268
275
|
if (index >= 0 && index < history.length) {
|
|
269
276
|
const historyEntry = history[index];
|
|
270
277
|
const newState = historyEntry.state;
|
|
271
|
-
|
|
278
|
+
currentIndexRef.current = index;
|
|
279
|
+
currentStateRef.current = newState;
|
|
272
280
|
setCurrentState(newState);
|
|
273
281
|
// Exit batch mode when jumping
|
|
274
282
|
if (batchModeRef.current) {
|
|
@@ -280,12 +288,13 @@ export function useAdjustmentHistory(initialState, controller, firebaseUid, curr
|
|
|
280
288
|
}, [history]);
|
|
281
289
|
// Clear all history and start fresh
|
|
282
290
|
const clearHistory = useCallback(() => {
|
|
283
|
-
|
|
284
|
-
|
|
291
|
+
console.log("clearHistory called setHistory");
|
|
292
|
+
setHistory([{ state: currentStateRef.current, taskId: `clear_${Date.now()}` }]);
|
|
293
|
+
currentIndexRef.current = 0;
|
|
285
294
|
batchModeRef.current = internalOptions.enableBatching;
|
|
286
295
|
batchStartIndexRef.current = null;
|
|
287
296
|
batchStartStateRef.current = null;
|
|
288
|
-
}, [
|
|
297
|
+
}, [internalOptions.enableBatching]);
|
|
289
298
|
// Get copy of entire history
|
|
290
299
|
const getHistory = useCallback(() => {
|
|
291
300
|
return history.map(entry => entry.state);
|
|
@@ -369,16 +378,16 @@ export function useAdjustmentHistory(initialState, controller, firebaseUid, curr
|
|
|
369
378
|
}, [enforceMaxSize]);
|
|
370
379
|
const setBatchMode = useCallback(async (enabled, forceHistory = false) => {
|
|
371
380
|
const wasInBatch = batchModeRef.current;
|
|
372
|
-
console.log(`🔧 setBatchMode called: enabled=${enabled}, wasInBatch=${wasInBatch}, currentIndex=${
|
|
381
|
+
console.log(`🔧 setBatchMode called: enabled=${enabled}, wasInBatch=${wasInBatch}, currentIndex=${currentIndexRef.current}, historyLength=${history.length}`);
|
|
373
382
|
if (enabled && !wasInBatch) {
|
|
374
383
|
// Starting batch mode - save current state as batch start
|
|
375
384
|
batchModeRef.current = true;
|
|
376
|
-
batchStartIndexRef.current =
|
|
377
|
-
batchStartStateRef.current =
|
|
385
|
+
batchStartIndexRef.current = currentIndexRef.current;
|
|
386
|
+
batchStartStateRef.current = currentStateRef.current;
|
|
378
387
|
console.log("🔧 setBatchMode(true): Starting batch mode", {
|
|
379
|
-
currentState,
|
|
380
|
-
currentIndex,
|
|
381
|
-
batchStartState:
|
|
388
|
+
currentState: currentStateRef.current,
|
|
389
|
+
currentIndex: currentIndexRef.current,
|
|
390
|
+
batchStartState: currentStateRef.current
|
|
382
391
|
});
|
|
383
392
|
}
|
|
384
393
|
else if (!enabled && wasInBatch) {
|
|
@@ -388,15 +397,15 @@ export function useAdjustmentHistory(initialState, controller, firebaseUid, curr
|
|
|
388
397
|
console.log("⚠️ setBatchMode(false) already processing, skipping duplicate call");
|
|
389
398
|
return;
|
|
390
399
|
}
|
|
391
|
-
console.log("🔧 setBatchMode: Ending batch mode",
|
|
400
|
+
console.log("🔧 setBatchMode: Ending batch mode", currentStateRef.current, `batchStartIndex=${batchStartIndexRef.current}`);
|
|
392
401
|
// Ending batch mode - commit final state to history
|
|
393
402
|
batchModeProcessingRef.current = true;
|
|
394
403
|
batchModeRef.current = false;
|
|
395
404
|
// Only add to history if state actually changed from batch start
|
|
396
405
|
const statesEqual = batchStartStateRef.current ?
|
|
397
|
-
compareAdjustmentStates(
|
|
406
|
+
compareAdjustmentStates(currentStateRef.current, batchStartStateRef.current) : true;
|
|
398
407
|
console.log("🔧 setBatchMode(false): Comparing states", {
|
|
399
|
-
currentState,
|
|
408
|
+
currentState: currentStateRef.current,
|
|
400
409
|
batchStartState: batchStartStateRef.current,
|
|
401
410
|
statesEqual,
|
|
402
411
|
forceHistory,
|
|
@@ -405,39 +414,42 @@ export function useAdjustmentHistory(initialState, controller, firebaseUid, curr
|
|
|
405
414
|
if (batchStartStateRef.current && (!statesEqual || forceHistory)) {
|
|
406
415
|
// Generate a unique task ID for this history entry
|
|
407
416
|
const taskId = `task_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
417
|
+
console.log('📋 Before SetHistory state for backend:', batchStartIndexRef.current, currentStateRef.current, history.length);
|
|
418
|
+
// Store variables for backend call BEFORE setHistory
|
|
419
|
+
let replaceFromTaskId;
|
|
420
|
+
const batchStartIndex = batchStartIndexRef.current ?? currentIndexRef.current;
|
|
421
|
+
const wasInMiddleOfHistory = batchStartIndex < history.length - 1;
|
|
422
|
+
if (wasInMiddleOfHistory) {
|
|
423
|
+
// Get the task_id from the original history entry to use as replace_from
|
|
424
|
+
const currentHistoryEntry = history[batchStartIndex];
|
|
425
|
+
replaceFromTaskId = currentHistoryEntry?.taskId;
|
|
426
|
+
console.log(`📍 Was in middle of history (index ${batchStartIndex}), using replace_from: ${replaceFromTaskId}`);
|
|
427
|
+
}
|
|
428
|
+
else {
|
|
429
|
+
console.log(`📍 At latest history (index ${batchStartIndex}), no replace_from needed`);
|
|
430
|
+
}
|
|
408
431
|
setHistory(prevHistory => {
|
|
409
432
|
// Check if we were in the middle of history BEFORE any truncation
|
|
410
433
|
// Handle case where batchStartIndexRef.current might be null (e.g., after undo)
|
|
411
|
-
const batchStartIndex = batchStartIndexRef.current ??
|
|
434
|
+
const batchStartIndex = batchStartIndexRef.current ?? currentIndexRef.current;
|
|
412
435
|
const truncatedHistory = prevHistory.slice(0, batchStartIndex + 1);
|
|
413
436
|
const newHistoryEntry = {
|
|
414
|
-
state:
|
|
437
|
+
state: currentStateRef.current,
|
|
415
438
|
taskId: taskId
|
|
416
439
|
};
|
|
417
440
|
const newHistory = [...truncatedHistory, newHistoryEntry];
|
|
418
|
-
|
|
441
|
+
currentIndexRef.current = newHistory.length - 1;
|
|
419
442
|
return newHistory;
|
|
420
443
|
});
|
|
421
444
|
// Call controller to create history in backend - OUTSIDE of setHistory callback
|
|
422
445
|
if (internalOptions.controller && internalOptions.firebaseUid && internalOptions.currentImageId) {
|
|
423
446
|
try {
|
|
424
447
|
console.log('🔄 Creating editor history in backend for batch mode end');
|
|
425
|
-
|
|
426
|
-
const batchStartIndex = batchStartIndexRef.current ?? currentIndex;
|
|
427
|
-
const wasInMiddleOfHistory = batchStartIndex < history.length - 1;
|
|
428
|
-
if (wasInMiddleOfHistory) {
|
|
429
|
-
// Get the task_id from the original history entry to use as replace_from
|
|
430
|
-
const currentHistoryEntry = history[batchStartIndex];
|
|
431
|
-
replaceFromTaskId = currentHistoryEntry?.taskId;
|
|
432
|
-
console.log(`📍 Was in middle of history (index ${batchStartIndex}), using replace_from: ${replaceFromTaskId}`);
|
|
433
|
-
}
|
|
434
|
-
else {
|
|
435
|
-
console.log(`📍 At latest history (index ${batchStartIndex}), no replace_from needed`);
|
|
436
|
-
}
|
|
448
|
+
console.log('📋 Current state for backend:', batchStartIndexRef.current, currentStateRef.current, history.length);
|
|
437
449
|
const createEditorConfigPayload = {
|
|
438
450
|
gallery_id: internalOptions.currentImageId,
|
|
439
451
|
task_id: taskId,
|
|
440
|
-
color_adjustment: convertAdjustmentStateToColorAdjustment(
|
|
452
|
+
color_adjustment: convertAdjustmentStateToColorAdjustment(currentStateRef.current),
|
|
441
453
|
...(replaceFromTaskId && { replace_from: replaceFromTaskId })
|
|
442
454
|
};
|
|
443
455
|
// Create editor config with current adjustments
|
|
@@ -469,7 +481,7 @@ export function useAdjustmentHistory(initialState, controller, firebaseUid, curr
|
|
|
469
481
|
batchStartStateRef.current = null;
|
|
470
482
|
batchModeProcessingRef.current = false; // Reset processing flag
|
|
471
483
|
}
|
|
472
|
-
}, [
|
|
484
|
+
}, [internalOptions, history]);
|
|
473
485
|
// Sync history from backend using getEditorHistory
|
|
474
486
|
const syncFromBackend = useCallback(async () => {
|
|
475
487
|
if (!internalOptions.controller || !internalOptions.firebaseUid || !internalOptions.currentImageId) {
|
|
@@ -479,17 +491,12 @@ export function useAdjustmentHistory(initialState, controller, firebaseUid, curr
|
|
|
479
491
|
try {
|
|
480
492
|
console.log('🔄 Syncing history from backend using getEditorHistory');
|
|
481
493
|
const historyResponse = await internalOptions.controller.getEditorHistory(internalOptions.firebaseUid, internalOptions.currentImageId);
|
|
482
|
-
console.log('📥 Received history response from backend:', historyResponse);
|
|
483
494
|
// Sort history by timestamp (oldest first) before processing
|
|
484
495
|
const sortedHistory = [...historyResponse.history].sort((a, b) => {
|
|
485
496
|
const timeA = new Date(a.log.created_at).getTime();
|
|
486
497
|
const timeB = new Date(b.log.created_at).getTime();
|
|
487
498
|
return timeA - timeB; // Ascending order (oldest first)
|
|
488
499
|
});
|
|
489
|
-
console.log('📋 Sorted history by timestamp:', sortedHistory.map(entry => ({
|
|
490
|
-
task_id: entry.task_id,
|
|
491
|
-
timestamp: entry.log.created_at
|
|
492
|
-
})));
|
|
493
500
|
// Convert backend history to AdjustmentState format with taskIds
|
|
494
501
|
const backendHistoryEntries = sortedHistory.map((entry) => ({
|
|
495
502
|
state: convertColorAdjustmentToAdjustmentState(entry.editor_config.color_adjustment),
|
|
@@ -518,8 +525,9 @@ export function useAdjustmentHistory(initialState, controller, firebaseUid, curr
|
|
|
518
525
|
}
|
|
519
526
|
// Update history state with backend data
|
|
520
527
|
setHistory(backendHistoryEntries);
|
|
521
|
-
|
|
528
|
+
currentIndexRef.current = Math.max(0, currentTaskIndex);
|
|
522
529
|
console.log(`📍 Setting current index to: ${Math.max(0, currentTaskIndex)} (task_id: ${historyResponse.current_task_id})`);
|
|
530
|
+
currentStateRef.current = backendHistoryEntries[Math.max(0, currentTaskIndex)].state;
|
|
523
531
|
setCurrentState(backendHistoryEntries[Math.max(0, currentTaskIndex)].state);
|
|
524
532
|
console.log(`✅ Successfully synced ${backendHistoryEntries.length} history entries from backend`);
|
|
525
533
|
console.log(`📍 Set current index to: ${Math.max(0, currentTaskIndex)} (task_id: ${historyResponse.current_task_id})`);
|
|
@@ -531,26 +539,24 @@ export function useAdjustmentHistory(initialState, controller, firebaseUid, curr
|
|
|
531
539
|
}, [internalOptions]);
|
|
532
540
|
// History info object
|
|
533
541
|
const historyInfo = useMemo(() => ({
|
|
534
|
-
canUndo:
|
|
535
|
-
canRedo:
|
|
536
|
-
currentIndex,
|
|
542
|
+
canUndo: currentIndexRef.current > 0,
|
|
543
|
+
canRedo: currentIndexRef.current < history.length - 1,
|
|
544
|
+
currentIndex: currentIndexRef.current,
|
|
537
545
|
totalStates: history.length,
|
|
538
546
|
historySize: getMemoryUsage(),
|
|
539
547
|
isBatchMode: batchModeRef.current
|
|
540
|
-
}), [
|
|
548
|
+
}), [history.length, getMemoryUsage]);
|
|
541
549
|
// Actions object - stabilized with useMemo
|
|
542
550
|
const actions = useMemo(() => ({
|
|
543
551
|
pushState,
|
|
544
552
|
undo,
|
|
545
553
|
redo,
|
|
546
|
-
reset,
|
|
547
554
|
jumpToIndex,
|
|
548
555
|
clearHistory,
|
|
549
556
|
getHistory,
|
|
550
557
|
trimHistory,
|
|
551
|
-
syncHistory,
|
|
552
558
|
syncFromBackend
|
|
553
|
-
}), [pushState, undo, redo,
|
|
559
|
+
}), [pushState, undo, redo, jumpToIndex, clearHistory, getHistory, trimHistory, syncFromBackend]);
|
|
554
560
|
// Config object - stabilized with useMemo
|
|
555
561
|
const config = useMemo(() => ({
|
|
556
562
|
setMaxSize,
|
|
@@ -564,6 +570,7 @@ export function useAdjustmentHistory(initialState, controller, firebaseUid, curr
|
|
|
564
570
|
}, [enforceMaxSize, checkPerformance]);
|
|
565
571
|
return {
|
|
566
572
|
currentState,
|
|
573
|
+
currentIndex,
|
|
567
574
|
historyInfo,
|
|
568
575
|
actions,
|
|
569
576
|
config
|
|
@@ -125,7 +125,7 @@ export function useEditorHeadless(options = {}) {
|
|
|
125
125
|
console.debug('HonchoEditor instance created successfully');
|
|
126
126
|
}
|
|
127
127
|
console.debug('Initializing HonchoEditor...');
|
|
128
|
-
await editorRef.current.initialize(
|
|
128
|
+
await editorRef.current.initialize(false);
|
|
129
129
|
console.debug('HonchoEditor initialized successfully');
|
|
130
130
|
setIsReady(true);
|
|
131
131
|
}
|