Main-thread dispatch adapter for the remote-control receiver. THE single place any deep-link / player seam is called for a normalized remote-control command — whether it arrives from the Roku voice roInput path (main.bs) or the ws:// receiver (RemoteControlTask). Runs on the MAIN thread (shares Main()'s m): stashDeepLink / onRuntimeDeepLink / getActiveView / callFunc all resolve there and must never be called from a Task. All sgRouter-era coupling is quarantined here.
source/ auto-scope reaches the seams without imports: stashDeepLink + onRuntimeDeepLink live in source/replayRoute.bs, getActiveView in source/utils/misc.bs, remoteCommand.ticksToSeconds in source/remotecontrol/remoteCommand.bs.
Methods
(static) dispatch(command) → {void}
Entry point: route a normalized command (remoteCommand.parseMessage output, marshalled from the RemoteControlTask) to the right seam. Transport goes through the shared dispatchTransport below (also used by main.bs's voice path); play/navigate ride the deep-link seam. keepalive/ignore never reach the main thread (the task answers keepalive itself and drops ignores).
| Name | Type | Description |
|---|---|---|
command | object |
- Type:
- void
(static) dispatchGoBack() → {void}
goback (GeneralCommand Back) -> pop the router one step. sgRouter.goBack is a no-op at the history root, so a remote Back never triggers the exit-confirmation / app exit.
- Type:
- void
(static) dispatchMessage(command) → {void}
message (GeneralCommand DisplayMessage) -> surface the sender's notification. TimeoutMs is the sender's intent: present -> transient (a toast); absent -> persistent (a dialog the user dismisses). Header is the title, Text the body — either may be empty. This is a trusted-LAN, authenticated sender (see remote-control.md), so interrupting with a dialog is acceptable.
| Name | Type | Description |
|---|---|---|
command | object |
- Type:
- void
(static) dispatchNavigate(command) → {void}
navigate (DisplayContent) -> springboard the item with action "open" (no autoplay). itemType is only a display hint that lands in the route path; ItemDetails resolves the real type.
| Name | Type | Description |
|---|---|---|
command | object |
- Type:
- void
(static) dispatchPlay(command) → {void}
play -> the deep-link play seam. Casts a SINGLE item (itemIds[startIndex]); the socket is already bound to the active server's session, so no serverId is minted (an empty guid resolves to the active server in onRuntimeDeepLink -> replayDeepLinkRuntime). Multi-item queue casting is a deferred follow-up.
| Name | Type | Description |
|---|---|---|
command | object |
- Type:
- void
(static) dispatchRoute(route) → {void}
route (GeneralCommand GoHome / GoToSearch / GoToSettings) -> navigate the router to a fixed path. GoHome's "/" clears the stack (clearStackOnResolve) so Home is the back-stack root. An active player is torn down by routing away (its onDestroy stops playback); from an idle screen this shares the render-thread-wake caveat noted in remote-control.md, but going home from playback wakes the render thread as the player unmounts.
| Name | Type | Description |
|---|---|---|
route | string |
- Type:
- void
(static) dispatchTransport(evt) → {object}
Shared transport adapter, extracted from main.bs's roInputEvent branch so the voice path and the ws:// receiver dispatch transport identically. Returns { status, nowPlaying }: main.bs's voice branch keeps the roInput.EventResponse + roAppManager.SetNowPlayingContentMetaData (both are main-thread-only) around this call; the ws:// path just fires it. A non-player active view (or none) yields "error.no-media"; a player that returns no status yields "unhandled".
| Name | Type | Description |
|---|---|---|
evt | object |
- Type:
- object
(static) playContentId(command) → {string}
Mint the deep-link contentId for a play command: "
| Name | Type | Description |
|---|---|---|
command | object |
- Type:
- string
(static) toTransportEvt(command) → {object}
Build the evt a player's handleTransport consumes from a transport command. Only "seekto" carries a position (absolute seconds, converted from Jellyfin ticks); every other verb passes the command alone, matching the voice path's { command } shape.
| Name | Type | Description |
|---|---|---|
command | object |
- Type:
- object