Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions docs-developers/frontend/state-and-data.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,20 @@ file/chapter list, in both the wide and phone branches, following the
section-per-concern pattern (the same shape as the bookmarks/notes sections). It
shows a description (collapsed past ~300 characters with a show-more toggle),
compact production details (publisher, release date, first published, an
"abridged" badge), a horizontal **more in this series** rail, and a quiet **View
on AudioSilo Meta** link.
"abridged" badge), a **Characters** section, a **Story so far** recap section, a
horizontal **more in this series** rail, and a quiet **View on AudioSilo Meta**
link.

The **Characters** and **Story so far** sections are the community expressive
layer (`work.characters` / `work.recaps`, the `BookMetaCharacter` /
`BookMetaRecap` types). They are spoiler-aware and rendered closed by default:
each character card shows name/role/aliases and "from chapter N" up front, with a
per-card accordion for the own-words description (no blur - a tap reveals it);
each recap likewise opens only when tapped, so the reader goes only as far as
they have listened. Both are absent from the envelope when the upstream has
none, so a work without them simply shows no such section. Pure label helpers
(`roleLabelKey`, `revealFromStart`, `recapDescriptor`, `sortRecaps`) are
unit-tested, and the strings live under `book.meta.*` in all locale catalogs.

Three details make it safe to add to a screen everyone sees:

Expand Down
43 changes: 42 additions & 1 deletion docs-developers/server/api/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -700,7 +700,24 @@ Response `200` on a match:
"authors": [{ "id": "andy-weir", "name": "Andy Weir" }],
"language": "en",
"first_published": "2011",
"description": "An astronaut is stranded on Mars…"
"description": "An astronaut is stranded on Mars…",
"characters": [
{
"id": "mark-watney",
"name": "Mark Watney",
"aliases": ["The Martian"],
"role": "protagonist",
"reveal": { "chapter": 1 },
"description": "The stranded astronaut, an engineer-botanist…"
}
],
"recaps": [
{
"through": { "chapter": 6 },
"scope": "book",
"text": "Watney has survived the storm and taken stock of Hab…"
}
]
},
"recording": {
"id": "podium-2013",
Expand Down Expand Up @@ -740,6 +757,30 @@ work's position in that series; `series[].works` is the full ordered rail,
**including the current work** (the client filters it out before drawing a "more
in this series" row). Positions are strings ("1", "2.5", "1-3.5").

`work.characters` and `work.recaps` are the community **expressive layer** (the
CC BY-SA content, spoiler-tagged and position-keyed); both are `omitempty`, so
they are absent when the upstream has none. A **position** is
`{ "chapter": <int >= 0> }` on the work's own, edition-independent timeline (the
logical work chapter, 1-based; `0` = front matter / prior-book knowledge), which
the client maps onto its recording's chapters.

- Each **character** carries an `id` (unique within the work, not global), a
`name`, optional `aliases` and `role` (`protagonist`/`antagonist`/`supporting`/
`minor`), a `reveal` position (where the character is first disclosed - the
spoiler gate), and an own-words `description`. Recurring characters are
re-described per book (Kindle-X-Ray style), so a client reveals only up to
where the listener is.
- Each **recap** carries a `through` position (safe to show once the listener has
finished that chapter), an optional `scope` (`book` or `series` - a
`chapter: 0` + `series` recap is the "previously, in earlier books" summary),
and own-words `text`.

These fields are additive: they are passed straight through from the upstream
`GET /works/{id}` (see the [three-repo seam](../../architecture/cross-repo-contract.md)),
not composed or reshaped like `recording`/`series`. The one field the server
drops is the character cross-reference (`xref`) - it is not exposed to clients. A
client that ignores these fields is unaffected.

When the book has neither an `asin` nor an `isbn`, or the upstream reports no
match, the response is `200 { "matched": false }` - a normal, non-error result
that the client treats as "nothing to show":
Expand Down
4 changes: 3 additions & 1 deletion docs-users/listening/browsing.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,12 @@ If the same book exists in more than one place (say, an M4B copy and an MP3 copy
Some books show an extra section below the chapters with more about the title:

- An **About** description of the story, and production details such as the **publisher**, **release date** and when the work was **first published**.
- A **Characters** section - community-written cards for the people in the book. Each card shows the name, role and any aliases, plus which chapter the character first appears in; tap a card to reveal its short description. Cards stay closed until you tap them, so you decide when to read on.
- A **Story so far** section - short "what's happened up to here" recaps, each labelled with the chapter it's safe to read after. They stay closed by default, so you only open the one for as far as you've listened and don't spoil what's ahead. A recap marked for the very start reads "Previously, in earlier books" - a catch-up from earlier in the series.
- A **More in this series** row - other books in the same series, each opening its page on the metadata site so you can see what to read next.
- A **View on AudioSilo Meta** link to the book's full entry.

This information comes from the **AudioSilo community metadata database** at [meta.audiosilo.app](https://meta.audiosilo.app), a free, community-run catalogue of audiobook details. It appears only when the book can be matched (it carries an ASIN or ISBN) and your server has the metadata lookup switched on. If a book has no extra section, it simply isn't matched or your admin has turned the feature off - nothing else on the page changes. A server admin can switch the lookup on or off at any time from the admin console's Overview section (see the [console tour](../admin/console-tour.md#community-metadata-lookup)); when it is off, no book shows this section.
This information comes from the **AudioSilo community metadata database** at [meta.audiosilo.app](https://meta.audiosilo.app), a free, community-run catalogue of audiobook details. It appears only when the book can be matched (it carries an ASIN or ISBN) and your server has the metadata lookup switched on. The **Characters** and **Story so far** sections are contributed by the community, so a matched book shows them only once someone has written them - many books will have the About and series details but not these yet. If a book has no extra section, it simply isn't matched or your admin has turned the feature off - nothing else on the page changes. A server admin can switch the lookup on or off at any time from the admin console's Overview section (see the [console tour](../admin/console-tour.md#community-metadata-lookup)); when it is off, no book shows this section.

## Search

Expand Down
Loading