Skip to content

feat(media): render hydrated article, gallery and livestream cards - #265

Merged
ewanc26 merged 2 commits into
mainfrom
feat/hydrated-external-cards
Oct 28, 2026
Merged

ewanc26 merged 2 commits into
mainfrom
feat/hydrated-external-cards

Conversation

@ewanc26

@ewanc26 ewanc26 commented Oct 28, 2026

Copy link
Copy Markdown
Owner

What this changes

Closes #102. A link card whose external.associatedRefs names a record is now hydrated once, on first draw, through the public AppView's app.bsky.embed.getEmbedExternalView, and composed into a richer card:

  • Article — publication name and reading time in the footer, replacing the bare host.
  • Gallery — up to four pictures in the same row as an image post, with the title beneath.
  • Livestream — a live/ended badge, the stream title and the publication.

The answer and any failed answer are cached for the process, so scrolling does not retry a link. Unhydrated links and posts without a ref keep the existing external#view card.

The data path lives in src/atproto/external_card.c; Wolfram parses the three view shapes, Cobalt only consumes them. Drawing stays in src/ui/postcard.c beside the existing image and external rows.

Verification

  • make -C tests test — unit tests and snapshot frames, including new article, gallery and livestream frames and fixture posts.
  • python3 tools/check-guide.py — guide screenshot map matches the files.
  • bash tools/check-parity.sh — parity row parses.
  • make host build and DEVKITPRO=/opt/devkitpro DEVKITARM=... make 3ds remote build.
  • Hydration fixtures are fake responses. No live Bluesky link and no hardware pass; the network path follows the existing avatar/image fetch, which is host-tested.

Docs

README.md, CHANGELOG.md, docs/PARITY.md, docs/guide.md and AGENTS.md describe the hydration path, its one-request-per-link cache and its limits. Three TV guide screenshots are added, and the fixture-count drift refreshes the existing timeline frames.

Checklist

  • CI is green (CI gate and flow / conventions)
  • No secrets, tokens or signing keys in the diff
  • Tests added or changed with the behaviour; none skipped, disabled or deleted

ewanc26 and others added 2 commits October 28, 2026 21:21
A link whose external view carries associatedRefs now gets the richer
card its canonical record describes: an article with publication and
reading time, a gallery with up to four pictures, or a livestream marked
live or ended.

The first ref is kept during feed flatten; the card's height is reserved
from it before any fetch, so the list does not jump when the answer
lands. atproto/external_card.c asks the public AppView (the PDS proxy
needs auth, and the image client deliberately has no token) on a loader
thread, once per url and canonical URI, with both cards and failed
answers cached. The plain card draws until a result arrives.

Fixtures and snapshot frames cover all three shapes; unit tests pin the
parser, URL builder and cache.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
Document the AppView hydration path beside the plain link card and add
one TV frame each for an article, a gallery and a livestream. The guide
screenshot map now names those frames, and the fixture count grows with
the three new posts, which refreshes the existing timeline counts.

README, parity and AGENTS describe the new card path and its limits:
public AppView, one request per link, host-tested only.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
@ewanc26
ewanc26 merged commit c6c4429 into main Oct 28, 2026
13 checks passed
@ewanc26
ewanc26 deleted the feat/hydrated-external-cards branch October 28, 2026 21:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: embed support for video and external-media posts

1 participant