@yogiswara/honcho-editor-ui 2.5.10 → 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 +10 -12
  10. package/dist/hooks/editor/useHonchoEditorBulk.js +126 -10
  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 +1 -1
  19. package/dist/hooks/usePaging.js +1 -1
  20. package/dist/hooks/usePreset.d.ts +1 -1
  21. package/dist/hooks/usePreset.js +35 -35
  22. package/dist/index.d.ts +3 -3
  23. package/dist/index.js +1 -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
@@ -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,6 +1,6 @@
1
1
  {
2
2
  "name": "@yogiswara/honcho-editor-ui",
3
- "version": "2.5.10",
3
+ "version": "2.6.0",
4
4
  "description": "A complete UI component library for the Honcho photo editor.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -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;
@@ -1,187 +0,0 @@
1
- 'use client';
2
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
- import { useState, useMemo, Suspense } from "react";
4
- import { Box, Stack, CircularProgress, Typography, Checkbox, Paper } from "@mui/material";
5
- import useColors from '../../themes/colors';
6
- import AutoFixHighIcon from '@mui/icons-material/AutoFixHigh'; // Magic Wand Icon
7
- import Script from "next/script";
8
- import useIsMobile from "../../utils/isMobile";
9
- // Components
10
- import HHeaderEditor from "./HHeaderEditor";
11
- import HAccordionColorAdjustment from "./HAccordionColorAdjustment";
12
- import HAccordionPreset from "./HAccordionPreset";
13
- import { HBaseDialog } from "./HDialogBox";
14
- import { HDialogCopy, HDialogPreset } from "./HDialogCopy";
15
- import HImageEditorMobile from "./HImageEditorMobile";
16
- import HImageEditorDesktop from "./HImageEditorDekstop";
17
- import HImageEditorBulkDekstop from "./HImageEditorBulkDekstop";
18
- import HImageEditorBulkMobile from "./HImageEditorBulkMobile";
19
- import HBulkAccordionColorAdjustment from "./HBulkAccordionColorAdjustment";
20
- import HBulkPreset from "./HBulkPreset";
21
- import HModalEditorDekstop from "./HModalEditorDekstop";
22
- import HFooter from "./HFooter";
23
- import { HTextField } from "./HTextField";
24
- import HWatermarkView from "./HWatermarkView";
25
- import HModalMobile from "./HModalMobile";
26
- import HPresetOptionsMenu from "./HPresetOptionMenu";
27
- import { HAlertInternetBox, HAlertCopyBox, HAlertInternetConnectionBox } from "./HAlertBox";
28
- // Hooks
29
- import { useHonchoEditor } from "../../hooks/editor/useHonchoEditor";
30
- const initialAdjustments = {
31
- tempScore: 0, tintScore: 0, vibranceScore: 0, exposureScore: 0, highlightsScore: 0, shadowsScore: 0,
32
- whitesScore: 0, blacksScore: 0, saturationScore: 0, contrastScore: 0, clarityScore: 0, sharpnessScore: 0,
33
- };
34
- // Helper to check if an image has any edits
35
- const hasAdjustments = (state) => {
36
- if (!state)
37
- return false;
38
- return Object.values(state).some(value => value !== 0);
39
- };
40
- function HImageEditorClient() {
41
- const localController = useMemo(() => ({
42
- /**
43
- * The handleBack logic is now defined directly inside the page component.
44
- */
45
- handleBack: function () {
46
- if (window.webkit?.messageHandlers?.nativeHandler) {
47
- window.webkit.messageHandlers.nativeHandler.postMessage("back");
48
- console.log("Sent 'back' message to iOS native handler.");
49
- }
50
- else if (window.Android?.goBack) {
51
- console.log("Android environment detected. Calling goBack().");
52
- window.Android.goBack();
53
- }
54
- else {
55
- console.log("Standard web browser detected. Navigating back in history.");
56
- window.history.back();
57
- }
58
- },
59
- // --- Provide placeholder implementations for other required methods ---
60
- // These are necessary to satisfy the Controller interface contract.
61
- onGetImage: async (imageID) => {
62
- console.log("onGetImage called with:", imageID);
63
- // Return a placeholder or the actual web implementation
64
- const imageUrl = `https://d2cxumz3vt1s04.cloudfront.net/staging/gallery-photo/67ee6b55b8e4273707f68978/preview/${imageID}.jpeg`;
65
- return imageUrl;
66
- },
67
- getImageList: async () => { return []; },
68
- syncConfig: async () => { },
69
- getPresets: async () => { return []; },
70
- createPreset: async () => { return null; },
71
- deletePreset: async () => { },
72
- renamePreset: async () => { },
73
- }), []);
74
- const editor = useHonchoEditor(localController);
75
- const isMobile = useIsMobile();
76
- const colors = useColors();
77
- const [displayedToken, setDisplayedToken] = useState(null);
78
- const [displayedImageId, setDisplayedImageId] = useState(null);
79
- // Dummy/placeholder handlers that remain in the component
80
- const handleScale = (event) => editor.setAnchorMenuZoom(event.currentTarget);
81
- const handleBeforeAfter = () => console.log("Before/After toggled!");
82
- // const handleZoomMenuClose = () => editor.setAnchorMenuZoom(null);
83
- // const handleZoomAction = (level: string) => { console.log(`Zoom: ${level}`); handleZoomMenuClose(); };
84
- const renderActivePanelBulk = () => {
85
- // MARK: Dekstop Bulk Editor panels
86
- switch (editor.activePanel) {
87
- case 'colorAdjustment':
88
- return (_jsx(HBulkAccordionColorAdjustment
89
- // Adjustments Colors
90
- , {
91
- // Adjustments Colors
92
- onTempDecreaseMax: editor.handleBulkTempDecreaseMax, onTempDecrease: editor.handleBulkTempDecrease, onTempIncrease: editor.handleBulkTempIncrease, onTempIncreaseMax: editor.handleBulkTempIncreaseMax, onTintDecreaseMax: editor.handleBulkTintDecreaseMax, onTintDecrease: editor.handleBulkTintDecrease, onTintIncrease: editor.handleBulkTintIncrease, onTintIncreaseMax: editor.handleBulkTintIncreaseMax, onVibranceDecreaseMax: editor.handleBulkVibranceDecreaseMax, onVibranceDecrease: editor.handleBulkVibranceDecrease, onVibranceIncrease: editor.handleBulkVibranceIncrease, onVibranceIncreaseMax: editor.handleBulkVibranceIncreaseMax, onSaturationDecreaseMax: editor.handleBulkSaturationDecreaseMax, onSaturationDecrease: editor.handleBulkSaturationDecrease, onSaturationIncrease: editor.handleBulkSaturationIncrease, onSaturationIncreaseMax: editor.handleBulkSaturationIncreaseMax,
93
- // Adjustments Light
94
- onExposureDecreaseMax: editor.handleBulkExposureDecreaseMax, onExposureDecrease: editor.handleBulkExposureDecrease, onExposureIncrease: editor.handleBulkExposureIncrease, onExposureIncreaseMax: editor.handleBulkExposureIncreaseMax, onContrastDecreaseMax: editor.handleBulkContrastDecreaseMax, onContrastDecrease: editor.handleBulkContrastDecrease, onContrastIncrease: editor.handleBulkContrastIncrease, onContrastIncreaseMax: editor.handleBulkContrastIncreaseMax, onHighlightsDecreaseMax: editor.handleBulkHighlightsDecreaseMax, onHighlightsDecrease: editor.handleBulkHighlightsDecrease, onHighlightsIncrease: editor.handleBulkHighlightsIncrease, onHighlightsIncreaseMax: editor.handleBulkHighlightsIncreaseMax, onShadowsDecreaseMax: editor.handleBulkShadowsDecreaseMax, onShadowsDecrease: editor.handleBulkShadowsDecrease, onShadowsIncrease: editor.handleBulkShadowsIncrease, onShadowsIncreaseMax: editor.handleBulkShadowsIncreaseMax, onWhitesDecreaseMax: editor.handleBulkWhitesDecreaseMax, onWhitesDecrease: editor.handleBulkWhitesDecrease, onWhitesIncrease: editor.handleBulkWhitesIncrease, onWhitesIncreaseMax: editor.handleBulkWhitesIncreaseMax, onBlacksDecreaseMax: editor.handleBulkBlacksDecreaseMax, onBlacksDecrease: editor.handleBulkBlacksDecrease, onBlacksIncrease: editor.handleBulkBlacksIncrease, onBlacksIncreaseMax: editor.handleBulkBlacksIncreaseMax,
95
- // Adjustments Details
96
- onClarityDecreaseMax: editor.handleBulkClarityDecreaseMax, onClarityDecrease: editor.handleBulkClarityDecrease, onClarityIncrease: editor.handleBulkClarityIncrease, onClarityIncreaseMax: editor.handleBulkClarityIncreaseMax, onSharpnessDecreaseMax: editor.handleBulkSharpnessDecreaseMax, onSharpnessDecrease: editor.handleBulkSharpnessDecrease, onSharpnessIncrease: editor.handleBulkSharpnessIncrease, onSharpnessIncreaseMax: editor.handleBulkSharpnessIncreaseMax,
97
- // Panels Management
98
- expandedPanels: editor.colorAdjustmentExpandedPanels, onPanelChange: editor.handleColorAccordionChange }));
99
- case 'preset':
100
- return (_jsx(HBulkPreset, { presets: editor.presets, selectedPreset: editor.selectedBulkPreset, onSelectPreset: editor.handleSelectBulkPreset, expandedPanels: editor.presetExpandedPanels, onPanelChange: editor.handlePresetAccordionChange, presetMenuAnchorEl: editor.presetMenuAnchorEl, activePresetMenuId: editor.activePresetMenuId, isMenuOpen: Boolean(editor.presetMenuAnchorEl), onPresetMenuClick: editor.handlePresetMenuClick, onPresetMenuClose: editor.handlePresetMenuClose, onRemovePreset: editor.handleRemovePreset, onRenamePreset: editor.handleOpenRenameModal, onDeletePreset: editor.handleDeletePreset, onOpenPresetModal: editor.handleOpenPresetModal }));
101
- default: return null;
102
- }
103
- };
104
- const renderActivePanel = () => {
105
- // MARK: Dekstop Editor panels
106
- switch (editor.activePanel) {
107
- case 'colorAdjustment':
108
- return (_jsx(HAccordionColorAdjustment, { tempScore: editor.tempScore, setTempScore: editor.setTempScore, tintScore: editor.tintScore, setTintScore: editor.setTintScore, vibranceScore: editor.vibranceScore, setVibranceScore: editor.setVibranceScore, saturationScore: editor.saturationScore, setSaturationScore: editor.setSaturationScore, exposureScore: editor.exposureScore, setExposureScore: editor.setExposureScore, HighlightsScore: editor.highlightsScore, setHighlightsScore: editor.setHighlightsScore, shadowsScore: editor.shadowsScore, setShadowsScore: editor.setShadowsScore, whitesScore: editor.whitesScore, setWhitesScore: editor.setWhitesScore, blacksScore: editor.blacksScore, setBlacksScore: editor.setBlacksScore, contrastScore: editor.contrastScore, setContrastScore: editor.setContrastScore, clarityScore: editor.clarityScore, setClarityScore: editor.setClarityScore, sharpnessScore: editor.sharpnessScore, setSharpnessScore: editor.setSharpnessScore, expandedPanels: editor.colorAdjustmentExpandedPanels, onPanelChange: editor.handleColorAccordionChange }));
109
- case 'preset':
110
- return (_jsx(HAccordionPreset, { presets: editor.presets, expandedPanels: editor.presetExpandedPanels, onChange: editor.handlePresetAccordionChange, onOpenPresetModal: editor.handleOpenPresetModal, onOpenWatermarkView: editor.handleOpenWatermarkView, selectedPreset: editor.selectedDesktopPreset, onSelectPreset: editor.handleSelectDesktopPreset, presetMenuAnchorEl: editor.presetMenuAnchorEl, onPresetMenuClick: editor.handlePresetMenuClick, onPresetMenuClose: editor.handlePresetMenuClose, activePresetMenuId: editor.activePresetMenuId, onRemovePreset: editor.handleRemovePreset, onRenamePreset: editor.handleOpenRenameModal, onDeletePreset: editor.handleDeletePreset }));
111
- default: return null;
112
- }
113
- };
114
- if (editor.isCreatingWatermark) {
115
- return (_jsx(HWatermarkView, { onSaveWatermark: editor.handleSaveWatermark, onCancelWatermark: editor.handleCancelWatermark }));
116
- }
117
- return (_jsxs(_Fragment, { children: [_jsx(Script, { src: "/honcho-photo-editor.js", strategy: "lazyOnload", onReady: () => {
118
- editor.handleScriptReady();
119
- } }), _jsxs(Stack, { direction: "column", justifyContent: "center", sx: { width: '100%', height: isMobile ? '100%' : '100vh', background: 'black', pl: isMobile ? 0 : "24px", pr: isMobile ? 0 : "0px" }, children: [editor.isConnectionSlow && _jsx(HAlertInternetConnectionBox, { onClose: editor.handleAlertClose }), !editor.isOnline && _jsx(HAlertInternetBox, {}), editor.isPresetCreated && !isMobile && _jsx(HAlertInternetBox, {}), editor.showCopyAlert && _jsx(HAlertCopyBox, {}), displayedToken && (_jsx(Box, { sx: { p: 1, mx: 2, backgroundColor: 'grey.900', borderRadius: 1, mt: 1 }, children: _jsxs(Typography, { variant: "caption", sx: { color: 'lime', fontFamily: 'monospace', wordBreak: 'break-all' }, children: [_jsx("strong", { children: "Token Received:" }), " ", displayedToken] }) })), displayedImageId && (_jsx(Box, { sx: { p: 1, mx: 2, backgroundColor: 'grey.900', borderRadius: 1, mt: 1 }, children: _jsxs(Typography, { variant: "caption", sx: { color: 'white', fontFamily: 'monospace', wordBreak: 'break-all' }, children: [_jsx("strong", { children: "Image ID:" }), " ", displayedImageId] }) })), _jsx(HHeaderEditor, { onBack: editor.handleBack, onUndo: editor.handleUndo, onRedo: editor.handleRedo, onRevert: editor.handleRevert, onCopyEdit: editor.handleOpenCopyDialog, onPasteEdit: editor.handlePasteEdit, isPasteEnabled: editor.isPasteAvailable, anchorEl: editor.headerMenuAnchorEl, onMenuClick: editor.handleHeaderMenuClick, onMenuClose: editor.handleHeaderMenuClose, onSelectButton: editor.toggleBulkEditing, valueSelect: editor.selectedImages }), _jsxs(Stack, { direction: isMobile ? "column" : "row", justifyContent: "space-between", alignItems: "stretch", sx: { width: '100%', flexGrow: 1, overflow: 'hidden' }, children: [_jsxs(Box, { sx: {
120
- flexGrow: 1,
121
- display: 'flex',
122
- justifyContent: 'center',
123
- alignItems: 'center', // This will now work correctly on mobile
124
- position: 'relative',
125
- p: isMobile ? 2 : 4,
126
- minHeight: 720
127
- }, children: [_jsx("input", { type: "file", ref: editor.fileInputRef, onChange: editor.handleFileChange, multiple: true, accept: "image/*", style: { display: 'none' } }), !editor.isImageLoaded ? (_jsxs(Box, { onClick: () => editor.fileInputRef.current?.click(), sx: { display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', border: '2px dashed grey', borderRadius: 2, p: 4, cursor: editor.isEditorReady ? 'pointer' : 'default', textAlign: 'center', color: 'grey.500', width: '100%', height: '300px' }, children: [!editor.isEditorReady && _jsx(CircularProgress, { color: "inherit", sx: { mb: 2 } }), _jsx(Typography, { variant: "h6", children: editor.editorStatus })] })) : (editor.isBulkEditing ? (
128
- // Responsive Image Grid for Bulk Edit
129
- _jsx(Box, { sx: {
130
- display: 'grid',
131
- gridTemplateColumns: 'repeat(auto-fill, minmax(250px, 1fr))',
132
- gap: 2,
133
- width: '100%',
134
- height: '100%',
135
- p: 1
136
- }, children: editor.imageList.map(image => {
137
- const imageAdjustments = editor.adjustmentsMap.get(image.id) || initialAdjustments;
138
- const isEdited = hasAdjustments(imageAdjustments);
139
- return (_jsxs(Paper, { elevation: 3, sx: {
140
- position: 'relative',
141
- overflow: 'hidden',
142
- aspectRatio: '1 / 1',
143
- '& img': {
144
- width: '100%',
145
- height: '100%',
146
- objectFit: 'cover',
147
- display: 'block',
148
- transition: 'opacity 0.2s ease-in-out',
149
- opacity: editor.selectedImageIds.has(image.id) ? 1 : 0.4,
150
- }
151
- }, children: [_jsx("img", { src: image.url, alt: image.name }), _jsx(Checkbox, { checked: editor.selectedImageIds.has(image.id), onChange: () => editor.handleToggleImageSelection(image.id), sx: {
152
- position: 'absolute', top: 4, left: 4, color: 'common.white',
153
- '&.Mui-checked': { color: '#1976d2' },
154
- backgroundColor: 'rgba(0, 0, 0, 0.5)',
155
- '&:hover': { backgroundColor: 'rgba(0, 0, 0, 0.7)' }
156
- } }), isEdited && (_jsx(AutoFixHighIcon, { fontSize: "small", sx: {
157
- position: 'absolute',
158
- bottom: 8,
159
- right: 8,
160
- color: 'white',
161
- backgroundColor: 'rgba(0, 0, 0, 0.5)',
162
- borderRadius: '50%',
163
- padding: '2px'
164
- } }))] }, image.id));
165
- }) })) : (
166
- // Canvas for Single Edit
167
- _jsx("canvas", { ref: editor.canvasRef, style: { display: 'block', maxWidth: '100%', maxHeight: '100%', width: 'auto', height: 'auto' } })))] }), !isMobile && !editor.isBulkEditing && (_jsx(HImageEditorDesktop, { activePanel: editor.activePanel, setActivePanel: editor.setActivePanel, onScale: handleScale, onBeforeAfter: handleBeforeAfter, isPanelOpen: !isMobile, anchorElZoom: editor.anchorMenuZoom, onZoomMenuClose: () => editor.setAnchorMenuZoom(null), onZoomAction: editor.handleZoomAction, footer: _jsx(HFooter, { anchorElZoom: editor.anchorMenuZoom, onScale: (event) => editor.setAnchorMenuZoom(event.currentTarget), onShowOriginal: editor.handleShowOriginal, onShowEdited: editor.handleShowEdited, onZoomMenuClose: () => editor.setAnchorMenuZoom(null), onZoomAction: editor.handleZoomAction, zoomLevelText: editor.zoomLevelText }), children: renderActivePanel() })), !isMobile && editor.isBulkEditing && (_jsx(HImageEditorBulkDekstop, { activePanel: editor.activePanel, setActivePanel: editor.setActivePanel, onScale: handleScale, onBeforeAfter: handleBeforeAfter, isPanelOpen: !isMobile, anchorElZoom: editor.anchorMenuZoom, onZoomMenuClose: () => editor.setAnchorMenuZoom(null), onZoomAction: editor.handleZoomAction, footer: _jsx(HFooter, { anchorElZoom: editor.anchorMenuZoom, onScale: (event) => editor.setAnchorMenuZoom(event.currentTarget), onShowOriginal: editor.handleShowOriginal, onShowEdited: editor.handleShowEdited, onZoomMenuClose: () => editor.setAnchorMenuZoom(null), onZoomAction: editor.handleZoomAction, zoomLevelText: editor.zoomLevelText }), children: renderActivePanelBulk() })), isMobile && !editor.isBulkEditing && (_jsx(HImageEditorMobile, { presets: editor.presets, contentRef: editor.contentRef, panelRef: editor.panelRef, panelHeight: editor.panelHeight, handleDragStart: editor.handleDragStart, onContentHeightChange: editor.handleContentHeightChange, activePanel: editor.activePanel, setActivePanel: (panel) => { editor.setActivePanel(panel); editor.setActiveSubPanel(''); }, activeSubPanel: editor.activeSubPanel, setActiveSubPanel: editor.setActiveSubPanel,
168
- // Color Adjustments
169
- tempScore: editor.tempScore, onTempChange: editor.setTempScore, tintScore: editor.tintScore, onTintChange: editor.setTintScore, vibranceScore: editor.vibranceScore, onVibranceChange: editor.setVibranceScore, saturationScore: editor.saturationScore, onSaturationChange: editor.setSaturationScore,
170
- // Adjustments Light
171
- exposureScore: editor.exposureScore, onExposureChange: editor.setExposureScore, contrastScore: editor.contrastScore, onContrastChange: editor.setContrastScore, highlightsScore: editor.highlightsScore, onHighlightsChange: editor.setHighlightsScore, shadowScore: editor.shadowsScore, onShadowsChange: editor.setShadowsScore, whiteScore: editor.whitesScore, onWhitesChange: editor.setWhitesScore, blackScore: editor.blacksScore, onBlacksChange: editor.setBlacksScore,
172
- // Adjustments Details
173
- clarityScore: editor.clarityScore, onClarityChange: editor.setClarityScore, sharpnessScore: editor.sharpnessScore, onSharpnessChange: editor.setSharpnessScore,
174
- // Modal Management
175
- onOpenPresetModal: editor.handleOpenPresetModalMobile, presetOptionModal: editor.handlePresetMenuClick, selectedPreset: editor.selectedMobilePreset, onSelectPreset: editor.handleSelectMobilePreset })), isMobile && editor.isBulkEditing && (_jsx(HImageEditorBulkMobile, { presets: editor.presets, contentRef: editor.contentRef, panelRef: editor.panelRef, panelHeight: editor.panelHeight, handleDragStart: editor.handleDragStart, onContentHeightChange: editor.handleContentHeightChange, activePanel: editor.activePanel, setActivePanel: (panel) => { editor.setActivePanel(panel); editor.setActiveSubPanel(''); }, activeSubPanel: editor.activeSubPanel, setActiveSubPanel: editor.setActiveSubPanel,
176
- // Color Adjustments
177
- onTempDecreaseMax: editor.handleBulkTempDecreaseMax, onTempDecrease: editor.handleBulkTempDecrease, onTempIncrease: editor.handleBulkTempIncrease, onTempIncreaseMax: editor.handleBulkTempIncreaseMax, onTintDecreaseMax: editor.handleBulkTintDecreaseMax, onTintDecrease: editor.handleBulkTintDecrease, onTintIncrease: editor.handleBulkTintIncrease, onTintIncreaseMax: editor.handleBulkTintIncreaseMax, onVibranceDecreaseMax: editor.handleBulkVibranceDecreaseMax, onVibranceDecrease: editor.handleBulkVibranceDecrease, onVibranceIncrease: editor.handleBulkVibranceIncrease, onVibranceIncreaseMax: editor.handleBulkVibranceIncreaseMax, onSaturationDecreaseMax: editor.handleBulkSaturationDecreaseMax, onSaturationDecrease: editor.handleBulkSaturationDecrease, onSaturationIncrease: editor.handleBulkSaturationIncrease, onSaturationIncreaseMax: editor.handleBulkSaturationIncreaseMax,
178
- // Adjustments Light
179
- onExposureDecreaseMax: editor.handleBulkExposureDecreaseMax, onExposureDecrease: editor.handleBulkExposureDecrease, onExposureIncrease: editor.handleBulkExposureIncrease, onExposureIncreaseMax: editor.handleBulkExposureIncreaseMax, onContrastDecreaseMax: editor.handleBulkContrastDecreaseMax, onContrastDecrease: editor.handleBulkContrastDecrease, onContrastIncrease: editor.handleBulkContrastIncrease, onContrastIncreaseMax: editor.handleBulkContrastIncreaseMax, onHighlightsDecreaseMax: editor.handleBulkHighlightsDecreaseMax, onHighlightsDecrease: editor.handleBulkHighlightsDecrease, onHighlightsIncrease: editor.handleBulkHighlightsIncrease, onHighlightsIncreaseMax: editor.handleBulkHighlightsIncreaseMax, onShadowsDecreaseMax: editor.handleBulkShadowsDecreaseMax, onShadowsDecrease: editor.handleBulkShadowsDecrease, onShadowsIncrease: editor.handleBulkShadowsIncrease, onShadowsIncreaseMax: editor.handleBulkShadowsIncreaseMax, onWhitesDecreaseMax: editor.handleBulkWhitesDecreaseMax, onWhitesDecrease: editor.handleBulkWhitesDecrease, onWhitesIncrease: editor.handleBulkWhitesIncrease, onWhitesIncreaseMax: editor.handleBulkWhitesIncreaseMax, onBlacksDecreaseMax: editor.handleBulkBlacksDecreaseMax, onBlacksDecrease: editor.handleBulkBlacksDecrease, onBlacksIncrease: editor.handleBulkBlacksIncrease, onBlacksIncreaseMax: editor.handleBulkBlacksIncreaseMax,
180
- // Adjustments Details
181
- onClarityDecreaseMax: editor.handleBulkClarityDecreaseMax, onClarityDecrease: editor.handleBulkClarityDecrease, onClarityIncrease: editor.handleBulkClarityIncrease, onClarityIncreaseMax: editor.handleBulkClarityIncreaseMax, onSharpnessDecreaseMax: editor.handleBulkSharpnessDecreaseMax, onSharpnessDecrease: editor.handleBulkSharpnessDecrease, onSharpnessIncrease: editor.handleBulkSharpnessIncrease, onSharpnessIncreaseMax: editor.handleBulkSharpnessIncreaseMax, selectedPresetBulk: editor.selectedBulkPreset, onOpenPresetModalBulk: editor.handleOpenPresetModalMobile, onSelectPresetBulk: editor.handleSelectBulkPreset, onPresetMenuClickBulk: editor.handlePresetMenuClick })), _jsx(HPresetOptionsMenu, { anchorEl: editor.presetMenuAnchorEl, isOpen: Boolean(editor.presetMenuAnchorEl), onClose: editor.handlePresetMenuClose, onRemove: editor.handleRemovePreset, onRename: editor.handleOpenRenameModal, onDelete: editor.handleDeletePreset, isPresetSelected: (editor.isBulkEditing ? editor.selectedBulkPreset : editor.selectedDesktopPreset) === editor.activePresetMenuId }), _jsx(HModalEditorDekstop, { modalName: "preset", modalOpen: editor.isPresetModalOpen, modalTitle: "Create Preset", modalInformation: "Choose settings to include in preset", action: _jsx(HDialogPreset, { colorChecks: editor.copyColorChecks, lightChecks: editor.copyLightChecks, detailsChecks: editor.copyDetailsChecks, setColorChecks: editor.setCopyColorChecks, setLightChecks: editor.setCopyLightChecks, setDetailsChecks: editor.setCopyDetailsChecks, expanded: editor.copyDialogExpanded, onParentChange: editor.handleCopyParentChange, onChildChange: editor.handleCopyChildChange, onToggleExpand: editor.handleToggleCopyDialogExpand }), modalClose: editor.handleClosePresetModal, onConfirm: editor.handleCreatePreset, children: _jsx(HTextField, { valueName: editor.presetName, setName: editor.handleNameChange }) }), _jsx(HModalMobile, { modalName: "preset", modalOpen: editor.isPresetModalOpenMobile, modalTitle: "Create Preset", modalInformation: "Create a preset with the current Light, Colour and Details settings", modalClose: editor.handleClosePresetModalMobile, onConfirm: editor.handleCreatePresetMobile, children: _jsx(HTextField, { valueName: editor.presetName, setName: editor.handleNameChange }) })] })] }), editor.isCopyDialogOpen && (_jsx(HBaseDialog, { open: editor.isCopyDialogOpen, title: "Copy Edits", onClose: editor.handleCloseCopyDialog, action: _jsx(HDialogCopy, { onCopyEdit: editor.handleConfirmCopy, colorChecks: editor.copyColorChecks, lightChecks: editor.copyLightChecks, detailsChecks: editor.copyDetailsChecks, setColorChecks: editor.setCopyColorChecks, setLightChecks: editor.setCopyLightChecks, setDetailsChecks: editor.setCopyDetailsChecks, expanded: editor.copyDialogExpanded, onParentChange: editor.handleCopyParentChange, onChildChange: editor.handleCopyChildChange, onToggleExpand: editor.handleToggleCopyDialogExpand }) }))] }));
182
- }
183
- export default function HImageEditorPage() {
184
- const colors = useColors();
185
- const fallbackUI = (_jsx(Stack, { sx: { width: '100%', height: '100vh', alignItems: 'center', justifyContent: 'center', background: 'black' }, children: _jsx(CircularProgress, { sx: { color: colors.onSurfaceVariant } }) }));
186
- return (_jsx(Suspense, { fallback: fallbackUI, children: _jsx(HImageEditorClient, {}) }));
187
- }
File without changes