Members
(static, constant) HOME_ROW_LIMIT_DEFAULT
Mirrors the uiHomeRowLimit default in settings/settings.json, and is reached only when that setting is missing or unusable. Pinned to the JSON by a unit test rather than by this comment, because a comment cannot fail.
- Default Value
- 32
- Source
Methods
(static) DeleteFromServerList(idOrUrl) → {void}
| Name | Type | Description |
|---|---|---|
idOrUrl | string |
- Source
- Type:
- void
(static) GetConfigTree() → {dynamic}
Read config tree from json config file and return
- Source
- Type:
- dynamic
(static) RegistryReadAll(section) → {dynamic}
Return all data found inside a registry section
| Name | Type | Description |
|---|---|---|
section | string |
- Source
- Type:
- dynamic
(static) SaveServerList() → {void}
Saved-server list persistence. Pure registry operations on the saved_servers key — config.bs's domain, alongside getSavedUsers — called from both SetServerScreen (render thread, delete) and the loginRouter coordinator (main thread, save).
- Source
- Type:
- void
(static) clampToSettingRange(value, bounds) → {integer}
Bring a typed integer inside a declared range.
Returns the value unchanged when it already fits, so a caller can compare against its input to decide whether the user needs telling. Kept separate from settingRangeBounds for that reason — the SCREEN needs to know that a change happened, not just what to store.
| Name | Type | Description |
|---|---|---|
value | integer | |
bounds | object |
- Source
- Type:
- integer
(static) findConfigTreeKey(key, tree) → {dynamic}
Recursivly search the config tree for entry with settingname equal to key
| Name | Type | Description |
|---|---|---|
key | string | |
tree | dynamic |
- Source
- Type:
- dynamic
(static) findServerInList(savedJson, guid) → {object}
Pure: match the saved_servers JSON against a server GUID, case-insensitively (via serverIdsMatch). Split out from the registry read (findSavedServerByGuid in replayRoute.bs) so the match logic is unit-testable without touching the registry (getSetting reads the real "JellyRock" section, which tests must not write). Lives here alongside the saved_servers shape.
| Name | Type | Description |
|---|---|---|
savedJson | dynamic | |
guid | string |
- Source
- Type:
- object
(static) getGlobalRegistrySection() → {string}
Helper to get the global registry section name Returns "test-global" during tests, "JellyRock" in production
- Source
- Type:
- string
(static) getRegistrySections() → {object}
Return an array of all the registry section keys
- Source
- Type:
- object
(static) getSavedUsers() → {object}
Returns an array of saved users from the registry that belong to the active server
- Source
- Type:
- object
(static) getSetting(key, defaultValueopt) → {dynamic}
"JellyRock" registry accessors for the default global settings
| Name | Type | Attributes | Default | Description |
|---|---|---|---|---|
key | dynamic | |||
defaultValue | dynamic | <optional> | invalid |
- Source
- Type:
- dynamic
(static) getSettingKeysToDelete(allKeys, preserveKeys) → {object}
Filter registry keys to find those that should be deleted during a settings reset Preserves session/identity keys, deletes everything else
| Name | Type | Description |
|---|---|---|
allKeys | object | associative array of all registry key-value pairs |
preserveKeys | object | array of key names to preserve |
- Source
- array of key names that should be deleted
- Type:
- object
(static) getUserSetting(key) → {dynamic}
User registry accessors for the currently active user
| Name | Type | Description |
|---|---|---|
key | string |
- Source
- Type:
- dynamic
(static) isGlobalSetting(key) → {boolean}
Helper to determine if a setting is global (applies to all users)
| Name | Type | Description |
|---|---|---|
key | string |
- Source
- Type:
- boolean
(static) isIntSafe(value) → {boolean}
Is this value safe to hand to Int()?
Int() faults with a Type Mismatch on anything that is not a number — measured on a Stick 4K — and BrighterScript cannot catch it, because every caller here holds the value as dynamic. So the check is by TYPE rather than by coercion: accepting "1" would legitimize two spellings of one field and let the JSON drift between them, and the schema test forces the right one at PR time. An absent value reports its type as invalid and lands here too, which is why callers need no separate isValid() check.
Named for the question rather than for either caller: it guards settingRangeBounds (authored JSON) and resolveHomeRowLimit (a node field), which share nothing except that both would fault on the same input.
| Name | Type | Description |
|---|---|---|
value | dynamic |
- Source
- Type:
- boolean
(static) registryDelete(key, sectionopt) → {void}
| Name | Type | Attributes | Default | Description |
|---|---|---|---|---|
key | dynamic | |||
section | dynamic | <optional> | invalid |
- Source
- Type:
- void
(static) registryRead(key, sectionopt) → {dynamic}
Generic registry accessors
| Name | Type | Attributes | Default | Description |
|---|---|---|---|---|
key | dynamic | |||
section | dynamic | <optional> | invalid |
- Source
- Type:
- dynamic
(static) registryWrite(key, value, sectionopt) → {void}
| Name | Type | Attributes | Default | Description |
|---|---|---|---|---|
key | dynamic | |||
value | dynamic | |||
section | dynamic | <optional> | invalid |
- Source
- Type:
- void
(static) resolveHomeRowLimit(settingValue) → {integer}
How many items a Home browse FEED asks the server for.
ONE number for all three feeds — Recently Added, On Now, Active Recordings — because they had no reason to differ. All three sent 16, and they were tied to each other only by comment ("16 to be consistent with Latest In", "parity with onNow"). Sharing the setting makes that parity a fact instead of a claim three files have to keep agreeing on by hand.
The line this setting does NOT cross is feed vs worklist:
FEED - a sample of a larger set (these three). A limit chooses how much of the sample to show, so it is a real user preference and nothing is hidden by raising it. WORKLIST - a set the user is trying to get THROUGH. Continue Watching and Next Up send no limit at all, deliberately: any cap hides something already started, and no number is the right one to hide at. Next Up sent an arbitrary 69 until this change removed it; Continue Watching has always sent none.
The Favorites TAB (itemsToLoad = "favorites", loaded by FavoritesRows) is not a Home row at all, so it is out of scope on identity rather than on this rule.
The number is the uiHomeRowLimit user setting; this is the guard for the setting not being there. NOT a second copy of the range enforced when the value is SAVED — components/settings/settings.bs reads min/max straight off the settings.json entry, so the range has one source of truth and it is not this function.
Zero is the case worth naming. It is what an integer node field reads before SaveDefaults() has populated it, and it is a legal value to send: Jellyfin would answer a Limit=0 with an empty list, so every affected row would silently come back EMPTY rather than fail. A fallback that only checked isValid would let that through.
Pure — the caller passes the field rather than this reading m.global — so it is unit testable without a global, and so a Task thread pays one rendezvous at its own call site instead of one hidden in here.
| Name | Type | Description |
|---|---|---|
settingValue | dynamic | the raw uiHomeRowLimit field, possibly unset |
- Source
the item limit to send, never below 1
- Type:
- integer
(static) serverIdsMatch(a, b) → {boolean}
True when two Jellyfin server ids refer to the same server. Jellyfin GUIDs are canonical lower-case hex, but fold both sides so a mis-cased id (e.g. from an external deep-link/cast sender) still matches. The single source of truth for "same server?" across the saved-server list and the saved-user filter — keeps every id comparison consistent.
| Name | Type | Description |
|---|---|---|
a | dynamic | |
b | dynamic |
- Source
- Type:
- boolean
(static) setSetting(key, value) → {void}
| Name | Type | Description |
|---|---|---|
key | dynamic | |
value | dynamic |
- Source
- Type:
- void
(static) setUserSetting(key, value) → {void}
| Name | Type | Description |
|---|---|---|
key | string | |
value | dynamic |
- Source
- Type:
- void
(static) settingRangeBounds(entry) → {object}
The range a settings.json entry declares, or invalid when it declares none.
Every rejection below exists because Int() on the alternative is a Type Mismatch that takes down the Settings screen the moment the user OPENS that setting. Both shapes were measured on a Stick 4K rather than reasoned about, and neither is exotic:
- ONE bound declared. Relaxing this to "honor whichever bound is present" makes the other one
Int(invalid). (The weaker reason — the dialog text names both ends, so one bound alone would read "the supported range of 1 to invalid" — is true, and is not the one that matters.) - A bound written as a STRING.
Int("1")faults the same way, and it is the likelier typo of the two:defaultin the SAME entry is conventionally a string ("16"), so"min": "1"reads as consistent while being the one spelling that crashes.
A malformed entry therefore degrades to "declares no range" — the setting still saves, it is just unbounded — rather than taking the screen down. It does not pass silently either: tests/scripts/unit/settings-schema.test.js fails the PR on every shape rejected here, so this guard is the runtime floor and the schema test is the enforcement.
Lives here rather than in the settings screen so it can be unit-tested without the component, alongside findConfigTreeKey which reads the same tree.
| Name | Type | Description |
|---|---|---|
entry | object |
- Source
- Type:
- object
(static) unsetSetting(key) → {void}
| Name | Type | Description |
|---|---|---|
key | dynamic |
- Source
- Type:
- void
(static) unsetUserSetting(key) → {void}
| Name | Type | Description |
|---|---|---|
key | string |
- Source
- Type:
- void
(static) valueToString(value) → {string}
Convert dynamic value to string for registry storage
| Name | Type | Description |
|---|---|---|
value | dynamic |
- Source
- Type:
- string