Selkies
Developer ReferenceDashboardComponents

components/Sidebar

The dashboard sidebar: every control the reference dashboard offers on top of selkies-core, talking to the core through window.postMessage alone.

Renders a draggable toggle handle, the core action buttons (video, audio, microphone, webcam, gamepad), the soft modifier keys and virtual keyboard button for touch clients, the collapsible video, screen, audio, stats, clipboard, files, apps, sharing, gamepads and shortcuts sections, the upload and clipboard notifications, the apps and files modals, and the second-screen placement arrows.

Messages it consumes from the core: serverSettings (the settings payload that gates which controls render and seeds their values), pipelineStatusUpdate and sidebarButtonStatusUpdate, effectiveCursorState, clientRoleUpdate, gamingModeUpdate, toggleDashboard and toggleTouchGamepad (the core-owned Ctrl+Shift+M and Ctrl+Shift+G chords), gamepadControl, clipboardContentUpdate, audioDeviceSelected (its own selection mirrored back, so the dropdowns show what the core was told), gamepadButtonUpdate and gamepadAxisUpdate, fileUpload (upload progress and every notification the core raises), and trackpadModeUpdate.

Messages it posts: settings (debounced), pipelineControl, gamepadControl, setManualResolution, resetResolutionToWindow, setScaleLocally, setAntiAliasing, audioDeviceSelected, clipboardUpdateFromUI, clipboardImageUpdate, requestFullscreen, requestGamingMode, mode, setSynth, sidebarVisibilityChanged, TOUCH_GAMEPAD_SETUP, TOUCH_GAMEPAD_VISIBILITY, touchinput:trackpad and touchinput:touch, plus whatever channel a conditional-settings spec propagates through. The soft keys dispatch synthetic KeyboardEvents on window, and the files section dispatches the requestFileUpload DOM event.

window state it reads: system_stats, gpu_stats, fps, currentAudioLevel, network_stats, webrtcInput.gamingMode, __SELKIES_STREAMING_MODE__ and __SELKIES_DUAL_MODE__; it sets __selkiesModeSwitching around a transport switch.

Persistence: every setting lives in localStorage under <storageAppName>_<key>, the keys in PER_DISPLAY_SETTINGS gaining a _display2 suffix on the #display2 hash so a secondary display keeps its own values; an explicit user choice of a derived setting writes a _explicit_choice marker beside its value. The theme is stored unprefixed because it is a per-browser preference.

Functions

deriveDpiFromDpr()

function deriveDpiFromDpr(): number;

Defined in: components/Sidebar.jsx:163

The scaling_dpi default derived from the local display scaling (devicePixelRatio), so the remote desktop's fonts and UI match the local environment; an explicit picker value wins over it. Same formula as the core's autoDeriveDpi and independent of the resolution. Snapping to the nearest option puts a density the options do not name on the closest one and clamps at both ends.

Returns

number

One of the dpiScalingOptions values.


formatBytes()

function formatBytes(
   bytes, 
   decimals?, 
   rawDict?
): string;

Defined in: components/Sidebar.jsx:231

Formats a byte count with a binary unit.

Parameters

ParameterTypeDefault valueDescription
bytesnumberundefinedByte count; empty or zero yields the zero label.
decimals?number2Fraction digits, clamped at zero.
rawDict?anyundefinedTranslation table supplying zeroBytes and byteUnits.

Returns

string


calculateGaugeOffset()

function calculateGaugeOffset(
   percentage, 
   radius, 
   circumference
): number;

Defined in: components/Sidebar.jsx:256

Stroke dash offset that fills a gauge ring to percentage (clamped to 0 to 100).

Parameters

ParameterType
percentageany
radiusany
circumferenceany

Returns

number


roundDownToEven()

function roundDownToEven(num): number;

Defined in: components/Sidebar.jsx:262

Parses a dimension and rounds it down to an even number; non-numbers become 0.

Parameters

ParameterType
numany

Returns

number


debounce()

function debounce(func, delay): Function;

Defined in: components/Sidebar.jsx:274

Trailing debounce: only the last call within delay milliseconds runs.

Parameters

ParameterTypeDescription
funcFunction-
delaynumber-

Returns

Function


GamingModeIcon()

function GamingModeIcon(): Element;

Defined in: components/Sidebar.jsx:294

Crosshair marking gaming mode, the wish dashboard's icon for it: one glyph names the control in both front ends and reads as a target, not a plus sign.

Returns

Element


function SelkiesLogo(props): Element;

Defined in: components/Sidebar.jsx:415

The mark from docs/assets/logo/selkies.svg. The gradient identifier is per-instance: two logos sharing one identifier would leave the second unpainted as soon as the instance that owns the definition unmounts.

Parameters

ParameterTypeDescription
props{ width?: number; height?: number; className?: string; t: Function; }-
props.width?number-
props.height?number-
props.className?string-
props.tFunctionTranslator, for the accessible label.

Returns

Element


readStreamAudioLevel()

function readStreamAudioLevel(meterRef): number;

Defined in: components/Sidebar.jsx:459

Audio level of the WebRTC stream's audio track through a dashboard-owned AnalyserNode, never routed to a destination so playback is unaffected. The websockets worklet path exposes window.currentAudioLevel instead.

Parameters

ParameterTypeDescription
meterRef{ current: any; }Ref holding the analyser, rebuilt when the stream changes.
meterRef.currentany-

Returns

number

RMS in 0 to 1, or null without an audio track.


AppsModal()

function AppsModal(props): Element;

Defined in: components/Sidebar.jsx:499

Catalog of proot-apps with install, remove, update and launch actions, posted as app commands through app-commands.js.

Parameters

ParameterTypeDescription
props{ isOpen: boolean; onClose: () => void; t: Function; commandsAvailable: boolean; commandsKnown: boolean; }-
props.isOpenbooleanRenders nothing while false.
props.onClose() => void-
props.tFunctionTranslator.
props.commandsAvailablebooleanWhether the server accepts remote commands; actions are disabled otherwise.
props.commandsKnownbooleanWhether serverSettings have arrived, so the disabled notice is only shown once known.

Returns

Element


handleInstall()

function handleInstall(appName): void;

Defined in: components/Sidebar.jsx:603

The apps command contract both dashboards share: app-commands.js posts the selkies-proot wrapper commands and tracks them for rollback, and the installed list is updated optimistically.

Parameters

ParameterType
appNameany

Returns

void


getPrefixedKey()

function getPrefixedKey(key): string;

Defined in: components/Sidebar.jsx:804

The localStorage key for a setting: the session prefix, plus the _display2 suffix for per-display settings on the secondary display.

Parameters

ParameterTypeDescription
keystring-

Returns

string


readStored()

function readStored(key): string;

Defined in: components/Sidebar.jsx:813

Reads a setting's stored value under its prefixed key.

Parameters

ParameterType
keyany

Returns

string


explicitChoiceKey()

function explicitChoiceKey(spec): string;

Defined in: components/Sidebar.jsx:827

The marker key, suffixed onto the already-prefixed value key so it inherits the per-display suffix and a secondary display keeps its own choice.

Parameters

ParameterType
specany

Returns

string


readExplicitStored()

function readExplicitStored(spec): (key) => string;

Defined in: components/Sidebar.jsx:830

A storage reader for a spec that returns the stored value only when it was an explicit choice.

Parameters

ParameterType
specany

Returns

(key) => string


useConditionalSetting()

function useConditionalSetting(
   spec, 
   serverSettings, 
   ctx, 
   deps, 
   read?
): [any, Function];

Defined in: components/Sidebar.jsx:849

Drives a conditional setting: lazy init, then a re-resolve whenever the server settings or any dependency in deps changes, which covers the server sync and the encoder or manual-resolution re-derivation uniformly. The resolver honors explicit choices, so a re-resolve never clobbers a pinned value. A re-resolve writes state rather than deriving during render because the caller edits the value afterwards; deriving would discard that.

Parameters

ParameterTypeDefault valueDescription
specanyundefinedA spec from conditional-settings.js.
serverSettingsanyundefinedThe last serverSettings payload.
ctxanyundefinedResolution context the spec reads.
depsany[]undefinedValues whose change triggers a re-resolve.
read?(key) => stringreadStoredStorage reader.

Returns

[any, Function]

The value and its setter, as useState returns them.


clampToggleHandleTopPct()

function clampToggleHandleTopPct(pct): number;

Defined in: components/Sidebar.jsx:870

Clamps the toggle handle's vertical position, a percentage of the viewport height, so the handle stays fully inside the viewport. The handle's inline top positions its center (Overlay.css keeps the translateY(-50%)), so the clamp is by half the handle height. Without a finite viewport height (headless, pre-layout) that half would be Infinity, so the clamp is a plain 0 to 100 until a real height is known; a handle at least as tall as the viewport inverts the bounds, so it is centered instead of pinned to an edge.

Parameters

ParameterTypeDescription
pctnumber-

Returns

number


function Sidebar(): Element;

Defined in: components/Sidebar.jsx:884

The sidebar component; see the module docblock for the message and storage contract it implements. Renders nothing when the server hides the sidebar (ui_show_sidebar), and viewer-role clients get no toggle handle.

Returns

Element


launchWindow()

function launchWindow(direction, screen?): void;

Defined in: components/Sidebar.jsx:1069

Opens the secondary display in a new window, sized to screen when the Window Management API found one in that direction.

Parameters

ParameterTypeDefault valueDescription
direction"up" | "down" | "left" | "right"undefined-
screen?anynull-

Returns

void


handleAddScreenClick()

function handleAddScreenClick(): Promise<void>;

Defined in: components/Sidebar.jsx:1084

Add Screen: places the second display on an adjacent physical screen when the Window Management API reports exactly one, offers the placement arrows when it reports several, and otherwise opens it to the right.

Returns

Promise<void>


sendKeyEvent()

function sendKeyEvent(
   type, 
   key, 
   code, 
   modifierState
): void;

Defined in: components/Sidebar.jsx:1165

Dispatches a synthetic keyboard event on window for the input core to forward.

Parameters

ParameterType
typeany
keyany
codeany
modifierStateany

Returns

void


handleHoldKeyClick()

function handleHoldKeyClick(key, code): void;

Defined in: components/Sidebar.jsx:1181

Soft modifier key: toggles the key held, and switches the core's synth mode on with the first held modifier and off with the last release.

Parameters

ParameterType
keyany
codeany

Returns

void


handleOnceKeyClick()

function handleOnceKeyClick(key, code): void;

Defined in: components/Sidebar.jsx:1203

Soft momentary key: a press and release carrying the held modifiers.

Parameters

ParameterType
keyany
codeany

Returns

void


writeConditional()

function writeConditional(
   spec, 
   uiValue, 
   setValue, 
   opts?
): void;

Defined in: components/Sidebar.jsx:1446

Uniform write path for conditional settings: optimistic setState, an optional persist (explicit choices pin, derived ones do not), and propagation through the spec.

Parameters

ParameterTypeDescription
specany-
uiValueanyThe value as the UI holds it.
setValueFunctionThe setting's state setter.
opts?{ persist?: boolean; }-
opts.persist?boolean-

Returns

void


handleDpiScalingChange()

function handleDpiScalingChange(event): void;

Defined in: components/Sidebar.jsx:1657

UI scaling pick: persisted, so it pins across reloads and stops the startup derived-default post.

Parameters

ParameterType
eventany

Returns

void


handleTogglePointerUp()

function handleTogglePointerUp(e): void;

Defined in: components/Sidebar.jsx:1750

Ends a handle drag and persists its position. pointerId is null when the pointerup had no matching pointerdown (capture lost), and hasPointerCapture(null) coerces to id 0 and could release a foreign capture, so capture is only released for the tracked pointer.

Parameters

ParameterType
eany

Returns

void


function handleCopyLink(textToCopy, label): Promise<void>;

Defined in: components/Sidebar.jsx:1925

Copies a sharing link and reports the outcome as a notification.

Parameters

ParameterType
textToCopyany
labelany

Returns

Promise<void>


rederiveRateControl()

function rederiveRateControl(ctxOverrides): void;

Defined in: components/Sidebar.jsx:1970

Re-derives rate control after an encoder or software-encoding change. Rate control follows those unless pinned by an explicit client or server choice, and a derived change is not persisted, so it keeps following.

Parameters

ParameterTypeDescription
ctxOverridesanyThe value just chosen, ahead of the re-render that would put it in conditionalCtx.

Returns

void


handleEncoderChange()

function handleEncoderChange(event): void;

Defined in: components/Sidebar.jsx:1987

Encoder pick, one knob for both transports; the server switches the pipeline encoder on it. The choice is persisted immediately so conditionalCtx.activeEncoder, which reads localStorage, does not lag during the post debounce and let a serverSettings sync re-derive rate control off the stale encoder.

Parameters

ParameterType
eventany

Returns

void


handleVideoBitrateChange()

function handleVideoBitrateChange(event): void;

Defined in: components/Sidebar.jsx:2012

Video bitrate slider: its value is an index into videoBitrateOptions.

Parameters

ParameterType
eventany

Returns

void


handleRateControlChange()

function handleRateControlChange(event): void;

Defined in: components/Sidebar.jsx:2063

Rate control pick: an explicit choice, persisted so encoder changes stop overriding it.

Parameters

ParameterType
eventany

Returns

void


handleManualWidthChange()

function handleManualWidthChange(event): void;

Defined in: components/Sidebar.jsx:2115

A half-typed size stays in component state: the stored manual_width and manual_height mean "a manual resolution is applied", which the HiDPI and UI-scaling derivations read, so only Set, a preset, or Reset may write them.

Parameters

ParameterType
eventany

Returns

void


handleHidpiToggle()

function handleHidpiToggle(): void;

Defined in: components/Sidebar.jsx:2132

HiDPI toggle: an explicit choice, pinned; the core persists useCssScaling when it applies the message.

Returns

void


deriveHidpiForResolution()

function deriveHidpiForResolution(manual): void;

Defined in: components/Sidebar.jsx:2142

Manual and preset resolutions pair with CSS scaling: HiDPI off when one is set, on when reset, as a derived (unpinned) write through the uniform path. An explicit toggle or a locked or overridden server value pins HiDPI and stops the resolution buttons from re-deriving it.

Parameters

ParameterTypeDescription
manualbooleanWhether a manual resolution is now applied.

Returns

void


resetDpiToDerivedDefault()

function resetDpiToDerivedDefault(): void;

Defined in: components/Sidebar.jsx:2153

Reset-to-window also returns UI scaling to its derived (devicePixelRatio) default: the pinned client choice is dropped so the derived default governs again, and the value propagates like a user change. Locked or operator-explicit (overridden) values govern scaling instead, the same gate as the startup derived-default post.

Returns

void


resetHidpiToDerivedDefault()

function resetHidpiToDerivedDefault(): void;

Defined in: components/Sidebar.jsx:2171

Reset-to-window also restores HiDPI to its default. Unlike the resolution-derived writes, which respect a pinned choice, a reset means "back to defaults", so the client's own pin is dropped even under an operator-explicit value: use_css_scaling's overridden does not imply locked, and a kept pin would keep outranking the operator's value in the resolution ladder. The operator value when explicit, else the derived default, is then applied without storing; only a locked value leaves everything alone.

Returns

void


handleUseBrowserCursorsToggle()

function handleUseBrowserCursorsToggle(): void;

Defined in: components/Sidebar.jsx:2197

Browser cursors toggle. The core owns persistence: the new preference is propagated and the core reports the effective value back. The next value derives from the displayed one: while multi-monitor forces the toggle on the base preference may be off, and negating the base would silently persist the forced value over the user's real choice.

Returns

void


exitFullscreen()

function exitFullscreen(): void;

Defined in: components/Sidebar.jsx:2276

Leaves fullscreen through whichever prefixed API exists. Entering is handed to the core, which owns what each mode locks; exiting is the browser's own call either way.

Returns

void


handleClipboardImageUpload()

function handleClipboardImageUpload(event): void;

Defined in: components/Sidebar.jsx:2298

Hands a picked image to the core's clipboardImageUpdate path (a File is a Blob), which sends it through the binary clipboard exactly like a focus-synced local clipboard image; any other file raises a warning notification. Same contract as the wish dashboard.

Parameters

ParameterType
eventany

Returns

void


handleClipboardBlur()

function handleClipboardBlur(event): void;

Defined in: components/Sidebar.jsx:2325

Pushes the edited clipboard text to the server on blur, never a truncated preview.

Parameters

ParameterType
eventany

Returns

void


handleStreamModeChange()

function handleStreamModeChange(event): Promise<void>;

Defined in: components/Sidebar.jsx:2350

Switches the transport through /api/switch, then posts mode so the core reloads into it. window.__selkiesModeSwitching is set before the request because the server tears down the old peer (WebSocket close code 4000) before it responds, and without the flag the active core would surface a spurious "Server disconnected" alert. The endpoint is gated on the master token (Bearer) when set, or Basic credentials via same-origin; with Basic Auth off the dashboard is not given the token, so a 401 prompts for it once, keeps it in sessionStorage, and retries; a token the server rejects is dropped so the next attempt re-prompts. A failed switch clears the flag again, since no reload follows and a kept flag would hide a real disconnect.

Parameters

ParameterType
eventany

Returns

Promise<void>

References

default

Renames and re-exports Sidebar

On this page

Edit on GitHub