Core Feature: History Gallery
Relevant source files
The following files were used as context for generating this wiki page:The History Gallery is a core user-facing feature that provides a client-side, persistent log of generated images. It allows users to view, select, and manage their creations directly within the browser. The entire history is stored in the browser's localStorage, ensuring user privacy as no image data or history is sent to a backend server for storage.
The gallery is implemented as a horizontally scrolling strip of thumbnails. Users can interact with the thumbnails to display a selected image in the main preview area, access its details, or delete it. The history state is managed centrally in the main App component and passed down to the HistoryGallery component for rendering.
Sources: README.md, App.tsx:103-116, components/HistoryGallery.tsx
Architecture and Data Flow
The History Gallery's functionality is split between the main App component, which handles all state and logic, and the HistoryGallery component, which is responsible for rendering the UI.
- State Initialization: On application load, the
Appcomponent initializes itshistorystate fromlocalStorage. It filters out any images older than one day. - Data Propagation: The
historyarray is passed as a prop to theHistoryGallerycomponent. - User Interaction: When a user clicks a thumbnail in the
HistoryGallery, it invokes theonSelectcallback function, passing the selected image object back up to theAppcomponent. - State Update: The
Appcomponent'shandleHistorySelectfunction receives the selected image and updates thecurrentImagestate. - UI Re-render: The change in
currentImagecauses the main preview area to re-render with the selected image. TheHistoryGalleryalso re-renders to highlight the newly selected thumbnail. - History Modification: Actions like generating a new image, upscaling, or deleting an image are handled in
App, which updates thehistorystate array. These changes are then automatically reflected in theHistoryGallery.
The following diagram illustrates the component interaction and data flow.
State Management and Persistence
History State
The primary state for the gallery is the history array, managed within the App.tsx component using useState.
// App.tsx:103-116
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 [];
}
});
- Initialization: The state is lazily initialized from
localStorageusing the keyai_image_gen_history. - Expiration Logic: Upon loading, the application filters the history, discarding any images that are more than 24 hours old based on their
timestamp. This prevents indefinite storage growth. - Persistence: A
useEffecthook inApp.tsxmonitors thehistorystate and writes any changes back tolocalStorage, ensuring persistence across sessions.
Sources: App.tsx:103-116, 126-128
Data Structure (GeneratedImage)
Each item in the history array is an object of type GeneratedImage. This structure contains all necessary information about a generated image.
| Field | Type | Description | Source File |
|---|---|---|---|
id | string | A unique ID for the image, generated using crypto.randomUUID(). | types.ts:5 |
url | string | The URL of the generated image file. | types.ts:6 |
prompt | string | The text prompt used to generate the image. | types.ts:7 |
aspectRatio | string | The aspect ratio setting (e.g., "1:1", "16:9"). | types.ts:8 |
timestamp | number | The Unix timestamp (in milliseconds) when the image was created. | types.ts:9 |
model | string | The name of the AI model used for generation. | types.ts:10 |
seed | number | (Optional) The seed value used for generation. | types.ts:11 |
duration | number | (Optional) The time taken to generate the image, in seconds. | types.ts:12 |
isBlurred | boolean | (Optional) A flag to indicate if the image should be displayed as blurred. | types.ts:13 |
isUpscaled | boolean | (Optional) A flag to indicate if the image has been upscaled. | types.ts:14 |
Sources: types.ts:4-15, services/hfService.ts:133, 163
HistoryGallery Component
This is a presentational component responsible for rendering the scrollable list of image thumbnails.
Sources: components/HistoryGallery.tsx
Component Properties
| Prop | Type | Description |
|---|---|---|
images | GeneratedImage[] | An array of image objects to display in the gallery. |
onSelect | (image: GeneratedImage) => void | A callback function triggered when a user clicks on a thumbnail. |
selectedId | string (optional) | The id of the currently selected image, used for applying a visual highlight. |
Sources: components/HistoryGallery.tsx:8-12
UI and Interaction
The component renders a div containing a series of image thumbnails.
- Scrolling: The container uses
overflow-x-autoand a customscrollbar-hideclass to create a scrollable area. Left and right chevron buttons allow for programmatic scrolling by 300px increments. - Selection: An
onClickhandler on each thumbnail calls theonSelectprop. - Highlighting: The currently selected image is highlighted with a purple ring, determined by comparing
img.idwith theselectedIdprop. - Blur Effect: If an image has
isBlurred: true, ablur-smclass is applied to its thumbnail.
The following sequence diagram shows the selection flow:
History Management in App
The App component contains the handlers that modify the history state.
handleGenerate: After a new image is successfully generated, the newGeneratedImageobject is prepended to thehistoryarray.
setHistory(prev => [newImage, ...prev]);handleDelete: Filters thehistoryarray to remove thecurrentImage. It then selects the next available image or clears the selection if the history is empty.
const newHistory = history.filter(img => img.id !== currentImage.id);handleApplyUpscale/handleToggleBlur: These functions update a specific image within thehistoryarray by mapping over it and replacing the object that has a matching ID.
Sources: App.tsx:189-190, 287-298, 240-244, 300-307
Conclusion
The History Gallery is a crucial feature for user experience, providing a simple yet effective way to manage generated assets. Its architecture is robust, centralizing state management in the App component while delegating rendering to the specialized HistoryGallery component. By leveraging localStorage for persistence and implementing a time-based cleanup mechanism, it offers a privacy-conscious and efficient solution for storing user creations on the client side.