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
| Parameter | Type | Default value | Description |
|---|---|---|---|
bytes | number | undefined | Byte count; empty or zero yields the zero label. |
decimals? | number | 2 | Fraction digits, clamped at zero. |
rawDict? | any | undefined | Translation 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
| Parameter | Type |
|---|---|
percentage | any |
radius | any |
circumference | any |
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
| Parameter | Type |
|---|---|
num | any |
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
| Parameter | Type | Description |
|---|---|---|
func | Function | - |
delay | number | - |
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
SelkiesLogo()
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
| Parameter | Type | Description |
|---|---|---|
props | { width?: number; height?: number; className?: string; t: Function; } | - |
props.width? | number | - |
props.height? | number | - |
props.className? | string | - |
props.t | Function | Translator, 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
| Parameter | Type | Description |
|---|---|---|
meterRef | { current: any; } | Ref holding the analyser, rebuilt when the stream changes. |
meterRef.current | any | - |
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
| Parameter | Type | Description |
|---|---|---|
props | { isOpen: boolean; onClose: () => void; t: Function; commandsAvailable: boolean; commandsKnown: boolean; } | - |
props.isOpen | boolean | Renders nothing while false. |
props.onClose | () => void | - |
props.t | Function | Translator. |
props.commandsAvailable | boolean | Whether the server accepts remote commands; actions are disabled otherwise. |
props.commandsKnown | boolean | Whether 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
| Parameter | Type |
|---|---|
appName | any |
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
| Parameter | Type | Description |
|---|---|---|
key | string | - |
Returns
string
readStored()
function readStored(key): string;Defined in: components/Sidebar.jsx:813
Reads a setting's stored value under its prefixed key.
Parameters
| Parameter | Type |
|---|---|
key | any |
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
| Parameter | Type |
|---|---|
spec | any |
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
| Parameter | Type |
|---|---|
spec | any |
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
| Parameter | Type | Default value | Description |
|---|---|---|---|
spec | any | undefined | A spec from conditional-settings.js. |
serverSettings | any | undefined | The last serverSettings payload. |
ctx | any | undefined | Resolution context the spec reads. |
deps | any[] | undefined | Values whose change triggers a re-resolve. |
read? | (key) => string | readStored | Storage 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
| Parameter | Type | Description |
|---|---|---|
pct | number | - |
Returns
number
Sidebar()
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
| Parameter | Type | Default value | Description |
|---|---|---|---|
direction | "up" | "down" | "left" | "right" | undefined | - |
screen? | any | null | - |
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
| Parameter | Type |
|---|---|
type | any |
key | any |
code | any |
modifierState | any |
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
| Parameter | Type |
|---|---|
key | any |
code | any |
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
| Parameter | Type |
|---|---|
key | any |
code | any |
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
| Parameter | Type | Description |
|---|---|---|
spec | any | - |
uiValue | any | The value as the UI holds it. |
setValue | Function | The 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
| Parameter | Type |
|---|---|
event | any |
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
| Parameter | Type |
|---|---|
e | any |
Returns
void
handleCopyLink()
function handleCopyLink(textToCopy, label): Promise<void>;Defined in: components/Sidebar.jsx:1925
Copies a sharing link and reports the outcome as a notification.
Parameters
| Parameter | Type |
|---|---|
textToCopy | any |
label | any |
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
| Parameter | Type | Description |
|---|---|---|
ctxOverrides | any | The 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
| Parameter | Type |
|---|---|
event | any |
Returns
void
handleVideoBitrateChange()
function handleVideoBitrateChange(event): void;Defined in: components/Sidebar.jsx:2012
Video bitrate slider: its value is an index into videoBitrateOptions.
Parameters
| Parameter | Type |
|---|---|
event | any |
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
| Parameter | Type |
|---|---|
event | any |
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
| Parameter | Type |
|---|---|
event | any |
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
| Parameter | Type | Description |
|---|---|---|
manual | boolean | Whether 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
| Parameter | Type |
|---|---|
event | any |
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
| Parameter | Type |
|---|---|
event | any |
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
| Parameter | Type |
|---|---|
event | any |
Returns
Promise<void>
References
default
Renames and re-exports Sidebar