State Management
Relevant source files
The following files were used as context for generating this wiki page:The application employs a client-side state management strategy centered within the main App component. It leverages React's built-in useState hook for managing component-level state and the browser's localStorage API for persisting user settings and generation history across sessions. This approach creates a self-contained, serverless architecture for user data.
All primary application state, such as user inputs, generation results, and UI status, is defined and controlled within App.tsx. State is then passed down to child components as props, and updates are handled via callback functions.
Sources: App.tsx:43-100, README.md:19-20
Core State Architecture
The state is managed almost exclusively in the App.tsx component using multiple useState hooks. This centralized model simplifies state tracking and data flow, as App.tsx acts as the single source of truth.
Main State Variables
The following table outlines the key state variables defined in App.tsx.
| State Variable | Type | Description |
|---|---|---|
lang | Language | Stores the current UI language ('en' or 'zh'). Persisted in localStorage. |
prompt | string | The user-provided text prompt for image generation. |
model | ModelOption | The selected AI model ('z-image-turbo' or 'qwen-image-fast'). |
aspectRatio | AspectRatioOption | The selected aspect ratio for the generated image. |
seed | string | The optional seed value for generation. |
enableHD | boolean | Flag to enable HD generation for the 'z-image-turbo' model. |
isLoading | boolean | True when an image generation is in progress. |
isOptimizing | boolean | True when a prompt optimization is in progress. |
isUpscaling | boolean | True when an image upscale is in progress. |
currentImage | GeneratedImage | null | The currently selected/displayed image object. |
history | GeneratedImage[] | An array of all generated images. Persisted in localStorage. |
error | string | null | Stores error messages from API calls. |
showSettings | boolean | Controls the visibility of the Settings modal. |
isComparing | boolean | True when in the before/after upscale comparison view. |
tempUpscaledImage | string | null | Temporarily stores the URL of an upscaled image before it's applied. |
Sources: App.tsx:43-80, types.ts
State Initialization and Data Flow
This diagram illustrates how state is initialized and flows through the application.
This diagram shows the process of initializing language and history state from localStorage on application load, and how useEffect hooks persist changes back to localStorage.
Sources: App.tsx:44-49, App.tsx:83-98, App.tsx:103-105, App.tsx:108-110
Data Structures
The core data model for a generated image is defined by the GeneratedImage interface.
Sources: types.ts:3-13
GeneratedImage Interface
This diagram shows the structure of the GeneratedImage object.
| Field | Type | Description |
|---|---|---|
id | string | A unique identifier for the image, generated using crypto.randomUUID(). |
url | string | The URL of the generated image. |
prompt | string | The prompt used to generate the image. |
aspectRatio | string | The aspect ratio used (e.g., "1:1"). |
timestamp | number | The Unix timestamp (in milliseconds) when the image was created. |
model | string | The model used for generation (e.g., 'z-image-turbo'). |
seed | number (optional) | The seed value used. |
duration | number (optional) | The time taken for generation in seconds. |
isBlurred | boolean (optional) | A flag to toggle a blur effect, often for NSFW content. |
isUpscaled | boolean (optional) | A flag indicating if the image has been successfully upscaled. |
Sources: types.ts:3-13, services/hfService.ts:133, App.tsx:251-255
State Persistence with localStorage
The application persists two key pieces of state to the browser's localStorage: user settings and image history. This ensures data is retained between sessions without needing a backend.
History Management
- Loading: On application start,
ai_image_gen_historyis read fromlocalStorage. Any images older than one day are filtered out to manage storage space. - Saving: A
useEffecthook monitors thehistorystate. Wheneverhistoryis updated (e.g., a new image is added or an existing one is modified/deleted), the entire array is serialized to JSON and saved back tolocalStorage.
// Initialization of history state from localStorage
const [history, setHistory] = useState<GeneratedImage[]>(() => {
try {
const saved = localStorage.getItem('ai_image_gen_history');
if (!saved) return [];
const parsedHistory: GeneratedImage[] = JSON.parse(saved);
const now = Date.now();
const oneDayInMs = 24 * 60 * 60 * 1000;
// Filter out images older than 1 day
return parsedHistory.filter(img => (now - img.timestamp) < oneDayInMs);
} catch (e) {
console.error("Failed to load history", e);
return [];
}
});
// Persistence of history state to localStorage
useEffect(() => {
localStorage.setItem('ai_image_gen_history', JSON.stringify(history));
}, [history]);
Sources: App.tsx:83-98, App.tsx:108-110
Settings Management
- Language: The
app_languageis loaded fromlocalStorageon init. If not present, it defaults based onnavigator.language. It is saved back whenever the user changes it in the settings modal. - Hugging Face Token: The
huggingFaceTokenis managed within theSettingsModalcomponent. It is read from and saved tolocalStorageonly when the modal is opened and the user clicks "Save". This token is not held in the mainAppcomponent's state.
Sources: App.tsx:44-49, 103-105, components/SettingsModal.tsx:21-26
State Update Flows
State updates are triggered by event handlers in App.tsx, which call the set... functions returned by useState.
Image Generation Flow (handleGenerate)
The following sequence diagram shows the state changes during the image generation process.
This flow demonstrates how isLoading is used to manage the UI during the asynchronous API call and how currentImage and history are updated upon success.
Sources: App.tsx:149-174, services/hfService.ts:182-190
Image History Selection
When a user clicks an image in the HistoryGallery, the onSelect callback is triggered. This calls the handleHistorySelect function in App.tsx, which updates the currentImage state to display the selected image and resets related UI states like the info popover and comparison view.
Sources: App.tsx:300-306, components/HistoryGallery.tsx:14, 69
Summary
The state management in this application is straightforward and effective for its scope. By centralizing state in App.tsx and using React hooks, the data flow is predictable. localStorage provides a simple yet powerful mechanism for persistence, creating a good user experience in a fully client-side application.