MainScreen displays the full channel catalog after a successful login. It provides category tab navigation, a scrollable channel list, and a selection overlay. It is the screen that satisfies the Roku AppLaunchComplete certification requirement.
Overlay mode
The screen operates in two modes controlled by theoverlayMode boolean field:
overlayMode = false— the list is hidden and focus is released (used when PlayerScreen is fullscreen in the background)overlayMode = true— the overlay is animated in and the channel list receives input
Channel grid layout
Channels are rendered as a manually managed list ofChannelRowItem nodes rather than relying on the built-in RowList component directly. This avoids RowList focus and animation quirks with live-switching.
Each row is 92px tall with 8px spacing (both scaled via the layout context). A sliding window of up to 5 visible rows is maintained:
ChannelRowItem tile
EachChannelRowItem (520×92px default) has:
- A colored badge on the left showing the channel number
- A name label (
numberLabel) showing the channel name - A category label (
nameLabel) showing the group - A focus frame (teal
0x2CD5C4FFborder) when focused - A purple background (
0x7F35B2BA) when the item is the currently playing channel
The
CHANNEL_TILE_MODE constant in AppConstants is set to "badge_only". This value is available for conditional rendering logic that shows only the number badge without thumbnail art.Category tabs
Categories are extracted from the playlist’sgroup field for each channel. A synthetic “Todos” category (key __all__) is always prepended.
0x2CD5C4FF) border on all four sides and a teal dot indicator below it. Inactive tabs use muted borders (0x2F2F2FBA).
Left/Right keys in overlay mode switch categories. A 140ms pulse animation plays on the tab rail during the switch.
AppLaunchComplete beacon
TheAppLaunchComplete Roku certification beacon is fired once, the first time channels are loaded and the row list is built:
onChannelsChanged() after the category index and row list are built.
Dispatching to PlayerScreen
When the user presses OK on a focused channel row,CommitFocusedChannel() resolves the flat index across all channels and emits it:
MainScene observes channelSelected and calls PlayChannel(flatIndex) on PlayerScreen.
Header elements
The top bar includes:- GlobalTV logo (right-aligned)
- Brand tagline labels
- A
WifiWidgetshowing current connection status - A live clock label updated every 5 seconds by
clockTimer