···11-# Timeline & Social Features
22-33-## Timeline View
44-55-Inspired by Aeronaut's timeline continuity — new posts prepend without losing scroll position.
66-77-### XRPC Endpoints (via jacquard)
88-99-| Action | Lexicon |
1010-| ------------------ | --------------------------------------------------------- |
1111-| Following timeline | `app.bsky.feed.getTimeline` |
1212-| Custom feed | `app.bsky.feed.getFeed` |
1313-| Author feed | `app.bsky.feed.getAuthorFeed` |
1414-| Post thread | `app.bsky.feed.getPostThread` |
1515-| Like a post | `app.bsky.feed.like` (create record) |
1616-| Repost | `app.bsky.feed.repost` (create record) |
1717-| Create post | `com.atproto.repo.createRecord` with `app.bsky.feed.post` |
1818-| Get likes list | `app.bsky.feed.getActorLikes` |
1919-| Get profile | `app.bsky.actor.getProfile` |
2020-| Follow/unfollow | `app.bsky.graph.follow` (create/delete record) |
2121-| Mute/block | `app.bsky.graph.muteActor` / `app.bsky.graph.block` |
2222-2323-### Feed Preferences
2424-2525-- Toggle reposts, replies, quote-posts per feed (like Aeronaut)
2626-- Store preferences per account in SQLite
2727-2828-## Post Composer
2929-3030-- Rich text via `jacquard::richtext` — auto-detect mentions, links, hashtags
3131-- Image/media upload via `com.atproto.repo.uploadBlob`
3232-- Reply threading with parent/root refs
3333-- Quote post embed
3434-3535-## Notifications
3636-3737-- `app.bsky.notification.listNotifications` — poll or use Jetstream
3838-- Separate tabs: Mentions vs Activity (Aeronaut pattern)
3939-- System notifications via Tauri
4040-4141-## Keyboard Shortcuts
4242-4343-| Key | Action |
4444-| ------------- | ------------------------ |
4545-| `n` | New post (open composer) |
4646-| `j` / `k` | Next / previous post |
4747-| `l` | Like focused post |
4848-| `r` | Reply to focused post |
4949-| `t` | Repost focused post |
5050-| `o` / `Enter` | Open thread |
5151-| `1`–`9` | Switch between feeds |
5252-5353-## UX Polish
5454-5555-- New posts slide in from top via `Motion` with spring easing; scroll position preserved
5656-- Like/repost actions: `Motion` scale pop on the icon (1.0 → 1.3 → 1.0)
5757-- Post card: subtle `Motion` fade-in on viewport enter during infinite scroll
5858-- Composer: `Presence` slide-up animation on open, slide-down on dismiss
5959-- Feed switcher: `Presence` crossfade between feed content on tab change
6060-- Skeleton screens while feeds load; error toast with retry button on network failure
6161-- Feed preferences stored per account in SQLite
6262-6363-## Direct Messages
6464-6565-- `chat.bsky.convo.*` lexicons for DM support
6666-- Deferred to post-MVP unless trivial to add
+49
docs/tasks/03-feeds.md
···11+# Task 03: Feeds
22+33+Spec: [feeds.md](../specs/feeds.md)
44+55+## Steps
66+77+### Backend — `src-tauri/src/feed.rs`
88+99+- [ ] `get_preferences()` — calls `app.bsky.actor.getPreferences`, extracts `savedFeedsPrefV2` items and `feedViewPref` entries
1010+- [ ] `get_feed_generators(uris: Vec<String>)` — calls `app.bsky.feed.getFeedGenerators` to hydrate display names/avatars
1111+- [ ] `get_timeline(cursor: Option<String>, limit: u32)` — calls `app.bsky.feed.getTimeline`
1212+- [ ] `get_feed(uri: String, cursor: Option<String>, limit: u32)` — calls `app.bsky.feed.getFeed` for custom feed generators
1313+- [ ] `get_list_feed(uri: String, cursor: Option<String>, limit: u32)` — calls `app.bsky.feed.getListFeed`
1414+- [ ] `get_post_thread(uri: String)` — thread view
1515+- [ ] `get_author_feed(did: String, cursor: Option<String>)`
1616+- [ ] `create_post(text: String, reply_to: Option<ReplyRef>, embed: Option<Embed>)` — with richtext facet detection via `jacquard::richtext`
1717+- [ ] `like_post(uri: String, cid: String)` / `unlike_post(uri: String)`
1818+- [ ] `repost(uri: String, cid: String)` / `unrepost(uri: String)`
1919+2020+### Frontend — Feed Tabs & Content
2121+2222+- [ ] Feed tab bar — pinned feeds as tabs, hydrated with generator display names/avatars; `1`–`9` keyboard shortcuts to switch
2323+- [ ] Feed content loader — dispatches to correct endpoint based on feed type (`timeline` / `feed` / `list`)
2424+- [ ] Infinite scroll with cursor pagination and scroll-position preservation
2525+- [ ] `Presence` crossfade animation on tab switch
2626+- [ ] Skeleton screens while feeds load
2727+2828+### Frontend — Post Card & Actions
2929+3030+- [ ] Post card component (author, text, embeds, timestamps, action bar) — `Motion` fade-in on viewport enter
3131+- [ ] Like/repost icon `Motion` scale pop animation (1.0 -> 1.3 -> 1.0)
3232+- [ ] `j/k` keyboard navigation between posts, `l` like, `r` reply, `t` repost, `o` open thread
3333+3434+### Frontend — Thread View
3535+3636+- [ ] Thread view with nested replies
3737+- [ ] Navigate into thread from post card (`o` / `Enter`)
3838+3939+### Frontend — Post Composer
4040+4141+- [ ] Composer with `Presence` slide-up/down, `n` keyboard shortcut to open
4242+- [ ] Mention/hashtag autocomplete
4343+- [ ] Reply threading with parent/root refs
4444+- [ ] Quote post embed
4545+4646+### Frontend — Feed Preferences
4747+4848+- [ ] Per-feed display toggles (hide reposts/replies/quotes) via `feedViewPref`
4949+- [ ] Feeds drawer for accessing saved (unpinned) feeds