UI State Management
Relevant source files
The following files were used as context for generating this wiki page:
The UI state management in hdrify is handled entirely on the client-side using vanilla JavaScript, encapsulated within a single class. This approach manages the application's lifecycle, from the initial file upload prompt to image processing, display, and user interaction. The system is designed to be simple and efficient for a single-page application, relying on direct DOM manipulation and CSS for visual state transitions.
State is not persisted and is reset when the user navigates away or manually resets the interface. The core logic resides in the HDRify class, which acts as a controller, responding to user events and managing the visibility and properties of different UI components defined in the HTML structure.
Core Architecture: The HDRify Class
The entire frontend logic is managed by the HDRify class. Upon page load, an instance of this class is created, which then initializes all necessary DOM element references and sets up event listeners to handle user interactions.
Sources: static/script.js:1-12, 401-412
Class Properties
The HDRify class maintains the application's state through several key properties.
| Property | Type | Description | Source |
|---|---|---|---|
currentImageData | string | Base64 encoded string of the original user-uploaded image, without the data URL prefix. Null when reset. | [static/script.js:3](https://github.com/wotschofsky/hdrify/blob/HEAD/static/script.js#L3) |
originalImageUrl | string | The complete data URL of the original uploaded image. Used for previews and fallbacks. | [static/script.js:4](https://github.com/wotschofsky/hdrify/blob/HEAD/static/script.js#L4) |
originalFileName | string | The filename of the uploaded image, used for generating the download filename. | [static/script.js:5](https://github.com/wotschofsky/hdrify/blob/HEAD/static/script.js#L5) |
processingTimeout | number | A timeout ID used to debounce requests to the processing API when the slider is moved. | [static/script.js:6](https://github.com/wotschofsky/hdrify/blob/HEAD/static/script.js#L6) |
imageCache | Map | A cache for processed images, mapping an HDR value (e.g., "1.5") to its base64 image data. | [static/script.js:7](https://github.com/wotschofsky/hdrify/blob/HEAD/static/script.js#L7) |
Class Diagram
This diagram shows the structure of the HDRify class, including its properties and key methods that manage the UI state.
Sources: static/script.js:1-399
UI States and Transitions
The application transitions through several distinct states, each with a unique visual representation controlled by manipulating DOM elements and CSS classes.
Sources: static/index.html, static/style.css, static/script.js
State Machine Diagram
The following diagram illustrates the primary UI states and the user/system actions that trigger transitions between them.
State Descriptions
-
Initial (Upload) State:
- Description: The default state on page load. The user is prompted to upload an image.
- Visible Elements:
#uploadArea. - Hidden Elements:
#imageDisplay,#controls,#error. - Styling: The
#uploadAreais a large, clickable, and droppable region. A.dragoverclass is added when a file is dragged over it. - Sources: static/index.html:23-27, static/style.css:78-95, static/script.js:61-76
-
Processing State:
- Description: This state is active while an image is being uploaded to the server and processed. It provides visual feedback that an operation is in progress.
- Visible Elements:
#imageDisplay,#controls,#processingOverlay. - Visuals: The original image is shown with a heavy blur (
blur(50px)) and reduced opacity, with a spinning loader (#processingOverlay) on top. - Sources: static/script.js:213-216, 276-279, static/style.css:114-142
-
Image Display State:
- Description: After processing is complete, the HDR-ified image is displayed. The user can adjust the HDR intensity and download the result.
- Visible Elements:
#imageDisplay,#controls. - Hidden Elements:
#processingOverlay. - Functionality: The
#hdrSlideris active. The download button (#downloadButton) is enabled with ahrefattribute. - Sources: static/script.js:296-304, 313-326, static/style.css:201-218
-
Error State:
- Description: If file validation fails or the server returns an error, this state is triggered.
- Visible Elements:
#errordiv with a message. - Functionality: The
fallbackToOriginal()method may be called, showing the original image without the processing overlay. The download button is disabled. - Sources: static/script.js:306-311, 392-396, static/style.css:220-226
Data Flow and Image Processing
The core user flow involves selecting a file, processing it on the server, and displaying the result. State management is crucial for handling the data at each step.
File Upload and Processing Sequence
This sequence diagram details the interaction between the user, the HDRify class, and the backend server. It also shows the role of the client-side cache.
Sources: static/script.js:148-311, src/main.rs:16-136
Client-Side Caching
To improve performance and reduce server load, the HDRify class implements a simple client-side cache using a Map.
- Key: The HDR value, formatted to one decimal place (e.g.,
"1.5"). - Value: The base64-encoded string of the processed image data.
When the user adjusts the slider, the processImage function first checks if a result for the selected HDR value already exists in imageCache. If a cached version is found, it is displayed instantly without making a new API request. The cache is cleared whenever a new image is uploaded.
Sources: static/script.js:7, 169, 243-251, 294-295
Resetting State
The reset() method returns the application to its initial state. This action can be triggered by the "Reset" button or the "Escape" key. It performs the following actions:
- Clears all state-holding properties (
currentImageData,originalImageUrl, etc.). - Clears the
imageCache. - Resets the file input and HDR slider to their default values.
- Disables the download button using
disableDownload(). - Hides the image display and controls, and shows the upload area.
Sources: static/script.js:357-390