@umituz/react-native-ai-generation-content 1.83.63 → 1.83.65

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umituz/react-native-ai-generation-content",
3
- "version": "1.83.63",
3
+ "version": "1.83.65",
4
4
  "description": "Provider-agnostic AI generation orchestration for React Native with result preview components",
5
5
  "main": "src/index.ts",
6
6
  "types": "src/index.ts",
@@ -3,7 +3,7 @@
3
3
  * Main wizard content with generation logic
4
4
  */
5
5
 
6
- import React, { useMemo, useEffect, useRef, useState } from "react";
6
+ import React, { useMemo, useEffect, useRef, useState, useCallback } from "react";
7
7
  import { View, StyleSheet } from "react-native";
8
8
  import { useAppDesignTokens } from "@umituz/react-native-design-system/theme";
9
9
  import { useFlow } from "../../../infrastructure/flow/useFlow";
@@ -197,6 +197,21 @@ export const WizardFlowContent: React.FC<WizardFlowContentProps> = (props) => {
197
197
  onCreditsExhausted,
198
198
  });
199
199
 
200
+ // Live credit calculator: computes credits for a selection value without store round-trip
201
+ const handleCalculateCreditForSelection = useCallback(
202
+ (stepId: string, value: string | string[]) => {
203
+ if (!calculateCredits) return creditCost;
204
+ const previewData = { ...customData, [stepId]: { selection: value } };
205
+ const outputType = validatedScenario.outputType as "video" | "image";
206
+ const hasImageInput = validatedScenario.inputType !== "text";
207
+ const duration = extractDuration(previewData.duration) ?? getConfigDefaultDuration(featureConfig.steps as unknown as Record<string, unknown>[]);
208
+ const resolution = extractResolution(previewData.resolution) ?? getConfigDefaultResolution(featureConfig.steps as unknown as Record<string, unknown>[]);
209
+ const result = calculateCredits({ duration, resolution, outputType, hasImageInput });
210
+ return Number.isFinite(result) && result > 0 ? Math.ceil(result) : creditCost;
211
+ },
212
+ [customData, featureConfig.steps, calculateCredits, creditCost, validatedScenario.outputType, validatedScenario.inputType],
213
+ );
214
+
200
215
  useEffect(() => {
201
216
  if (currentStep && onStepChange && prevStepIdRef.current !== currentStep.id) {
202
217
  prevStepIdRef.current = currentStep.id;
@@ -219,6 +234,7 @@ export const WizardFlowContent: React.FC<WizardFlowContentProps> = (props) => {
219
234
  onNext={handlers.handleNextStep}
220
235
  onBack={handlers.handleBack}
221
236
  onPhotoContinue={handlers.handlePhotoContinue}
237
+ calculateCreditForSelection={calculateCredits ? handleCalculateCreditForSelection : undefined}
222
238
  onDownload={handleDownload}
223
239
  onShare={handleShare}
224
240
  onRate={() => setShowRatingPicker(true)}
@@ -27,6 +27,7 @@ export const WizardStepRenderer: React.FC<WizardStepRendererProps> = ({
27
27
  onNext,
28
28
  onBack,
29
29
  onPhotoContinue,
30
+ calculateCreditForSelection,
30
31
  onDownload,
31
32
  onShare,
32
33
  onRate,
@@ -94,7 +95,7 @@ export const WizardStepRenderer: React.FC<WizardStepRendererProps> = ({
94
95
  return renderTextInputStep({ key: step.id, step, customData, onBack, onPhotoContinue, t, alertMessages, creditCost });
95
96
 
96
97
  case StepType.FEATURE_SELECTION:
97
- return renderSelectionStep({ key: step.id, step, customData, onBack, onPhotoContinue, t, creditCost });
98
+ return renderSelectionStep({ key: step.id, step, customData, onBack, onPhotoContinue, calculateCreditForSelection, t, creditCost });
98
99
 
99
100
  default:
100
101
  if (typeof __DEV__ !== "undefined" && __DEV__) {
@@ -17,6 +17,8 @@ export interface WizardStepRendererProps {
17
17
  readonly onNext: () => void;
18
18
  readonly onBack: () => void;
19
19
  readonly onPhotoContinue: (stepId: string, image: UploadedImage) => void;
20
+ /** Computes credit cost for a given selection value (local, no store round-trip) */
21
+ readonly calculateCreditForSelection?: (stepId: string, value: string | string[]) => number;
20
22
  readonly onDownload: () => void;
21
23
  readonly onShare: () => void;
22
24
  readonly onRate?: () => void;
@@ -14,6 +14,8 @@ interface SelectionStepProps {
14
14
  readonly customData: Record<string, unknown>;
15
15
  readonly onBack: () => void;
16
16
  readonly onPhotoContinue: (stepId: string, image: UploadedImage) => void;
17
+ /** Computes credit cost for a given selection value (local, no store round-trip) */
18
+ readonly calculateCreditForSelection?: (stepId: string, value: string | string[]) => number;
17
19
  readonly t: (key: string) => string;
18
20
  /** Calculated credit cost from parent */
19
21
  readonly creditCost?: number;
@@ -25,6 +27,7 @@ export function renderSelectionStep({
25
27
  customData,
26
28
  onBack,
27
29
  onPhotoContinue,
30
+ calculateCreditForSelection,
28
31
  t,
29
32
  creditCost,
30
33
  }: SelectionStepProps): React.ReactElement {
@@ -79,6 +82,7 @@ export function renderSelectionStep({
79
82
  }}
80
83
  initialValue={initialValue}
81
84
  creditCost={creditCost}
85
+ calculateCreditForSelection={calculateCreditForSelection ? (value) => calculateCreditForSelection(step.id, value) : undefined}
82
86
  onBack={onBack}
83
87
  onContinue={(value) => {
84
88
  onPhotoContinue(step.id, { uri: String(value), selection: value, previewUrl: "" } as UploadedImage);
@@ -21,6 +21,7 @@ export const SelectionScreen: React.FC<SelectionScreenProps> = ({
21
21
  config,
22
22
  initialValue,
23
23
  creditCost,
24
+ calculateCreditForSelection,
24
25
  onBack,
25
26
  onContinue,
26
27
  }) => {
@@ -57,6 +58,12 @@ export const SelectionScreen: React.FC<SelectionScreenProps> = ({
57
58
  });
58
59
  }
59
60
 
61
+ // Live credit cost based on current selection
62
+ const displayCreditCost = useMemo(() => {
63
+ if (!calculateCreditForSelection) return creditCost;
64
+ return calculateCreditForSelection(selected);
65
+ }, [calculateCreditForSelection, selected, creditCost]);
66
+
60
67
  const handleSelect = useCallback((optionId: string) => {
61
68
  if (isMultiSelect) {
62
69
  setSelected((prev) => {
@@ -118,7 +125,7 @@ export const SelectionScreen: React.FC<SelectionScreenProps> = ({
118
125
  title=""
119
126
  onBackPress={onBack}
120
127
  rightElement={
121
- <WizardContinueButton canContinue={canContinue} onPress={handleContinue} label={translations.continueButton} icon="arrow-forward" creditCost={creditCost} />
128
+ <WizardContinueButton canContinue={canContinue} onPress={handleContinue} label={translations.continueButton} icon="arrow-forward" creditCost={displayCreditCost} />
122
129
  }
123
130
  />
124
131
  <ScreenLayout scrollable={true} edges={["left", "right"]} hideScrollIndicator={true} contentContainerStyle={styles.scrollContent}>
@@ -28,8 +28,10 @@ export interface SelectionScreenProps {
28
28
  readonly options: readonly SelectionOption[];
29
29
  readonly config?: SelectionScreenConfig;
30
30
  readonly initialValue?: string | string[];
31
- /** Calculated credit cost - passed from parent */
31
+ /** Static credit cost - used when no calculator provided */
32
32
  readonly creditCost?: number;
33
+ /** Live credit calculator - returns credit cost for given selection value */
34
+ readonly calculateCreditForSelection?: (value: string | string[]) => number;
33
35
  readonly onBack: () => void;
34
36
  readonly onContinue: (selectedValue: string | string[]) => void;
35
37
  }