@umituz/react-native-ai-generation-content 1.20.12 → 1.20.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/package.json +1 -1
  2. package/src/features/ai-hug/presentation/components/AIHugFeature.tsx +2 -14
  3. package/src/features/ai-kiss/presentation/components/AIKissFeature.tsx +2 -17
  4. package/src/features/anime-selfie/presentation/components/AnimeSelfieFeature.tsx +2 -19
  5. package/src/features/anime-selfie/presentation/hooks/useAnimeSelfieFeature.ts +1 -1
  6. package/src/features/face-swap/presentation/components/FaceSwapFeature.tsx +2 -18
  7. package/src/features/hd-touch-up/presentation/components/HDTouchUpFeature.tsx +2 -18
  8. package/src/features/image-to-image/presentation/hooks/useDualImageFeature.ts +1 -1
  9. package/src/features/image-to-image/presentation/hooks/useImageWithPromptFeature.ts +1 -1
  10. package/src/features/image-to-image/presentation/hooks/useSingleImageFeature.ts +2 -5
  11. package/src/features/photo-restoration/presentation/components/PhotoRestoreFeature.tsx +2 -18
  12. package/src/features/remove-background/presentation/components/RemoveBackgroundFeature.tsx +2 -14
  13. package/src/features/remove-object/presentation/components/RemoveObjectFeature.tsx +5 -26
  14. package/src/features/remove-object/presentation/hooks/useRemoveObjectFeature.ts +1 -1
  15. package/src/features/replace-background/presentation/components/ReplaceBackgroundFeature.tsx +2 -18
  16. package/src/features/shared/dual-image-video/presentation/hooks/useDualImageVideoFeature.ts +1 -1
  17. package/src/features/text-to-video/presentation/hooks/useTextToVideoFeature.ts +1 -1
  18. package/src/features/upscaling/presentation/components/UpscaleFeature.tsx +2 -18
  19. package/src/features/wizard/presentation/components/AIGenerationWizard.tsx +2 -6
  20. package/src/index.ts +10 -11
  21. package/src/presentation/components/AIGenerationForm.tsx +0 -16
  22. package/src/presentation/components/index.ts +0 -6
  23. package/src/presentation/layouts/DualImageFeatureLayout.tsx +65 -56
  24. package/src/presentation/layouts/DualImageVideoFeatureLayout.tsx +65 -56
  25. package/src/presentation/layouts/SingleImageFeatureLayout.tsx +63 -54
  26. package/src/presentation/layouts/SingleImageWithPromptFeatureLayout.tsx +65 -56
  27. package/src/presentation/layouts/index.ts +0 -7
  28. package/src/presentation/layouts/types/index.ts +1 -5
  29. package/src/presentation/layouts/types/layout-props.ts +13 -21
  30. package/src/presentation/layouts/types/result-props.ts +0 -8
  31. package/src/presentation/components/GenerationProgressModal.tsx +0 -134
package/src/index.ts CHANGED
@@ -85,7 +85,7 @@ export type {
85
85
  } from "./presentation/hooks";
86
86
 
87
87
  export {
88
- GenerationProgressModal, GenerationProgressContent, GenerationProgressBar, PendingJobCard,
88
+ GenerationProgressContent, GenerationProgressBar, PendingJobCard,
89
89
  PendingJobProgressBar, PendingJobCardActions, GenerationResultContent, ResultHeader,
90
90
  ResultImageCard, ResultStoryCard, ResultActions, DEFAULT_RESULT_CONFIG, PhotoStep,
91
91
  DualImagePicker, PromptInput, AIGenerationHero, ExamplePrompts, ModerationSummary,
@@ -105,20 +105,19 @@ export type {
105
105
  SingleImageInputRenderProps, SingleImageWithPromptInputRenderProps,
106
106
  SingleImageWithPromptFeatureState, SingleImageWithPromptFeatureLayoutProps,
107
107
  DualImageInputRenderProps, ResultRenderProps, CustomResultRenderProps,
108
- ProcessingModalRenderProps, SingleImageFeatureLayoutProps, DualImageFeatureLayoutProps,
108
+ SingleImageFeatureLayoutProps, DualImageFeatureLayoutProps,
109
109
  DualImageVideoFeatureState, DualImageVideoFeatureLayoutProps,
110
110
  } from "./presentation/layouts";
111
111
 
112
112
  export type {
113
- GenerationProgressModalProps, GenerationProgressRenderProps, GenerationProgressContentProps,
114
- GenerationProgressBarProps, PendingJobCardProps, StatusLabels, PendingJobProgressBarProps,
115
- PendingJobCardActionsProps, GenerationResultData, GenerationResultContentProps, ResultHeaderProps,
116
- ResultImageCardProps, ResultStoryCardProps, ResultActionsProps, ResultConfig, ResultHeaderConfig,
117
- ResultImageConfig, ResultStoryConfig, ResultActionsConfig, ResultLayoutConfig, ResultActionButton,
118
- PhotoStepProps, DualImagePickerProps, PromptInputProps, AIGenerationHeroProps, ExamplePromptsProps,
119
- ModerationSummaryProps, StylePresetsGridProps, StylePreset, GenerateButtonProps, ResultDisplayProps,
120
- ResultDisplayAction, AIGenerationResultProps, AIGenerationResultAction, ErrorDisplayProps,
121
- FeatureHeaderProps, AIGenScreenHeaderProps, NavigationButtonType, CreditBadgeProps,
113
+ GenerationProgressContentProps, GenerationProgressBarProps, PendingJobCardProps, StatusLabels,
114
+ PendingJobProgressBarProps, PendingJobCardActionsProps, GenerationResultData, GenerationResultContentProps,
115
+ ResultHeaderProps, ResultImageCardProps, ResultStoryCardProps, ResultActionsProps, ResultConfig,
116
+ ResultHeaderConfig, ResultImageConfig, ResultStoryConfig, ResultActionsConfig, ResultLayoutConfig,
117
+ ResultActionButton, PhotoStepProps, DualImagePickerProps, PromptInputProps, AIGenerationHeroProps,
118
+ ExamplePromptsProps, ModerationSummaryProps, StylePresetsGridProps, StylePreset, GenerateButtonProps,
119
+ ResultDisplayProps, ResultDisplayAction, AIGenerationResultProps, AIGenerationResultAction,
120
+ ErrorDisplayProps, FeatureHeaderProps, AIGenScreenHeaderProps, NavigationButtonType, CreditBadgeProps,
122
121
  PhotoUploadCardProps, PhotoUploadCardConfig, SettingsSheetProps, StyleSelectorProps,
123
122
  AspectRatioSelectorProps, DurationSelectorProps, GridSelectorProps, GridSelectorOption,
124
123
  StyleOption, AspectRatioOption, DurationValue, AspectRatioTranslations, DurationOption,
@@ -14,7 +14,6 @@ import { PromptInput } from "./PromptInput";
14
14
  import { GenerateButton } from "./buttons/GenerateButton";
15
15
  import { ExamplePrompts } from "./prompts/ExamplePrompts";
16
16
  import { StylePresetsGrid } from "./StylePresetsGrid";
17
- import { GenerationProgressModal } from "./GenerationProgressModal";
18
17
  import type { AIGenerationFormProps } from "./AIGenerationForm.types";
19
18
 
20
19
  export const AIGenerationForm: React.FC<AIGenerationFormProps> = ({
@@ -35,10 +34,6 @@ export const AIGenerationForm: React.FC<AIGenerationFormProps> = ({
35
34
  onGenerate,
36
35
  isGenerating,
37
36
  hideGenerateButton,
38
- progress,
39
- progressIcon,
40
- isProgressModalVisible,
41
- onCloseProgressModal,
42
37
  generateButtonProps,
43
38
  showAdvanced,
44
39
  onAdvancedToggle,
@@ -155,17 +150,6 @@ export const AIGenerationForm: React.FC<AIGenerationFormProps> = ({
155
150
  )}
156
151
  </>
157
152
  )}
158
-
159
- {/* MANDATORY: Progress Modal shows automatically when isGenerating */}
160
- <GenerationProgressModal
161
- visible={isProgressModalVisible ?? isGenerating}
162
- progress={progress ?? 0}
163
- icon={progressIcon || "sparkles-outline"}
164
- title={translations.progressTitle || translations.generatingButton}
165
- message={translations.progressMessage || translations.progressHint}
166
- onClose={onCloseProgressModal}
167
- backgroundHint={onCloseProgressModal ? translations.progressBackgroundHint : undefined}
168
- />
169
153
  </>
170
154
  );
171
155
  };
@@ -1,4 +1,3 @@
1
- export { GenerationProgressModal } from "./GenerationProgressModal";
2
1
  export { GenerationProgressContent } from "./GenerationProgressContent";
3
2
  export { GenerationProgressBar } from "./GenerationProgressBar";
4
3
  export { PendingJobCard } from "./PendingJobCard";
@@ -10,11 +9,6 @@ export * from "./StylePresetsGrid";
10
9
  export * from "./AIGenerationForm";
11
10
  export * from "./AIGenerationForm.types";
12
11
 
13
- export type {
14
- GenerationProgressModalProps,
15
- GenerationProgressRenderProps,
16
- } from "./GenerationProgressModal";
17
-
18
12
  export type { GenerationProgressContentProps } from "./GenerationProgressContent";
19
13
  export type { GenerationProgressBarProps } from "./GenerationProgressBar";
20
14
 
@@ -1,11 +1,12 @@
1
1
  /**
2
2
  * DualImageFeatureLayout
3
3
  * Centralized layout for all dual-image processing features (face-swap, ai-kiss, ai-hug)
4
- * Handles: Modal, ScrollView, AIGenerationForm, AIGenerationResult
4
+ * Handles: ScrollView, AIGenerationForm, AIGenerationResult, GenerationProgressContent
5
+ * Note: No Modal wrapper - shows fullscreen progress when processing (FutureUS pattern)
5
6
  */
6
7
 
7
8
  import React, { useCallback } from "react";
8
- import { ScrollView, StyleSheet } from "react-native";
9
+ import { View, ScrollView, StyleSheet } from "react-native";
9
10
  import {
10
11
  useAppDesignTokens,
11
12
  useResponsive,
@@ -13,7 +14,7 @@ import {
13
14
  } from "@umituz/react-native-design-system";
14
15
  import { AIGenerationForm } from "../components/AIGenerationForm";
15
16
  import { AIGenerationResult } from "../components/display/AIGenerationResult";
16
- import { GenerationProgressModal } from "../components/GenerationProgressModal";
17
+ import { GenerationProgressContent } from "../components/GenerationProgressContent";
17
18
  import type { DualImageFeatureLayoutProps } from "./types";
18
19
 
19
20
  export const DualImageFeatureLayout: React.FC<DualImageFeatureLayoutProps> = ({
@@ -24,7 +25,6 @@ export const DualImageFeatureLayout: React.FC<DualImageFeatureLayoutProps> = ({
24
25
  renderInput,
25
26
  renderResult,
26
27
  description,
27
- renderProcessingModal,
28
28
  children,
29
29
  }) => {
30
30
  const tokens = useAppDesignTokens();
@@ -47,19 +47,29 @@ export const DualImageFeatureLayout: React.FC<DualImageFeatureLayoutProps> = ({
47
47
  void feature.selectTargetImage();
48
48
  }, [feature]);
49
49
 
50
- // Default modal
51
- const defaultModal = (
52
- <GenerationProgressModal
53
- visible={feature.isProcessing}
54
- progress={feature.progress}
55
- icon={modalIcon}
56
- title={modalTranslations.title}
57
- message={modalTranslations.message}
58
- hint={modalTranslations.hint}
59
- backgroundHint={modalTranslations.backgroundHint}
60
- onClose={() => {}}
61
- />
62
- );
50
+ // Processing view - fullscreen (FutureUS pattern, no Modal)
51
+ if (feature.isProcessing) {
52
+ return (
53
+ <View
54
+ style={[
55
+ styles.processingContainer,
56
+ { backgroundColor: tokens.colors.backgroundPrimary },
57
+ ]}
58
+ >
59
+ <GenerationProgressContent
60
+ progress={feature.progress}
61
+ icon={modalIcon}
62
+ title={modalTranslations.title}
63
+ message={modalTranslations.message}
64
+ hint={modalTranslations.hint}
65
+ backgroundHint={modalTranslations.backgroundHint}
66
+ backgroundColor={tokens.colors.surface}
67
+ textColor={tokens.colors.textPrimary}
68
+ progressColor={tokens.colors.primary}
69
+ />
70
+ </View>
71
+ );
72
+ }
63
73
 
64
74
  // Result view
65
75
  if (feature.processedUrl) {
@@ -88,48 +98,42 @@ export const DualImageFeatureLayout: React.FC<DualImageFeatureLayoutProps> = ({
88
98
 
89
99
  // Input view
90
100
  return (
91
- <>
92
- <ScrollView
93
- style={[styles.container, { backgroundColor: tokens.colors.backgroundPrimary }]}
94
- contentContainerStyle={styles.content}
95
- showsVerticalScrollIndicator={false}
101
+ <ScrollView
102
+ style={[styles.container, { backgroundColor: tokens.colors.backgroundPrimary }]}
103
+ contentContainerStyle={styles.content}
104
+ showsVerticalScrollIndicator={false}
105
+ >
106
+ <AIGenerationForm
107
+ onGenerate={handleProcess}
108
+ isGenerating={feature.isProcessing}
109
+ progress={feature.progress}
110
+ translations={{
111
+ generateButton: translations.processButtonText,
112
+ generatingButton: translations.processingText,
113
+ progressTitle: translations.processingText,
114
+ }}
96
115
  >
97
- <AIGenerationForm
98
- onGenerate={handleProcess}
99
- isGenerating={feature.isProcessing}
100
- progress={feature.progress}
101
- translations={{
102
- generateButton: translations.processButtonText,
103
- generatingButton: translations.processingText,
104
- progressTitle: translations.processingText,
105
- }}
106
- >
107
- {description && (
108
- <AtomicText
109
- type="bodyLarge"
110
- style={[styles.description, { color: tokens.colors.textSecondary }]}
111
- >
112
- {description}
113
- </AtomicText>
114
- )}
116
+ {description && (
117
+ <AtomicText
118
+ type="bodyLarge"
119
+ style={[styles.description, { color: tokens.colors.textSecondary }]}
120
+ >
121
+ {description}
122
+ </AtomicText>
123
+ )}
115
124
 
116
- {children}
125
+ {children}
117
126
 
118
- {renderInput({
119
- sourceImageUri: feature.sourceImageUri,
120
- targetImageUri: feature.targetImageUri,
121
- onSelectSource: handleSelectSource,
122
- onSelectTarget: handleSelectTarget,
123
- isDisabled: feature.isProcessing,
124
- isProcessing: feature.isProcessing,
125
- })}
126
- </AIGenerationForm>
127
- </ScrollView>
128
-
129
- {renderProcessingModal
130
- ? renderProcessingModal({ visible: feature.isProcessing, progress: feature.progress })
131
- : defaultModal}
132
- </>
127
+ {renderInput({
128
+ sourceImageUri: feature.sourceImageUri,
129
+ targetImageUri: feature.targetImageUri,
130
+ onSelectSource: handleSelectSource,
131
+ onSelectTarget: handleSelectTarget,
132
+ isDisabled: feature.isProcessing,
133
+ isProcessing: feature.isProcessing,
134
+ })}
135
+ </AIGenerationForm>
136
+ </ScrollView>
133
137
  );
134
138
  };
135
139
 
@@ -146,4 +150,9 @@ const styles = StyleSheet.create({
146
150
  marginBottom: 24,
147
151
  lineHeight: 24,
148
152
  },
153
+ processingContainer: {
154
+ flex: 1,
155
+ justifyContent: "center",
156
+ alignItems: "center",
157
+ },
149
158
  });
@@ -1,18 +1,19 @@
1
1
  /**
2
2
  * DualImageVideoFeatureLayout
3
3
  * Centralized layout for dual-image video features (ai-kiss, ai-hug)
4
- * Handles: Modal, ScrollView, AIGenerationForm, AIGenerationResult
4
+ * Handles: ScrollView, AIGenerationForm, AIGenerationResult, GenerationProgressContent
5
+ * Note: No Modal wrapper - shows fullscreen progress when processing (FutureUS pattern)
5
6
  */
6
7
 
7
8
  import React, { useCallback } from "react";
8
- import { ScrollView, StyleSheet } from "react-native";
9
+ import { View, ScrollView, StyleSheet } from "react-native";
9
10
  import {
10
11
  useAppDesignTokens,
11
12
  AtomicText,
12
13
  } from "@umituz/react-native-design-system";
13
14
  import { AIGenerationForm } from "../components/AIGenerationForm";
14
15
  import { AIGenerationResult } from "../components/display/AIGenerationResult";
15
- import { GenerationProgressModal } from "../components/GenerationProgressModal";
16
+ import { GenerationProgressContent } from "../components/GenerationProgressContent";
16
17
  import type { DualImageVideoFeatureLayoutProps } from "./types";
17
18
 
18
19
  export const DualImageVideoFeatureLayout: React.FC<DualImageVideoFeatureLayoutProps> = ({
@@ -22,7 +23,6 @@ export const DualImageVideoFeatureLayout: React.FC<DualImageVideoFeatureLayoutPr
22
23
  modalIcon = "sparkles",
23
24
  renderInput,
24
25
  description,
25
- renderProcessingModal,
26
26
  children,
27
27
  }) => {
28
28
  const tokens = useAppDesignTokens();
@@ -43,19 +43,29 @@ export const DualImageVideoFeatureLayout: React.FC<DualImageVideoFeatureLayoutPr
43
43
  void feature.selectTargetImage();
44
44
  }, [feature]);
45
45
 
46
- // Default modal
47
- const defaultModal = (
48
- <GenerationProgressModal
49
- visible={feature.isProcessing}
50
- progress={feature.progress}
51
- icon={modalIcon}
52
- title={modalTranslations.title}
53
- message={modalTranslations.message}
54
- hint={modalTranslations.hint}
55
- backgroundHint={modalTranslations.backgroundHint}
56
- onClose={() => {}}
57
- />
58
- );
46
+ // Processing view - fullscreen (FutureUS pattern, no Modal)
47
+ if (feature.isProcessing) {
48
+ return (
49
+ <View
50
+ style={[
51
+ styles.processingContainer,
52
+ { backgroundColor: tokens.colors.backgroundPrimary },
53
+ ]}
54
+ >
55
+ <GenerationProgressContent
56
+ progress={feature.progress}
57
+ icon={modalIcon}
58
+ title={modalTranslations.title}
59
+ message={modalTranslations.message}
60
+ hint={modalTranslations.hint}
61
+ backgroundHint={modalTranslations.backgroundHint}
62
+ backgroundColor={tokens.colors.surface}
63
+ textColor={tokens.colors.textPrimary}
64
+ progressColor={tokens.colors.primary}
65
+ />
66
+ </View>
67
+ );
68
+ }
59
69
 
60
70
  // Result view (video features show result without embedded content)
61
71
  if (feature.processedVideoUrl) {
@@ -82,48 +92,42 @@ export const DualImageVideoFeatureLayout: React.FC<DualImageVideoFeatureLayoutPr
82
92
 
83
93
  // Input view
84
94
  return (
85
- <>
86
- <ScrollView
87
- style={[styles.container, { backgroundColor: tokens.colors.backgroundPrimary }]}
88
- contentContainerStyle={styles.content}
89
- showsVerticalScrollIndicator={false}
95
+ <ScrollView
96
+ style={[styles.container, { backgroundColor: tokens.colors.backgroundPrimary }]}
97
+ contentContainerStyle={styles.content}
98
+ showsVerticalScrollIndicator={false}
99
+ >
100
+ <AIGenerationForm
101
+ onGenerate={handleProcess}
102
+ isGenerating={feature.isProcessing}
103
+ progress={feature.progress}
104
+ translations={{
105
+ generateButton: translations.processButtonText,
106
+ generatingButton: translations.processingText,
107
+ progressTitle: translations.processingText,
108
+ }}
90
109
  >
91
- <AIGenerationForm
92
- onGenerate={handleProcess}
93
- isGenerating={feature.isProcessing}
94
- progress={feature.progress}
95
- translations={{
96
- generateButton: translations.processButtonText,
97
- generatingButton: translations.processingText,
98
- progressTitle: translations.processingText,
99
- }}
100
- >
101
- {description && (
102
- <AtomicText
103
- type="bodyLarge"
104
- style={[styles.description, { color: tokens.colors.textSecondary }]}
105
- >
106
- {description}
107
- </AtomicText>
108
- )}
110
+ {description && (
111
+ <AtomicText
112
+ type="bodyLarge"
113
+ style={[styles.description, { color: tokens.colors.textSecondary }]}
114
+ >
115
+ {description}
116
+ </AtomicText>
117
+ )}
109
118
 
110
- {children}
119
+ {children}
111
120
 
112
- {renderInput({
113
- sourceImageUri: feature.sourceImageUri,
114
- targetImageUri: feature.targetImageUri,
115
- onSelectSource: handleSelectSource,
116
- onSelectTarget: handleSelectTarget,
117
- isDisabled: feature.isProcessing,
118
- isProcessing: feature.isProcessing,
119
- })}
120
- </AIGenerationForm>
121
- </ScrollView>
122
-
123
- {renderProcessingModal
124
- ? renderProcessingModal({ visible: feature.isProcessing, progress: feature.progress })
125
- : defaultModal}
126
- </>
121
+ {renderInput({
122
+ sourceImageUri: feature.sourceImageUri,
123
+ targetImageUri: feature.targetImageUri,
124
+ onSelectSource: handleSelectSource,
125
+ onSelectTarget: handleSelectTarget,
126
+ isDisabled: feature.isProcessing,
127
+ isProcessing: feature.isProcessing,
128
+ })}
129
+ </AIGenerationForm>
130
+ </ScrollView>
127
131
  );
128
132
  };
129
133
 
@@ -140,4 +144,9 @@ const styles = StyleSheet.create({
140
144
  marginBottom: 24,
141
145
  lineHeight: 24,
142
146
  },
147
+ processingContainer: {
148
+ flex: 1,
149
+ justifyContent: "center",
150
+ alignItems: "center",
151
+ },
143
152
  });
@@ -1,11 +1,12 @@
1
1
  /**
2
2
  * SingleImageFeatureLayout
3
3
  * Centralized layout for all single-image processing features
4
- * Handles: Modal, ScrollView, AIGenerationForm, AIGenerationResult
4
+ * Handles: ScrollView, AIGenerationForm, AIGenerationResult, GenerationProgressContent
5
+ * Note: No Modal wrapper - shows fullscreen progress when processing (FutureUS pattern)
5
6
  */
6
7
 
7
8
  import React, { useCallback } from "react";
8
- import { ScrollView, StyleSheet } from "react-native";
9
+ import { View, ScrollView, StyleSheet } from "react-native";
9
10
  import {
10
11
  useAppDesignTokens,
11
12
  useResponsive,
@@ -13,7 +14,7 @@ import {
13
14
  } from "@umituz/react-native-design-system";
14
15
  import { AIGenerationForm } from "../components/AIGenerationForm";
15
16
  import { AIGenerationResult } from "../components/display/AIGenerationResult";
16
- import { GenerationProgressModal } from "../components/GenerationProgressModal";
17
+ import { GenerationProgressContent } from "../components/GenerationProgressContent";
17
18
  import type { SingleImageFeatureLayoutProps } from "./types";
18
19
 
19
20
  export const SingleImageFeatureLayout: React.FC<SingleImageFeatureLayoutProps> = ({
@@ -25,7 +26,6 @@ export const SingleImageFeatureLayout: React.FC<SingleImageFeatureLayoutProps> =
25
26
  renderResult,
26
27
  renderCustomResult,
27
28
  description,
28
- renderProcessingModal,
29
29
  children,
30
30
  }) => {
31
31
  const tokens = useAppDesignTokens();
@@ -44,19 +44,29 @@ export const SingleImageFeatureLayout: React.FC<SingleImageFeatureLayoutProps> =
44
44
  void feature.selectImage();
45
45
  }, [feature]);
46
46
 
47
- // Default modal
48
- const defaultModal = (
49
- <GenerationProgressModal
50
- visible={feature.isProcessing}
51
- progress={feature.progress}
52
- icon={modalIcon}
53
- title={modalTranslations.title}
54
- message={modalTranslations.message}
55
- hint={modalTranslations.hint}
56
- backgroundHint={modalTranslations.backgroundHint}
57
- onClose={() => {}}
58
- />
59
- );
47
+ // Processing view - fullscreen (FutureUS pattern, no Modal)
48
+ if (feature.isProcessing) {
49
+ return (
50
+ <View
51
+ style={[
52
+ styles.processingContainer,
53
+ { backgroundColor: tokens.colors.backgroundPrimary },
54
+ ]}
55
+ >
56
+ <GenerationProgressContent
57
+ progress={feature.progress}
58
+ icon={modalIcon}
59
+ title={modalTranslations.title}
60
+ message={modalTranslations.message}
61
+ hint={modalTranslations.hint}
62
+ backgroundHint={modalTranslations.backgroundHint}
63
+ backgroundColor={tokens.colors.surface}
64
+ textColor={tokens.colors.textPrimary}
65
+ progressColor={tokens.colors.primary}
66
+ />
67
+ </View>
68
+ );
69
+ }
60
70
 
61
71
  // Custom result view (for comparison sliders, etc.)
62
72
  if (feature.processedUrl && renderCustomResult && feature.imageUri) {
@@ -104,46 +114,40 @@ export const SingleImageFeatureLayout: React.FC<SingleImageFeatureLayoutProps> =
104
114
 
105
115
  // Input view
106
116
  return (
107
- <>
108
- <ScrollView
109
- style={[styles.container, { backgroundColor: tokens.colors.backgroundPrimary }]}
110
- contentContainerStyle={styles.content}
111
- showsVerticalScrollIndicator={false}
117
+ <ScrollView
118
+ style={[styles.container, { backgroundColor: tokens.colors.backgroundPrimary }]}
119
+ contentContainerStyle={styles.content}
120
+ showsVerticalScrollIndicator={false}
121
+ >
122
+ <AIGenerationForm
123
+ onGenerate={handleProcess}
124
+ isGenerating={feature.isProcessing}
125
+ progress={feature.progress}
126
+ translations={{
127
+ generateButton: translations.processButtonText,
128
+ generatingButton: translations.processingText,
129
+ progressTitle: translations.processingText,
130
+ }}
112
131
  >
113
- <AIGenerationForm
114
- onGenerate={handleProcess}
115
- isGenerating={feature.isProcessing}
116
- progress={feature.progress}
117
- translations={{
118
- generateButton: translations.processButtonText,
119
- generatingButton: translations.processingText,
120
- progressTitle: translations.processingText,
121
- }}
122
- >
123
- {description && (
124
- <AtomicText
125
- type="bodyLarge"
126
- style={[styles.description, { color: tokens.colors.textSecondary }]}
127
- >
128
- {description}
129
- </AtomicText>
130
- )}
132
+ {description && (
133
+ <AtomicText
134
+ type="bodyLarge"
135
+ style={[styles.description, { color: tokens.colors.textSecondary }]}
136
+ >
137
+ {description}
138
+ </AtomicText>
139
+ )}
131
140
 
132
- {children}
141
+ {children}
133
142
 
134
- {renderInput({
135
- imageUri: feature.imageUri,
136
- onSelect: handleSelectImage,
137
- isDisabled: feature.isProcessing,
138
- isProcessing: feature.isProcessing,
139
- })}
140
- </AIGenerationForm>
141
- </ScrollView>
142
-
143
- {renderProcessingModal
144
- ? renderProcessingModal({ visible: feature.isProcessing, progress: feature.progress })
145
- : defaultModal}
146
- </>
143
+ {renderInput({
144
+ imageUri: feature.imageUri,
145
+ onSelect: handleSelectImage,
146
+ isDisabled: feature.isProcessing,
147
+ isProcessing: feature.isProcessing,
148
+ })}
149
+ </AIGenerationForm>
150
+ </ScrollView>
147
151
  );
148
152
  };
149
153
 
@@ -160,4 +164,9 @@ const styles = StyleSheet.create({
160
164
  marginBottom: 24,
161
165
  lineHeight: 24,
162
166
  },
167
+ processingContainer: {
168
+ flex: 1,
169
+ justifyContent: "center",
170
+ alignItems: "center",
171
+ },
163
172
  });