@yogiswara/honcho-editor-ui 2.7.13 → 2.7.14
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/package.json +1 -1
- package/dist/color.d.ts +0 -9
- package/dist/color.js +0 -9
- package/dist/components/editor/GalleryAlbum/AlbumImageGallery.d.ts +0 -8
- package/dist/components/editor/GalleryAlbum/AlbumImageGallery.js +0 -28
- package/dist/components/editor/GalleryAlbum/ImageItem.d.ts +0 -10
- package/dist/components/editor/GalleryAlbum/ImageItem.js +0 -81
- package/dist/components/editor/HAccordionAspectRatio.d.ts +0 -14
- package/dist/components/editor/HAccordionAspectRatio.js +0 -102
- package/dist/components/editor/HAccordionColor.d.ts +0 -16
- package/dist/components/editor/HAccordionColor.js +0 -282
- package/dist/components/editor/HAccordionColorAdjustment.d.ts +0 -35
- package/dist/components/editor/HAccordionColorAdjustment.js +0 -31
- package/dist/components/editor/HAccordionDetails.d.ts +0 -12
- package/dist/components/editor/HAccordionDetails.js +0 -157
- package/dist/components/editor/HAccordionLight.d.ts +0 -20
- package/dist/components/editor/HAccordionLight.js +0 -414
- package/dist/components/editor/HAccordionPreset.d.ts +0 -23
- package/dist/components/editor/HAccordionPreset.js +0 -50
- package/dist/components/editor/HAlertBox.d.ts +0 -8
- package/dist/components/editor/HAlertBox.js +0 -55
- package/dist/components/editor/HAspectRatioMobile.d.ts +0 -0
- package/dist/components/editor/HAspectRatioMobile.js +0 -1
- package/dist/components/editor/HBulkAccordionColorAdjustment.d.ts +0 -55
- package/dist/components/editor/HBulkAccordionColorAdjustment.js +0 -31
- package/dist/components/editor/HBulkAccordionColorAdjustmentColors.d.ts +0 -20
- package/dist/components/editor/HBulkAccordionColorAdjustmentColors.js +0 -121
- package/dist/components/editor/HBulkAccordionColorAdjustmentDetails.d.ts +0 -12
- package/dist/components/editor/HBulkAccordionColorAdjustmentDetails.js +0 -65
- package/dist/components/editor/HBulkAccordionColorAdjustmentLight.d.ts +0 -28
- package/dist/components/editor/HBulkAccordionColorAdjustmentLight.js +0 -177
- package/dist/components/editor/HBulkColorAdjustmentMobile.d.ts +0 -53
- package/dist/components/editor/HBulkColorAdjustmentMobile.js +0 -16
- package/dist/components/editor/HBulkColorMobile.d.ts +0 -20
- package/dist/components/editor/HBulkColorMobile.js +0 -121
- package/dist/components/editor/HBulkDetailsMobile.d.ts +0 -12
- package/dist/components/editor/HBulkDetailsMobile.js +0 -65
- package/dist/components/editor/HBulkLightMobile.d.ts +0 -28
- package/dist/components/editor/HBulkLightMobile.js +0 -192
- package/dist/components/editor/HBulkPreset.d.ts +0 -24
- package/dist/components/editor/HBulkPreset.js +0 -43
- package/dist/components/editor/HBulkPresetMobile.d.ts +0 -15
- package/dist/components/editor/HBulkPresetMobile.js +0 -26
- package/dist/components/editor/HDialogBox.d.ts +0 -18
- package/dist/components/editor/HDialogBox.js +0 -51
- package/dist/components/editor/HDialogCopy.d.ts +0 -40
- package/dist/components/editor/HDialogCopy.js +0 -80
- package/dist/components/editor/HFooter.d.ts +0 -12
- package/dist/components/editor/HFooter.js +0 -24
- package/dist/components/editor/HHeaderEditor.d.ts +0 -17
- package/dist/components/editor/HHeaderEditor.js +0 -36
- package/dist/components/editor/HImageEditorBulkDekstop.d.ts +0 -15
- package/dist/components/editor/HImageEditorBulkDekstop.js +0 -29
- package/dist/components/editor/HImageEditorBulkMobile.d.ts +0 -72
- package/dist/components/editor/HImageEditorBulkMobile.js +0 -81
- package/dist/components/editor/HImageEditorDekstop.d.ts +0 -15
- package/dist/components/editor/HImageEditorDekstop.js +0 -29
- package/dist/components/editor/HImageEditorMobile.d.ts +0 -51
- package/dist/components/editor/HImageEditorMobile.js +0 -92
- package/dist/components/editor/HImageEditorMobileLayout.d.ts +0 -14
- package/dist/components/editor/HImageEditorMobileLayout.js +0 -58
- package/dist/components/editor/HModalEditorDekstop.d.ts +0 -13
- package/dist/components/editor/HModalEditorDekstop.js +0 -22
- package/dist/components/editor/HModalMobile.d.ts +0 -13
- package/dist/components/editor/HModalMobile.js +0 -7
- package/dist/components/editor/HPresetDelete.d.ts +0 -7
- package/dist/components/editor/HPresetDelete.js +0 -7
- package/dist/components/editor/HPresetOptionMenu.d.ts +0 -9
- package/dist/components/editor/HPresetOptionMenu.js +0 -20
- package/dist/components/editor/HSliderColorMobile.d.ts +0 -16
- package/dist/components/editor/HSliderColorMobile.js +0 -270
- package/dist/components/editor/HSliderDetailsMobile.d.ts +0 -12
- package/dist/components/editor/HSliderDetailsMobile.js +0 -154
- package/dist/components/editor/HSliderLightMobile.d.ts +0 -20
- package/dist/components/editor/HSliderLightMobile.js +0 -420
- package/dist/components/editor/HTabAspectRatioMobile.d.ts +0 -0
- package/dist/components/editor/HTabAspectRatioMobile.js +0 -1
- package/dist/components/editor/HTabColorAdjustmentMobile.d.ts +0 -33
- package/dist/components/editor/HTabColorAdjustmentMobile.js +0 -16
- package/dist/components/editor/HTabPresetMobile.d.ts +0 -14
- package/dist/components/editor/HTabPresetMobile.js +0 -10
- package/dist/components/editor/HTextField.d.ts +0 -14
- package/dist/components/editor/HTextField.js +0 -51
- package/dist/components/editor/HWatermarkView.d.ts +0 -6
- package/dist/components/editor/HWatermarkView.js +0 -16
- package/dist/components/editor/svg/Tick.d.ts +0 -2
- package/dist/components/editor/svg/Tick.js +0 -6
- package/dist/components/modal/HModalDialog.d.ts +0 -12
- package/dist/components/modal/HModalDialog.js +0 -18
- package/dist/components/modal/HModalRename.d.ts +0 -14
- package/dist/components/modal/HModalRename.js +0 -35
- package/dist/hooks/demo/HonchoEditorBulkDemo.d.ts +0 -3
- package/dist/hooks/demo/HonchoEditorBulkDemo.js +0 -410
- package/dist/hooks/demo/HonchoEditorSingleCleanDemo.d.ts +0 -3
- package/dist/hooks/demo/HonchoEditorSingleCleanDemo.js +0 -354
- package/dist/hooks/demo/index.d.ts +0 -2
- package/dist/hooks/demo/index.js +0 -2
- package/dist/hooks/editor/type.d.ts +0 -174
- package/dist/hooks/editor/type.js +0 -1
- package/dist/hooks/editor/useHonchoEditorBulk.d.ts +0 -96
- package/dist/hooks/editor/useHonchoEditorBulk.js +0 -427
- package/dist/hooks/editor/useHonchoEditorSingle.d.ts +0 -44
- package/dist/hooks/editor/useHonchoEditorSingle.js +0 -162
- package/dist/hooks/useAdjustmentHistory.d.ts +0 -97
- package/dist/hooks/useAdjustmentHistory.js +0 -493
- package/dist/hooks/useAdjustmentHistoryBatch.d.ts +0 -177
- package/dist/hooks/useAdjustmentHistoryBatch.js +0 -1189
- package/dist/hooks/useGallerySwipe.d.ts +0 -36
- package/dist/hooks/useGallerySwipe.js +0 -344
- package/dist/hooks/usePaging.d.ts +0 -89
- package/dist/hooks/usePaging.js +0 -211
- package/dist/hooks/usePreset.d.ts +0 -82
- package/dist/hooks/usePreset.js +0 -344
- package/dist/index.d.ts +0 -41
- package/dist/index.js +0 -44
- package/dist/lib/context/EditorContext.d.ts +0 -28
- package/dist/lib/context/EditorContext.js +0 -60
- package/dist/lib/context/EditorProcessingService.d.ts +0 -36
- package/dist/lib/context/EditorProcessingService.js +0 -249
- package/dist/lib/editor/honcho-editor.d.ts +0 -324
- package/dist/lib/editor/honcho-editor.js +0 -825
- package/dist/lib/hooks/useEditor.d.ts +0 -22
- package/dist/lib/hooks/useEditor.js +0 -35
- package/dist/lib/hooks/useEditorHeadless.d.ts +0 -34
- package/dist/lib/hooks/useEditorHeadless.js +0 -207
- package/dist/lib/hooks/useImageProcessor.d.ts +0 -18
- package/dist/lib/hooks/useImageProcessor.js +0 -113
- package/dist/setupTests.d.ts +0 -1
- package/dist/setupTests.js +0 -1
- package/dist/themes/colors.d.ts +0 -12
- package/dist/themes/colors.js +0 -12
- package/dist/themes/honchoTheme.d.ts +0 -25
- package/dist/themes/honchoTheme.js +0 -94
- package/dist/utils/adjustment.d.ts +0 -6
- package/dist/utils/adjustment.js +0 -48
- package/dist/utils/imageLoader.d.ts +0 -11
- package/dist/utils/imageLoader.js +0 -48
- package/dist/utils/isMobile.d.ts +0 -1
- package/dist/utils/isMobile.js +0 -5
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
type Preset = {
|
|
3
|
-
id: string;
|
|
4
|
-
name: string;
|
|
5
|
-
};
|
|
6
|
-
interface Props {
|
|
7
|
-
presets: Preset[];
|
|
8
|
-
selectedPreset: string | null;
|
|
9
|
-
presetOptionModal: (event: React.MouseEvent<HTMLElement>, presetId: string) => void;
|
|
10
|
-
onOpenPresetModal: () => void;
|
|
11
|
-
onSelectPreset: (id: string) => void;
|
|
12
|
-
}
|
|
13
|
-
export default function HTabPresetMobile(props: Props): import("react/jsx-runtime").JSX.Element;
|
|
14
|
-
export {};
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { Stack, IconButton, CardMedia, Button } from "@mui/material";
|
|
3
|
-
import useHonchoTypography from "../../themes/honchoTheme";
|
|
4
|
-
import useColors from '../../themes/colors';
|
|
5
|
-
// Static `presets` array has been removed.
|
|
6
|
-
export default function HTabPresetMobile(props) {
|
|
7
|
-
const typography = useHonchoTypography();
|
|
8
|
-
const colors = useColors();
|
|
9
|
-
return (_jsx(_Fragment, { children: _jsxs(Stack, { direction: "column", spacing: 0, sx: { px: "0px", mx: "0px" }, children: [props.presets.map((preset) => (_jsxs(Stack, { direction: "row", alignItems: "center", justifyContent: "space-between", children: [_jsx(Button, { sx: { ...typography.bodyMedium, color: colors.surface, justifyContent: 'flex-start', flexGrow: 1, textTransform: 'none' }, onClick: () => props.onSelectPreset(preset.id), children: preset.name }), _jsxs(Stack, { direction: "row", alignItems: "center", spacing: 1, children: [props.selectedPreset === preset.id && (_jsx(CardMedia, { component: "img", image: "v1/svg/check-ratio-editor.svg", sx: { width: "20px", height: "20px", px: "2px" } })), _jsx(IconButton, { "aria-label": preset.name, sx: { px: "8px" }, onClick: (event) => props.presetOptionModal(event, preset.id), children: _jsx(CardMedia, { component: "img", image: "/v1/svg/dots-editor.svg", alt: "Options" }) })] })] }, preset.id))), _jsx(Button, { variant: "text", sx: { color: colors.surface, border: "1px solid", borderColor: colors.surface, borderRadius: "40px", mt: "12px", textTransform: 'none' }, onClick: props.onOpenPresetModal, children: "Create Preset" })] }) }));
|
|
10
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
interface Props {
|
|
3
|
-
valueName: string;
|
|
4
|
-
setName: (event: React.ChangeEvent<HTMLInputElement>) => void;
|
|
5
|
-
}
|
|
6
|
-
export declare function HTextField(props: Props): import("react/jsx-runtime").JSX.Element;
|
|
7
|
-
interface PropsRename {
|
|
8
|
-
valueName: string;
|
|
9
|
-
setName: (event: React.ChangeEvent<HTMLInputElement>) => void;
|
|
10
|
-
onSaveRenamePreset: () => void;
|
|
11
|
-
onCancel: () => void;
|
|
12
|
-
}
|
|
13
|
-
export declare function HTextFieldRename(props: PropsRename): import("react/jsx-runtime").JSX.Element;
|
|
14
|
-
export {};
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { TextField, Stack, Button } from "@mui/material";
|
|
3
|
-
import useHonchoTypography from "../../themes/honchoTheme";
|
|
4
|
-
import useColors from '../../themes/colors';
|
|
5
|
-
export function HTextField(props) {
|
|
6
|
-
const colors = useColors();
|
|
7
|
-
const typography = useHonchoTypography();
|
|
8
|
-
return (_jsx(_Fragment, { children: _jsx(TextField, { autoFocus: true, margin: "dense", id: "name", label: "Preset Name", type: "text", fullWidth: true, variant: "standard", defaultValue: props.valueName, onChange: props.setName, sx: {
|
|
9
|
-
backgroundColor: "#F6F6F6",
|
|
10
|
-
p: "7px",
|
|
11
|
-
borderRadius: "6px",
|
|
12
|
-
'& .MuiInputLabel-root': {
|
|
13
|
-
color: colors.onSurfaceVariant, // A slightly dimmer color for the placeholder
|
|
14
|
-
pt: '10px',
|
|
15
|
-
pl: '10px',
|
|
16
|
-
},
|
|
17
|
-
'& .MuiInput-input': {
|
|
18
|
-
color: colors.onSurface,
|
|
19
|
-
},
|
|
20
|
-
'& .MuiInputLabel-root.Mui-focused': {
|
|
21
|
-
color: colors.onSurfaceVariant, // Or a different color if you prefer
|
|
22
|
-
},
|
|
23
|
-
} }) }));
|
|
24
|
-
}
|
|
25
|
-
export function HTextFieldRename(props) {
|
|
26
|
-
const colors = useColors();
|
|
27
|
-
const typography = useHonchoTypography();
|
|
28
|
-
return (_jsx(_Fragment, { children: _jsxs(Stack, { direction: "column", spacing: 2, children: [_jsx(TextField, { autoFocus: true, type: "text", fullWidth: true, variant: "standard", defaultValue: props.valueName, onChange: props.setName, sx: {
|
|
29
|
-
backgroundColor: "#F6F6F6",
|
|
30
|
-
p: "7px",
|
|
31
|
-
borderRadius: "6px",
|
|
32
|
-
'& .MuiInputLabel-root': {
|
|
33
|
-
pt: '10px',
|
|
34
|
-
pl: '10px',
|
|
35
|
-
},
|
|
36
|
-
} }), _jsxs(Stack, { direction: "row", justifyContent: "end", alignItems: "center", children: [_jsx(Button, { color: "primary", onClick: props.onCancel, sx: {
|
|
37
|
-
backgroundColor: colors.surface,
|
|
38
|
-
color: colors.onSurface,
|
|
39
|
-
'&:hover': {
|
|
40
|
-
backgroundColor: colors.onSurfaceVariant1,
|
|
41
|
-
},
|
|
42
|
-
...typography.titleMedium,
|
|
43
|
-
}, children: "Cancel" }), _jsx(Button, { color: "primary", onClick: props.onSaveRenamePreset, sx: {
|
|
44
|
-
backgroundColor: colors.surface,
|
|
45
|
-
color: colors.onSurface,
|
|
46
|
-
'&:hover': {
|
|
47
|
-
backgroundColor: colors.onSurfaceVariant1,
|
|
48
|
-
},
|
|
49
|
-
...typography.titleMedium,
|
|
50
|
-
}, children: "Save" })] })] }) }));
|
|
51
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { TextField, Button, Stack } from "@mui/material";
|
|
3
|
-
import useHonchoTypography from "../../themes/honchoTheme";
|
|
4
|
-
import useColors from '../../themes/colors';
|
|
5
|
-
export default function HWatermarkView(props) {
|
|
6
|
-
const colors = useColors();
|
|
7
|
-
const typography = useHonchoTypography();
|
|
8
|
-
return (_jsx(_Fragment, { children: _jsxs(Stack, { direction: "column", alignItems: "center", spacing: 5, sx: { pt: "20px", color: colors.surface }, children: [_jsx(TextField, { id: "watermark-name", label: "watermark name", variant: "standard", sx: {
|
|
9
|
-
'& .MuiInput-underline:before': {
|
|
10
|
-
borderBottomColor: colors.surface
|
|
11
|
-
},
|
|
12
|
-
'& .MuiInputBase-input': {
|
|
13
|
-
color: colors.surface
|
|
14
|
-
}
|
|
15
|
-
} }), _jsxs(Stack, { direction: "row", spacing: 0.5, children: [_jsx(Button, { variant: "text", sx: { color: colors.surface }, children: "Landscape" }), _jsx(Button, { variant: "text", sx: { color: colors.surface }, children: "Portrait" }), _jsx(Button, { variant: "text", sx: { color: colors.surface }, children: "Square" })] })] }) }));
|
|
16
|
-
}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { SvgIcon } from "@mui/material";
|
|
3
|
-
const Tick = () => {
|
|
4
|
-
return (_jsx(SvgIcon, { style: { width: "29px", height: "29px" }, children: _jsxs("svg", { width: "36", height: "36", viewBox: "0 0 36 36", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [_jsx("rect", { x: "5", y: "5", width: "22", height: "22", rx: "11", fill: "black" }), _jsx("path", { d: "M20 13L14.5 18.5L12 16", stroke: "white", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })] }) }));
|
|
5
|
-
};
|
|
6
|
-
export default Tick;
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
interface ModalDialogProps {
|
|
2
|
-
isOpen: boolean;
|
|
3
|
-
isLoading?: boolean;
|
|
4
|
-
title?: string;
|
|
5
|
-
description?: string;
|
|
6
|
-
onCancel: () => void;
|
|
7
|
-
onSubmit: () => void;
|
|
8
|
-
cancelLabel?: string;
|
|
9
|
-
submitLabel?: string;
|
|
10
|
-
}
|
|
11
|
-
declare function ModalDialog(props: ModalDialogProps): import("react/jsx-runtime").JSX.Element;
|
|
12
|
-
export default ModalDialog;
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Button, Dialog, DialogActions, DialogContent, DialogTitle, Grid, Typography, useTheme, } from "@mui/material";
|
|
3
|
-
import useHonchoTypography from "../../themes/honchoTheme";
|
|
4
|
-
import useColors from '../../themes/colors';
|
|
5
|
-
const defaultPaperStyle = {
|
|
6
|
-
borderRadius: "28px",
|
|
7
|
-
width: { xs: "100%", sm: "456px" },
|
|
8
|
-
boxShadow: "none",
|
|
9
|
-
};
|
|
10
|
-
function ModalDialog(props) {
|
|
11
|
-
const { isOpen, isLoading = false, title, description, onCancel, onSubmit, cancelLabel = "Cancel", submitLabel = "Confirm", } = props;
|
|
12
|
-
const theme = useTheme();
|
|
13
|
-
const typography = useHonchoTypography();
|
|
14
|
-
const colors = useColors();
|
|
15
|
-
return (_jsxs(Dialog, { disableScrollLock: true, open: isOpen, onClose: onCancel, "aria-labelledby": "dialog-title", PaperProps: { sx: defaultPaperStyle }, children: ["``", title && (_jsx(DialogTitle, { children: _jsx(Typography, { variant: "labelLarge", color: colors.onSurface, children: title }) })), _jsx(DialogContent, { sx: { padding: { xs: "24px 24px 0 24px", sm: "24px 24px 0 24px" } }, children: description && (_jsx(Typography, { sx: { color: "#656369", fontSize: 14 }, variant: "bodyMedium", children: description })) }), _jsx(DialogActions, { sx: { padding: 3 }, children: _jsxs(Grid, { container: true, direction: "row", justifyContent: "end", alignItems: "center", gap: 1, children: [_jsx(Button, { variant: "text", onClick: onCancel, children: cancelLabel }), _jsx(Button, { variant: "text", color: "error", disabled: isLoading, onClick: () => onSubmit(), children: submitLabel })] }) })] }));
|
|
16
|
-
}
|
|
17
|
-
;
|
|
18
|
-
export default ModalDialog;
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
interface ModalRenameProps {
|
|
2
|
-
isOpen: boolean;
|
|
3
|
-
title?: string;
|
|
4
|
-
description?: string;
|
|
5
|
-
action?: React.ReactNode;
|
|
6
|
-
onCancel: () => void;
|
|
7
|
-
onSubmit: () => void;
|
|
8
|
-
cancelLabel?: string;
|
|
9
|
-
submitLabel?: string;
|
|
10
|
-
valueName: string;
|
|
11
|
-
setName: (event: React.ChangeEvent<HTMLInputElement>) => void;
|
|
12
|
-
}
|
|
13
|
-
declare function ModalRename(props: ModalRenameProps): import("react/jsx-runtime").JSX.Element;
|
|
14
|
-
export default ModalRename;
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Button, Dialog, DialogActions, DialogContent, DialogTitle, Grid, Typography, useTheme, TextField, } from "@mui/material";
|
|
3
|
-
import useColors from '../../themes/colors';
|
|
4
|
-
import useHonchoTypography from "../../themes/honchoTheme";
|
|
5
|
-
const defaultPaperStyle = {
|
|
6
|
-
borderRadius: "28px",
|
|
7
|
-
width: { xs: "100%", sm: "456px" },
|
|
8
|
-
boxShadow: "none",
|
|
9
|
-
};
|
|
10
|
-
function ModalRename(props) {
|
|
11
|
-
const { isOpen, title, onCancel, onSubmit, cancelLabel = "Cancel", submitLabel = "Confirm", valueName, setName } = props;
|
|
12
|
-
const colors = useColors();
|
|
13
|
-
const theme = useTheme();
|
|
14
|
-
const typography = useHonchoTypography();
|
|
15
|
-
return (_jsxs(Dialog, { disableScrollLock: true, open: isOpen, onClose: onCancel, "aria-labelledby": "dialog-title", PaperProps: { sx: defaultPaperStyle }, children: [title && (_jsx(DialogTitle, { children: _jsx(Typography, { variant: "labelLarge", color: colors.onSurface, children: title }) })), _jsx(DialogContent, { sx: { padding: { xs: "24px 24px 0 24px", sm: "24px 24px 0 24px" } }, children: _jsx(TextField, { autoFocus: true, margin: "dense", id: "name", label: "Preset Name", type: "text", fullWidth: true, variant: "standard", value: valueName, onChange: setName, sx: {
|
|
16
|
-
backgroundColor: "#F6F6F6",
|
|
17
|
-
p: "7px",
|
|
18
|
-
borderRadius: "6px",
|
|
19
|
-
'& .MuiInputLabel-root': {
|
|
20
|
-
color: colors.onSurfaceVariant,
|
|
21
|
-
pt: '10px',
|
|
22
|
-
pl: '10px',
|
|
23
|
-
},
|
|
24
|
-
'& .MuiInput-input': {
|
|
25
|
-
color: colors.onSurface,
|
|
26
|
-
},
|
|
27
|
-
'& .MuiInputLabel-root.Mui-focused': {
|
|
28
|
-
color: colors.onSurfaceVariant,
|
|
29
|
-
},
|
|
30
|
-
} }) }), _jsx(DialogActions, { sx: { padding: 3 }, children: _jsxs(Grid, { container: true, direction: "row", justifyContent: "end", alignItems: "center", gap: 1, children: [_jsx(Button, { variant: "text", onClick: onCancel, children: cancelLabel }), _jsx(Button, { variant: "text", color: "info",
|
|
31
|
-
// The "disabled" attribute has been removed
|
|
32
|
-
onClick: onSubmit, children: submitLabel })] }) })] }));
|
|
33
|
-
}
|
|
34
|
-
;
|
|
35
|
-
export default ModalRename;
|
|
@@ -1,410 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import React, { useState, useMemo, useRef, useEffect } from 'react';
|
|
3
|
-
import { Box, Container, Typography, Button, Grid, Card, CardContent, Checkbox, Chip, Alert, CircularProgress, ButtonGroup, Paper, Divider, FormControl, InputLabel, Select, MenuItem, Stack } from '@mui/material';
|
|
4
|
-
import { useHonchoEditorBulk } from '../editor/useHonchoEditorBulk';
|
|
5
|
-
import { useImageProcessor } from "../../lib/hooks/useImageProcessor";
|
|
6
|
-
// Mock data for demonstration
|
|
7
|
-
const createMockGallery = (id, adjustments) => ({
|
|
8
|
-
id,
|
|
9
|
-
uid: 'demo-user',
|
|
10
|
-
event_id: 'demo-event',
|
|
11
|
-
download: {
|
|
12
|
-
key: `${id}-download`,
|
|
13
|
-
path: `https://s3.ap-southeast-1.amazonaws.com/dev.pronto.ubersnap/event/689c514d225024b1172ed297/media/95d811da-72a1-4e97-91cc-94446f0a10ad/original.jpeg`,
|
|
14
|
-
size: 1024000,
|
|
15
|
-
width: 800,
|
|
16
|
-
height: 600,
|
|
17
|
-
},
|
|
18
|
-
download_edited: {
|
|
19
|
-
key: `${id}-download-edited`,
|
|
20
|
-
path: `https://s3.ap-southeast-1.amazonaws.com/dev.pronto.ubersnap/event/689c514d225024b1172ed297/media/95d811da-72a1-4e97-91cc-94446f0a10ad/original.jpeg`,
|
|
21
|
-
size: 1024000,
|
|
22
|
-
width: 800,
|
|
23
|
-
height: 600,
|
|
24
|
-
},
|
|
25
|
-
thumbnail: {
|
|
26
|
-
key: `${id}-thumb`,
|
|
27
|
-
path: `https://s3.ap-southeast-1.amazonaws.com/dev.pronto.ubersnap/event/689c514d225024b1172ed297/media/95d811da-72a1-4e97-91cc-94446f0a10ad/original.jpeg`,
|
|
28
|
-
size: 50000,
|
|
29
|
-
width: 300,
|
|
30
|
-
height: 200,
|
|
31
|
-
},
|
|
32
|
-
thumbnail_edited: {
|
|
33
|
-
key: `${id}-thumb-edited`,
|
|
34
|
-
path: `https://s3.ap-southeast-1.amazonaws.com/dev.pronto.ubersnap/event/689c514d225024b1172ed297/media/95d811da-72a1-4e97-91cc-94446f0a10ad/thumbnail.jpeg`,
|
|
35
|
-
size: 50000,
|
|
36
|
-
width: 300,
|
|
37
|
-
height: 200,
|
|
38
|
-
},
|
|
39
|
-
is_original: true,
|
|
40
|
-
available: true,
|
|
41
|
-
show_gallery: true,
|
|
42
|
-
editor_config: {
|
|
43
|
-
color_adjustment: {
|
|
44
|
-
temperature: adjustments?.tempScore || 0,
|
|
45
|
-
tint: adjustments?.tintScore || 0,
|
|
46
|
-
vibrance: adjustments?.vibranceScore || 0,
|
|
47
|
-
saturation: adjustments?.saturationScore || 0,
|
|
48
|
-
exposure: adjustments?.exposureScore || 0,
|
|
49
|
-
highlights: adjustments?.highlightsScore || 0,
|
|
50
|
-
shadows: adjustments?.shadowsScore || 0,
|
|
51
|
-
whites: adjustments?.whitesScore || 0,
|
|
52
|
-
blacks: adjustments?.blacksScore || 0,
|
|
53
|
-
contrast: adjustments?.contrastScore || 0,
|
|
54
|
-
clarity: adjustments?.clarityScore || 0,
|
|
55
|
-
sharpness: adjustments?.sharpnessScore || 0,
|
|
56
|
-
},
|
|
57
|
-
transformation_adjustment: [],
|
|
58
|
-
watermarks: [],
|
|
59
|
-
},
|
|
60
|
-
log: {
|
|
61
|
-
created_at: new Date().toISOString(),
|
|
62
|
-
updated_at: new Date().toISOString(),
|
|
63
|
-
},
|
|
64
|
-
});
|
|
65
|
-
// Mock Controller implementation
|
|
66
|
-
const createMockController = () => {
|
|
67
|
-
console.log('[Controller] 🏭 createMockController() called - Creating new mock controller instance for bulk editor');
|
|
68
|
-
// Generate mock images from 1 to 1277 using picsum.dev static URLs
|
|
69
|
-
const mockImages = [];
|
|
70
|
-
for (let i = 1; i <= 1000; i++) {
|
|
71
|
-
const id = i.toString();
|
|
72
|
-
// let adjustments: Partial<AdjustmentState> | undefined;
|
|
73
|
-
mockImages.push(createMockGallery(id, undefined));
|
|
74
|
-
}
|
|
75
|
-
return {
|
|
76
|
-
onGetImage: async (uid, imageId) => {
|
|
77
|
-
console.log(`[Controller] 📷 onGetImage called: uid=${uid}, imageId=${imageId}`);
|
|
78
|
-
await new Promise(resolve => setTimeout(resolve, 500));
|
|
79
|
-
const image = mockImages.find(img => img.id === imageId);
|
|
80
|
-
if (!image) {
|
|
81
|
-
console.error(`[Controller] ❌ Image ${imageId} not found`);
|
|
82
|
-
throw new Error(`Image ${imageId} not found`);
|
|
83
|
-
}
|
|
84
|
-
console.log(`[Controller] 📷 onGetImage returning image:`, image.id);
|
|
85
|
-
return image;
|
|
86
|
-
},
|
|
87
|
-
getImageList: async (uid, eventId, page) => {
|
|
88
|
-
console.log(`[Controller] 📋 getImageList called: uid=${uid}, eventId=${eventId}, page=${page}`);
|
|
89
|
-
await new Promise(resolve => setTimeout(resolve, 800));
|
|
90
|
-
const pageSize = 1000; // Increased page size for better UX with more images
|
|
91
|
-
const startIndex = (page - 1) * pageSize;
|
|
92
|
-
const endIndex = startIndex + pageSize;
|
|
93
|
-
const pageImages = mockImages.slice(startIndex, endIndex);
|
|
94
|
-
const result = {
|
|
95
|
-
gallery: pageImages,
|
|
96
|
-
limit: pageSize,
|
|
97
|
-
current_page: page,
|
|
98
|
-
prev_page: page > 1 ? page - 1 : 0,
|
|
99
|
-
next_page: endIndex < mockImages.length ? page + 1 : 0,
|
|
100
|
-
sum_of_image: pageImages.length,
|
|
101
|
-
};
|
|
102
|
-
console.log(`[Controller] 📋 getImageList returning ${pageImages.length} images for page ${page} (total available: ${mockImages.length})`, result);
|
|
103
|
-
return result;
|
|
104
|
-
},
|
|
105
|
-
syncConfig: async (uid) => {
|
|
106
|
-
console.log(`[Controller] 🔄 syncConfig called: uid=${uid}`);
|
|
107
|
-
await new Promise(resolve => setTimeout(resolve, 200));
|
|
108
|
-
console.log(`[Controller] 🔄 syncConfig completed for uid=${uid}`);
|
|
109
|
-
},
|
|
110
|
-
handleBack: (uid, imageId) => {
|
|
111
|
-
console.log(`[Controller] ⬅️ handleBack called: uid=${uid}, imageId=${imageId}`);
|
|
112
|
-
console.log(`[Controller] ⬅️ Back to: ${imageId}`);
|
|
113
|
-
},
|
|
114
|
-
getPresets: async (uid) => {
|
|
115
|
-
console.log(`[Controller] 🎨 getPresets called: uid=${uid}`);
|
|
116
|
-
await new Promise(resolve => setTimeout(resolve, 300));
|
|
117
|
-
const presets = [
|
|
118
|
-
{ id: '1', name: 'Warm Sunset', is_default: false, temperature: 15, tint: 5, saturation: 8, vibrance: 12, exposure: 2, contrast: 5, highlights: -10, shadows: 8, whites: 3, blacks: -5, clarity: 4, sharpness: 6 },
|
|
119
|
-
{ id: '2', name: 'Cool Morning', is_default: false, temperature: -12, tint: -3, saturation: -2, vibrance: 5, exposure: 1, contrast: 3, highlights: -5, shadows: 12, whites: 8, blacks: -8, clarity: 6, sharpness: 4 },
|
|
120
|
-
{ id: '3', name: 'High Contrast', is_default: false, temperature: 0, tint: 0, saturation: 5, vibrance: 8, exposure: 0, contrast: 20, highlights: -15, shadows: 15, whites: 10, blacks: -10, clarity: 15, sharpness: 8 },
|
|
121
|
-
];
|
|
122
|
-
console.log(`[Controller] 🎨 getPresets returning ${presets.length} presets`, presets.map(p => ({ id: p.id, name: p.name })));
|
|
123
|
-
return presets;
|
|
124
|
-
},
|
|
125
|
-
createPreset: async (uid, name, settings) => {
|
|
126
|
-
console.log(`[Controller] ➕ createPreset called: uid=${uid}, name=${name}`, settings);
|
|
127
|
-
await new Promise(resolve => setTimeout(resolve, 500));
|
|
128
|
-
console.log(`[Controller] ➕ createPreset completed: ${name}`);
|
|
129
|
-
},
|
|
130
|
-
deletePreset: async (uid, presetId) => {
|
|
131
|
-
console.log(`[Controller] 🗑️ deletePreset called: uid=${uid}, presetId=${presetId}`);
|
|
132
|
-
await new Promise(resolve => setTimeout(resolve, 300));
|
|
133
|
-
console.log(`[Controller] 🗑️ deletePreset completed: ${presetId}`);
|
|
134
|
-
},
|
|
135
|
-
updatePreset: async (uid, data) => {
|
|
136
|
-
console.log(`[Controller] 🔄 updatePreset called: uid=${uid}`, data);
|
|
137
|
-
await new Promise(resolve => setTimeout(resolve, 300));
|
|
138
|
-
console.log(`[Controller] 🔄 updatePreset completed:`, data.name);
|
|
139
|
-
},
|
|
140
|
-
createEditorConfig: async (uid, payload) => {
|
|
141
|
-
console.log(`[Controller] ⚙️ createEditorConfig called: uid=${uid}`, payload);
|
|
142
|
-
await new Promise(resolve => setTimeout(resolve, 300));
|
|
143
|
-
console.log(`[Controller] ⚙️ createEditorConfig completed for gallery_id=${payload.gallery_id}, task_id=${payload.task_id}`);
|
|
144
|
-
},
|
|
145
|
-
getEditorHistory: async (uid, imageId) => {
|
|
146
|
-
console.log(`[Controller] 📚 getEditorHistory called: uid=${uid}, imageId=${imageId}`);
|
|
147
|
-
await new Promise(resolve => setTimeout(resolve, 200));
|
|
148
|
-
const result = {
|
|
149
|
-
current_task_id: "",
|
|
150
|
-
history: []
|
|
151
|
-
};
|
|
152
|
-
console.log(`[Controller] 📚 getEditorHistory returning empty history for demo:`, result);
|
|
153
|
-
return result;
|
|
154
|
-
},
|
|
155
|
-
getGalleryUpdateTimestamp: async (uid, eventId) => {
|
|
156
|
-
console.log(`[Controller] ⏰ getGalleryUpdateTimestamp called: uid=${uid}, eventId=${eventId}`);
|
|
157
|
-
await new Promise(resolve => setTimeout(resolve, 100));
|
|
158
|
-
const result = {
|
|
159
|
-
gallery: []
|
|
160
|
-
};
|
|
161
|
-
console.log(`[Controller] ⏰ getGalleryUpdateTimestamp returning:`, result);
|
|
162
|
-
return result;
|
|
163
|
-
},
|
|
164
|
-
setHistoryIndex: async (uid, imageId, taskId) => {
|
|
165
|
-
console.log(`[Controller] 📍 setHistoryIndex called: uid=${uid}, imageId=${imageId}, taskId=${taskId}`);
|
|
166
|
-
await new Promise(resolve => setTimeout(resolve, 100));
|
|
167
|
-
console.log(`[Controller] 📍 setHistoryIndex completed - Set history index for image ${imageId} to task ${taskId}`);
|
|
168
|
-
},
|
|
169
|
-
};
|
|
170
|
-
};
|
|
171
|
-
const AdjustmentControls = ({ label, onDecreaseMax, onDecrease, onIncrease, onIncreaseMax, disabled = false }) => (_jsxs(Box, { mb: 2, children: [_jsx(Typography, { variant: "body2", gutterBottom: true, children: label }), _jsxs(ButtonGroup, { size: "small", variant: "outlined", children: [_jsx(Button, { onClick: onDecreaseMax, disabled: disabled, children: "--" }), _jsx(Button, { onClick: onDecrease, disabled: disabled, children: "-" }), _jsx(Button, { onClick: onIncrease, disabled: disabled, children: "+" }), _jsx(Button, { onClick: onIncreaseMax, disabled: disabled, children: "++" })] })] }));
|
|
172
|
-
const ImageCard = React.memo(({ image, onToggleSelection }) => {
|
|
173
|
-
const [isVisible, setIsVisible] = useState(false);
|
|
174
|
-
const [shouldLoadImage, setShouldLoadImage] = useState(false);
|
|
175
|
-
const [isInView, setIsInView] = useState(false);
|
|
176
|
-
const cardRef = useRef(null);
|
|
177
|
-
const abortControllerRef = useRef(null);
|
|
178
|
-
useEffect(() => {
|
|
179
|
-
const visibilityObserver = new IntersectionObserver(([entry]) => {
|
|
180
|
-
if (entry.isIntersecting) {
|
|
181
|
-
setIsVisible(true);
|
|
182
|
-
setIsInView(true);
|
|
183
|
-
// Delay image loading slightly to ensure smooth scrolling
|
|
184
|
-
setTimeout(() => setShouldLoadImage(true), 100);
|
|
185
|
-
// Don't disconnect here as we want to track when it goes out of view
|
|
186
|
-
}
|
|
187
|
-
else {
|
|
188
|
-
setIsInView(false);
|
|
189
|
-
// Cancel processing when going out of view
|
|
190
|
-
if (abortControllerRef.current) {
|
|
191
|
-
console.debug(`[ImageCard] Cancelling processing for image ${image.key} - out of view`);
|
|
192
|
-
abortControllerRef.current.abort();
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
}, {
|
|
196
|
-
threshold: 0.1, // Trigger when 10% of the element is visible
|
|
197
|
-
rootMargin: '100px', // Start loading 100px before the element comes into view
|
|
198
|
-
});
|
|
199
|
-
if (cardRef.current) {
|
|
200
|
-
visibilityObserver.observe(cardRef.current);
|
|
201
|
-
}
|
|
202
|
-
return () => {
|
|
203
|
-
visibilityObserver.disconnect();
|
|
204
|
-
// Cancel any ongoing processing when component unmounts
|
|
205
|
-
if (abortControllerRef.current) {
|
|
206
|
-
abortControllerRef.current.abort();
|
|
207
|
-
}
|
|
208
|
-
};
|
|
209
|
-
}, [image.key]);
|
|
210
|
-
// Track adjustments changes for debugging
|
|
211
|
-
useEffect(() => {
|
|
212
|
-
console.log("[ImageCard] Adjustments changed for image", image.key, ":", image.adjustments);
|
|
213
|
-
}, [image.adjustments, image.key]);
|
|
214
|
-
// Create a key that changes when adjustments change to force abort controller recreation
|
|
215
|
-
const adjustmentsKey = useMemo(() => {
|
|
216
|
-
return JSON.stringify(image.adjustments);
|
|
217
|
-
}, [image.adjustments]);
|
|
218
|
-
// Store the current abort signal in a ref to prevent it from changing on every render
|
|
219
|
-
const currentAbortSignalRef = useRef();
|
|
220
|
-
const isInitializedRef = useRef(false);
|
|
221
|
-
// Much more conservative abort controller management - only recreate when absolutely necessary
|
|
222
|
-
useEffect(() => {
|
|
223
|
-
if (shouldLoadImage && isInView) {
|
|
224
|
-
// Only create abort controller if we don't have one OR if this is the first time
|
|
225
|
-
if (!abortControllerRef.current || !isInitializedRef.current) {
|
|
226
|
-
console.debug(`[ImageCard] Creating initial abort controller for image ${image.key}`);
|
|
227
|
-
if (abortControllerRef.current) {
|
|
228
|
-
abortControllerRef.current.abort();
|
|
229
|
-
}
|
|
230
|
-
abortControllerRef.current = new AbortController();
|
|
231
|
-
currentAbortSignalRef.current = abortControllerRef.current.signal;
|
|
232
|
-
isInitializedRef.current = true;
|
|
233
|
-
}
|
|
234
|
-
// For adjustment changes, don't recreate the controller - let useImageProcessor handle it
|
|
235
|
-
}
|
|
236
|
-
else {
|
|
237
|
-
// Only clean up when not visible or not loading
|
|
238
|
-
if (abortControllerRef.current && isInitializedRef.current) {
|
|
239
|
-
console.debug(`[ImageCard] Cleaning up abort controller for image ${image.key} - not visible or not loading`);
|
|
240
|
-
abortControllerRef.current.abort();
|
|
241
|
-
abortControllerRef.current = null;
|
|
242
|
-
currentAbortSignalRef.current = undefined;
|
|
243
|
-
isInitializedRef.current = false;
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
return () => {
|
|
247
|
-
if (abortControllerRef.current) {
|
|
248
|
-
abortControllerRef.current.abort();
|
|
249
|
-
abortControllerRef.current = null;
|
|
250
|
-
currentAbortSignalRef.current = undefined;
|
|
251
|
-
isInitializedRef.current = false;
|
|
252
|
-
}
|
|
253
|
-
};
|
|
254
|
-
}, [shouldLoadImage, isInView, image.key]); // Remove adjustmentsKey from dependencies
|
|
255
|
-
// Separate effect to handle adjustment changes without recreating abort controller
|
|
256
|
-
useEffect(() => {
|
|
257
|
-
if (shouldLoadImage && isInView && isInitializedRef.current) {
|
|
258
|
-
console.debug(`[ImageCard] Adjustments changed for image ${image.key} - letting useImageProcessor handle the change`);
|
|
259
|
-
}
|
|
260
|
-
}, [adjustmentsKey, shouldLoadImage, isInView, image.key]);
|
|
261
|
-
// Memoize the useImageProcessor call to prevent unnecessary hook calls
|
|
262
|
-
const imageProcessorParams = useMemo(() => ({
|
|
263
|
-
photoId: image.key,
|
|
264
|
-
photoSrc: image.src,
|
|
265
|
-
adjustments: image.adjustments,
|
|
266
|
-
enableEditor: shouldLoadImage && isInView, // Only enable when we should load the image AND it's in view
|
|
267
|
-
abortSignal: currentAbortSignalRef.current // Use stable abort signal
|
|
268
|
-
}), [image.key, image.src, image.adjustments, shouldLoadImage, isInView]);
|
|
269
|
-
// Only call useImageProcessor when the card is visible AND we should load the image AND it's in view
|
|
270
|
-
const { processedImageSrc, isProcessingComplete, cancelProcessing, isProcessing } = useImageProcessor(imageProcessorParams);
|
|
271
|
-
// Cancel processing when card goes out of view
|
|
272
|
-
useEffect(() => {
|
|
273
|
-
if (!isInView && isProcessing) {
|
|
274
|
-
console.debug(`[ImageCard] Cancelling processing for image ${image.key} - no longer in view`);
|
|
275
|
-
cancelProcessing();
|
|
276
|
-
}
|
|
277
|
-
}, [isInView, isProcessing, cancelProcessing, image.key]);
|
|
278
|
-
// Memoize the toggle selection handler to prevent unnecessary re-renders
|
|
279
|
-
const handleToggleSelection = useMemo(() => {
|
|
280
|
-
return () => onToggleSelection(image.key);
|
|
281
|
-
}, [onToggleSelection, image.key]);
|
|
282
|
-
const handleCheckboxClick = useMemo(() => {
|
|
283
|
-
return (e) => {
|
|
284
|
-
e.stopPropagation();
|
|
285
|
-
onToggleSelection(image.key);
|
|
286
|
-
};
|
|
287
|
-
}, [onToggleSelection, image.key]);
|
|
288
|
-
// Create placeholder content for non-visible cards
|
|
289
|
-
const renderPlaceholder = () => (_jsxs(Box, { sx: {
|
|
290
|
-
height: 200,
|
|
291
|
-
backgroundColor: 'grey.100',
|
|
292
|
-
display: 'flex',
|
|
293
|
-
alignItems: 'center',
|
|
294
|
-
justifyContent: 'center',
|
|
295
|
-
flexDirection: 'column'
|
|
296
|
-
}, children: [_jsx(CircularProgress, { size: 24, sx: { mb: 1 } }), _jsx(Typography, { variant: "caption", color: "text.secondary", children: "Loading..." })] }));
|
|
297
|
-
// Create processing indicator
|
|
298
|
-
const renderProcessingOverlay = () => {
|
|
299
|
-
return isProcessing && shouldLoadImage && isInView ? (_jsxs(Box, { sx: {
|
|
300
|
-
position: 'absolute',
|
|
301
|
-
top: 8,
|
|
302
|
-
right: 8,
|
|
303
|
-
backgroundColor: 'rgba(0, 0, 0, 0.8)',
|
|
304
|
-
color: 'white',
|
|
305
|
-
borderRadius: 1,
|
|
306
|
-
px: 1,
|
|
307
|
-
py: 0.5,
|
|
308
|
-
display: 'flex',
|
|
309
|
-
alignItems: 'center',
|
|
310
|
-
gap: 0.5,
|
|
311
|
-
zIndex: 1,
|
|
312
|
-
maxWidth: '120px'
|
|
313
|
-
}, children: [_jsx(CircularProgress, { size: 12, color: "inherit" }), _jsx(Typography, { variant: "caption", children: "Processing" })] })) : null;
|
|
314
|
-
};
|
|
315
|
-
return (_jsxs(Card, { ref: cardRef, sx: {
|
|
316
|
-
border: image.isSelected ? 2 : 1,
|
|
317
|
-
borderColor: image.isSelected ? 'primary.main' : 'divider',
|
|
318
|
-
cursor: 'pointer',
|
|
319
|
-
transition: 'all 0.2s',
|
|
320
|
-
position: 'relative',
|
|
321
|
-
opacity: 1,
|
|
322
|
-
'&:hover': {
|
|
323
|
-
transform: 'translateY(-2px)',
|
|
324
|
-
boxShadow: 2,
|
|
325
|
-
}
|
|
326
|
-
}, onClick: handleToggleSelection, children: [shouldLoadImage ? (_jsxs(Box, { sx: { position: 'relative', width: '100%', height: '200px' }, children: [_jsx("img", { id: "image-card-media", src: processedImageSrc, alt: "", style: {
|
|
327
|
-
width: '100%',
|
|
328
|
-
height: '200px',
|
|
329
|
-
objectFit: 'cover',
|
|
330
|
-
opacity: 1,
|
|
331
|
-
display: 'block'
|
|
332
|
-
}, loading: "lazy" }), renderProcessingOverlay()] })) : (renderPlaceholder()), _jsx(CardContent, { sx: { pb: 1 }, children: _jsxs(Box, { display: "flex", alignItems: "center", justifyContent: "space-between", children: [_jsxs(Typography, { variant: "body2", color: "text.secondary", children: ["Image ", image.key, !shouldLoadImage && (_jsx(Typography, { component: "span", variant: "caption", sx: { ml: 1 }, children: "(waiting...)" })), !isInView && shouldLoadImage && (_jsx(Typography, { component: "span", variant: "caption", sx: { ml: 1, color: 'warning.main' }, children: "(paused)" }))] }), _jsx(Checkbox, { checked: image.isSelected, size: "small", onClick: handleCheckboxClick })] }) })] }));
|
|
333
|
-
}, (prevProps, nextProps) => {
|
|
334
|
-
// Custom comparison function for React.memo - be more strict to prevent unnecessary re-renders
|
|
335
|
-
const prevAdj = prevProps.image.adjustments || {};
|
|
336
|
-
const nextAdj = nextProps.image.adjustments || {};
|
|
337
|
-
// Only re-render if key properties actually change
|
|
338
|
-
const shouldUpdate = (prevProps.image.key !== nextProps.image.key ||
|
|
339
|
-
prevProps.image.isSelected !== nextProps.image.isSelected ||
|
|
340
|
-
prevProps.image.src !== nextProps.image.src ||
|
|
341
|
-
// Compare individual adjustment properties to avoid JSON.stringify issues
|
|
342
|
-
prevAdj.temperature !== nextAdj.temperature ||
|
|
343
|
-
prevAdj.tint !== nextAdj.tint ||
|
|
344
|
-
prevAdj.exposure !== nextAdj.exposure ||
|
|
345
|
-
prevAdj.contrast !== nextAdj.contrast ||
|
|
346
|
-
prevAdj.clarity !== nextAdj.clarity ||
|
|
347
|
-
prevAdj.vibrance !== nextAdj.vibrance ||
|
|
348
|
-
prevAdj.saturation !== nextAdj.saturation ||
|
|
349
|
-
prevAdj.highlights !== nextAdj.highlights ||
|
|
350
|
-
prevAdj.shadows !== nextAdj.shadows ||
|
|
351
|
-
prevAdj.whites !== nextAdj.whites ||
|
|
352
|
-
prevAdj.blacks !== nextAdj.blacks ||
|
|
353
|
-
prevAdj.sharpness !== nextAdj.sharpness);
|
|
354
|
-
// Return false to re-render, true to skip re-render
|
|
355
|
-
return !shouldUpdate;
|
|
356
|
-
});
|
|
357
|
-
export const HonchoEditorBulkDemo = () => {
|
|
358
|
-
const [controller] = useState(() => createMockController());
|
|
359
|
-
const [showAdjustments, setShowAdjustments] = useState(false);
|
|
360
|
-
const { imageData, isLoading, error, selectedIds, hasMore, selectedBulkPreset, presets, // Add presets
|
|
361
|
-
activePreset, // Add activePreset
|
|
362
|
-
handleToggleImageSelection, handleLoadMore, handleRefresh, handleSelectBulkPreset, handleBackCallbackBulk,
|
|
363
|
-
// Temperature adjustments
|
|
364
|
-
handleBulkTempDecreaseMax, handleBulkTempDecrease, handleBulkTempIncrease, handleBulkTempIncreaseMax,
|
|
365
|
-
// Tint adjustments
|
|
366
|
-
handleBulkTintDecreaseMax, handleBulkTintDecrease, handleBulkTintIncrease, handleBulkTintIncreaseMax,
|
|
367
|
-
// Exposure adjustments
|
|
368
|
-
handleBulkExposureDecreaseMax, handleBulkExposureDecrease, handleBulkExposureIncrease, handleBulkExposureIncreaseMax,
|
|
369
|
-
// Contrast adjustments
|
|
370
|
-
handleBulkContrastDecreaseMax, handleBulkContrastDecrease, handleBulkContrastIncrease, handleBulkContrastIncreaseMax,
|
|
371
|
-
// Clarity adjustments
|
|
372
|
-
handleBulkClarityDecreaseMax, handleBulkClarityDecrease, handleBulkClarityIncrease, handleBulkClarityIncreaseMax,
|
|
373
|
-
// History actions
|
|
374
|
-
handleUndo, handleRedo, handleReset, historyInfo, } = useHonchoEditorBulk(controller, 'demo-event', 'demo-user');
|
|
375
|
-
const selectedCount = selectedIds.length;
|
|
376
|
-
const totalCount = imageData.length;
|
|
377
|
-
return (_jsxs(Container, { maxWidth: "xl", sx: { py: 4 }, children: [_jsx(Typography, { variant: "h3", gutterBottom: true, align: "center", children: "Honcho Editor Bulk Demo" }), _jsx(Typography, { variant: "subtitle1", align: "center", color: "text.secondary", gutterBottom: true, children: "This demo shows the useHonchoEditorBulk hook with 1,277 mock images from picsum.dev" }), error && (_jsx(Alert, { severity: "error", sx: { mb: 3 }, children: error })), _jsx(Paper, { sx: { p: 3, mb: 3 }, children: _jsxs(Stack, { direction: "row", spacing: 2, alignItems: "center", flexWrap: "wrap", children: [_jsx(Button, { variant: "contained", onClick: handleRefresh, disabled: isLoading, children: isLoading ? _jsx(CircularProgress, { size: 20 }) : 'Refresh Images' }), _jsxs(Button, { variant: "outlined", onClick: () => setShowAdjustments(!showAdjustments), children: [showAdjustments ? 'Hide' : 'Show', " Adjustments"] }), _jsx(Button, { variant: "outlined", onClick: () => {
|
|
378
|
-
// Select all images on current page
|
|
379
|
-
imageData.forEach(image => {
|
|
380
|
-
if (!image.isSelected) {
|
|
381
|
-
handleToggleImageSelection(image.key);
|
|
382
|
-
}
|
|
383
|
-
});
|
|
384
|
-
}, disabled: isLoading || imageData.length === 0, children: "Select All" }), _jsx(Button, { variant: "outlined", onClick: () => {
|
|
385
|
-
// Deselect all images
|
|
386
|
-
imageData.forEach(image => {
|
|
387
|
-
if (image.isSelected) {
|
|
388
|
-
handleToggleImageSelection(image.key);
|
|
389
|
-
}
|
|
390
|
-
});
|
|
391
|
-
}, disabled: isLoading || selectedCount === 0, children: "Clear Selection" }), _jsx(Button, { variant: "outlined", onClick: () => {
|
|
392
|
-
console.log('Debug Info:', {
|
|
393
|
-
selectedIds,
|
|
394
|
-
selectedCount,
|
|
395
|
-
showAdjustments,
|
|
396
|
-
presets: presets.map(p => ({ id: p.id, name: p.name })),
|
|
397
|
-
selectedBulkPreset,
|
|
398
|
-
activePreset: activePreset ? { id: activePreset.id, name: activePreset.name } : null,
|
|
399
|
-
imageData: imageData.map(img => ({ key: img.key, isSelected: img.isSelected }))
|
|
400
|
-
});
|
|
401
|
-
}, children: "Debug Selection" }), _jsx(Button, { variant: "outlined", onClick: handleBackCallbackBulk, children: "Back" }), _jsx(Chip, { label: `${selectedCount} of ${totalCount} selected`, color: selectedCount > 0 ? "primary" : "default" }), hasMore && (_jsx(Button, { variant: "outlined", onClick: handleLoadMore, disabled: isLoading, children: "Load More" })), _jsxs(FormControl, { size: "small", sx: { minWidth: 150 }, children: [_jsx(InputLabel, { children: "Bulk Preset" }), _jsxs(Select, { value: selectedBulkPreset, onChange: handleSelectBulkPreset, label: "Bulk Preset", displayEmpty: true, children: [_jsx(MenuItem, { value: "", children: _jsx("em", { children: "No Preset" }) }), presets.map((preset) => (_jsxs(MenuItem, { value: preset.id, children: [preset.name, activePreset?.id === preset.id && ' ✓'] }, preset.id)))] })] }), _jsxs(Typography, { variant: "body2", sx: { ml: 2, opacity: 0.7 }, children: ["Active: ", activePreset ? activePreset.name : 'None', " | Presets: ", presets.length] })] }) }), showAdjustments && (_jsxs(Paper, { sx: { p: 3, mb: 3 }, children: [_jsxs(Stack, { direction: "row", justifyContent: "space-between", alignItems: "center", sx: { mb: 2 }, children: [_jsxs(Typography, { variant: "h6", children: ["Bulk Adjustments (", selectedCount, " images selected)"] }), _jsxs(Stack, { direction: "row", spacing: 1, children: [_jsx(Button, { variant: "outlined", size: "small", onClick: handleUndo, disabled: !historyInfo.canUndo, sx: { minWidth: 80 }, children: "Undo" }), _jsx(Button, { variant: "outlined", size: "small", onClick: handleRedo, disabled: !historyInfo.canRedo, sx: { minWidth: 80 }, children: "Redo" }), _jsx(Button, { variant: "outlined", size: "small", onClick: () => handleReset(), disabled: selectedCount === 0, color: "warning", sx: { minWidth: 80 }, children: "Reset" })] })] }), selectedCount === 0 && (_jsx(Typography, { variant: "body2", color: "text.secondary", sx: { mb: 2 }, children: "Select one or more images below to enable bulk adjustments" })), _jsxs(Typography, { variant: "body2", color: "text.secondary", sx: { mb: 2 }, children: ["History: ", historyInfo.currentIndex + 1, "/", historyInfo.totalStates, " states | Can Undo: ", historyInfo.canUndo ? 'Yes' : 'No', " | Can Redo: ", historyInfo.canRedo ? 'Yes' : 'No'] }), _jsxs(Grid, { container: true, spacing: 3, children: [_jsxs(Grid, { item: true, xs: 12, md: 3, children: [_jsx(Typography, { variant: "subtitle2", gutterBottom: true, children: "Color" }), _jsx(AdjustmentControls, { label: "Temperature", onDecreaseMax: handleBulkTempDecreaseMax, onDecrease: handleBulkTempDecrease, onIncrease: handleBulkTempIncrease, onIncreaseMax: handleBulkTempIncreaseMax, disabled: selectedCount === 0 }), _jsx(AdjustmentControls, { label: "Tint", onDecreaseMax: handleBulkTintDecreaseMax, onDecrease: handleBulkTintDecrease, onIncrease: handleBulkTintIncrease, onIncreaseMax: handleBulkTintIncreaseMax, disabled: selectedCount === 0 })] }), _jsxs(Grid, { item: true, xs: 12, md: 3, children: [_jsx(Typography, { variant: "subtitle2", gutterBottom: true, children: "Light" }), _jsx(AdjustmentControls, { label: "Exposure", onDecreaseMax: handleBulkExposureDecreaseMax, onDecrease: handleBulkExposureDecrease, onIncrease: handleBulkExposureIncrease, onIncreaseMax: handleBulkExposureIncreaseMax, disabled: selectedCount === 0 }), _jsx(AdjustmentControls, { label: "Contrast", onDecreaseMax: handleBulkContrastDecreaseMax, onDecrease: handleBulkContrastDecrease, onIncrease: handleBulkContrastIncrease, onIncreaseMax: handleBulkContrastIncreaseMax, disabled: selectedCount === 0 })] }), _jsxs(Grid, { item: true, xs: 12, md: 3, children: [_jsx(Typography, { variant: "subtitle2", gutterBottom: true, children: "Details" }), _jsx(AdjustmentControls, { label: "Clarity", onDecreaseMax: handleBulkClarityDecreaseMax, onDecrease: handleBulkClarityDecrease, onIncrease: handleBulkClarityIncrease, onIncreaseMax: handleBulkClarityIncreaseMax, disabled: selectedCount === 0 })] })] })] })), _jsx(Grid, { container: true, spacing: 2, children: imageData.map((image) => (_jsx(Grid, { item: true, xs: 12, sm: 6, md: 4, lg: 3, children: _jsx(ImageCard, { image: image, onToggleSelection: handleToggleImageSelection }) }, image.key))) }), isLoading && imageData.length === 0 && (_jsx(Box, { display: "flex", justifyContent: "center", py: 4, children: _jsx(CircularProgress, {}) })), _jsxs(Box, { mt: 4, children: [_jsx(Divider, {}), _jsx(Typography, { variant: "body2", color: "text.secondary", align: "center", sx: { mt: 2 }, children: "Demo Notes: This uses mock data and simulated API calls. Select images and try the bulk adjustment controls above." })] })] }));
|
|
402
|
-
};
|
|
403
|
-
// Add debugging function to global scope for manual testing
|
|
404
|
-
if (typeof window !== 'undefined') {
|
|
405
|
-
window.testPresetSelection = () => {
|
|
406
|
-
console.log("🧪 Manual preset test - this would normally be called by the UI");
|
|
407
|
-
console.log("🧪 To test properly, use the actual preset dropdown in the UI above");
|
|
408
|
-
};
|
|
409
|
-
}
|
|
410
|
-
export default HonchoEditorBulkDemo;
|