remoteDispatch

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).

Parameters:
NameTypeDescription
commandobject
Returns:
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.

Returns:
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.

Parameters:
NameTypeDescription
commandobject
Returns:
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.

Parameters:
NameTypeDescription
commandobject
Returns:
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.

Parameters:
NameTypeDescription
commandobject
Returns:
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.

Parameters:
NameTypeDescription
routestring
Returns:
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".

Parameters:
NameTypeDescription
evtobject
Returns:
Type: 
object

(static) playContentId(command) → {string}

Mint the deep-link contentId for a play command: "|action=". Uses the single cast item itemIds[startIndex] (out-of-range index falls back to 0); returns "" when the command carries no usable item. The bare-id form is exactly what parseDeepLinkContentId consumes.

Parameters:
NameTypeDescription
commandobject
Returns:
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.

Parameters:
NameTypeDescription
commandobject
Returns:
Type: 
object