@umituz/react-native-ai-generation-content 1.17.148 → 1.17.149
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/src/features/ai-hug/presentation/components/AIHugFeature.tsx +4 -0
- package/src/features/ai-hug/presentation/hooks/useAIHugFeature.ts +1 -0
- package/src/features/ai-kiss/presentation/components/AIKissFeature.tsx +4 -0
- package/src/features/ai-kiss/presentation/hooks/useAIKissFeature.ts +1 -0
- package/src/features/anime-selfie/presentation/components/AnimeSelfieFeature.tsx +4 -0
- package/src/features/anime-selfie/presentation/hooks/useAnimeSelfieFeature.ts +8 -2
- package/src/features/face-swap/presentation/components/FaceSwapFeature.tsx +4 -0
- package/src/features/face-swap/presentation/hooks/useFaceSwapFeature.ts +3 -2
- package/src/features/hd-touch-up/presentation/components/HDTouchUpFeature.tsx +4 -0
- package/src/features/hd-touch-up/presentation/hooks/useHDTouchUpFeature.ts +8 -2
- package/src/features/image-to-image/domain/types/base.types.ts +4 -0
- package/src/features/image-to-image/presentation/hooks/useDualImageFeature.ts +8 -2
- package/src/features/image-to-image/presentation/hooks/useImageWithPromptFeature.ts +10 -2
- package/src/features/image-to-image/presentation/hooks/useSingleImageFeature.ts +8 -2
- package/src/features/photo-restoration/presentation/components/PhotoRestoreFeature.tsx +4 -0
- package/src/features/photo-restoration/presentation/hooks/usePhotoRestoreFeature.ts +8 -2
- package/src/features/remove-background/presentation/components/RemoveBackgroundFeature.tsx +4 -0
- package/src/features/remove-background/presentation/hooks/useRemoveBackgroundFeature.ts +3 -2
- package/src/features/remove-object/presentation/components/RemoveObjectFeature.tsx +4 -0
- package/src/features/remove-object/presentation/hooks/useRemoveObjectFeature.ts +8 -2
- package/src/features/replace-background/presentation/components/ReplaceBackgroundFeature.tsx +4 -0
- package/src/features/replace-background/presentation/hooks/useReplaceBackgroundFeature.ts +3 -2
- package/src/features/shared/dual-image-video/domain/types/dual-image-video.types.ts +2 -0
- package/src/features/shared/dual-image-video/presentation/hooks/useDualImageVideoFeature.ts +7 -2
- package/src/features/upscaling/presentation/components/UpscaleFeature.tsx +4 -0
- package/src/features/upscaling/presentation/hooks/useUpscaleFeature.ts +3 -2
package/package.json
CHANGED
|
@@ -29,6 +29,8 @@ export interface AIHugFeatureProps {
|
|
|
29
29
|
onSaveVideo: (videoUrl: string) => Promise<void>;
|
|
30
30
|
/** Custom video player renderer - required for video playback */
|
|
31
31
|
renderVideoPlayer: (props: { videoUrl: string; size: number }) => React.ReactNode;
|
|
32
|
+
/** Called before processing starts. Return false to cancel. */
|
|
33
|
+
onBeforeProcess?: () => Promise<boolean>;
|
|
32
34
|
/** Optional custom processing modal renderer */
|
|
33
35
|
renderProcessingModal?: (props: {
|
|
34
36
|
visible: boolean;
|
|
@@ -43,6 +45,7 @@ export const AIHugFeature: React.FC<AIHugFeatureProps> = ({
|
|
|
43
45
|
onSelectTargetImage,
|
|
44
46
|
onSaveVideo,
|
|
45
47
|
renderVideoPlayer,
|
|
48
|
+
onBeforeProcess,
|
|
46
49
|
renderProcessingModal,
|
|
47
50
|
}) => {
|
|
48
51
|
const tokens = useAppDesignTokens();
|
|
@@ -54,6 +57,7 @@ export const AIHugFeature: React.FC<AIHugFeatureProps> = ({
|
|
|
54
57
|
onSelectSourceImage,
|
|
55
58
|
onSelectTargetImage,
|
|
56
59
|
onSaveVideo,
|
|
60
|
+
onBeforeProcess,
|
|
57
61
|
});
|
|
58
62
|
|
|
59
63
|
const handleProcess = useCallback(() => {
|
|
@@ -15,6 +15,7 @@ export interface UseAIHugFeatureProps {
|
|
|
15
15
|
onSelectSourceImage: () => Promise<string | null>;
|
|
16
16
|
onSelectTargetImage: () => Promise<string | null>;
|
|
17
17
|
onSaveVideo: (videoUrl: string) => Promise<void>;
|
|
18
|
+
onBeforeProcess?: () => Promise<boolean>;
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
export interface UseAIHugFeatureReturn extends AIHugFeatureState {
|
|
@@ -24,6 +24,8 @@ export interface AIKissFeatureProps {
|
|
|
24
24
|
onSaveVideo: (videoUrl: string) => Promise<void>;
|
|
25
25
|
/** Custom video player renderer - required for video playback */
|
|
26
26
|
renderVideoPlayer: (props: { videoUrl: string; size: number }) => React.ReactNode;
|
|
27
|
+
/** Called before processing starts. Return false to cancel. */
|
|
28
|
+
onBeforeProcess?: () => Promise<boolean>;
|
|
27
29
|
renderProcessingModal?: (props: {
|
|
28
30
|
visible: boolean;
|
|
29
31
|
progress: number;
|
|
@@ -37,6 +39,7 @@ export const AIKissFeature: React.FC<AIKissFeatureProps> = ({
|
|
|
37
39
|
onSelectTargetImage,
|
|
38
40
|
onSaveVideo,
|
|
39
41
|
renderVideoPlayer,
|
|
42
|
+
onBeforeProcess,
|
|
40
43
|
renderProcessingModal,
|
|
41
44
|
}) => {
|
|
42
45
|
const tokens = useAppDesignTokens();
|
|
@@ -48,6 +51,7 @@ export const AIKissFeature: React.FC<AIKissFeatureProps> = ({
|
|
|
48
51
|
onSelectSourceImage,
|
|
49
52
|
onSelectTargetImage,
|
|
50
53
|
onSaveVideo,
|
|
54
|
+
onBeforeProcess,
|
|
51
55
|
});
|
|
52
56
|
|
|
53
57
|
const handleProcess = useCallback(() => {
|
|
@@ -15,6 +15,7 @@ export interface UseAIKissFeatureProps {
|
|
|
15
15
|
onSelectSourceImage: () => Promise<string | null>;
|
|
16
16
|
onSelectTargetImage: () => Promise<string | null>;
|
|
17
17
|
onSaveVideo: (videoUrl: string) => Promise<void>;
|
|
18
|
+
onBeforeProcess?: () => Promise<boolean>;
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
export interface UseAIKissFeatureReturn extends AIKissFeatureState {
|
|
@@ -21,6 +21,8 @@ export interface AnimeSelfieFeatureProps {
|
|
|
21
21
|
translations: AnimeSelfieTranslations;
|
|
22
22
|
onSelectImage: () => Promise<string | null>;
|
|
23
23
|
onSaveImage: (imageUrl: string) => Promise<void>;
|
|
24
|
+
/** Called before processing starts. Return false to cancel. */
|
|
25
|
+
onBeforeProcess?: () => Promise<boolean>;
|
|
24
26
|
renderProcessingModal?: (props: {
|
|
25
27
|
visible: boolean;
|
|
26
28
|
progress: number;
|
|
@@ -32,6 +34,7 @@ export const AnimeSelfieFeature: React.FC<AnimeSelfieFeatureProps> = ({
|
|
|
32
34
|
translations,
|
|
33
35
|
onSelectImage,
|
|
34
36
|
onSaveImage,
|
|
37
|
+
onBeforeProcess,
|
|
35
38
|
renderProcessingModal,
|
|
36
39
|
}) => {
|
|
37
40
|
const tokens = useAppDesignTokens();
|
|
@@ -42,6 +45,7 @@ export const AnimeSelfieFeature: React.FC<AnimeSelfieFeatureProps> = ({
|
|
|
42
45
|
config,
|
|
43
46
|
onSelectImage,
|
|
44
47
|
onSaveImage,
|
|
48
|
+
onBeforeProcess,
|
|
45
49
|
});
|
|
46
50
|
|
|
47
51
|
const photoTranslations = useMemo(
|
|
@@ -15,6 +15,7 @@ export interface UseAnimeSelfieFeatureProps {
|
|
|
15
15
|
config: AnimeSelfieFeatureConfig;
|
|
16
16
|
onSelectImage: () => Promise<string | null>;
|
|
17
17
|
onSaveImage: (imageUrl: string) => Promise<void>;
|
|
18
|
+
onBeforeProcess?: () => Promise<boolean>;
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
export interface UseAnimeSelfieFeatureReturn extends AnimeSelfieFeatureState {
|
|
@@ -35,7 +36,7 @@ const initialState: AnimeSelfieFeatureState = {
|
|
|
35
36
|
export function useAnimeSelfieFeature(
|
|
36
37
|
props: UseAnimeSelfieFeatureProps,
|
|
37
38
|
): UseAnimeSelfieFeatureReturn {
|
|
38
|
-
const { config, onSelectImage, onSaveImage } = props;
|
|
39
|
+
const { config, onSelectImage, onSaveImage, onBeforeProcess } = props;
|
|
39
40
|
const [state, setState] = useState<AnimeSelfieFeatureState>(initialState);
|
|
40
41
|
|
|
41
42
|
const selectImage = useCallback(async () => {
|
|
@@ -58,6 +59,11 @@ export function useAnimeSelfieFeature(
|
|
|
58
59
|
const process = useCallback(async () => {
|
|
59
60
|
if (!state.imageUri) return;
|
|
60
61
|
|
|
62
|
+
if (onBeforeProcess) {
|
|
63
|
+
const canProceed = await onBeforeProcess();
|
|
64
|
+
if (!canProceed) return;
|
|
65
|
+
}
|
|
66
|
+
|
|
61
67
|
setState((prev) => ({
|
|
62
68
|
...prev,
|
|
63
69
|
isProcessing: true,
|
|
@@ -93,7 +99,7 @@ export function useAnimeSelfieFeature(
|
|
|
93
99
|
}));
|
|
94
100
|
config.onError?.(errorMessage);
|
|
95
101
|
}
|
|
96
|
-
}, [state.imageUri, config, handleProgress]);
|
|
102
|
+
}, [state.imageUri, config, handleProgress, onBeforeProcess]);
|
|
97
103
|
|
|
98
104
|
const save = useCallback(async () => {
|
|
99
105
|
if (!state.processedUrl) return;
|
|
@@ -22,6 +22,8 @@ export interface FaceSwapFeatureProps {
|
|
|
22
22
|
onSelectSourceImage: () => Promise<string | null>;
|
|
23
23
|
onSelectTargetImage: () => Promise<string | null>;
|
|
24
24
|
onSaveImage: (imageUrl: string) => Promise<void>;
|
|
25
|
+
/** Called before processing starts. Return false to cancel. */
|
|
26
|
+
onBeforeProcess?: () => Promise<boolean>;
|
|
25
27
|
renderProcessingModal?: (props: {
|
|
26
28
|
visible: boolean;
|
|
27
29
|
progress: number;
|
|
@@ -34,6 +36,7 @@ export const FaceSwapFeature: React.FC<FaceSwapFeatureProps> = ({
|
|
|
34
36
|
onSelectSourceImage,
|
|
35
37
|
onSelectTargetImage,
|
|
36
38
|
onSaveImage,
|
|
39
|
+
onBeforeProcess,
|
|
37
40
|
renderProcessingModal,
|
|
38
41
|
}) => {
|
|
39
42
|
const tokens = useAppDesignTokens();
|
|
@@ -45,6 +48,7 @@ export const FaceSwapFeature: React.FC<FaceSwapFeatureProps> = ({
|
|
|
45
48
|
onSelectSourceImage,
|
|
46
49
|
onSelectTargetImage,
|
|
47
50
|
onSaveImage,
|
|
51
|
+
onBeforeProcess,
|
|
48
52
|
});
|
|
49
53
|
|
|
50
54
|
const handleProcess = useCallback(() => {
|
|
@@ -14,15 +14,16 @@ export interface UseFaceSwapFeatureProps {
|
|
|
14
14
|
onSelectSourceImage: () => Promise<string | null>;
|
|
15
15
|
onSelectTargetImage: () => Promise<string | null>;
|
|
16
16
|
onSaveImage: (imageUrl: string) => Promise<void>;
|
|
17
|
+
onBeforeProcess?: () => Promise<boolean>;
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
export function useFaceSwapFeature(
|
|
20
21
|
props: UseFaceSwapFeatureProps,
|
|
21
22
|
): BaseDualImageHookReturn {
|
|
22
|
-
const { config, onSelectSourceImage, onSelectTargetImage, onSaveImage } = props;
|
|
23
|
+
const { config, onSelectSourceImage, onSelectTargetImage, onSaveImage, onBeforeProcess } = props;
|
|
23
24
|
|
|
24
25
|
return useDualImageFeature<FaceSwapFeatureConfig, FaceSwapResult>(
|
|
25
|
-
{ config, onSelectSourceImage, onSelectTargetImage, onSaveImage },
|
|
26
|
+
{ config, onSelectSourceImage, onSelectTargetImage, onSaveImage, onBeforeProcess },
|
|
26
27
|
{
|
|
27
28
|
buildInput: (sourceBase64, targetBase64, cfg) => ({
|
|
28
29
|
imageBase64: sourceBase64,
|
|
@@ -21,6 +21,8 @@ export interface HDTouchUpFeatureProps {
|
|
|
21
21
|
translations: HDTouchUpTranslations;
|
|
22
22
|
onSelectImage: () => Promise<string | null>;
|
|
23
23
|
onSaveImage: (imageUrl: string) => Promise<void>;
|
|
24
|
+
/** Called before processing starts. Return false to cancel. */
|
|
25
|
+
onBeforeProcess?: () => Promise<boolean>;
|
|
24
26
|
renderProcessingModal?: (props: {
|
|
25
27
|
visible: boolean;
|
|
26
28
|
progress: number;
|
|
@@ -32,6 +34,7 @@ export const HDTouchUpFeature: React.FC<HDTouchUpFeatureProps> = ({
|
|
|
32
34
|
translations,
|
|
33
35
|
onSelectImage,
|
|
34
36
|
onSaveImage,
|
|
37
|
+
onBeforeProcess,
|
|
35
38
|
renderProcessingModal,
|
|
36
39
|
}) => {
|
|
37
40
|
const tokens = useAppDesignTokens();
|
|
@@ -42,6 +45,7 @@ export const HDTouchUpFeature: React.FC<HDTouchUpFeatureProps> = ({
|
|
|
42
45
|
config,
|
|
43
46
|
onSelectImage,
|
|
44
47
|
onSaveImage,
|
|
48
|
+
onBeforeProcess,
|
|
45
49
|
});
|
|
46
50
|
|
|
47
51
|
const photoTranslations = useMemo(
|
|
@@ -15,6 +15,7 @@ export interface UseHDTouchUpFeatureProps {
|
|
|
15
15
|
config: HDTouchUpFeatureConfig;
|
|
16
16
|
onSelectImage: () => Promise<string | null>;
|
|
17
17
|
onSaveImage: (imageUrl: string) => Promise<void>;
|
|
18
|
+
onBeforeProcess?: () => Promise<boolean>;
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
export interface UseHDTouchUpFeatureReturn extends HDTouchUpFeatureState {
|
|
@@ -35,7 +36,7 @@ const initialState: HDTouchUpFeatureState = {
|
|
|
35
36
|
export function useHDTouchUpFeature(
|
|
36
37
|
props: UseHDTouchUpFeatureProps,
|
|
37
38
|
): UseHDTouchUpFeatureReturn {
|
|
38
|
-
const { config, onSelectImage, onSaveImage } = props;
|
|
39
|
+
const { config, onSelectImage, onSaveImage, onBeforeProcess } = props;
|
|
39
40
|
const [state, setState] = useState<HDTouchUpFeatureState>(initialState);
|
|
40
41
|
|
|
41
42
|
const selectImage = useCallback(async () => {
|
|
@@ -58,6 +59,11 @@ export function useHDTouchUpFeature(
|
|
|
58
59
|
const process = useCallback(async () => {
|
|
59
60
|
if (!state.imageUri) return;
|
|
60
61
|
|
|
62
|
+
if (onBeforeProcess) {
|
|
63
|
+
const canProceed = await onBeforeProcess();
|
|
64
|
+
if (!canProceed) return;
|
|
65
|
+
}
|
|
66
|
+
|
|
61
67
|
setState((prev) => ({
|
|
62
68
|
...prev,
|
|
63
69
|
isProcessing: true,
|
|
@@ -93,7 +99,7 @@ export function useHDTouchUpFeature(
|
|
|
93
99
|
}));
|
|
94
100
|
config.onError?.(errorMessage);
|
|
95
101
|
}
|
|
96
|
-
}, [state.imageUri, config, handleProgress]);
|
|
102
|
+
}, [state.imageUri, config, handleProgress, onBeforeProcess]);
|
|
97
103
|
|
|
98
104
|
const save = useCallback(async () => {
|
|
99
105
|
if (!state.processedUrl) return;
|
|
@@ -141,6 +141,8 @@ export interface BaseSingleImageHookProps<
|
|
|
141
141
|
config: TConfig;
|
|
142
142
|
onSelectImage: () => Promise<string | null>;
|
|
143
143
|
onSaveImage: (imageUrl: string) => Promise<void>;
|
|
144
|
+
/** Called before processing starts. Return false to cancel. */
|
|
145
|
+
onBeforeProcess?: () => Promise<boolean>;
|
|
144
146
|
}
|
|
145
147
|
|
|
146
148
|
/**
|
|
@@ -153,6 +155,8 @@ export interface BaseDualImageHookProps<
|
|
|
153
155
|
onSelectSourceImage: () => Promise<string | null>;
|
|
154
156
|
onSelectTargetImage: () => Promise<string | null>;
|
|
155
157
|
onSaveImage: (imageUrl: string) => Promise<void>;
|
|
158
|
+
/** Called before processing starts. Return false to cancel. */
|
|
159
|
+
onBeforeProcess?: () => Promise<boolean>;
|
|
156
160
|
}
|
|
157
161
|
|
|
158
162
|
/**
|
|
@@ -37,7 +37,7 @@ export function useDualImageFeature<
|
|
|
37
37
|
props: BaseDualImageHookProps<TConfig>,
|
|
38
38
|
options?: DualImageFeatureOptions<TConfig>,
|
|
39
39
|
): BaseDualImageHookReturn {
|
|
40
|
-
const { config, onSelectSourceImage, onSelectTargetImage, onSaveImage } = props;
|
|
40
|
+
const { config, onSelectSourceImage, onSelectTargetImage, onSaveImage, onBeforeProcess } = props;
|
|
41
41
|
const [state, setState] = useState<BaseDualImageState>(INITIAL_STATE);
|
|
42
42
|
|
|
43
43
|
const selectSourceImage = useCallback(async () => {
|
|
@@ -73,6 +73,12 @@ export function useDualImageFeature<
|
|
|
73
73
|
const process = useCallback(async () => {
|
|
74
74
|
if (!state.sourceImageUri || !state.targetImageUri) return;
|
|
75
75
|
|
|
76
|
+
// Check if processing is allowed (credit check, etc.)
|
|
77
|
+
if (onBeforeProcess) {
|
|
78
|
+
const canProceed = await onBeforeProcess();
|
|
79
|
+
if (!canProceed) return;
|
|
80
|
+
}
|
|
81
|
+
|
|
76
82
|
setState((prev) => ({
|
|
77
83
|
...prev,
|
|
78
84
|
isProcessing: true,
|
|
@@ -126,7 +132,7 @@ export function useDualImageFeature<
|
|
|
126
132
|
}));
|
|
127
133
|
config.onError?.(message);
|
|
128
134
|
}
|
|
129
|
-
}, [state.sourceImageUri, state.targetImageUri, config, options, handleProgress]);
|
|
135
|
+
}, [state.sourceImageUri, state.targetImageUri, config, options, handleProgress, onBeforeProcess]);
|
|
130
136
|
|
|
131
137
|
const save = useCallback(async () => {
|
|
132
138
|
if (!state.processedUrl) return;
|
|
@@ -32,6 +32,8 @@ export interface ImageWithPromptHookProps<
|
|
|
32
32
|
config: TConfig;
|
|
33
33
|
onSelectImage: () => Promise<string | null>;
|
|
34
34
|
onSaveImage: (imageUrl: string) => Promise<void>;
|
|
35
|
+
/** Called before processing starts. Return false to cancel. */
|
|
36
|
+
onBeforeProcess?: () => Promise<boolean>;
|
|
35
37
|
}
|
|
36
38
|
|
|
37
39
|
export interface ImageWithPromptHookReturn extends BaseImageWithPromptState {
|
|
@@ -58,7 +60,7 @@ export function useImageWithPromptFeature<
|
|
|
58
60
|
props: ImageWithPromptHookProps<TConfig>,
|
|
59
61
|
options?: ImageWithPromptOptions,
|
|
60
62
|
): ImageWithPromptHookReturn {
|
|
61
|
-
const { config, onSelectImage, onSaveImage } = props;
|
|
63
|
+
const { config, onSelectImage, onSaveImage, onBeforeProcess } = props;
|
|
62
64
|
const [state, setState] = useState<BaseImageWithPromptState>({
|
|
63
65
|
...INITIAL_STATE,
|
|
64
66
|
prompt: config.defaultPrompt || "",
|
|
@@ -92,6 +94,12 @@ export function useImageWithPromptFeature<
|
|
|
92
94
|
const process = useCallback(async () => {
|
|
93
95
|
if (!state.imageUri) return;
|
|
94
96
|
|
|
97
|
+
// Check if processing is allowed (credit check, etc.)
|
|
98
|
+
if (onBeforeProcess) {
|
|
99
|
+
const canProceed = await onBeforeProcess();
|
|
100
|
+
if (!canProceed) return;
|
|
101
|
+
}
|
|
102
|
+
|
|
95
103
|
if (options?.promptRequired && !state.prompt.trim()) {
|
|
96
104
|
const error = "Prompt is required";
|
|
97
105
|
setState((prev) => ({ ...prev, error }));
|
|
@@ -149,7 +157,7 @@ export function useImageWithPromptFeature<
|
|
|
149
157
|
}));
|
|
150
158
|
config.onError?.(message);
|
|
151
159
|
}
|
|
152
|
-
}, [state.imageUri, state.prompt, config, options, handleProgress]);
|
|
160
|
+
}, [state.imageUri, state.prompt, config, options, handleProgress, onBeforeProcess]);
|
|
153
161
|
|
|
154
162
|
const save = useCallback(async () => {
|
|
155
163
|
if (!state.processedUrl) return;
|
|
@@ -32,7 +32,7 @@ export function useSingleImageFeature<
|
|
|
32
32
|
props: BaseSingleImageHookProps<TConfig>,
|
|
33
33
|
options?: SingleImageFeatureOptions<TConfig>,
|
|
34
34
|
): BaseSingleImageHookReturn {
|
|
35
|
-
const { config, onSelectImage, onSaveImage } = props;
|
|
35
|
+
const { config, onSelectImage, onSaveImage, onBeforeProcess } = props;
|
|
36
36
|
const [state, setState] = useState<BaseSingleImageState>(INITIAL_STATE);
|
|
37
37
|
|
|
38
38
|
const selectImage = useCallback(async () => {
|
|
@@ -55,6 +55,12 @@ export function useSingleImageFeature<
|
|
|
55
55
|
const process = useCallback(async () => {
|
|
56
56
|
if (!state.imageUri) return;
|
|
57
57
|
|
|
58
|
+
// Check if processing is allowed (credit check, etc.)
|
|
59
|
+
if (onBeforeProcess) {
|
|
60
|
+
const canProceed = await onBeforeProcess();
|
|
61
|
+
if (!canProceed) return;
|
|
62
|
+
}
|
|
63
|
+
|
|
58
64
|
setState((prev) => ({
|
|
59
65
|
...prev,
|
|
60
66
|
isProcessing: true,
|
|
@@ -105,7 +111,7 @@ export function useSingleImageFeature<
|
|
|
105
111
|
}));
|
|
106
112
|
config.onError?.(message);
|
|
107
113
|
}
|
|
108
|
-
}, [state.imageUri, config, options, handleProgress]);
|
|
114
|
+
}, [state.imageUri, config, options, handleProgress, onBeforeProcess]);
|
|
109
115
|
|
|
110
116
|
const save = useCallback(async () => {
|
|
111
117
|
if (!state.processedUrl) return;
|
|
@@ -25,6 +25,8 @@ export interface PhotoRestoreFeatureProps {
|
|
|
25
25
|
onSelectImage: () => Promise<string | null>;
|
|
26
26
|
/** Save image callback */
|
|
27
27
|
onSaveImage: (imageUrl: string) => Promise<void>;
|
|
28
|
+
/** Called before processing starts. Return false to cancel. */
|
|
29
|
+
onBeforeProcess?: () => Promise<boolean>;
|
|
28
30
|
/** Optional custom processing modal renderer */
|
|
29
31
|
renderProcessingModal?: (props: {
|
|
30
32
|
visible: boolean;
|
|
@@ -37,6 +39,7 @@ export const PhotoRestoreFeature: React.FC<PhotoRestoreFeatureProps> = ({
|
|
|
37
39
|
translations,
|
|
38
40
|
onSelectImage,
|
|
39
41
|
onSaveImage,
|
|
42
|
+
onBeforeProcess,
|
|
40
43
|
renderProcessingModal,
|
|
41
44
|
}) => {
|
|
42
45
|
const tokens = useAppDesignTokens();
|
|
@@ -45,6 +48,7 @@ export const PhotoRestoreFeature: React.FC<PhotoRestoreFeatureProps> = ({
|
|
|
45
48
|
config,
|
|
46
49
|
onSelectImage,
|
|
47
50
|
onSaveImage,
|
|
51
|
+
onBeforeProcess,
|
|
48
52
|
});
|
|
49
53
|
|
|
50
54
|
const photoTranslations = useMemo(
|
|
@@ -15,6 +15,7 @@ export interface UsePhotoRestoreFeatureProps {
|
|
|
15
15
|
config: PhotoRestoreFeatureConfig;
|
|
16
16
|
onSelectImage: () => Promise<string | null>;
|
|
17
17
|
onSaveImage: (imageUrl: string) => Promise<void>;
|
|
18
|
+
onBeforeProcess?: () => Promise<boolean>;
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
export interface UsePhotoRestoreFeatureReturn extends PhotoRestoreFeatureState {
|
|
@@ -35,7 +36,7 @@ const initialState: PhotoRestoreFeatureState = {
|
|
|
35
36
|
export function usePhotoRestoreFeature(
|
|
36
37
|
props: UsePhotoRestoreFeatureProps,
|
|
37
38
|
): UsePhotoRestoreFeatureReturn {
|
|
38
|
-
const { config, onSelectImage, onSaveImage } = props;
|
|
39
|
+
const { config, onSelectImage, onSaveImage, onBeforeProcess } = props;
|
|
39
40
|
const [state, setState] = useState<PhotoRestoreFeatureState>(initialState);
|
|
40
41
|
|
|
41
42
|
const selectImage = useCallback(async () => {
|
|
@@ -58,6 +59,11 @@ export function usePhotoRestoreFeature(
|
|
|
58
59
|
const process = useCallback(async () => {
|
|
59
60
|
if (!state.imageUri) return;
|
|
60
61
|
|
|
62
|
+
if (onBeforeProcess) {
|
|
63
|
+
const canProceed = await onBeforeProcess();
|
|
64
|
+
if (!canProceed) return;
|
|
65
|
+
}
|
|
66
|
+
|
|
61
67
|
setState((prev) => ({
|
|
62
68
|
...prev,
|
|
63
69
|
isProcessing: true,
|
|
@@ -93,7 +99,7 @@ export function usePhotoRestoreFeature(
|
|
|
93
99
|
}));
|
|
94
100
|
config.onError?.(errorMessage);
|
|
95
101
|
}
|
|
96
|
-
}, [state.imageUri, config, handleProgress]);
|
|
102
|
+
}, [state.imageUri, config, handleProgress, onBeforeProcess]);
|
|
97
103
|
|
|
98
104
|
const save = useCallback(async () => {
|
|
99
105
|
if (!state.processedUrl) return;
|
|
@@ -21,6 +21,8 @@ export interface RemoveBackgroundFeatureProps {
|
|
|
21
21
|
translations: RemoveBackgroundTranslations;
|
|
22
22
|
onSelectImage: () => Promise<string | null>;
|
|
23
23
|
onSaveImage: (imageUrl: string) => Promise<void>;
|
|
24
|
+
/** Called before processing starts. Return false to cancel. */
|
|
25
|
+
onBeforeProcess?: () => Promise<boolean>;
|
|
24
26
|
renderProcessingModal?: (props: {
|
|
25
27
|
visible: boolean;
|
|
26
28
|
progress: number;
|
|
@@ -32,6 +34,7 @@ export const RemoveBackgroundFeature: React.FC<RemoveBackgroundFeatureProps> = (
|
|
|
32
34
|
translations,
|
|
33
35
|
onSelectImage,
|
|
34
36
|
onSaveImage,
|
|
37
|
+
onBeforeProcess,
|
|
35
38
|
renderProcessingModal,
|
|
36
39
|
}) => {
|
|
37
40
|
const tokens = useAppDesignTokens();
|
|
@@ -42,6 +45,7 @@ export const RemoveBackgroundFeature: React.FC<RemoveBackgroundFeatureProps> = (
|
|
|
42
45
|
config,
|
|
43
46
|
onSelectImage,
|
|
44
47
|
onSaveImage,
|
|
48
|
+
onBeforeProcess,
|
|
45
49
|
});
|
|
46
50
|
|
|
47
51
|
const photoTranslations = useMemo(
|
|
@@ -16,15 +16,16 @@ export interface UseRemoveBackgroundFeatureProps {
|
|
|
16
16
|
config: RemoveBackgroundFeatureConfig;
|
|
17
17
|
onSelectImage: () => Promise<string | null>;
|
|
18
18
|
onSaveImage: (imageUrl: string) => Promise<void>;
|
|
19
|
+
onBeforeProcess?: () => Promise<boolean>;
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
export function useRemoveBackgroundFeature(
|
|
22
23
|
props: UseRemoveBackgroundFeatureProps,
|
|
23
24
|
): BaseSingleImageHookReturn {
|
|
24
|
-
const { config, onSelectImage, onSaveImage } = props;
|
|
25
|
+
const { config, onSelectImage, onSaveImage, onBeforeProcess } = props;
|
|
25
26
|
|
|
26
27
|
return useSingleImageFeature<RemoveBackgroundFeatureConfig, RemoveBackgroundResult>(
|
|
27
|
-
{ config, onSelectImage, onSaveImage },
|
|
28
|
+
{ config, onSelectImage, onSaveImage, onBeforeProcess },
|
|
28
29
|
{
|
|
29
30
|
buildInput: (imageBase64, cfg) => ({
|
|
30
31
|
imageBase64,
|
|
@@ -25,6 +25,8 @@ export interface RemoveObjectFeatureProps {
|
|
|
25
25
|
translations: RemoveObjectTranslations;
|
|
26
26
|
onSelectImage: () => Promise<string | null>;
|
|
27
27
|
onSaveImage: (imageUrl: string) => Promise<void>;
|
|
28
|
+
/** Called before processing starts. Return false to cancel. */
|
|
29
|
+
onBeforeProcess?: () => Promise<boolean>;
|
|
28
30
|
renderProcessingModal?: (props: {
|
|
29
31
|
visible: boolean;
|
|
30
32
|
progress: number;
|
|
@@ -36,6 +38,7 @@ export const RemoveObjectFeature: React.FC<RemoveObjectFeatureProps> = ({
|
|
|
36
38
|
translations,
|
|
37
39
|
onSelectImage,
|
|
38
40
|
onSaveImage,
|
|
41
|
+
onBeforeProcess,
|
|
39
42
|
renderProcessingModal,
|
|
40
43
|
}) => {
|
|
41
44
|
const tokens = useAppDesignTokens();
|
|
@@ -46,6 +49,7 @@ export const RemoveObjectFeature: React.FC<RemoveObjectFeatureProps> = ({
|
|
|
46
49
|
config,
|
|
47
50
|
onSelectImage,
|
|
48
51
|
onSaveImage,
|
|
52
|
+
onBeforeProcess,
|
|
49
53
|
});
|
|
50
54
|
|
|
51
55
|
const photoTranslations = useMemo(
|
|
@@ -16,6 +16,7 @@ export interface UseRemoveObjectFeatureProps {
|
|
|
16
16
|
onSelectImage: () => Promise<string | null>;
|
|
17
17
|
onSelectMask?: () => Promise<string | null>;
|
|
18
18
|
onSaveImage: (imageUrl: string) => Promise<void>;
|
|
19
|
+
onBeforeProcess?: () => Promise<boolean>;
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
export interface UseRemoveObjectFeatureReturn extends RemoveObjectFeatureState {
|
|
@@ -40,7 +41,7 @@ const initialState: RemoveObjectFeatureState = {
|
|
|
40
41
|
export function useRemoveObjectFeature(
|
|
41
42
|
props: UseRemoveObjectFeatureProps,
|
|
42
43
|
): UseRemoveObjectFeatureReturn {
|
|
43
|
-
const { config, onSelectImage, onSelectMask, onSaveImage } = props;
|
|
44
|
+
const { config, onSelectImage, onSelectMask, onSaveImage, onBeforeProcess } = props;
|
|
44
45
|
const [state, setState] = useState<RemoveObjectFeatureState>(initialState);
|
|
45
46
|
|
|
46
47
|
const selectImage = useCallback(async () => {
|
|
@@ -82,6 +83,11 @@ export function useRemoveObjectFeature(
|
|
|
82
83
|
const process = useCallback(async () => {
|
|
83
84
|
if (!state.imageUri) return;
|
|
84
85
|
|
|
86
|
+
if (onBeforeProcess) {
|
|
87
|
+
const canProceed = await onBeforeProcess();
|
|
88
|
+
if (!canProceed) return;
|
|
89
|
+
}
|
|
90
|
+
|
|
85
91
|
setState((prev) => ({
|
|
86
92
|
...prev,
|
|
87
93
|
isProcessing: true,
|
|
@@ -124,7 +130,7 @@ export function useRemoveObjectFeature(
|
|
|
124
130
|
}));
|
|
125
131
|
config.onError?.(errorMessage);
|
|
126
132
|
}
|
|
127
|
-
}, [state.imageUri, state.maskUri, state.prompt, config, handleProgress]);
|
|
133
|
+
}, [state.imageUri, state.maskUri, state.prompt, config, handleProgress, onBeforeProcess]);
|
|
128
134
|
|
|
129
135
|
const save = useCallback(async () => {
|
|
130
136
|
if (!state.processedUrl) return;
|
package/src/features/replace-background/presentation/components/ReplaceBackgroundFeature.tsx
CHANGED
|
@@ -25,6 +25,8 @@ export interface ReplaceBackgroundFeatureProps {
|
|
|
25
25
|
translations: ReplaceBackgroundTranslations;
|
|
26
26
|
onSelectImage: () => Promise<string | null>;
|
|
27
27
|
onSaveImage: (imageUrl: string) => Promise<void>;
|
|
28
|
+
/** Called before processing starts. Return false to cancel. */
|
|
29
|
+
onBeforeProcess?: () => Promise<boolean>;
|
|
28
30
|
renderProcessingModal?: (props: {
|
|
29
31
|
visible: boolean;
|
|
30
32
|
progress: number;
|
|
@@ -36,6 +38,7 @@ export const ReplaceBackgroundFeature: React.FC<ReplaceBackgroundFeatureProps> =
|
|
|
36
38
|
translations,
|
|
37
39
|
onSelectImage,
|
|
38
40
|
onSaveImage,
|
|
41
|
+
onBeforeProcess,
|
|
39
42
|
renderProcessingModal,
|
|
40
43
|
}) => {
|
|
41
44
|
const tokens = useAppDesignTokens();
|
|
@@ -46,6 +49,7 @@ export const ReplaceBackgroundFeature: React.FC<ReplaceBackgroundFeatureProps> =
|
|
|
46
49
|
config,
|
|
47
50
|
onSelectImage,
|
|
48
51
|
onSaveImage,
|
|
52
|
+
onBeforeProcess,
|
|
49
53
|
});
|
|
50
54
|
|
|
51
55
|
const photoTranslations = useMemo(
|
|
@@ -18,6 +18,7 @@ export interface UseReplaceBackgroundFeatureProps {
|
|
|
18
18
|
config: ReplaceBackgroundFeatureConfig;
|
|
19
19
|
onSelectImage: () => Promise<string | null>;
|
|
20
20
|
onSaveImage: (imageUrl: string) => Promise<void>;
|
|
21
|
+
onBeforeProcess?: () => Promise<boolean>;
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
export interface UseReplaceBackgroundFeatureReturn extends ImageWithPromptHookReturn {
|
|
@@ -28,11 +29,11 @@ export interface UseReplaceBackgroundFeatureReturn extends ImageWithPromptHookRe
|
|
|
28
29
|
export function useReplaceBackgroundFeature(
|
|
29
30
|
props: UseReplaceBackgroundFeatureProps,
|
|
30
31
|
): UseReplaceBackgroundFeatureReturn {
|
|
31
|
-
const { config, onSelectImage, onSaveImage } = props;
|
|
32
|
+
const { config, onSelectImage, onSaveImage, onBeforeProcess } = props;
|
|
32
33
|
const [mode, setMode] = useState<ReplaceBackgroundMode>(config.defaultMode || "replace");
|
|
33
34
|
|
|
34
35
|
const baseHook = useImageWithPromptFeature<ReplaceBackgroundFeatureConfig, ReplaceBackgroundResult>(
|
|
35
|
-
{ config, onSelectImage, onSaveImage },
|
|
36
|
+
{ config, onSelectImage, onSaveImage, onBeforeProcess },
|
|
36
37
|
{
|
|
37
38
|
buildInput: (imageBase64, prompt) => ({
|
|
38
39
|
imageBase64,
|
|
@@ -56,6 +56,8 @@ export interface UseDualImageVideoFeatureProps {
|
|
|
56
56
|
onSelectSourceImage: () => Promise<string | null>;
|
|
57
57
|
onSelectTargetImage: () => Promise<string | null>;
|
|
58
58
|
onSaveVideo: (videoUrl: string) => Promise<void>;
|
|
59
|
+
/** Called before processing starts. Return false to cancel. */
|
|
60
|
+
onBeforeProcess?: () => Promise<boolean>;
|
|
59
61
|
}
|
|
60
62
|
|
|
61
63
|
export interface UseDualImageVideoFeatureReturn extends DualImageVideoFeatureState {
|
|
@@ -24,7 +24,7 @@ const initialState: DualImageVideoFeatureState = {
|
|
|
24
24
|
export function useDualImageVideoFeature(
|
|
25
25
|
props: UseDualImageVideoFeatureProps,
|
|
26
26
|
): UseDualImageVideoFeatureReturn {
|
|
27
|
-
const { featureType, config, onSelectSourceImage, onSelectTargetImage, onSaveVideo } = props;
|
|
27
|
+
const { featureType, config, onSelectSourceImage, onSelectTargetImage, onSaveVideo, onBeforeProcess } = props;
|
|
28
28
|
const [state, setState] = useState<DualImageVideoFeatureState>(initialState);
|
|
29
29
|
|
|
30
30
|
const selectSourceImage = useCallback(async () => {
|
|
@@ -60,6 +60,11 @@ export function useDualImageVideoFeature(
|
|
|
60
60
|
const process = useCallback(async () => {
|
|
61
61
|
if (!state.sourceImageUri || !state.targetImageUri) return;
|
|
62
62
|
|
|
63
|
+
if (onBeforeProcess) {
|
|
64
|
+
const canProceed = await onBeforeProcess();
|
|
65
|
+
if (!canProceed) return;
|
|
66
|
+
}
|
|
67
|
+
|
|
63
68
|
setState((prev) => ({
|
|
64
69
|
...prev,
|
|
65
70
|
isProcessing: true,
|
|
@@ -96,7 +101,7 @@ export function useDualImageVideoFeature(
|
|
|
96
101
|
}));
|
|
97
102
|
config.onError?.(errorMessage);
|
|
98
103
|
}
|
|
99
|
-
}, [state.sourceImageUri, state.targetImageUri, featureType, config, handleProgress]);
|
|
104
|
+
}, [state.sourceImageUri, state.targetImageUri, featureType, config, handleProgress, onBeforeProcess]);
|
|
100
105
|
|
|
101
106
|
const save = useCallback(async () => {
|
|
102
107
|
if (!state.processedVideoUrl) return;
|
|
@@ -28,6 +28,8 @@ export interface UpscaleFeatureProps {
|
|
|
28
28
|
onSelectImage: () => Promise<string | null>;
|
|
29
29
|
/** Save image callback */
|
|
30
30
|
onSaveImage: (imageUrl: string) => Promise<void>;
|
|
31
|
+
/** Called before processing starts. Return false to cancel. */
|
|
32
|
+
onBeforeProcess?: () => Promise<boolean>;
|
|
31
33
|
/** Optional custom processing modal renderer */
|
|
32
34
|
renderProcessingModal?: (props: {
|
|
33
35
|
visible: boolean;
|
|
@@ -40,6 +42,7 @@ export const UpscaleFeature: React.FC<UpscaleFeatureProps> = ({
|
|
|
40
42
|
translations,
|
|
41
43
|
onSelectImage,
|
|
42
44
|
onSaveImage,
|
|
45
|
+
onBeforeProcess,
|
|
43
46
|
renderProcessingModal,
|
|
44
47
|
}) => {
|
|
45
48
|
const tokens = useAppDesignTokens();
|
|
@@ -48,6 +51,7 @@ export const UpscaleFeature: React.FC<UpscaleFeatureProps> = ({
|
|
|
48
51
|
config,
|
|
49
52
|
onSelectImage,
|
|
50
53
|
onSaveImage,
|
|
54
|
+
onBeforeProcess,
|
|
51
55
|
});
|
|
52
56
|
|
|
53
57
|
const photoTranslations = useMemo(
|
|
@@ -13,15 +13,16 @@ export interface UseUpscaleFeatureProps {
|
|
|
13
13
|
config: UpscaleFeatureConfig;
|
|
14
14
|
onSelectImage: () => Promise<string | null>;
|
|
15
15
|
onSaveImage: (imageUrl: string) => Promise<void>;
|
|
16
|
+
onBeforeProcess?: () => Promise<boolean>;
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
export function useUpscaleFeature(
|
|
19
20
|
props: UseUpscaleFeatureProps,
|
|
20
21
|
): BaseSingleImageHookReturn {
|
|
21
|
-
const { config, onSelectImage, onSaveImage } = props;
|
|
22
|
+
const { config, onSelectImage, onSaveImage, onBeforeProcess } = props;
|
|
22
23
|
|
|
23
24
|
return useSingleImageFeature<UpscaleFeatureConfig, UpscaleResult>(
|
|
24
|
-
{ config, onSelectImage, onSaveImage },
|
|
25
|
+
{ config, onSelectImage, onSaveImage, onBeforeProcess },
|
|
25
26
|
{
|
|
26
27
|
buildInput: (imageBase64, cfg) => ({
|
|
27
28
|
imageBase64,
|