@yogiswara/honcho-editor-ui 2.1.0 → 2.1.2
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.
|
@@ -61,24 +61,24 @@ export interface Gallery {
|
|
|
61
61
|
uid: string;
|
|
62
62
|
event_id: string;
|
|
63
63
|
download: Content;
|
|
64
|
-
download_edited: Content
|
|
64
|
+
download_edited: Content;
|
|
65
65
|
raw?: Content;
|
|
66
66
|
raw_edited?: Content;
|
|
67
67
|
raw_preview?: Content;
|
|
68
68
|
raw_thumbnail?: Content;
|
|
69
69
|
original?: Content;
|
|
70
|
-
original_edited?: Content
|
|
70
|
+
original_edited?: Content;
|
|
71
71
|
large?: Content;
|
|
72
|
-
large_edited?: Content
|
|
73
|
-
medium?: Content
|
|
74
|
-
medium_edited?: Content
|
|
75
|
-
small?: Content
|
|
76
|
-
small_edited?: Content
|
|
77
|
-
mini?: Content
|
|
78
|
-
mini_edited?: Content
|
|
72
|
+
large_edited?: Content;
|
|
73
|
+
medium?: Content;
|
|
74
|
+
medium_edited?: Content;
|
|
75
|
+
small?: Content;
|
|
76
|
+
small_edited?: Content;
|
|
77
|
+
mini?: Content;
|
|
78
|
+
mini_edited?: Content;
|
|
79
79
|
create_from?: string[];
|
|
80
80
|
thumbnail: Content;
|
|
81
|
-
thumbnail_edited: Content
|
|
81
|
+
thumbnail_edited: Content;
|
|
82
82
|
is_original: boolean;
|
|
83
83
|
available: boolean;
|
|
84
84
|
show_gallery: boolean;
|
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import { SelectChangeEvent } from "@mui/material";
|
|
2
2
|
import { AdjustmentState, ImageItem, Controller, Preset } from './useHonchoEditor';
|
|
3
3
|
import { Gallery, ResponseGalleryPaging } from '../../hooks/editor/type';
|
|
4
|
+
export interface PhotoData {
|
|
5
|
+
key: string;
|
|
6
|
+
src: string;
|
|
7
|
+
width: number;
|
|
8
|
+
height: number;
|
|
9
|
+
alt: string;
|
|
10
|
+
isSelected: boolean;
|
|
11
|
+
originalData: Gallery;
|
|
12
|
+
}
|
|
4
13
|
export interface ControllerBulk {
|
|
5
14
|
onGetImage(firebaseUid: string, imageID: string): Promise<Gallery>;
|
|
6
15
|
getImageList(firebaseUid: string, eventID: string, page: number): Promise<ResponseGalleryPaging>;
|
|
@@ -11,17 +20,26 @@ export interface ControllerBulk {
|
|
|
11
20
|
deletePreset(firebaseUid: string, presetId: string): Promise<void>;
|
|
12
21
|
}
|
|
13
22
|
export declare function useHonchoEditorBulk(controllerBulk: Controller, eventID: string, firebaseUid: string): {
|
|
23
|
+
imageCollection: PhotoData[];
|
|
24
|
+
isSelectedMode: boolean;
|
|
25
|
+
isLoading: boolean;
|
|
26
|
+
error: string | null;
|
|
27
|
+
selectedImageIds: string[];
|
|
28
|
+
handleSelectedMode: () => void;
|
|
29
|
+
handleToggleSelect: (photoToToggle: PhotoData) => () => void;
|
|
30
|
+
handlePreview: (photo: PhotoData) => () => void;
|
|
31
|
+
handleBackCallbackBulk: () => void;
|
|
14
32
|
isBulkEditing: boolean;
|
|
15
33
|
selectedImages: string;
|
|
16
34
|
imageList: ImageItem[];
|
|
17
|
-
|
|
35
|
+
currentBatch: import("../useAdjustmentHistoryBatch").BatchAdjustmentState;
|
|
36
|
+
selectedIds: string[];
|
|
37
|
+
allImageIds: string[];
|
|
18
38
|
adjustmentsMap: Map<string, AdjustmentState>;
|
|
19
39
|
selectedBulkPreset: string;
|
|
20
|
-
handleFileChangeBulk: (event: React.ChangeEvent<HTMLInputElement>) => void;
|
|
21
40
|
handleToggleImageSelection: (imageId: string) => void;
|
|
22
41
|
toggleBulkEditing: () => void;
|
|
23
42
|
handleSelectBulkPreset: (event: SelectChangeEvent<string>) => void;
|
|
24
|
-
handleBackCallbackBulk: () => void;
|
|
25
43
|
setTempScore: (value: number) => void;
|
|
26
44
|
setTintScore: (value: number) => void;
|
|
27
45
|
setVibranceScore: (value: number) => void;
|
|
@@ -1,81 +1,83 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { useState, useCallback, useEffect } from 'react';
|
|
2
|
+
import { useState, useCallback, useEffect, useMemo } from 'react';
|
|
3
3
|
import { useAdjustmentHistory } from '../useAdjustmentHistory';
|
|
4
4
|
import { useAdjustmentHistoryBatch } from '../useAdjustmentHistoryBatch';
|
|
5
|
+
// Helper function to map the API response to the format our UI component needs
|
|
6
|
+
const mapGalleryToPhotoData = (gallery) => ({
|
|
7
|
+
key: gallery.id,
|
|
8
|
+
src: gallery.raw_edited?.path || gallery.download?.path || '',
|
|
9
|
+
width: gallery.raw_edited?.width || 1, // Default to 1 to prevent division by zero
|
|
10
|
+
height: gallery.raw_edited?.height || 1,
|
|
11
|
+
alt: gallery.id || 'gallery image',
|
|
12
|
+
isSelected: false, // All images start as unselected
|
|
13
|
+
originalData: gallery,
|
|
14
|
+
});
|
|
5
15
|
const initialAdjustments = {
|
|
6
16
|
tempScore: 0, tintScore: 0, vibranceScore: 0, exposureScore: 0, highlightsScore: 0, shadowsScore: 0,
|
|
7
17
|
whitesScore: 0, blacksScore: 0, saturationScore: 0, contrastScore: 0, clarityScore: 0, sharpnessScore: 0,
|
|
8
18
|
};
|
|
9
19
|
const clamp = (value) => Math.max(-100, Math.min(100, value));
|
|
20
|
+
function mapColorAdjustmentToAdjustmentState(adj) {
|
|
21
|
+
return {
|
|
22
|
+
tempScore: adj.temperature || 0,
|
|
23
|
+
tintScore: adj.tint || 0,
|
|
24
|
+
vibranceScore: adj.vibrance || 0,
|
|
25
|
+
saturationScore: adj.saturation || 0,
|
|
26
|
+
exposureScore: adj.exposure || 0,
|
|
27
|
+
highlightsScore: adj.highlights || 0,
|
|
28
|
+
shadowsScore: adj.shadows || 0,
|
|
29
|
+
whitesScore: adj.whites || 0,
|
|
30
|
+
blacksScore: adj.blacks || 0,
|
|
31
|
+
contrastScore: adj.contrast || 0,
|
|
32
|
+
clarityScore: adj.clarity || 0,
|
|
33
|
+
sharpnessScore: adj.sharpness || 0,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
10
36
|
export function useHonchoEditorBulk(controllerBulk, eventID, firebaseUid) {
|
|
11
|
-
const { currentState, actions: historyActions,
|
|
12
|
-
const { currentBatch, selectedIds, allImageIds, actions: batchActions, } = useAdjustmentHistoryBatch({
|
|
13
|
-
maxSize: historyInfo.historySize,
|
|
14
|
-
defaultAdjustmentState: currentState,
|
|
15
|
-
});
|
|
37
|
+
const { currentState, actions: historyActions, } = useAdjustmentHistory(initialAdjustments);
|
|
38
|
+
const { currentBatch, selectedIds, allImageIds, actions: batchActions, historyInfo } = useAdjustmentHistoryBatch({});
|
|
16
39
|
// State for Bulk Editing
|
|
40
|
+
const [imageCollection, setImageCollection] = useState([]);
|
|
41
|
+
const [isSelectedMode, setIsSelectedMode] = useState(false);
|
|
42
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
43
|
+
const [error, setError] = useState(null);
|
|
17
44
|
const [isBulkEditing, setIsBulkEditing] = useState(false);
|
|
18
45
|
const [selectedImages, setSelectedImages] = useState('Select');
|
|
19
46
|
const [imageList, setImageList] = useState([]);
|
|
20
|
-
const [selectedImageIds, setSelectedImageIds] = useState(new Set());
|
|
21
47
|
const [adjustmentsMap, setAdjustmentsMap] = useState(new Map());
|
|
22
48
|
const [selectedBulkPreset, setSelectedBulkPreset] = useState('preset1');
|
|
49
|
+
const [isEditorReady, setIsEditorReady] = useState(false);
|
|
50
|
+
const selectedImageIds = useMemo(() => imageCollection.filter(p => p.isSelected).map(p => p.key), [imageCollection]);
|
|
23
51
|
const handleBackCallbackBulk = useCallback(() => {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
// 2. Determine which ID to send back.
|
|
27
|
-
// - If any images are selected, get the ID of the LAST one in the array.
|
|
28
|
-
// - If no images are selected, fall back to using the eventID.
|
|
29
|
-
const idToSendBack = selectedIdsArray.length > 0
|
|
30
|
-
? selectedIdsArray[selectedIdsArray.length - 1]
|
|
31
|
-
: eventID;
|
|
32
|
-
// 3. Check if we have an ID to send, otherwise log a warning.
|
|
33
|
-
if (!idToSendBack) {
|
|
34
|
-
console.warn("handleBack called, but no selected image ID or eventID was available.");
|
|
35
|
-
window.history.back();
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
// 4. Call the controller with the chosen ID (either the last imageId or the eventId).
|
|
39
|
-
controllerBulk.handleBack(firebaseUid, idToSendBack);
|
|
52
|
+
const lastSelectedId = selectedImageIds.length > 0 ? selectedImageIds[selectedImageIds.length - 1] : eventID;
|
|
53
|
+
controllerBulk.handleBack(firebaseUid, lastSelectedId);
|
|
40
54
|
}, [controllerBulk, firebaseUid, selectedImageIds, eventID]);
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
55
|
+
const handleSelectedMode = useCallback(() => {
|
|
56
|
+
setIsSelectedMode(true);
|
|
57
|
+
}, []);
|
|
58
|
+
const handleToggleSelect = useCallback((photoToToggle) => () => {
|
|
59
|
+
setImageCollection(currentCollection => currentCollection.map(photo => photo.key === photoToToggle.key
|
|
60
|
+
? { ...photo, isSelected: !photo.isSelected }
|
|
61
|
+
: photo));
|
|
62
|
+
// Automatically enter selection mode on first selection
|
|
63
|
+
if (!isSelectedMode) {
|
|
64
|
+
setIsSelectedMode(true);
|
|
50
65
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
};
|
|
67
|
-
const handleToggleImageSelection = useCallback((imageId) => {
|
|
68
|
-
const newSelectedIds = new Set(selectedImageIds);
|
|
69
|
-
if (newSelectedIds.has(imageId)) {
|
|
70
|
-
if (newSelectedIds.size > 1) { // Prevent deselecting the last image
|
|
71
|
-
newSelectedIds.delete(imageId);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
else {
|
|
75
|
-
newSelectedIds.add(imageId);
|
|
76
|
-
}
|
|
77
|
-
setSelectedImageIds(newSelectedIds);
|
|
78
|
-
}, [selectedImageIds]);
|
|
66
|
+
}, [isSelectedMode]);
|
|
67
|
+
const handlePreview = useCallback((photo) => () => {
|
|
68
|
+
console.log("Previewing image:", photo.key);
|
|
69
|
+
}, []);
|
|
70
|
+
// const handleToggleImageSelection = useCallback((imageId: string) => {
|
|
71
|
+
// const newSelectedIds = new Set(selectedImageIds);
|
|
72
|
+
// if (newSelectedIds.has(imageId)) {
|
|
73
|
+
// if (newSelectedIds.size > 1) { // Prevent deselecting the last image
|
|
74
|
+
// newSelectedIds.delete(imageId);
|
|
75
|
+
// }
|
|
76
|
+
// } else {
|
|
77
|
+
// newSelectedIds.add(imageId);
|
|
78
|
+
// }
|
|
79
|
+
// setSelectedImageIds(newSelectedIds);
|
|
80
|
+
// }, [selectedImageIds]);
|
|
79
81
|
const toggleBulkEditing = () => {
|
|
80
82
|
setIsBulkEditing(prev => {
|
|
81
83
|
const isNowBulk = !prev;
|
|
@@ -85,19 +87,6 @@ export function useHonchoEditorBulk(controllerBulk, eventID, firebaseUid) {
|
|
|
85
87
|
};
|
|
86
88
|
const handleSelectBulkPreset = (event) => setSelectedBulkPreset(event.target.value);
|
|
87
89
|
// This factory creates functions that adjust a value for all selected images
|
|
88
|
-
const createAbsoluteSetter = (key, setter) => (value) => {
|
|
89
|
-
setter(value); // Update UI slider
|
|
90
|
-
if (isBulkEditing) {
|
|
91
|
-
setAdjustmentsMap(prevMap => {
|
|
92
|
-
const newMap = new Map(prevMap);
|
|
93
|
-
selectedImageIds.forEach(id => {
|
|
94
|
-
const currentState = newMap.get(id) || initialAdjustments;
|
|
95
|
-
newMap.set(id, { ...currentState, [key]: value });
|
|
96
|
-
});
|
|
97
|
-
return newMap;
|
|
98
|
-
});
|
|
99
|
-
}
|
|
100
|
-
};
|
|
101
90
|
const updateAdjustments = useCallback((newValues) => {
|
|
102
91
|
const newState = { ...currentState, ...newValues };
|
|
103
92
|
historyActions.pushState(newState);
|
|
@@ -108,18 +97,6 @@ export function useHonchoEditorBulk(controllerBulk, eventID, firebaseUid) {
|
|
|
108
97
|
const newValue = clamp(currentValue + amount);
|
|
109
98
|
updateAdjustments({ [key]: newValue });
|
|
110
99
|
};
|
|
111
|
-
useEffect(() => {
|
|
112
|
-
if (!isBulkEditing)
|
|
113
|
-
return;
|
|
114
|
-
setAdjustmentsMap(prevMap => {
|
|
115
|
-
const newMap = new Map(prevMap);
|
|
116
|
-
selectedImageIds.forEach(id => {
|
|
117
|
-
// Apply the new global state to each selected image
|
|
118
|
-
newMap.set(id, currentState);
|
|
119
|
-
});
|
|
120
|
-
return newMap;
|
|
121
|
-
});
|
|
122
|
-
}, [currentState, selectedImageIds, isBulkEditing]);
|
|
123
100
|
const setTempScore = (value) => updateAdjustments({ tempScore: value });
|
|
124
101
|
const setTintScore = (value) => updateAdjustments({ tintScore: value });
|
|
125
102
|
const setVibranceScore = (value) => updateAdjustments({ vibranceScore: value });
|
|
@@ -180,18 +157,57 @@ export function useHonchoEditorBulk(controllerBulk, eventID, firebaseUid) {
|
|
|
180
157
|
const handleBulkSharpnessDecrease = createRelativeAdjuster('sharpnessScore', -5);
|
|
181
158
|
const handleBulkSharpnessIncrease = createRelativeAdjuster('sharpnessScore', 5);
|
|
182
159
|
const handleBulkSharpnessIncreaseMax = createRelativeAdjuster('sharpnessScore', 20);
|
|
160
|
+
// Extract selected image IDs for other operations (like applying bulk adjustments)
|
|
161
|
+
useEffect(() => {
|
|
162
|
+
if (eventID && firebaseUid) {
|
|
163
|
+
setIsLoading(true);
|
|
164
|
+
setError(null);
|
|
165
|
+
controllerBulk.getImageList(firebaseUid, eventID, 1)
|
|
166
|
+
.then(response => {
|
|
167
|
+
const images = response.gallery;
|
|
168
|
+
// Prepare the initial data for the batch history hook
|
|
169
|
+
const imageConfigs = images.map(img => ({
|
|
170
|
+
imageId: img.id,
|
|
171
|
+
adjustment: img.editor_config?.color_adjustment
|
|
172
|
+
? mapColorAdjustmentToAdjustmentState(img.editor_config.color_adjustment)
|
|
173
|
+
: initialAdjustments
|
|
174
|
+
}));
|
|
175
|
+
// Populate the batch history with all fetched images
|
|
176
|
+
batchActions.setSelection(imageConfigs);
|
|
177
|
+
// Immediately clear the selection so no images are selected by default
|
|
178
|
+
batchActions.clearSelection();
|
|
179
|
+
})
|
|
180
|
+
.catch(err => {
|
|
181
|
+
console.error("Failed to fetch gallery:", err);
|
|
182
|
+
setError(err.message || "Could not load images.");
|
|
183
|
+
})
|
|
184
|
+
.finally(() => {
|
|
185
|
+
setIsLoading(false);
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
}, [eventID, firebaseUid, controllerBulk, batchActions]);
|
|
183
189
|
return {
|
|
190
|
+
imageCollection,
|
|
191
|
+
isSelectedMode,
|
|
192
|
+
isLoading,
|
|
193
|
+
error,
|
|
194
|
+
selectedImageIds,
|
|
195
|
+
// Gallery Handlers
|
|
196
|
+
handleSelectedMode,
|
|
197
|
+
handleToggleSelect,
|
|
198
|
+
handlePreview,
|
|
199
|
+
handleBackCallbackBulk,
|
|
184
200
|
isBulkEditing,
|
|
185
201
|
selectedImages,
|
|
186
202
|
imageList,
|
|
187
|
-
|
|
203
|
+
currentBatch,
|
|
204
|
+
selectedIds,
|
|
205
|
+
allImageIds,
|
|
188
206
|
adjustmentsMap,
|
|
189
207
|
selectedBulkPreset,
|
|
190
|
-
|
|
191
|
-
handleToggleImageSelection,
|
|
208
|
+
handleToggleImageSelection: batchActions.toggleSelection,
|
|
192
209
|
toggleBulkEditing,
|
|
193
210
|
handleSelectBulkPreset,
|
|
194
|
-
handleBackCallbackBulk,
|
|
195
211
|
// Bulk Adjustment Handlers
|
|
196
212
|
setTempScore,
|
|
197
213
|
setTintScore,
|