More Menu
Overview
The More Menu feature serves as a central hub for users to access a wide variety of functionalities and settings within the app. It consolidates key functionalities such as profile viewing and settings customization, and provides quick access to various app screens. Additionally, it interfaces with several external services, such as LiveChat Support and account verification. The menu UI also dynamically adapts to display a design based on the user's login status and brand. For non-production environments (UAT build), an exclusive UAT section becomes available and offers access to Toggle Feature Flags, QA Toggles, and other essential configurations for testing and development purposes.
Android
The shared logic for the More Menu is centralized in 'src/main'
, which holds MoreMenuEntry.kt
among other components. Here, we find the foundation for the More Menu, such as the general layout and navigation paths, which remain consistent across all brands.
MoreMenuItems.kt:
MoreMenuItems.kt
is present within the /presentation/common
directory for each brand. This file defines the components reused across Ladbrokes, Neds, TabNZ, and Betcha, with their own modifications for each brand.
We can find bannerItems
as a list of BannerCardItem
, which will then be used by the BannerSection
composable function. The GetUserCard
composable function will be used to display the UserCardHeader
.
As mentioned before, each brand features different items in the Feature Section, and the GetListFeaturesItems
composable function will be handling the items for each brand in their respective MoreMenuItems.kt
file.
UserCardHeader.kt:
We can find UserCardHeader.kt
in the /presentation/usercard
directory in each brand folder. This file contains the UserCardHeader
composable, which displays the user's social profile tile and is invoked from GetUserCard
within the MoreMenuItems.kt
file. Ladbrokes, Neds, and TabNZ have their own layout for the social profile tile, while TabNZ does not show any components.
BannerCard.kt:
Finally, we have the BannerCard.kt
file, which is located in the /presentation/components/banner
directory. This file features the BannerCard
composable and handles the differences between brands by rendering each of the banner cards as specified for each brand. The BannerCard
is then called by the previously mentioned BannerSection in MoreMenuItems.kt
.
Considerations when adding a new brand
While adding a new brand, we should first identify if there are any differences with the core components previously mentioned in MoreMenuEntry.kt
. If modifications are required in the MoreMenuEntry.kt
file, then we should consider how these changes will impact the other brands.
We should also consider the differences in brand visuals, color schemes, typography, navigations, and any brand-specific drawable and string resources.
The file MoreMenuItems.kt
exists within the /presentation/common
directory for each brand and is required for any new brand we create. This file defines the unique components and menu items specific to a new brand.
If the new brand requires Banner Cards (BannerCardItem
), then a list of BannerCardItem's
should be defined as bannerItems
in MoreMenuItems.kt
. Additionally, we will need a composable to draw the BannerCard
; in this case, we can create a copy of BannerCard.kt
in the /presentation/components/banner
directory and modify it as required. If we don't need Banner Cards, we can simply set bannerItems
to null, and in the BannerSection
composable function, we can either set it with an empty body or add a spacer to it.
If the new brand requires the Social Profile Tile of the User to be shown in the More Menu, then the GetUserCard
composable function can draw the component using a copy of UserCardHeader.kt
, located in the /presentation/usercard
directory.
Finally, the GetListFeaturesItems
function will be drawing the list of ListRow
items for the Feature Section. Any modifications to the feature list should be done here.
iOS
Subviews
On iOS subviews are named differently than on Android. Subviews are either classed as “Rows” (which are stacked vertically) or “Tiles” (which are stacked horizontally). The diagram below shows the name of each subview on iOS.
Architecture
Logic for the More Menu is split across the MoreUI
package in the Presentation Layer and the More
package on the DomainLayer.
MoreUI
The MoreUI
package follows the Viper/Venom pattern that is used throughout the app. The MorePresenter
communicates with the DomainLayer, passing the data it receives into the MoreTransformer
. The transformer uses this data to update the MoreViewModel
upon which the MoreView
is built.
Subviews have their own transformers, views and view models, all of which are contained within the MoreUI
package. The exception to this is the MenuItemRow
subview. This is built using the ListItem
component, pulled in from the EntainComponentLibrary
.
The MoreCoordinator
initialises the MorePresenter
, and so it is this that is called by other parts of the app when navigating to the More Menu.
When a user takes an action, the MoreView
alerts the MorePresenter
to the action that has taken place. If navigation is required, the MorePresenter
alerts the MoreCoordinator
which then handles the logic of choosing which screen to navigate to and making the appropriate call. For other requirements - for example fetching data or initialising the app’s Live Chat feature - the MorePresenter
alerts the Domain Layer.
More
Following Viper architecture, the More Domain Layer package contains the MoreInteractor
, which receives data from the Data Layer and passes this through to the Presentation Layer and vice-versa, transforming the data if necessary.
For this transformation, the MoreInteractor
has a helper class: MoreDataTransformer
, which is broken out into its own file. This class transforms data received from the interactor and converts it to a MoreData
object. This MoreData
object is then passed by the interactor to the MorePresenter
, and it contains most of the data required to build the MoreView
.
Other packages that the More
package communicates with include:
- LiveChat (Mobile) - the
MoreInteractor
is the delegate of theLiveChatBridge
. TheMoreInteractor
has astartChat()
function which tells theLiveChatBridge
to start the chat. - Authentication (Data Layer) - the
MoreInteractor
requests log in status and receives authentication updates from theAuthentication
package and alerts it when a logout request has been made. - ClientDetails (Domain Layer) - the
MoreInteractor
requests user data from theClientDetails
package. - GraphQLOperations (Data Layer) - the
MoreInteractor
requests user data from theSocialProfileAchievementsQuery
GraphQLQuery. - Networking (Data Layer) - the
MoreInteractor
uses theNetworkRESTService
to request the user’s card data. - FeatureDirector (Domain Layer) - the
MoreInteractor
fetches feature flagged data from theFeatureDirector
. - AppConfig (Domain Layer) - the
MoreInteractor
uses theAppConfig
package to request data from the React Native codebase.
More Menu items & Branding
Besides the difference in brand colours, the More Menu overall has a similar layout and functionality across all brands (Ladbrokes, Neds, TabNZ, and Betcha). The image below shows every section that could be shown in the More Menu with the exception of the racing links which is only available for TabNZ:
- Social Profile: Shown if the user is logged in and the social profile feature is available.
- Verification Centre: Shown if the user is logged in and verification is required.
- Social Tiles: Shown if the user is logged in.
- Account List: Shown if the user is logged in.
- Generosity Tiles: Shown if the user is logged in.
- Deposit List: Shown if the user is logged in.
- Features List: Always shown.
- Racing Links: Shown for TabNZ if the user is logged in.
- Help List: Always shown.
- UAT List: Shown if the user is using the UAT version of the app.
- Logout: Shown if the user is logged in.
- Phone and Version: Always shown.
- Footer: Always shown on Australian brands Ladbrokes and Neds.
Below is a summary of each section along with the branding differences and any additional notes:
Social Profile
Ladbrokes, Neds and Betcha feature a Social Profile Tile, which displays the Social Profile Name, a description, and an avatar selected by the user. This section is only visible when the user is logged in. TabNZ does not feature a social profile.
On clicking the social profile card:
- Display the Confirm Profile native screen if
ClientDetailsStartUpQuery.client.socialProfile.id
is nil or in an unconfirmed state. - Otherwise, navigate to RN screen
ProfileHome
. This navigation requires parameters:profileId
- the user’s SocialProfile id -ClientDetailsStartUpQuery.client.socialProfile.id
reactivate
- true if the user should be taken to a screen to reactivate their profile, so ifClientDetailsStartUpQuery.client.socialProfile.type
= deactivated or banned
Verification Centre
The Verification Centre is a feature that is only present when the user is logged in and there are tasks that require the user to take action on. At the time of writing, there are only 2 tasks that could be displayed in this section:
Identity Verification
Id verification behaves differently between AU and NZ, with AU only having a single possible verification tile, while for NZ there are multiple possible tiles that a user may see in regards to id verification. Across all four brands, verification-related tiles within the "Action Required" section will consistently be positioned beneath the social profile tile.
Ladbrokes & Neds
"Verify Your Identity"
If ClientDetailsStartUpQuery.client.verification.verificationApproved
is true, this row is not shown. Or if ClientDetailsStartUpQuery.client.verification.verificationSubmitted = true AND ClientDetailsStartUpQuery.client.verification.verificationId = “ABC”
, this row is not shown. In all other scenarios, the row is shown.
Clicking on this tile navigates to RN screen AccountVerificationCentre
.
TabNZ & Betcha
The following tiles can only be shown if ClientDetailsStartUpQuery.client.verification.verificationApproved
is false, if the verificationApproved value is true then no tile is shown.
"ID Verification Required"
If ClientGetExternalClientVerificationQuery
returns STATE_IN_PROGRESS
or STATE_UNSPECIFIED
and ClientDetailsStartUpQuery.client.verification.verificationRequiredTime
returns a time in the future, then the following tile is shown.

The "7 hours" is calculated on the client side by comparing the current time to the verificationRequiredTime value.
If the time returned is before the current time then the following tile is shown instead.

Selecting "Verify Now" will invoke a verification centre bottom sheet, unless the user is in a locked out state. In that case, it follows the "Other Identity Document" path below without showing the bottom sheet option.
Android | iOS |
---|---|
![]() | ![]() |
"NZ Drivers License or Passport" - navigates the user either to the ModalAccountVerification
RN screen or the Native Green ID Modal, depending on the
id-verification-modal-native
feature flag.
"Other Identity Document" - launches a URL fetched from the app config in an external browser.
"Cancel" - simply dismisses the bottom sheet.
If ClientGetExternalClientVerificationQuery
returns STATE_LOCKED_OUT
then the following tile is shown.

"Contact Us" - navigates the user to RN screen AccountContactUs
.
"ID Verification in Review "
If ClientGetExternalClientVerificationQuery
returns STATE_PENDING then the following tile is shown.

All the text in this tile is hardcoded.
Card Verification
The app fetches a CreditCardResponse
for each card associated with a user’s account. Each card will have an associated CreatedDate
, equal either to CreditCardResponse.created
or CreditCardResponse.createTime
. There is also an IgnoreDate
which is pulled from RN. If, for any of their cards, CreditCardResponse.verified is false AND CreditCardResponse.verifyMethod != “P” AND the card’s CreatedDate is after “IgnoreDate”
, this row is shown.
Clicking on this tile navigates to RN screen AccountVerificationCentre
.
Social Tiles
Below the social profile and the Verification Centre, there are two tiles:
- Ladbrokes: 'Racing Club' or 'The Hub' depending on the
isAccessible
flag coming from the RN RacingClubModule, and 'Mates Mode,' - Neds: 'The Wrap' and 'Groups.'
- TabNZ: 'TAB Racing Club' and 'Boys Get Paid'
- Betcha: 'Bet Social' and 'The Playbook'
Although these tiles have different names for each brand, they navigate to the same destinations.
Racing Club (Ladbrokes)/TAB Racing Club(TabNZ) - navigate to RN screen
“RacingClubLanding”
The Hub (Ladbrokes)/The Wrap (Neds)/The Playbook(Betcha) - navigate to RN screen
“ContentHubWebView”
Mates Mode (Ladbrokes)/Groups (Neds)/Boys Get Paid (TabNZ)/Bet Social (Social) - navigate to RN screen
“GroupModeHome”
Account, Generosity Tiles and Deposit items
- My Account – navigate to RN screen
“AccountHome”
- Betslip Settings – navigate to RN screen
“AccountBetslipSettings”
- My Bets – navigate to RN screen
“AccountTransactions”
- Punter Assist – navigate to RN screen
“AccountPunterAssist”
- Bonus Bets – navigate to RN screen
“BonusOffers”
- Promotions – navigate to RN screen
“Promotions”
- Deposit – navigate to RN screen
“AccountDeposit”
- Withdraw – navigate to RN screen
“AccountWithdraw”
- Elite Portal - Only available to TabNZ costumers if the user has the
client.settings.catalystAvailability.elitePortalAvailable
flag on. Navigate to RN screen"elite"
or as configured bythirdparty.catalyst.elite-portal
Features
Each brand also has some differences in the arrangement and naming of buttons in the Feature section.
- Blackbook – navigate to RN screen
“BlackbookHome”
- Easy Form/ Filter Form – navigate to RN screen
“RacingEasyForm”
- The Hub/ The Wrap/ Punters Lounge/ The Playbook – navigate to native screen
“ContentHubWebView”
- Sports Multi Builder – navigate to RN screen
“MultiBuilder”
- Bet Live – Only available to AU brands. Navigate to RN screen
“BetLive”
- Owners Incentive Scheme – navigate to RN screen
“WebViewIntoApp”
. This navigation requires parameters:“path” - “/lois”
- Trackside Radio – only available to NZ brands. Displayed if the feature flag is on. Call the TracksideRadioModule RN module to start the Trackside Radio
- Promotions – navigate to RN screen
“Promotions”
- Everest Mega Millions – Only available to TabNZ. Displayed if the feature flag is on, the user is logged in and the user is not suspended for fraud. Navigate to RN screen
“EverestMegaMillion”
Racing Links
The Racing Links section is a TabNZ feature only. It displays the following items:
The navigation of these items is completely configurable through the thirdparty.catalyst
app config. Each of these items includes:
- Link: thirdparty.catalyst.${feature}.link - The link to navigate to
- Browser: thirdparty.catalyst.${feature}.browser - Whether to display the link in the preferred browser or a web view
- Should Auth: thirdparty.catalyst.${feature}.should-auth - Whether the app should pass auth credentials to the link
- Heading: thirdparty.catalyst.${feature}.modal-heading - The heading of the web view.
Features and default values:
calendar
- Default link:
https://${thirdparty.catalyst.domain}/iframe/calendar
- Display in Browser: true
- ShouldAuth: false
- Heading: ""
- Default link:
jackpots
- Default link:
https://${thirdparty.catalyst.domain}/iframe/jackpots
- Display in Browser: false
- ShouldAuth: false
- Heading: ""
- Default link:
racing-form
- Default link:
https://${thirdparty.catalyst.domain}/iframe/racing-form
- Display in Browser: false
- ShouldAuth: false
- Heading: ""
- Default link:
racing-index
- Default link:
https://${thirdparty.catalyst.domain}/iframe/racing-index
- Display in Browser: false
- ShouldAuth: false
- Heading: ""
- Default link:
results
- Default link:
https://${thirdparty.catalyst.domain}/iframe/results
- Display in Browser: false
- ShouldAuth: false
- Heading: ""
- Default link:
racing-schedule
- Default link:
https://${thirdparty.catalyst.domain}/iframe/racing-schedule
- Display in Browser: false
- ShouldAuth: false
- Heading: ""
- Default link:
scratchings
- Default link:
https://${thirdparty.catalyst.domain}/iframe/scratchings
- Display in Browser: false
- ShouldAuth: false
- Heading: ""
- Default link:
tv-schedule
- Default link:
https://${thirdparty.catalyst.domain}/iframe/tv-schedule
- Display in Browser: false
- ShouldAuth: false
- Heading: ""
- Default link:
Help
- Store Locator – Only available to NZ brands. Navigate to RN screen
"ModalWebView"
with link:https://new.tab.co.nz/iframe/store-locator
or as configured inthirdparty.catalyst.store-locator
- Contact Us – navigate to RN screen
“AccountContactUs”
- Live Chat – If the user is logged, launch LiveChat modal screen. If the user is logged out navigate to native screen
“ModalLogin”
. - FAQs And Help – open URL which is pulled in from RN’s app configuration module.
- How To Guides – navigate to RN screen
“WebViewIntoApp”
. This navigation requires parameters:“path” - “how-to”
- Rules Terms and Conditions – navigate to RN screen
“WebViewIntoApp”
. This navigation requires parameters:“path” - “rules-terms-and-conditions”
- Responsible Gambling – open URL which is pulled in from the native app configuration with the reference
“RESPONSIBLE_GAMBLING_URL”
. - Logout – log the user out and navigate to native screen
“Home”
UAT Only
- Storybook Testing Sandbox – navigate to RN screen
“StorybookTestingSandbox”
- Component Library – navigate to RN screen
“ComponentLibrary”
- Toggle Feature Flags – navigate to RN screen
“FeatureToggleScreen”
- QA Toggle – navigate to RN screen
“QAScreen”
- Developer Panel – navigate to RN screen
“DeveloperPanel”
Integrations
This section provides an overview of the integrations involved in supporting the More Menu functionality. These integrations close in to internal configurations, external services and data management systems.
Feature Flags
deposit-credit-card-nuvola
- determines which credit cards data source to use.content-hub-native
- This flag will determine if the navigation should be done to the native or the RN Content Hub screen.salesforce-live-chat-show-prechat-native
- It determines if the chat shows a pre-chat.salesforce-live-chat-show-minimised-native
- It determines if the chat should start minimized.menu-tab-elite-portal-native
- It determines if the Elite Portal should be shownmenu-tab-racing-calendar-native
- It determines if the Calendar item should be shownmenu-tab-racing-jackpots-native
- It determines if the Jackpots item should be shownmenu-tab-racing-pdf-form-native
- It determines if the PDF Form item should be shownmenu-tab-racing-hub-native
- It determines if the Racing Hub item should be shownmenu-tab-racing-results-native
- It determines if the Results item should be shownmenu-tab-racing-schedule-native
- It determines if the Schedule item should be shownmenu-tab-racing-scratchings-native
- It determines if the Scratchings item should be shownmenu-tab-racing-tv-schedule-native
- It determines if the TV Schedule item should be shownmenu-tab-store-locator-native
- It determines if the Store Locator item should be shownsalesforce-live-chat–native
- It determines if the Live Chat item should be showneverest-mega-millions-native
- It determines if the Everest Mega millions item should be shownid-verification-modal-native
- It determines if the native or the RN id verification modal is navigated to from the verification centre bottom sheet.
Configuration
domain.urls.help
- Help URL - from App Config.domain.actionRequiredAlerts.unverifiedCreditCard.ignoreCardsCreatedBefore
: This configuration is used to retrieve the date of the card that should be ignored during verification.thirdparty.chat.enabled
- Determines whether to show or not the live chat feature.domain.groupMode.joinOnlyProductName
- Used to configure the TabNZ group mode tile name.- Catalyst products configuration (only available to TabNZ):
thirdparty.catalyst.domain
- The domain to use when navigating to a catalyst product. Default values:new-uat.tab.co.nz
(UAT) ornew.tab.co.nz
(Prod)thirdparty.catalyst.elite-portal
- Configures theElite Portal
in the Account sectionthirdparty.catalyst.calendar
- Configures theCalendar
item in the Racing Linksthirdparty.catalyst.jackpots
- Configures theJackpots
item in the Racing Linksthirdparty.catalyst.racing-form
- Configures thePDF Form
item in the Racing Linksthirdparty.catalyst.racing-index
- Configures theRacing Hub
item in the Racing Linksthirdparty.catalyst.results
- Configures theResults
item in the Racing Linksthirdparty.catalyst.racing-schedule
- Configures theSchedule
item in the Racing Linksthirdparty.catalyst.scratchings
- Configures theScratchings
item in the Racing Linksthirdparty.catalyst.tv-schedule
- Configures theTV Schedule
item in the Racing Linksthirdparty.catalyst.store-locator
- Configures theStore Locator
item in the Help section
domain.urls.secureDocs
- The URL that gets launched in an external browser when the user selects "Other Identity Document" in the verification centre bottom sheet
Inputs
RN: GraphQLModule
- ClientDetailsStartupQuery: Used to get the user social profile info.
- SocialProfileAchievementsQuery: Used to get the ProfileAchievement and check if the onboarding is completed.
RN: UserInfoModule
- Receives updates the unread messages for group/mates mode
RN: RacingClubModule
- Receives updates for
isAccessible
which determines whether to show the Racing Club Social Tile for Ladbrokes and TabNZ
GQL: RacingClubListWinningBallotEntryQuery
- Used to get the badge number for the Tab Racing Club social tile.
REST: GET finance/finance-v2/ListCreditCards
- Used if nuvola feature flag is enabled to get the list of credit cards for verification alerts.
REST: GET finance/get-stored-credit-cards-enabled
- Used if nuvola feature flag is disabled to get the list of credit cards for verification alerts.
GQL: ClientGetExternalClientVerificationQuery
- Used to get the client verification status if
ClientDetailsStartUpQuery.client.verification.verificationApproved
is false.
Outputs
RN: TracksideRadioModule
- Used to start the Trackside Radio for NZ brands
Third-Party Dependencies
Salesforce Service Chat SDK
A chat client is built and the chat is started and ended.
Troubleshooting
Static Resources from the "static-ui" Project
When managing static resources across different brands, the preferred approach is to use resources from the "static-ui" project. This repository has a comprehensive collection of static images, files, and assets used in all of the brands under Entain.
To access these resources, clone the repository and follow the setup instructions provided. For more details, visit the following link: https://git.neds.sh/technology/code/ui/static
Android
Adapting and Testing UI Across Android Versions and Screen Sizes
To develop adaptable UIs with Jetpack Compose, we must make sure we maintian compatibility across a wide range of Android devices, featuring various Android versions and screen sizes.
Preview Annotations: Using preview annotations such as @EntainPreview, @SmallPreview and @Preview allows us visualize UI components on different screen devices. It is best to customize the parameters on these annotations to address any potential layout discrepancies. Beyond IDE previews, testing the UI on emulators and physical devices also helps identifying any possible issue related to visualization or version compatibility.
Version Compatiblity: Always consider the impact of different Android versions on the app's UI and functionality. Test across different devices to ensure behavior is consistent.
Resources
- Epic - Jira
- NZ Theming Epic - Jira
- Reported Bugs - Jira
- Tech Debt - Jira
- Salesforce Service Chat SDK - Android
- Salesforce Service Chat SDK - iOS
Role | Contact |
---|---|
PM | TBC |
Android Lead | Anthony Librio |
iOS Lead | Nicholas Vella |