The SKELETON-cell convention: a row that exists before its items have landed.
Both cell components render skeletons — JRRowItem for Home's rows and GridItem for the item grid's genre rows — and several views build and guard against them. The whole convention lives here: the placeholder a producer appends, the predicate a consumer guards with, and the spinner the cells draw. A hand-typed "Loading" literal at any site is drift waiting to happen — a misspelled construction site would send a bare ContentNode into the media render path, where reading absent fields crashes the render thread.
- Source
Members
(static, constant) PLACEHOLDER_TYPE
The type field value that marks a placeholder. Compare via isPlaceholder(), construct via createPlaceholder() — never hand-type this string elsewhere.
- Default Value
- Loading
- Source
(static, constant) SPINNER_SIZE
Diameter of the spinner graphic, in px. Small enough to read as "this cell is waiting" rather than as content in its own right.
- Default Value
- 48
- Source
Methods
(static) createPlaceholder() → {object}
Builds the placeholder child a skeleton row carries so the RowList renders the row (a childless row is not laid out at all) at its correct slot size.
- Source
- Type:
- object
(static) hideSpinner(spinner) → {void}
Hides and stops spinner if the caller ever created one.
Call this on every non-skeleton render, not just when leaving a skeleton: cells are RECYCLED, so the cell now rendering a real item may be the same node that showed a spinner a moment ago. A spinner left running would keep animating over real content.
| Name | Type | Description |
|---|---|---|
spinner | dynamic |
- Source
- Type:
- void
(static) isPlaceholder(node) → {boolean}
True when node is a skeleton placeholder. Safe on invalid and on nodes with no type field (a bare ContentNode reads invalid there).
| Name | Type | Description |
|---|---|---|
node | dynamic |
- Source
- Type:
- boolean
(static) showSpinner(owner, spinner, slotWidth, posterHeight, posterTopopt) → {object}
Lazy-creates, centers and starts the spinner over owner's poster area.
The node is passed in and handed back rather than kept in an m here: these run inside a component's scope, where m is that component instance. The caller owns the reference (one spinner per recycled cell); this only knows how to size, place and start it.
Creation work (sizing the graphic, parenting to owner) happens ONCE, in the create branch — cells are recycled and re-bound often, an appendChild of an already-parented child is a detach+reattach scene-graph mutation, and control = "start" on a running spinner visibly resets the animation. The steady-state path only re-places (slot sizes differ across rows) and re-shows.
within the full cell, whose height includes the title area below the poster) sits at the cell origin, as in JRRowItem; GridItem offsets it)
| Name | Type | Attributes | Default | Description |
|---|---|---|---|---|
owner | object | the cell node the spinner is parented to (constant per caller) | ||
spinner | dynamic | the caller's existing spinner, or invalid on first use | ||
slotWidth | float | the cell's width | ||
posterHeight | float | the poster area's height (the spinner centers within it, NOT | ||
posterTop | float | <optional> | 0 | the poster area's y offset within the cell (0 when the poster |
- Source
the spinner node, for the caller to hold onto across recycles
- Type:
- object