Add Followed/Public toggle to /feed for signed-in users
Stream A from docs/information-architecture.md: signed-in users now
have a single /feed destination with two views — Followed (default,
people they accepted-follow) and Public (instance-wide). Logging in no
longer hides the public instance feed; switching is a query-param flip
that's bookmarkable and SSR-rendered.
- apps/journal/app/routes/feed.tsx — loader reads ?view=, branches
fetch (listSocialFeed vs listRecentPublicActivities, both already
exist), passes view to the component. Component renders a tab strip
at the top using plain <Link>s so the toggle works without JS. Per-
view <meta> title and empty state. The "see public feed" escape
from the empty Followed view now points at ?view=public instead of
/, keeping the user on /feed.
- packages/i18n/src/locales/{en,de}.ts — new social.feed.toggle.{ },
social.feed.public.{heading,empty}, and social.feed.seePublic
keys; old social.feed.publicFeedLink renamed to seePublic.
- openspec/specs/social-follows/spec.md — Social activity feed
requirement extended with the two-view structure, including the
Public view, the toggle, and the unrecognized-value fallback.
- openspec/specs/activity-feed/spec.md — Instance-wide public
activity feed requirement notes the Public view of /feed is now a
consumer alongside the visitor home.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
7d1999d037
commit
b6d8c621f8
5 changed files with 122 additions and 29 deletions
|
|
@ -62,15 +62,19 @@ Activities SHALL be allowed to exist without a linked route.
|
|||
- **THEN** the activity is stored with route_id as null
|
||||
|
||||
### Requirement: Instance-wide public activity feed
|
||||
The Journal SHALL expose a reverse-chronological feed of every activity on the instance with visibility `public`. This feed powers the instance home page (see `journal-landing`). `private` and `unlisted` activities SHALL NOT appear in this feed; `unlisted` stays reachable by direct URL only.
|
||||
The Journal SHALL expose a reverse-chronological feed of every activity on the instance with visibility `public`. This feed powers the visitor home page (see `journal-landing`) for anonymous traffic and the Public view of `/feed` (see `social-follows` spec, "Social activity feed") for signed-in viewers. `private` and `unlisted` activities SHALL NOT appear in this feed; `unlisted` stays reachable by direct URL only.
|
||||
|
||||
#### Scenario: Public activity appears in the instance feed
|
||||
- **WHEN** an owner marks an activity as `public` and another visitor loads the home page
|
||||
#### Scenario: Public activity appears in the visitor home feed
|
||||
- **WHEN** an owner marks an activity as `public` and an anonymous visitor loads the home page
|
||||
- **THEN** the visitor sees the activity in the instance feed, with the owner's display name, distance, and start date
|
||||
|
||||
#### Scenario: Public activity appears in the signed-in /feed?view=public view
|
||||
- **WHEN** an owner marks an activity as `public` and a signed-in user loads `/feed?view=public`
|
||||
- **THEN** the signed-in user sees the activity in the Public view, regardless of whether they follow the owner
|
||||
|
||||
#### Scenario: Private or unlisted activities stay out of the feed
|
||||
- **WHEN** an activity's visibility is `private` or `unlisted`
|
||||
- **THEN** it does not appear in the instance feed, regardless of who is viewing
|
||||
- **THEN** it does not appear in the instance feed on either surface, regardless of who is viewing
|
||||
|
||||
### Requirement: Activity visibility
|
||||
The Journal SHALL persist a `visibility` value on every activity and SHALL allow the owner to change it.
|
||||
|
|
|
|||
|
|
@ -82,22 +82,34 @@ A signed-in user SHALL have an actionable surface listing every Pending follow r
|
|||
- **THEN** they are redirected to `/auth/login`
|
||||
|
||||
### Requirement: Social activity feed
|
||||
The Journal SHALL expose a feed at `/feed`, visible only to signed-in users, listing public activities from the local users they follow with an accepted relation. `private` and `unlisted` activities SHALL NOT appear regardless of follow state. Pending follows SHALL NOT contribute content to the feed.
|
||||
The Journal SHALL expose a feed at `/feed`, visible only to signed-in users, with two views selectable via `?view=`: **Followed** (default; public activities from the local users they follow with an accepted relation) and **Public** (instance-wide public activities — see `activity-feed` spec, "Instance-wide public activity feed"). The page SHALL render a tab/toggle at the top so the viewer can switch between the two views. `private` and `unlisted` activities SHALL NOT appear in either view. Pending follows SHALL NOT contribute content to the Followed view.
|
||||
|
||||
#### Scenario: Feed aggregates accepted-followed users' public activities
|
||||
- **WHEN** a signed-in user with one or more accepted follows loads `/feed`
|
||||
- **THEN** the page shows the most recent public activities across all accepted-followed users, reverse-chronological, up to 50 per page, with owner attribution, distance, date, and a map thumbnail
|
||||
#### Scenario: Followed view aggregates accepted-followed users' public activities
|
||||
- **WHEN** a signed-in user with one or more accepted follows loads `/feed` (or `/feed?view=followed`)
|
||||
- **THEN** the Followed view is selected and shows the most recent public activities across all accepted-followed users, reverse-chronological, up to 50 per page, with owner attribution, distance, date, and a map thumbnail
|
||||
|
||||
#### Scenario: Pending follows don't contribute to the feed
|
||||
- **WHEN** a signed-in user has only Pending follows (no acceptance yet)
|
||||
- **THEN** the feed renders the empty state — no Pending-target content is fetched or shown
|
||||
#### Scenario: Public view aggregates instance-wide public activities
|
||||
- **WHEN** a signed-in user loads `/feed?view=public`
|
||||
- **THEN** the Public view is selected and shows the most recent public activities across the entire instance, reverse-chronological, up to 50 per page, regardless of follow state
|
||||
|
||||
#### Scenario: Empty feed state
|
||||
#### Scenario: Pending follows don't contribute to the Followed view
|
||||
- **WHEN** a signed-in user has only Pending follows (no acceptance yet) and loads the Followed view
|
||||
- **THEN** the view renders the empty state — no Pending-target content is fetched or shown
|
||||
|
||||
#### Scenario: Empty Followed view links to the Public view
|
||||
- **WHEN** a signed-in user with zero accepted follows loads `/feed`
|
||||
- **THEN** the page shows an empty-state message pointing them to `/users/:username` pages to follow someone, and suggests the instance public feed as an alternative
|
||||
- **THEN** the Followed view shows an empty-state message and an in-page link to switch to the Public view (`?view=public`), so they can browse the instance without leaving `/feed`
|
||||
|
||||
#### Scenario: Empty Public view
|
||||
- **WHEN** the instance has zero public activities and a signed-in user loads `/feed?view=public`
|
||||
- **THEN** the Public view shows an empty-state message; no link to elsewhere is required
|
||||
|
||||
#### Scenario: Unrecognized view value falls back to Followed
|
||||
- **WHEN** a signed-in user loads `/feed?view=<anything-other-than-public>`
|
||||
- **THEN** the loader treats the request as the Followed view (default) without raising an error — the parameter is opaque from the client's perspective
|
||||
|
||||
#### Scenario: Logged-out visitor cannot access the feed
|
||||
- **WHEN** an unauthenticated visitor requests `/feed`
|
||||
- **WHEN** an unauthenticated visitor requests `/feed` (any view)
|
||||
- **THEN** they are redirected to `/auth/login`
|
||||
|
||||
### Requirement: Schema is forward-compatible with federation
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue