@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.
- package/dist/components/editor/HBulkPreset.js +12 -2
- package/dist/hooks/demo/HonchoEditorBulkDemo.d.ts +3 -0
- package/dist/hooks/demo/HonchoEditorBulkDemo.js +228 -0
- package/dist/hooks/demo/HonchoEditorSingleCleanDemo.d.ts +3 -0
- package/dist/hooks/demo/HonchoEditorSingleCleanDemo.js +354 -0
- package/dist/hooks/demo/index.d.ts +2 -0
- package/dist/hooks/demo/index.js +2 -0
- package/dist/hooks/editor/type.d.ts +71 -0
- package/dist/hooks/editor/useHonchoEditorBulk.d.ts +12 -12
- package/dist/hooks/editor/useHonchoEditorBulk.js +155 -42
- package/dist/hooks/editor/useHonchoEditorSingle.d.ts +43 -0
- package/dist/hooks/editor/useHonchoEditorSingle.js +158 -0
- package/dist/hooks/useAdjustmentHistory.d.ts +9 -5
- package/dist/hooks/useAdjustmentHistory.js +187 -31
- package/dist/hooks/useAdjustmentHistoryBatch.d.ts +18 -1
- package/dist/hooks/useAdjustmentHistoryBatch.js +627 -201
- package/dist/hooks/useGallerySwipe.d.ts +1 -1
- package/dist/hooks/usePaging.d.ts +89 -0
- package/dist/hooks/usePaging.js +211 -0
- package/dist/hooks/usePreset.d.ts +1 -1
- package/dist/hooks/usePreset.js +35 -35
- package/dist/index.d.ts +4 -3
- package/dist/index.js +3 -1
- package/dist/lib/context/EditorContext.d.ts +10 -0
- package/dist/lib/context/EditorContext.js +4 -2
- package/dist/lib/hooks/useEditorHeadless.d.ts +18 -2
- package/dist/lib/hooks/useEditorHeadless.js +142 -63
- package/dist/utils/adjustment.d.ts +2 -1
- package/dist/utils/adjustment.js +16 -0
- package/dist/utils/imageLoader.d.ts +11 -0
- package/dist/utils/imageLoader.js +53 -0
- package/package.json +1 -1
- package/dist/components/editor/GalleryAlbum/SimplifiedAlbumGallery.d.ts +0 -17
- package/dist/components/editor/GalleryAlbum/SimplifiedAlbumGallery.js +0 -14
- package/dist/components/editor/GalleryAlbum/SimplifiedImageItem.d.ts +0 -8
- package/dist/components/editor/GalleryAlbum/SimplifiedImageItem.js +0 -30
- package/dist/components/editor/HImageEditorPage.d.ts +0 -1
- package/dist/components/editor/HImageEditorPage.js +0 -187
- package/dist/hooks/__tests__/useGallerySwipe.test.d.ts +0 -0
- package/dist/hooks/__tests__/useGallerySwipe.test.js +0 -619
- package/dist/hooks/editor/useHonchoEditor.d.ts +0 -203
- package/dist/hooks/editor/useHonchoEditor.js +0 -716
- package/dist/hooks/useAdjustmentHistory.demo.d.ts +0 -8
- package/dist/hooks/useAdjustmentHistory.demo.js +0 -106
- package/dist/hooks/useAdjustmentHistory.example.d.ts +0 -38
- package/dist/hooks/useAdjustmentHistory.example.js +0 -182
- package/dist/hooks/useAdjustmentHistory.syncDemo.d.ts +0 -8
- package/dist/hooks/useAdjustmentHistory.syncDemo.js +0 -180
- package/dist/hooks/useGallerySwipe.example.d.ts +0 -24
- package/dist/hooks/useGallerySwipe.example.js +0 -184
|
@@ -1,41 +1,110 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { useState, useEffect, useRef, useCallback } from 'react';
|
|
3
|
-
import {
|
|
4
|
-
export function useEditorHeadless() {
|
|
3
|
+
import { loadImageAsFile } from '../../utils/imageLoader';
|
|
4
|
+
export function useEditorHeadless(options = {}) {
|
|
5
|
+
const { scriptUrl = '/honcho-photo-editor.js', wasmUrl = '/honcho-photo-editor.wasm' } = options;
|
|
5
6
|
const editorRef = useRef(null);
|
|
6
7
|
const [isReady, setIsReady] = useState(false);
|
|
7
8
|
const [error, setError] = useState(null);
|
|
8
9
|
const [isScriptLoaded, setIsScriptLoaded] = useState(false);
|
|
9
10
|
// Load script dynamically without component
|
|
10
11
|
useEffect(() => {
|
|
11
|
-
const
|
|
12
|
-
// Check if
|
|
13
|
-
if (
|
|
12
|
+
const loadScripts = async () => {
|
|
13
|
+
// Check if HonchoEditor is already available
|
|
14
|
+
if (window.HonchoEditor) {
|
|
15
|
+
console.debug('HonchoEditor already available globally');
|
|
14
16
|
setIsScriptLoaded(true);
|
|
15
17
|
return;
|
|
16
18
|
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
// Load WASM module first
|
|
20
|
+
const loadWasmModule = () => {
|
|
21
|
+
return new Promise((resolve, reject) => {
|
|
22
|
+
// Check if WASM module is already loaded
|
|
23
|
+
if (document.querySelector(`script[src="${scriptUrl}"]`)) {
|
|
24
|
+
console.debug('WASM module script already exists');
|
|
25
|
+
resolve();
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
console.debug(`Loading WASM module from: ${scriptUrl}`);
|
|
29
|
+
const wasmScript = document.createElement('script');
|
|
30
|
+
wasmScript.src = scriptUrl;
|
|
31
|
+
wasmScript.async = true;
|
|
32
|
+
wasmScript.onload = () => {
|
|
33
|
+
console.debug('WASM module script loaded');
|
|
34
|
+
resolve();
|
|
35
|
+
};
|
|
36
|
+
wasmScript.onerror = () => {
|
|
37
|
+
console.error(`Failed to load WASM module from: ${scriptUrl}`);
|
|
38
|
+
reject(new Error('Failed to load WASM module'));
|
|
39
|
+
};
|
|
40
|
+
document.head.appendChild(wasmScript);
|
|
41
|
+
});
|
|
23
42
|
};
|
|
24
|
-
script
|
|
25
|
-
|
|
26
|
-
|
|
43
|
+
// Load wrapper script that creates HonchoEditor constructor
|
|
44
|
+
const loadWrapperScript = () => {
|
|
45
|
+
return new Promise((resolve, reject) => {
|
|
46
|
+
const wrapperUrl = '/honcho-editor.js';
|
|
47
|
+
// Check if wrapper script is already loaded
|
|
48
|
+
if (document.querySelector(`script[src="${wrapperUrl}"]`)) {
|
|
49
|
+
console.debug('Wrapper script already exists');
|
|
50
|
+
resolve();
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
console.debug(`Loading HonchoEditor wrapper from: ${wrapperUrl}`);
|
|
54
|
+
const wrapperScript = document.createElement('script');
|
|
55
|
+
wrapperScript.src = wrapperUrl;
|
|
56
|
+
wrapperScript.async = true;
|
|
57
|
+
wrapperScript.onload = () => {
|
|
58
|
+
console.debug('Wrapper script loaded');
|
|
59
|
+
resolve();
|
|
60
|
+
};
|
|
61
|
+
wrapperScript.onerror = () => {
|
|
62
|
+
console.error(`Failed to load wrapper script from: ${wrapperUrl}`);
|
|
63
|
+
reject(new Error('Failed to load wrapper script'));
|
|
64
|
+
};
|
|
65
|
+
document.head.appendChild(wrapperScript);
|
|
66
|
+
});
|
|
27
67
|
};
|
|
28
|
-
|
|
68
|
+
try {
|
|
69
|
+
// Load WASM module first
|
|
70
|
+
await loadWasmModule();
|
|
71
|
+
// Then load the wrapper that creates the constructor
|
|
72
|
+
await loadWrapperScript();
|
|
73
|
+
// Wait for HonchoEditor constructor to be available
|
|
74
|
+
const waitForConstructor = () => {
|
|
75
|
+
return new Promise((resolve, reject) => {
|
|
76
|
+
const checkInterval = setInterval(() => {
|
|
77
|
+
if (window.HonchoEditor && typeof window.HonchoEditor === 'function') {
|
|
78
|
+
console.debug('HonchoEditor constructor now available');
|
|
79
|
+
clearInterval(checkInterval);
|
|
80
|
+
resolve();
|
|
81
|
+
}
|
|
82
|
+
}, 100);
|
|
83
|
+
// Timeout after 10 seconds
|
|
84
|
+
setTimeout(() => {
|
|
85
|
+
clearInterval(checkInterval);
|
|
86
|
+
if (!window.HonchoEditor) {
|
|
87
|
+
console.error('Timeout waiting for HonchoEditor constructor');
|
|
88
|
+
reject(new Error('Timeout waiting for HonchoEditor constructor'));
|
|
89
|
+
}
|
|
90
|
+
}, 10000);
|
|
91
|
+
});
|
|
92
|
+
};
|
|
93
|
+
await waitForConstructor();
|
|
94
|
+
setIsScriptLoaded(true);
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
console.error('Failed to load HonchoEditor scripts:', error);
|
|
98
|
+
setError(error instanceof Error ? error : new Error(String(error)));
|
|
99
|
+
}
|
|
29
100
|
};
|
|
30
|
-
|
|
31
|
-
// Cleanup
|
|
101
|
+
loadScripts();
|
|
102
|
+
// Cleanup scripts on unmount (but be careful not to remove if other components need it)
|
|
32
103
|
return () => {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
script.remove();
|
|
36
|
-
}
|
|
104
|
+
// Don't remove the scripts on unmount as other components might need them
|
|
105
|
+
// The scripts should stay loaded for the lifetime of the app
|
|
37
106
|
};
|
|
38
|
-
}, []);
|
|
107
|
+
}, [scriptUrl]);
|
|
39
108
|
// Initialize editor when script is loaded
|
|
40
109
|
useEffect(() => {
|
|
41
110
|
if (!isScriptLoaded)
|
|
@@ -43,10 +112,21 @@ export function useEditorHeadless() {
|
|
|
43
112
|
const initialize = async () => {
|
|
44
113
|
try {
|
|
45
114
|
console.debug('Script loaded, initializing editor...');
|
|
115
|
+
// Double-check that HonchoEditor is available
|
|
116
|
+
if (!window.HonchoEditor) {
|
|
117
|
+
throw new Error('window.HonchoEditor is not available');
|
|
118
|
+
}
|
|
119
|
+
if (typeof window.HonchoEditor !== 'function') {
|
|
120
|
+
throw new Error(`window.HonchoEditor is not a constructor (type: ${typeof window.HonchoEditor})`);
|
|
121
|
+
}
|
|
46
122
|
if (!editorRef.current) {
|
|
47
|
-
|
|
123
|
+
console.debug('Creating new HonchoEditor instance...');
|
|
124
|
+
editorRef.current = new window.HonchoEditor();
|
|
125
|
+
console.debug('HonchoEditor instance created successfully');
|
|
48
126
|
}
|
|
127
|
+
console.debug('Initializing HonchoEditor...');
|
|
49
128
|
await editorRef.current.initialize(false);
|
|
129
|
+
console.debug('HonchoEditor initialized successfully');
|
|
50
130
|
setIsReady(true);
|
|
51
131
|
}
|
|
52
132
|
catch (e) {
|
|
@@ -56,39 +136,12 @@ export function useEditorHeadless() {
|
|
|
56
136
|
};
|
|
57
137
|
initialize();
|
|
58
138
|
return () => {
|
|
59
|
-
editorRef.current
|
|
139
|
+
if (editorRef.current) {
|
|
140
|
+
console.debug('Cleaning up HonchoEditor...');
|
|
141
|
+
editorRef.current?.cleanup();
|
|
142
|
+
}
|
|
60
143
|
};
|
|
61
144
|
}, [isScriptLoaded]);
|
|
62
|
-
// Helper function to load image as blob with fallback
|
|
63
|
-
const loadImageAsBlob = async (url) => {
|
|
64
|
-
try {
|
|
65
|
-
// Try direct fetch first (faster, no server load)
|
|
66
|
-
const response = await fetch(url, {
|
|
67
|
-
mode: 'cors',
|
|
68
|
-
credentials: 'omit'
|
|
69
|
-
});
|
|
70
|
-
if (!response.ok) {
|
|
71
|
-
throw new Error(`Direct fetch failed: ${response.statusText}`);
|
|
72
|
-
}
|
|
73
|
-
return response.blob();
|
|
74
|
-
}
|
|
75
|
-
catch (error) {
|
|
76
|
-
console.warn(`Direct fetch failed for ${url}, trying proxy fallback:`, error);
|
|
77
|
-
// Fallback to proxy API if CORS or other fetch issues
|
|
78
|
-
try {
|
|
79
|
-
const proxyUrl = `/api/image?imageUrl=${encodeURIComponent(url)}`;
|
|
80
|
-
const response = await fetch(proxyUrl);
|
|
81
|
-
if (!response.ok) {
|
|
82
|
-
throw new Error(`Proxy fetch failed: ${response.statusText}`);
|
|
83
|
-
}
|
|
84
|
-
return response.blob();
|
|
85
|
-
}
|
|
86
|
-
catch (proxyError) {
|
|
87
|
-
console.error(`Both direct and proxy fetch failed for ${url}:`, proxyError);
|
|
88
|
-
throw new Error(`Failed to load image: ${proxyError instanceof Error ? proxyError.message : 'Unknown error'}`);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
};
|
|
92
145
|
// Process single image task
|
|
93
146
|
const processImage = useCallback(async (task) => {
|
|
94
147
|
if (!editorRef.current || !isReady) {
|
|
@@ -96,20 +149,17 @@ export function useEditorHeadless() {
|
|
|
96
149
|
}
|
|
97
150
|
try {
|
|
98
151
|
console.debug(`Processing image: ${task.id}`);
|
|
99
|
-
// Load original image as
|
|
100
|
-
const
|
|
101
|
-
// Convert blob to File for HonchoEditor
|
|
102
|
-
const imageFile = new File([imageBlob], `image-${task.id}`, { type: imageBlob.type });
|
|
152
|
+
// Load original image as File using the new utility
|
|
153
|
+
const imageFile = await loadImageAsFile(task.path);
|
|
103
154
|
// Load frame if provided
|
|
104
155
|
let frameFile = null;
|
|
105
156
|
if (task.frame) {
|
|
106
|
-
|
|
107
|
-
frameFile = new File([frameBlob], `frame-${task.id}`, { type: frameBlob.type });
|
|
157
|
+
frameFile = await loadImageAsFile(task.frame);
|
|
108
158
|
}
|
|
109
159
|
// Process image using HonchoEditor's one-shot method
|
|
110
160
|
const processedImageData = await editorRef.current.processImageOneShot(imageFile, task.adjustments, frameFile);
|
|
111
161
|
// Convert ImageData to Blob
|
|
112
|
-
const processedBlob = await HonchoEditorUtils.imageDataToBlob(processedImageData);
|
|
162
|
+
const processedBlob = await window.HonchoEditorUtils.imageDataToBlob(processedImageData);
|
|
113
163
|
// Create blob URL for processed result
|
|
114
164
|
const blobUrl = URL.createObjectURL(processedBlob);
|
|
115
165
|
return { id: task.id, path: blobUrl };
|
|
@@ -118,11 +168,40 @@ export function useEditorHeadless() {
|
|
|
118
168
|
console.error(`Failed to process image ${task.id}:`, error);
|
|
119
169
|
throw new Error(`Failed to process image: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
120
170
|
}
|
|
121
|
-
}, [isReady
|
|
171
|
+
}, [isReady]);
|
|
172
|
+
// Helper function to load image from URL with CORS handling
|
|
173
|
+
const loadImageFromUrl = useCallback(async (url) => {
|
|
174
|
+
if (!editorRef.current || !isReady) {
|
|
175
|
+
throw new Error('Editor not ready');
|
|
176
|
+
}
|
|
177
|
+
try {
|
|
178
|
+
console.debug(`Loading image from URL: ${url}`);
|
|
179
|
+
// First try direct load with CORS
|
|
180
|
+
try {
|
|
181
|
+
const size = await editorRef.current.loadImageFromUrl(url);
|
|
182
|
+
console.debug('Image loaded successfully via direct URL');
|
|
183
|
+
return size;
|
|
184
|
+
}
|
|
185
|
+
catch (directError) {
|
|
186
|
+
console.warn('Direct URL load failed, trying blob approach:', directError);
|
|
187
|
+
// Fallback: Load as File using the new utility
|
|
188
|
+
const imageFile = await loadImageAsFile(url);
|
|
189
|
+
// Load via file method
|
|
190
|
+
const size = await editorRef.current.loadImageFromFile(imageFile);
|
|
191
|
+
console.debug('Image loaded successfully via file fallback');
|
|
192
|
+
return size;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
catch (error) {
|
|
196
|
+
console.error(`Failed to load image from URL ${url}:`, error);
|
|
197
|
+
throw new Error(`Failed to load image: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
198
|
+
}
|
|
199
|
+
}, [isReady]);
|
|
122
200
|
return {
|
|
123
201
|
editor: editorRef.current,
|
|
124
202
|
isReady,
|
|
125
203
|
error,
|
|
126
|
-
processImage
|
|
204
|
+
processImage,
|
|
205
|
+
loadImageFromUrl
|
|
127
206
|
};
|
|
128
207
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ColorAdjustment } from "../hooks/editor/type";
|
|
2
|
-
import { AdjustmentState } from "../hooks/editor/
|
|
2
|
+
import { AdjustmentState } from "../hooks/editor/type";
|
|
3
3
|
import { AdjustmentValues } from "../lib/editor/honcho-editor";
|
|
4
4
|
export declare function mapAdjustmentStateToAdjustmentEditor(state: AdjustmentState): AdjustmentValues;
|
|
5
5
|
export declare function mapColorAdjustmentToAdjustmentState(colors: ColorAdjustment): AdjustmentState;
|
|
6
|
+
export declare function mapAdjustmentStateToColorAdjustment(state: AdjustmentState): ColorAdjustment;
|
package/dist/utils/adjustment.js
CHANGED
|
@@ -30,3 +30,19 @@ export function mapColorAdjustmentToAdjustmentState(colors) {
|
|
|
30
30
|
sharpnessScore: colors.sharpness
|
|
31
31
|
};
|
|
32
32
|
}
|
|
33
|
+
export function mapAdjustmentStateToColorAdjustment(state) {
|
|
34
|
+
return {
|
|
35
|
+
temperature: state.tempScore,
|
|
36
|
+
tint: state.tintScore,
|
|
37
|
+
vibrance: state.vibranceScore,
|
|
38
|
+
saturation: state.saturationScore,
|
|
39
|
+
exposure: state.exposureScore,
|
|
40
|
+
contrast: state.contrastScore,
|
|
41
|
+
highlights: state.highlightsScore,
|
|
42
|
+
shadows: state.shadowsScore,
|
|
43
|
+
whites: state.whitesScore,
|
|
44
|
+
blacks: state.blacksScore,
|
|
45
|
+
clarity: state.clarityScore,
|
|
46
|
+
sharpness: state.sharpnessScore
|
|
47
|
+
};
|
|
48
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Image loading utilities with CORS handling and fallback mechanisms
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Load image as blob with CORS handling and proxy fallback
|
|
6
|
+
*/
|
|
7
|
+
export declare function loadImageAsBlob(url: string): Promise<Blob>;
|
|
8
|
+
/**
|
|
9
|
+
* Load image from URL and convert to File object with CORS handling and fallback mechanisms
|
|
10
|
+
*/
|
|
11
|
+
export declare function loadImageAsFile(url: string): Promise<File>;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Image loading utilities with CORS handling and fallback mechanisms
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Load image as blob with CORS handling and proxy fallback
|
|
6
|
+
*/
|
|
7
|
+
export async function loadImageAsBlob(url) {
|
|
8
|
+
try {
|
|
9
|
+
// Try direct fetch first (faster, no server load)
|
|
10
|
+
const response = await fetch(url, {
|
|
11
|
+
mode: 'cors',
|
|
12
|
+
credentials: 'omit'
|
|
13
|
+
});
|
|
14
|
+
if (!response.ok) {
|
|
15
|
+
throw new Error(`Direct fetch failed: ${response.statusText}`);
|
|
16
|
+
}
|
|
17
|
+
return response.blob();
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
console.warn(`Direct fetch failed for ${url}, trying proxy fallback:`, error);
|
|
21
|
+
// Fallback to proxy API if CORS or other fetch issues
|
|
22
|
+
try {
|
|
23
|
+
const proxyUrl = `/api/image?imageUrl=${encodeURIComponent(url)}`;
|
|
24
|
+
const response = await fetch(proxyUrl);
|
|
25
|
+
if (!response.ok) {
|
|
26
|
+
throw new Error(`Proxy fetch failed: ${response.statusText}`);
|
|
27
|
+
}
|
|
28
|
+
return response.blob();
|
|
29
|
+
}
|
|
30
|
+
catch (proxyError) {
|
|
31
|
+
console.error(`Both direct and proxy fetch failed for ${url}:`, proxyError);
|
|
32
|
+
throw new Error(`Failed to load image: ${proxyError instanceof Error ? proxyError.message : 'Unknown error'}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Load image from URL and convert to File object with CORS handling and fallback mechanisms
|
|
38
|
+
*/
|
|
39
|
+
export async function loadImageAsFile(url) {
|
|
40
|
+
try {
|
|
41
|
+
console.debug(`Loading image from URL: ${url}`);
|
|
42
|
+
// Load image as blob with CORS handling
|
|
43
|
+
const imageBlob = await loadImageAsBlob(url);
|
|
44
|
+
// Convert blob to File for HonchoEditor
|
|
45
|
+
const imageFile = new File([imageBlob], 'image', { type: imageBlob.type });
|
|
46
|
+
console.debug('Image loaded and converted to File successfully');
|
|
47
|
+
return imageFile;
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
console.error(`Failed to load image from URL ${url}:`, error);
|
|
51
|
+
throw new Error(`Failed to load image: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
52
|
+
}
|
|
53
|
+
}
|
package/package.json
CHANGED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import type { Gallery } from "../../../hooks/editor/type";
|
|
2
|
-
export interface PhotoData {
|
|
3
|
-
key: string;
|
|
4
|
-
src: string;
|
|
5
|
-
width: number;
|
|
6
|
-
height: number;
|
|
7
|
-
alt: string;
|
|
8
|
-
isSelected: boolean;
|
|
9
|
-
originalData: Gallery;
|
|
10
|
-
}
|
|
11
|
-
interface SimplifiedAlbumGalleryProps {
|
|
12
|
-
imageCollection: PhotoData[];
|
|
13
|
-
onToggleSelect: (photo: PhotoData) => void;
|
|
14
|
-
onPreview: (photo: PhotoData) => void;
|
|
15
|
-
}
|
|
16
|
-
export default function SimplifiedAlbumGallery({ imageCollection, onToggleSelect, onPreview }: SimplifiedAlbumGalleryProps): import("react/jsx-runtime").JSX.Element;
|
|
17
|
-
export {};
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { Box } from '@mui/material';
|
|
3
|
-
import SimplifiedImageItem from './SimplifiedImageItem'; // Import the child component
|
|
4
|
-
export default function SimplifiedAlbumGallery({ imageCollection, onToggleSelect, onPreview }) {
|
|
5
|
-
return (_jsx(Box, { sx: {
|
|
6
|
-
display: 'grid',
|
|
7
|
-
gridTemplateColumns: 'repeat(auto-fill, minmax(200px, 1fr))',
|
|
8
|
-
gap: '16px',
|
|
9
|
-
width: '100%',
|
|
10
|
-
height: '100%',
|
|
11
|
-
overflowY: 'auto',
|
|
12
|
-
p: 1
|
|
13
|
-
}, children: imageCollection.map(photo => (_jsx(SimplifiedImageItem, { photo: photo, onToggleSelect: onToggleSelect, onPreview: onPreview }, photo.key))) }));
|
|
14
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type { PhotoData } from './SimplifiedAlbumGallery';
|
|
2
|
-
interface SimplifiedImageItemProps {
|
|
3
|
-
photo: PhotoData;
|
|
4
|
-
onToggleSelect: (photo: PhotoData) => void;
|
|
5
|
-
onPreview: (photo: PhotoData) => void;
|
|
6
|
-
}
|
|
7
|
-
export default function SimplifiedImageItem({ photo, onToggleSelect, onPreview }: SimplifiedImageItemProps): import("react/jsx-runtime").JSX.Element;
|
|
8
|
-
export {};
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useState } from 'react';
|
|
3
|
-
import { Box } from '@mui/material';
|
|
4
|
-
import CheckCircleIcon from '@mui/icons-material/CheckCircle';
|
|
5
|
-
import RadioButtonUncheckedIcon from '@mui/icons-material/RadioButtonUnchecked';
|
|
6
|
-
export default function SimplifiedImageItem({ photo, onToggleSelect, onPreview }) {
|
|
7
|
-
const [isHovered, setIsHovered] = useState(false);
|
|
8
|
-
return (_jsxs(Box, { onClick: () => onPreview(photo), onMouseEnter: () => setIsHovered(true), onMouseLeave: () => setIsHovered(false), sx: {
|
|
9
|
-
position: 'relative',
|
|
10
|
-
cursor: 'pointer',
|
|
11
|
-
overflow: 'hidden',
|
|
12
|
-
borderRadius: '8px',
|
|
13
|
-
'& img': {
|
|
14
|
-
display: 'block',
|
|
15
|
-
width: '100%',
|
|
16
|
-
transition: 'transform 0.2s ease-in-out',
|
|
17
|
-
transform: isHovered ? 'scale(1.05)' : 'scale(1)',
|
|
18
|
-
},
|
|
19
|
-
}, children: [_jsx("img", { src: photo.src, alt: photo.alt, style: { aspectRatio: `${photo.width} / ${photo.height}` } }), _jsx(Box, { onClick: (e) => {
|
|
20
|
-
e.stopPropagation(); // Prevent onPreview from firing when clicking checkbox
|
|
21
|
-
onToggleSelect(photo);
|
|
22
|
-
}, sx: {
|
|
23
|
-
position: 'absolute',
|
|
24
|
-
top: '8px',
|
|
25
|
-
left: '8px',
|
|
26
|
-
color: 'white',
|
|
27
|
-
opacity: photo.isSelected || isHovered ? 1 : 0,
|
|
28
|
-
transition: 'opacity 0.2s ease-in-out',
|
|
29
|
-
}, children: photo.isSelected ? (_jsx(CheckCircleIcon, { sx: { fontSize: '28px', background: 'rgba(0,0,0,0.3)', borderRadius: '50%' } })) : (_jsx(RadioButtonUncheckedIcon, { sx: { fontSize: '28px', background: 'rgba(0,0,0,0.3)', borderRadius: '50%' } })) })] }));
|
|
30
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export default function HImageEditorPage(): import("react/jsx-runtime").JSX.Element;
|