Brand and design · Hi-fi screens · S17 Library · Library
Data-binding map: S17 Library · Library
Data-binding map of Library · Library: every field to its source, and what each required state shows.
Generated by
botgumi-design indexfrom../../screens.json. Edit that file, not this page.
Every field S17 shows and where it comes from.
| Field | Source (endpoint or local state) | Format | Fallback |
|---|---|---|---|
| language filter | call GET /articles · local:library.filter.language → GET /v1/articles?language=; options = config.supported_practice_languages |
"All languages" + endonyms; default = all practice languages (no param) | — |
| language filter | local library.filter.language |
||
| language filter | api GET /config supported_practice_languages |
||
| topic chips + counts | call GET /topics · GET /v1/topics → name (Accept-Language), article_count |
chip with count | hide counts if missing |
| status segment | local library.filter.status · local:library.filter.status → ?status=all|unseen|completed |
— | — |
| row tile | api GET /articles items[].topic.glyph · articles.items[n].topic.glyph / color_token (glyph Accept-Language: 产 / Pr) |
48pt square | — |
| row tile | api GET /articles items[].topic.color_token |
||
| row title | api GET /articles items[].title · articles.items[n].title (article language) |
lang= |
— |
| row language tag | api GET /articles items[].language · articles.items[n].language |
lang.short.<tag> — only when the list mixes languages |
hidden |
| row meta | api GET /articles items[].topic.name · topic.name, length.label (Accept-Language), difficulty |
topic · length · Level n |
— |
| row meta | api GET /articles items[].length.label |
||
| row meta | api GET /articles items[].difficulty |
||
| status tag | api GET /articles items[].user_status · user_status, best_overall, locked + CCR-3 unlock_hint |
New / In progress / Best N / lock | — |
| status tag | api GET /articles items[].best_overall |
||
| status tag | api GET /articles items[].locked |
||
| status tag | api GET /articles items[].unlock_hint |
||
| pagination | api GET /articles next_cursor · next_cursor |
infinite scroll | — |
| empty | api GET /articles items · items = [] for filter |
library.empty.* |
— |
GET /v1/articles?language=en |
call GET /articles · From the board's data-bind; no row in data-binding.md yet. |
||
GET /v1/articles?language=zh-Hans |
call GET /articles · From the board's data-bind; no row in data-binding.md yet. |
||
GET /v1/articles?status=all|unseen|completed |
call GET /articles · From the board's data-bind; no row in data-binding.md yet. |
||
GET /v1/articles?topic=tech → items = [] |
api GET /articles items · From the board's data-bind; no row in data-binding.md yet. |
||
GET /v1/topics → topics[].name / article_count (Accept-Language) |
call GET /topics · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[0].best_overall |
api GET /articles items[].best_overall · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[0].id |
api GET /articles items[].id · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[0].language |
api GET /articles items[].language · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[0].title |
api GET /articles items[].title · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[0].topic |
api GET /articles items[].topic · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[0].topic.name / length.label / difficulty |
api GET /articles items[].topic.name · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[0].topic.name / length.label / difficulty |
api GET /articles items[].length.label |
||
articles.items[0].topic.name / length.label / difficulty |
api GET /articles items[].difficulty |
||
articles.items[0].user_status |
api GET /articles items[].user_status · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[1].best_overall |
api GET /articles items[].best_overall · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[1].id |
api GET /articles items[].id · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[1].language |
api GET /articles items[].language · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[1].title |
api GET /articles items[].title · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[1].topic |
api GET /articles items[].topic · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[1].topic.name / length.label / difficulty |
api GET /articles items[].topic.name · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[1].topic.name / length.label / difficulty |
api GET /articles items[].length.label |
||
articles.items[1].topic.name / length.label / difficulty |
api GET /articles items[].difficulty |
||
articles.items[1].user_status |
api GET /articles items[].user_status · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[2].best_overall |
api GET /articles items[].best_overall · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[2].id |
api GET /articles items[].id · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[2].language |
api GET /articles items[].language · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[2].title |
api GET /articles items[].title · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[2].topic |
api GET /articles items[].topic · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[2].topic.name / length.label / difficulty |
api GET /articles items[].topic.name · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[2].topic.name / length.label / difficulty |
api GET /articles items[].length.label |
||
articles.items[2].topic.name / length.label / difficulty |
api GET /articles items[].difficulty |
||
articles.items[3].id |
api GET /articles items[].id · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[3].language |
api GET /articles items[].language · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[3].title |
api GET /articles items[].title · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[3].topic |
api GET /articles items[].topic · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[3].topic.name / length.label / difficulty |
api GET /articles items[].topic.name · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[3].topic.name / length.label / difficulty |
api GET /articles items[].length.label |
||
articles.items[3].topic.name / length.label / difficulty |
api GET /articles items[].difficulty |
||
articles.items[3].user_status |
api GET /articles items[].user_status · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[4].best_overall |
api GET /articles items[].best_overall · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[4].id |
api GET /articles items[].id · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[4].language |
api GET /articles items[].language · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[4].title |
api GET /articles items[].title · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[4].topic |
api GET /articles items[].topic · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[4].topic.name / length.label / difficulty |
api GET /articles items[].topic.name · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[4].topic.name / length.label / difficulty |
api GET /articles items[].length.label |
||
articles.items[4].topic.name / length.label / difficulty |
api GET /articles items[].difficulty |
||
articles.items[4].user_status |
api GET /articles items[].user_status · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[5].id |
api GET /articles items[].id · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[5].language |
api GET /articles items[].language · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[5].title |
api GET /articles items[].title · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[5].topic |
api GET /articles items[].topic · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[5].topic.name / length.label / difficulty |
api GET /articles items[].topic.name · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[5].topic.name / length.label / difficulty |
api GET /articles items[].length.label |
||
articles.items[5].topic.name / length.label / difficulty |
api GET /articles items[].difficulty |
||
articles.items[5].user_status |
api GET /articles items[].user_status · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[6].id |
api GET /articles items[].id · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[6].language |
api GET /articles items[].language · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[6].locked + unlock_hint (CCR-3) |
api GET /articles items[].locked · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[6].locked + unlock_hint (CCR-3) |
api GET /articles items[].unlock_hint |
||
articles.items[6].title |
api GET /articles items[].title · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[6].topic |
api GET /articles items[].topic · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[6].topic.name / length.label / difficulty |
api GET /articles items[].topic.name · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[6].topic.name / length.label / difficulty |
api GET /articles items[].length.label |
||
articles.items[6].topic.name / length.label / difficulty |
api GET /articles items[].difficulty |
||
articles.items[6].user_status |
api GET /articles items[].user_status · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[7].id |
api GET /articles items[].id · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[7].language |
api GET /articles items[].language · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[7].locked + unlock_hint (CCR-3) |
api GET /articles items[].locked · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[7].locked + unlock_hint (CCR-3) |
api GET /articles items[].unlock_hint |
||
articles.items[7].title |
api GET /articles items[].title · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[7].topic |
api GET /articles items[].topic · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[7].topic.name / length.label / difficulty |
api GET /articles items[].topic.name · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[7].topic.name / length.label / difficulty |
api GET /articles items[].length.label |
||
articles.items[7].topic.name / length.label / difficulty |
api GET /articles items[].difficulty |
||
articles.items[7].user_status |
api GET /articles items[].user_status · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[8].id |
api GET /articles items[].id · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[8].locked + unlock_hint (CCR-3) |
api GET /articles items[].locked · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[8].locked + unlock_hint (CCR-3) |
api GET /articles items[].unlock_hint |
||
articles.items[8].title |
api GET /articles items[].title · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[8].topic |
api GET /articles items[].topic · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[8].topic.name / length.label / difficulty |
api GET /articles items[].topic.name · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[8].topic.name / length.label / difficulty |
api GET /articles items[].length.label |
||
articles.items[8].topic.name / length.label / difficulty |
api GET /articles items[].difficulty |
||
articles.items[9].id |
api GET /articles items[].id · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[9].locked + unlock_hint (CCR-3) |
api GET /articles items[].locked · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[9].locked + unlock_hint (CCR-3) |
api GET /articles items[].unlock_hint |
||
articles.items[9].title |
api GET /articles items[].title · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[9].topic |
api GET /articles items[].topic · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[9].topic.name / length.label / difficulty |
api GET /articles items[].topic.name · From the board's data-bind; no row in data-binding.md yet. |
||
articles.items[9].topic.name / length.label / difficulty |
api GET /articles items[].length.label |
||
articles.items[9].topic.name / length.label / difficulty |
api GET /articles items[].difficulty |
||
error.code |
status GET /articles 5XX internal · pending CCR-14 · From the board's data-bind; no row in data-binding.md yet. |
||
error.message (Accept-Language) |
status GET /articles 5XX internal · pending CCR-14 · From the board's data-bind; no row in data-binding.md yet. |
Contract change requests
Fields above that no endpoint sends yet. Until each lands, the screen falls back as noted.
| Change | Request | Fallback until it lands |
|---|---|---|
| CCR-14 | Document the error responses on every operation the screens read: 4XX and 5XX → #/components/responses/Error (ErrorEnvelope), and 402 entitlement_required on the hard-paywalled reads the API description lists (/home, /articles*, /topics, /sessions, /growth, /achievements, /weekly-quests, /plan). Today only a few operations list any error, GET /home none. |
The client decodes any non-2xx body as ErrorEnvelope, as the API description says. |
Binds on the boards
The data-bind values across every state.
GET /v1/articles?language=enGET /v1/articles?language=zh-HansGET /v1/articles?status=all|unseen|completedGET /v1/articles?topic=tech → items = []GET /v1/topics → topics[].name / article_count (Accept-Language)articles.items[0].best_overallarticles.items[0].idarticles.items[0].languagearticles.items[0].titlearticles.items[0].topicarticles.items[0].topic.name / length.label / difficultyarticles.items[0].user_statusarticles.items[1].best_overallarticles.items[1].idarticles.items[1].languagearticles.items[1].titlearticles.items[1].topicarticles.items[1].topic.name / length.label / difficultyarticles.items[1].user_statusarticles.items[2].best_overallarticles.items[2].idarticles.items[2].languagearticles.items[2].titlearticles.items[2].topicarticles.items[2].topic.name / length.label / difficultyarticles.items[3].idarticles.items[3].languagearticles.items[3].titlearticles.items[3].topicarticles.items[3].topic.name / length.label / difficultyarticles.items[3].user_statusarticles.items[4].best_overallarticles.items[4].idarticles.items[4].languagearticles.items[4].titlearticles.items[4].topicarticles.items[4].topic.name / length.label / difficultyarticles.items[4].user_statusarticles.items[5].idarticles.items[5].languagearticles.items[5].titlearticles.items[5].topicarticles.items[5].topic.name / length.label / difficultyarticles.items[5].user_statusarticles.items[6].idarticles.items[6].languagearticles.items[6].locked + unlock_hint (CCR-3)articles.items[6].titlearticles.items[6].topicarticles.items[6].topic.name / length.label / difficultyarticles.items[6].user_statusarticles.items[7].idarticles.items[7].languagearticles.items[7].locked + unlock_hint (CCR-3)articles.items[7].titlearticles.items[7].topicarticles.items[7].topic.name / length.label / difficultyarticles.items[7].user_statusarticles.items[8].idarticles.items[8].locked + unlock_hint (CCR-3)articles.items[8].titlearticles.items[8].topicarticles.items[8].topic.name / length.label / difficultyarticles.items[9].idarticles.items[9].locked + unlock_hint (CCR-3)articles.items[9].titlearticles.items[9].topicarticles.items[9].topic.name / length.label / difficultyerror.codeerror.message (Accept-Language)
States
- Loading: Skeleton rows. No import button in v1 (config.flags.import_enabled = false).
- Empty: From states.md (Library): library--filter-empty
- Error (retryable / not): Retryable load failure. No import button in v1 (config.flags.import_enabled = false).
- Offline: From states.md (Library): cached first page + banner; filters on cached data only