Skip to content

Commit bc83d5c

Browse files
authored
Merge pull request CyberTimon#1389 from VailElla/codex/ts-01-shared-contracts
fix(frontend): align shared TypeScript contracts
2 parents e8139b8 + ee6c768 commit bc83d5c

15 files changed

Lines changed: 147 additions & 72 deletions

src/components/modals/CollageModal.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ interface CollageModalProps {
2828
isOpen: boolean;
2929
onClose(): void;
3030
onSave(base64Data: string, firstPath: string): Promise<string>;
31-
sourceImages: ImageFile[];
31+
sourceImages: Array<Pick<ImageFile, 'path'>>;
3232
thumbnails: Record<string, string>;
3333
}
3434

@@ -152,7 +152,7 @@ export default function CollageModal({ isOpen, onClose, onSave, sourceImages }:
152152
path: imageFile.path,
153153
jsAdjustments: adjustments,
154154
});
155-
const blob = new Blob([imageData], { type: 'image/jpeg' });
155+
const blob = new Blob([new Uint8Array(imageData)], { type: 'image/jpeg' });
156156
const url = URL.createObjectURL(blob);
157157

158158
return new Promise<LoadedImage>((resolve, reject) => {

src/components/panel/Editor.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { invoke } from '@tauri-apps/api/core';
66
import { toast } from 'react-toastify';
77
import debounce from 'lodash.debounce';
88

9-
import { ImageDimensions, useImageRenderSize } from '../../hooks/useImageRenderSize';
9+
import { ImageDimensions, RenderSize, useImageRenderSize } from '../../hooks/useImageRenderSize';
1010
import { Adjustments, AiPatch, MaskContainer } from '../../utils/adjustments';
1111
import { calculateCenteredCrop, rotateCropCenter } from '../../utils/cropUtils';
1212
import EditorToolbar from './editor/EditorToolbar';
@@ -209,7 +209,7 @@ export default function Editor({ onBackToLibrary, onContextMenu, transformWrappe
209209
}, [isFullScreen, selectedImage, targetZoom, setUI]);
210210

211211
const handleDisplaySizeChange = useCallback(
212-
(size: any) => {
212+
(size: RenderSize) => {
213213
setEditor({ displaySize: { width: size.width, height: size.height } });
214214
if (size.scale) {
215215
const baseWidth = size.width / size.scale;
@@ -222,7 +222,7 @@ export default function Editor({ onBackToLibrary, onContextMenu, transformWrappe
222222
containerWidth: size.containerWidth || 0,
223223
containerHeight: size.containerHeight || 0,
224224
};
225-
setEditor({ baseRenderSize: newSize as any });
225+
setEditor({ baseRenderSize: newSize });
226226
}
227227
},
228228
[setEditor],
@@ -1334,7 +1334,7 @@ export default function Editor({ onBackToLibrary, onContextMenu, transformWrappe
13341334
return JSON.stringify({
13351335
id: activeMaskDef.id,
13361336
invert: activeMaskDef.invert,
1337-
opacity: activeMaskDef.opacity,
1337+
...('opacity' in activeMaskDef ? { opacity: activeMaskDef.opacity } : {}),
13381338
subMasks,
13391339
geometry,
13401340
renderSize: { w: imageRenderSize.width, h: imageRenderSize.height },

src/components/panel/editor/ExifIcons.tsx

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import React from 'react';
2+
import type { SVGProps } from 'react';
23

34
const iconProps = {
45
width: 16,
@@ -11,15 +12,17 @@ const iconProps = {
1112
strokeLinejoin: 'round' as const,
1213
};
1314

14-
export const IconAperture = () => (
15-
<svg {...iconProps}>
15+
type ExifIconProps = SVGProps<SVGSVGElement>;
16+
17+
export const IconAperture = (props: ExifIconProps) => (
18+
<svg {...iconProps} {...props}>
1619
<circle cx="12" cy="12" r="10" />
1720
<path d="M14.31 8l5.74 9.94M9.69 8h11.48M7.38 12l5.74-9.94M9.69 16L3.95 6.06M14.31 16H2.83M16.62 12l-5.74 9.94" />
1821
</svg>
1922
);
2023

21-
export const IconShutter = () => (
22-
<svg {...iconProps}>
24+
export const IconShutter = (props: ExifIconProps) => (
25+
<svg {...iconProps} {...props}>
2326
<circle cx="12" cy="12" r="10" />
2427
<path d="M12 12V7" />
2528
<path d="M12 2v2" />
@@ -33,41 +36,41 @@ export const IconShutter = () => (
3336
</svg>
3437
);
3538

36-
export const IconIso = () => (
37-
<svg {...iconProps}>
39+
export const IconIso = (props: ExifIconProps) => (
40+
<svg {...iconProps} {...props}>
3841
<rect x="2" y="4" width="20" height="16" rx="2" />
3942
<circle cx="12" cy="12" r="3" />
4043
<path d="M6 8h.01M6 16h.01M18 8h.01M18 16h.01" />
4144
</svg>
4245
);
4346

44-
export const IconFocalLength = () => (
45-
<svg {...iconProps}>
47+
export const IconFocalLength = (props: ExifIconProps) => (
48+
<svg {...iconProps} {...props}>
4649
<path d="M2 12L22 12" />
4750
<path d="M17 12a5 5 0 0 0-5-5 5 5 0 0 0-5 5" />
4851
<path d="M2 12l6 8" />
4952
<path d="M22 12l-6 8" />
5053
</svg>
5154
);
5255

53-
export const IconCalendar = () => (
54-
<svg {...iconProps}>
56+
export const IconCalendar = (props: ExifIconProps) => (
57+
<svg {...iconProps} {...props}>
5558
<rect x="3" y="4" width="18" height="18" rx="2" ry="2" />
5659
<line x1="16" y1="2" x2="16" y2="6" />
5760
<line x1="8" y1="2" x2="8" y2="6" />
5861
<line x1="3" y1="10" x2="21" y2="10" />
5962
</svg>
6063
);
6164

62-
export const IconClock = () => (
63-
<svg {...iconProps}>
65+
export const IconClock = (props: ExifIconProps) => (
66+
<svg {...iconProps} {...props}>
6467
<circle cx="12" cy="12" r="10" />
6568
<polyline points="12 6 12 12 16 14" />
6669
</svg>
6770
);
6871

69-
export const IconLens = () => (
70-
<svg {...iconProps}>
72+
export const IconLens = (props: ExifIconProps) => (
73+
<svg {...iconProps} {...props}>
7174
<circle cx="12" cy="12" r="10" />
7275
<circle cx="12" cy="12" r="5" />
7376
<path d="M12 7a5 5 0 0 1 5 5" strokeWidth="1.5" strokeOpacity="0.4" />

src/components/panel/editor/ImageCanvas.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1997,7 +1997,7 @@ const ImageCanvas = memo(
19971997
return;
19981998
}
19991999

2000-
if (isAiSubjectActive && previewBoxRef.current) {
2000+
if (isAiSubjectActive && previewBoxRef.current && pos) {
20012001
const updatedBox = { ...previewBoxRef.current, end: pos };
20022002
previewBoxRef.current = updatedBox;
20032003
setPreviewBox(updatedBox);

src/components/panel/right/ExportPanel.tsx

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -506,13 +506,12 @@ export default function ExportPanel({
506506

507507
if (isAndroid || outputFolderOrFile) {
508508
if (!isAndroid) {
509-
const dir =
510-
shouldChooseOutputFile
511-
? outputFolderOrFile.substring(
512-
0,
513-
Math.max(outputFolderOrFile.lastIndexOf('/'), outputFolderOrFile.lastIndexOf('\\')),
514-
)
515-
: outputFolderOrFile;
509+
const dir = shouldChooseOutputFile
510+
? outputFolderOrFile.substring(
511+
0,
512+
Math.max(outputFolderOrFile.lastIndexOf('/'), outputFolderOrFile.lastIndexOf('\\')),
513+
)
514+
: outputFolderOrFile;
516515
if (dir) saveLastUsedPreset(dir);
517516
}
518517

@@ -599,7 +598,7 @@ export default function ExportPanel({
599598
}
600599
max={100}
601600
min={1}
602-
onChange={(e) => setJpegQuality(parseInt(e.target.value))}
601+
onChange={(e) => setJpegQuality(Number(e.target.value))}
603602
step={1}
604603
value={jpegQuality}
605604
fillOrigin="min"
@@ -729,7 +728,7 @@ export default function ExportPanel({
729728
max={50}
730729
step={1}
731730
value={watermarkScale}
732-
onChange={(e) => setWatermarkScale(parseInt(e.target.value))}
731+
onChange={(e) => setWatermarkScale(Number(e.target.value))}
733732
disabled={isExporting}
734733
defaultValue={10}
735734
/>
@@ -739,7 +738,7 @@ export default function ExportPanel({
739738
max={25}
740739
step={1}
741740
value={watermarkSpacing}
742-
onChange={(e) => setWatermarkSpacing(parseInt(e.target.value))}
741+
onChange={(e) => setWatermarkSpacing(Number(e.target.value))}
743742
disabled={isExporting}
744743
defaultValue={5}
745744
/>
@@ -749,7 +748,7 @@ export default function ExportPanel({
749748
max={100}
750749
step={1}
751750
value={watermarkOpacity}
752-
onChange={(e) => setWatermarkOpacity(parseInt(e.target.value))}
751+
onChange={(e) => setWatermarkOpacity(Number(e.target.value))}
753752
disabled={isExporting}
754753
defaultValue={75}
755754
/>

src/components/panel/right/PresetsPanel.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -648,7 +648,7 @@ export default function PresetsPanel({ onNavigateToCommunity }: PresetsPanelProp
648648
break;
649649
}
650650

651-
const blob = new Blob([imageData], { type: 'image/jpeg' });
651+
const blob = new Blob([new Uint8Array(imageData)], { type: 'image/jpeg' });
652652
const url = URL.createObjectURL(blob);
653653
setPreviews((prev: Record<string, string | null>) => {
654654
const oldUrl = prev[preset.id];
@@ -714,7 +714,7 @@ export default function PresetsPanel({ onNavigateToCommunity }: PresetsPanelProp
714714

715715
if (pathAtStart !== currentImagePathRef.current) return;
716716

717-
const blob = new Blob([imageData], { type: 'image/jpeg' });
717+
const blob = new Blob([new Uint8Array(imageData)], { type: 'image/jpeg' });
718718
const url = URL.createObjectURL(blob);
719719

720720
setPreviews((prev: Record<string, string | null>) => {

src/components/ui/AppProperties.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,8 @@ export interface AppSettings {
172172
enableLivePreviews?: boolean;
173173
livePreviewQuality?: string;
174174
enableAiTagging?: boolean;
175+
aiTagCount?: number;
176+
customAiTags?: string[];
175177
filterCriteria?: FilterCriteria;
176178
lastFolderState?: any;
177179
pinnedFolders?: any;
@@ -209,7 +211,10 @@ export interface AppSettings {
209211
folderIcons?: Record<string, string>;
210212
exifOverlay?: ExifOverlay;
211213
language?: string;
214+
fontFamily?: string;
212215
folderTreeSort?: FolderTreeSort;
216+
rootFolders?: string[];
217+
taggingShortcuts?: string[];
213218
}
214219

215220
export interface BrushSettings {

src/components/ui/Button.tsx

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
11
import clsx from 'clsx';
2+
import type { ButtonHTMLAttributes, ReactNode } from 'react';
23

3-
interface ButtonProps {
4-
autoFocus?: boolean;
5-
children: any;
6-
className?: string;
7-
disabled?: boolean;
8-
onClick: any;
4+
interface ButtonProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'children' | 'size'> {
5+
children: ReactNode;
96
size?: string;
10-
title?: string;
117
variant?: string;
128
}
139

14-
const Button = ({ children, onClick, disabled, className = '', ...props }: ButtonProps) => {
10+
const Button = ({
11+
children,
12+
onClick,
13+
disabled,
14+
className = '',
15+
size: _size,
16+
variant: _variant,
17+
...props
18+
}: ButtonProps) => {
1519
const baseClasses = `
1620
flex items-center justify-center gap-2
1721
font-semibold py-2 px-4 rounded-md

src/components/ui/LUTControl.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ export default function LUTControl({
154154
console.error('Failed to resolve Android URI:', e);
155155
return path;
156156
}
157-
})
157+
}),
158158
);
159159
const allowedExtensions = new Set(['cube', '3dl']);
160160
validPaths = sourcePaths.filter((_, index) => {
@@ -297,7 +297,7 @@ export default function LUTControl({
297297
step={1}
298298
value={lutIntensity}
299299
defaultValue={100}
300-
onChange={(e) => onIntensityChange(parseInt(e.target.value, 10))}
300+
onChange={(e) => onIntensityChange(Number(e.target.value))}
301301
onDragStateChange={onDragStateChange}
302302
fillOrigin="min"
303303
/>

0 commit comments

Comments
 (0)