3 min read
Common customisations
Add SlotsContent to a domain model
If you want to add Dynamic content to a domain model and start receiving content through the API, you need to:
- Add SlotsContent model to your domain model.
- Add
List<NetworkSlotResponse>?to your network model. - Use NetworkToDomainSlotsContentMapper to map between network and domain models.
- Call GetDynamicContentRequest to get all DynamicContentRequest.
- Use MapDynamicContentHeaders to map all
DynamicContentRequestto headers. - Add the mapped dynamic content requests headers to your API request.
Add a new Slot to a screen
If you want to add a new Slot to a screen where the domain model already contains SlotsContents, you need to use different components depending if you will add it to Compose, a View or a RecyclerView.
Compose
- Add
UiSlotsContentto your UI state model mapping it fromSlotsContentusing DomainToUiSlotsContentMapper. - On your composable, get the
UiDynamicComponentfrom theUiSlotsContent.componentsMap using the slot id for the slot to render. - Use DynamicComponentComposable to display your
UiDynamicComponent.
View
- Expose
UiSlotsContenton your ViewModel mapping it fromSlotsContentusing DomainToUiSlotsContentMapper. - Add PoqDynamicComponentView to your view hierarchy.
- Use the binding adapter to send the appropiate
UiDynamicComponent:<com.poqstudio.platform.content.dynamiccontent.ui.PoqDynamicComponentViewandroid:layout_width="match_parent"android:layout_height="wrap_content"app:slot='@{"top"}' // Use your SlotIdapp:slotsContent="@{viewModel.slots}" />
RecyclerView
- Add
UiDynamicComponentto your the RecyclerView UI model mapping it fromSlotsContent.componentusing DomainToUiDynamicComponentMapper using the appropriate slot id for your slot. - Use SlotComponentViewHolderFactory to create a BaseSlotComponentViewHolder.
- Call
BaseSlotComponentViewHolder.onBindpassing the appropriateUiSlotComponent:override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {return when (viewType) {TYPE_DYNAMIC_COMPONENT -> dynamicComponentViewHolderFactory.create(parent)...}}override fun onBindViewHolder(viewHolder: RecyclerView.ViewHolder, position: Int) {when (getItemViewType(position)) {TYPE_DYNAMIC_COMPONENT -> (viewHolder as BaseDynamicComponentViewHolder).onBind((getItem(position) as YourUiModel.DynamicComponent).component,)...}}
Create a new DynamicComponent
Dynamic content supports custom DynamicComponents. To create a new DynamicComponent you need to:
- Define the network model for your new DynamicComponent.
- Define your domain model that implements
DynamicComponentCustomCustomDatawhich your new Composable will receive. - Define your network to domain mapper that implements NetworkToDomainDynamicComponentCustomMapper.
content: Anycan be safely cast to your network model. - To support
DynamicAction.UpdateComponent, you need to:- Define your update model that implements
DynamicComponentCustomUpdateCustomDatawhich usually is a copy of your domain model with all fields nullable. - Define your update to domain mapper that implements DynamicComponentCustomUpdateToCustomDataMapper where you create a new
DynamicComponentCustomCustomDataupdating the existing one with the new field received onDynamicComponentCustomUpdateCustomData
- Define your update model that implements
- Create your new Composable component that receives a Modifier and the UiDynamicComponent.
- Create an object of CustomDynamicComponentRegister.Default in your
Application.onCreate:CustomDynamicComponentRegister.Default(dynamicComponentType = "your dynamic component type identifier",networkToDomainMapper = inject<MyNetworkToDomainlotComponentCustomMapper>(),networkModelClass = MyNetworkDynamicComponent::class.java,updateMapper = inject<MyDynamicComponentCustomUpdateToCustomDataMapper>(),composable = { modifier, dynamicComponent -> MyDynamicComponent(modifier, dynamicComponent.customData as MyDomainModel) },).register()
Custom DynamicComponent with validation
If your new DynamicComponent requires validation rules (such as a mandatory text field), your domain model needs to also implement UiValidationComponent
Create a new DynamicComponent Container
Dynamic content supports custom DynamicComponents Container, a specialized component that shows other components (like a column or a row). To create a new DynamicComponent.Container, the steps are the same as create a default DynamicComponent with these differences:
- Your network to domain mapper needs to implement NetworkToDomainDynamicComponentCustomContainerMapper
- Create an object of CustomDynamicComponentRegister.Container in your
Application.onCreate:CustomDynamicComponentRegister.Container(dynamicComponentType = "your dynamic component type identifier",networkToDomainMapper = inject<MyNetworkToDomainDynamicComponentCustomContainerMapper>(),networkModelClass = MyNetworkDynamicComponent::class.java,updateMapper = inject<MyDynamicComponentCustomUpdateToCustomDataMapper>(),composable = { modifier, dynamicComponent -> MyDynamicComponent(modifier, dynamicComponent.customData as MyDomainModel) },).register()
Create a new Modifier
Dynamic content supports the creation of custom modifiers. To create a new Modifier, you need to:
- Define your network model that implements
NetworkDynamicModifiersCustomDatadefining all your new Modifiers. - Define your domain model that implements
DynamicModifierCustomCustomDatadefining all your new Modifiers. - Define your network to domain mapper that implements NetworkToDomainDynamicCustomDataMapper and provide your implementation via Koin.
- Define your domain to UI mapper that implements DomainToUiModifierCustomMapper returning all your new modifiers as a single Compose modifier. Provide your mapper implementation via Koin.
How to add a new headers to Dynamic content requests
Dynamic content supports adding new headers to all requests. To add a new headers, you need to:
- Define your domain modile that implements
DynamicContentRequestCustomDatadefining your extra header data. - Decorate
GetDynamicContentRequestto include your new data intoDynamicContentRequest. - Decorate
MapDynamicContentHeadersto map your new header and merge it with result from the PoqSDK implementation.
How to add a new custom conditions to the existing header
Dynamic content supports conditions to personalize the content. To add custom conditions, you need to include them into DynamicContentRequest.customConditions, the PoqSDK takes care of the rest. You can include your custom conditions decorating GetDynamicContentRequest if you want to include them to all Dynamic content requests.
How to add a new Dynamic content provider
Dynamic content supports the personalisation of the content via API headers defined with DynamicContentUser. If you need to add a new Dynamic content provider, you need to:
- Define your user model that implements DynamicContentUser
- Define your user initializer use case that complies with DynamicContentUserInitializer
- Define your get user use case that complies with DynamicContentUserGetter
- Define the mapper between your user and API headers that complies with DynamicUserHeadersMapper
- Call InitDynamicContentUsers.addInitializer, GetDynamicContentUsers.addGetter and MapDynamicUsersHeaders.addMapper in your
Application.onCreatewith your new classes.
Create a new Dynamic action
Dynamic content supports custom DynamicAction. To create a new DynamicAction you need to:
- Define the network model for your new DynamicAction.
- Define your domain model that implements
DynamicActionCustomCustomDatawhich your new action will receive. - Define your network to domain mapper that implements NetworkToDomainDynamicActionCustomMapper.
content: Anycan be safely cast to your network model. - You can create these custom actions:
Default: a generic DynamicAction. You need to implementdefaultActionfunction.Navigation: a DynamicAction to navigate the user. You need to implementnavigatefunction with your navigation logic.Suspend: a DynamicAction to long operation which requires show a loading to the user. You need to implementsuspendActionfunction
- Create an object of CustomDynamicActionRegister in your
Application.onCreate:CustomDynamicComponentRegister.{Type}(action = "your new action type identifier",networkToDomainMapper = inject<MyNetworkToDomainDynamicActionCustomMapper>(),networkModelClass = MyNetworkDynamicActionClass::class.java,action = { ... },).register()
How to support Dynamic actions on a new screen
If you are adding slots to a new screen and you want to support dynamic actions on that screen, you need to:
- Implement
DynamicActionHoston your ViewModel where:dynamicPageId: String?: unique id for your screendynamicContext: MutableDynamicContext: usually an empty mutable map.setIsLoading(isLoading: Boolean): add logic to hide/show a loading statesetError(poqError: PoqError): add logic to show an error statenavigate(action: DynamicAction.Navigation): add logic to Navigate, you can use DynamicActionNavigatoronDynamicAction(actions: List<DynamicAction>): add logic to handle dynamic actions using DynamicActionListHandler
- Send your instance of your
DynamicActionHostto theUiDynamicComponents, usually using DomainToUiDynamicComponentMapper