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
UiSlotComponentfrom theUiSlotsContent.componentsMap using the slot id for the slot to render. - Use SlotComponentComposable to display your
UiSlotComponent.
View
- Expose
UiSlotsContenton your ViewModel mapping it fromSlotsContentusing DomainToUiSlotsContentMapper. - Add PoqSlotComponentView to your view hierarchy.
- Use the binding adapter to send the appropiate
UiSlotComponent:<com.poqstudio.platform.content.dynamiccontent.ui.PoqSlotComponentViewandroid:layout_width="match_parent"android:layout_height="wrap_content"app:slot='@{"top"}' // Use your SlotIdapp:slotsContent="@{viewModel.slots}" />
RecyclerView
- Add
UiSlotComponentto your the RecyclerView UI model mapping it fromSlotsContent.componentusing DomainToUiSlotComponentMapper 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_SLOT_COMPONENT -> slotComponentViewHolderFactory.create(parent)...}}override fun onBindViewHolder(viewHolder: RecyclerView.ViewHolder, position: Int) {when (getItemViewType(position)) {TYPE_SLOT_COMPONENT -> (viewHolder as BaseSlotComponentViewHolder).onBind((getItem(position) as YourUiModel.SlotComponent).component,)...}}
Create a new SlotComponent
Dynamic content supports custom SlotComponents. To create a new SlotComponent you need to:
- Define the network model for your new SlotComponent.
- Define your domain model that implements
SlotComponentCustomCustomDatawhich your new Composable will receive. - Define your network to domain mapper that implements NetworkToDomainSlotComponentCustomMapper.
content: Anycan be safely cast to your network model. - To support
DynamicAction.UpdateComponent, you need to:- Define your update model that implements
SlotComponentCustomUpdateCustomDatawhich usually is a copy of your domain model with all fields nullable. - Define your update to domain mapper that implements SlotComponentCustomUpdateToCustomDataMapper where you create a new
SlotComponentCustomCustomDataupdating the existing one with the new field received onSlotComponentCustomUpdateCustomData
- Define your update model that implements
- Create your new Composable component that receives a Modifier and the UiSlotComponent.
- Create an object of CustomSlotComponentRegister.Default in your
Application.onCreate:CustomSlotComponentRegister.Default(slotComponentType = "your slot component type identifier",networkToDomainMapper = inject<MyNetworkToDomainlotComponentCustomMapper>(),networkModelClass = MyNetworkSlotComponent::class.java,updateMapper = inject<MySlotComponentCustomUpdateToCustomDataMapper>(),composable = { modifier, slotComponent -> MySlotComponent(modifier, slotComponent.customData as MyDomainModel) },).register()
Custom SlotComponent with validation
If your new SlotComponent requires validation rules (such as a mandatory text field), your domain model needs to also implement UiValidationComponent
Create a new SlotComponent Container
Dynamic content supports custom SlotComponents Container, a specialized component that shows other components (like a column or a row). To create a new SlotComponent.Container, the steps are the same as create a default SlotComponent with these differences:
- Your network to domain mapper needs to implement NetworkToDomainSlotComponentCustomContainerMapper
- Create an object of CustomSlotComponentRegister.Container in your
Application.onCreate:CustomSlotComponentRegister.Container(slotComponentType = "your slot component type identifier",networkToDomainMapper = inject<MyNetworkToDomainSlotComponentCustomContainerMapper>(),networkModelClass = MyNetworkSlotComponent::class.java,updateMapper = inject<MySlotComponentCustomUpdateToCustomDataMapper>(),composable = { modifier, slotComponent -> MySlotComponent(modifier, slotComponent.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
NetworkSlotComponentModifiersCustomDatadefining all your new Modifiers. - Define your domain model that implements
SlotComponentModifierCustomCustomDatadefining all your new Modifiers. - Define your network to domain mapper that implements NetworkToDomainSlotComponentCustomDataMapper 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:CustomSlotComponentRegister.{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 theUiSlotComponents, usually using DomainToUiSlotComponentMapper