Skip to content

Conversation

@spoorthipujariadobe
Copy link
Contributor

@spoorthipujariadobe spoorthipujariadobe commented Oct 22, 2025

Description

This PR implements inbox container UI for displaying content cards. The following classes were added as a part of the change:

Data provider

  • ContentCardContainerUIProvider - Reactive data provider implementing AepContainerUIContentProvider interface

Data modes & state management

  • AepCardUIState and implementations - Updated to add read status
  • InboxContainerUI - Primary UI class extending BaseContainerUI for inbox-specific functionality
  • InboxContainerUITemplate - Configuration template supporting heading, capacity, empty states, and unread styling
  • InboxContainerUIState - Sealed interface with Loading, Success, and Error states for reactive UI updates

Styling

  • InboxContainerUIStyle - Comprehensive styling class with Builder pattern for all visual aspects

Composables

  • AepContainer - Universal container dispatcher that routes different container types (currently supports InboxContainerUI) to their appropriate rendering components
  • InboxContainer - Main Compose UI component that renders inbox with loading, error, and success states
  • AepCircularProgressIndicator - Centered circular progress indicator component for loading states
  • EmptyInboxContainer - Dedicated component for handling empty states with custom messages and images
  • AepLazyColumn - Reusable lazy column component with customizable styling
  • AepListItems - Extension function for LazyListScope that renders lists of AEP UI items with unread styling support and icon overlays

Related Issue

Motivation and Context

The implementation of AepContainerUIContentProvider class uses a declarative, reactive pipeline to load and display content.

  1. The process is initiated when a consumer collects the Flow returned by the public getContentCardContainerUI() function.
  2. When the Flow is first collected, its onStart operator calls the refreshContainer() function. This function is responsible for fetching the container's configuration and emitting it into an internal StateFlow, which holds the current state of the container.
  3. If the initial fetch for the container configuration fails, containerUIFlow will emit a Failure result. The flatMapLatest block checks for this condition. If the container is null (because of the failure), the logic bypasses the content fetching entirely and immediately emits a Result.failure downstream, ensuring that UI consumers are promptly notified of the error.
  4. If the container UI is successfully fetched, the flatMapLatest operator observes this internal StateFlow. As soon as a new container state is emitted, flatMapLatest immediately subscribes to a new inner Flow provided by contentCardUIProvider.getUIContent().
  5. The subscription from flatMapLatest triggers the onStart block within the getUIContent() stream. It does two things in parallel:
    1. It emits a Loading state immediately, allowing the UI to show a loading indicator.
    2. It triggers the API call to fetch the actual list of content cards from the server.
  6. Once the content card API call completes, the .map operator takes the result and transforms it into the final UI state, which can be either Success (containing the list of content cards) or Error.

This approach has the following advantages:

  • Simple integration logic: A developer needs to collect a single Flow from getContentCardContainerUI(). This Flow encapsulates all the API calls, state transitions(Loading, Success, Error), and cancellation logic.
  • Data Consistency & Race Condition Safety: The flatMapLatest operator ensures that only the data request corresponding to the latest call will be processed. For example, if a consumer calls refreshContainer() multiple times (e.g., from a pull-to-refresh action), any older, in-flight requests are automatically cancelled, which prevents stale data incorrectly updating the UI.

How Has This Been Tested?

Screenshots (if appropriate):

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist:

  • I have signed the Adobe Open Source CLA.
  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant