Skip to main content

Module web

Module web 

Source
Expand description

The axum web layer — server-rendered HTML + a dash of htmx, no SPA.

This module owns the HTTP surface: router builds an axum::Router over the shared AppState, wiring the store, feed, atproto, and config seams into a small set of typography-first, dark-mode-ready views rendered with askama templates (under templates/). Progressive enhancement is a single vendored htmx script plus a tiny keyboard handler (static/keyboard.js); every interaction also works as a plain HTML form POST, so the reader is fully usable with JavaScript disabled.

§HTTP surface

  • GET /health — liveness + version, as text/plain.
  • GET / — the reader: a folders/feeds sidebar (from the PDS records layer) plus the main article list. Query params pick the scope (?feed=… / ?folder=… / all) and the view (?view=unread|all|starred).
  • GET /entries/{id} — the clean, distraction-free reader for one entry, with prev/next within the current list.
  • POST /entries/{id}/read — mark an entry read/unread (htmx row swap).
  • POST /entries/{id}/star — star/unstar; writes a community.lexicon.rss.saved record to the user’s PDS.
  • POST /read-all — mark-all-read (per feed via ?feed=…, else everything).
  • POST /subscriptions — subscribe by URL (autodiscover → PDS record).
  • POST /subscriptions/{rkey}/delete — unsubscribe (delete the PDS record).
  • POST /subscriptions/{rkey}/rename — retitle / move a feed to a folder.
  • POST /folders — create a folder record.
  • POST /folders/{rkey}/rename — rename a folder record.
  • POST /folders/{rkey}/delete — delete a folder record.
  • POST /opml — OPML import (multipart upload or pasted textarea) → bulk subscription records in the PDS.
  • GET /opml/export — OPML export (records → a downloadable document).
  • GET /login + POST /login + /oauth/callback + /logout — the atproto OAuth sign-in flow (routed through the sidecar).

Per-request identity comes from a signed session cookie (fr_session) keyed by the logged-in DID, set by [oauth_callback] and read by [current_session] / [current_did]. For local runs without the sidecar, Config::dev_did (env FEATHERREADER_DEV_DID) supplies a fallback identity. All PDS writes route through the crate::atproto::SidecarClient; a live-PDS write needs a real OAuth session, but the full write path is built and unit- tested to the sidecar boundary.

Functions§

router
Build the application router over shared AppState.