From ecd72015a706265694d1e3420776387682dc5a00 Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Wed, 9 Sep 2026 22:46:04 -0400 Subject: [PATCH] feat: the front door answers "what arrived?" (milestone 387 step B1) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Moves FRONT_DOOR from /showcase to /latest. Showcase is a random TABLESAMPLE — lean-back, and it can never tell you anything is wrong. The feed is the only view where a failing source surfaces on its own, as a creator who has gone quiet. The per-artist "new since last visit" badges (#597) were a workaround for this view not being the door. Showcase is demoted to a nav entry, not removed. Nothing is being replaced, so rule 22's delete-the-legacy-path does not apply. Deviation from the filed plan, deliberate: the step said write a new LatestView.vue. Rejected — PostsView is ALREADY a self-contained feed (own container, own store, infinite scroll, filters, deep-link anchoring, empty state), and Browse only ever wrapped it in a tab strip. A new view would have duplicated 231 working lines to gain nothing. Mounting PostsView directly at its own route IS the whole difference the promotion was after: a door you arrive at, not a hub you navigate out of. Rule 28. Backend untouched, as scoped — PostFeedService.scroll already does cursor-paginated newest-first. Two things this shook loose: PostsView's deep-link "All posts" button was a hard `{ name: 'posts' }`, which redirects into Browse. Correct while the view only ever rendered inside Browse's tab; from the front door it would have yanked the operator sideways into a different surface. Now returns to the current route minus post_id, so Browse keeps its tab and any active scope. The README claimed "A Showcase front page". That block is the SOURCE the release notes quote (scripts/release_notes.py product_overview), not a generated copy, so it is fixed here — a document contradicting the code is the characteristic defect of the public-surface area. No stickyChrome on the route: unlike Browse/Gallery/Settings this view has no sticky sub-header for the nav to butt against. The router spec pinned FRONT_DOOR to /showcase and now pins /latest, plus that Showcase stayed reachable and in the nav — the demotion is asserted, not assumed. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01LNXXULQDjVZmbuNa2G9mD9 --- README.md | 5 +++-- frontend/src/router.js | 21 ++++++++++++++++++++- frontend/src/views/PostsView.vue | 14 +++++++++++++- frontend/test/router.spec.js | 25 +++++++++++++++++++++++-- 4 files changed, 59 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index a7c35e0..4c2fee2 100644 --- a/README.md +++ b/README.md @@ -13,8 +13,9 @@ tags it, and gives you something better than a folder full of images to look through afterwards. - **Gallery and browsing.** Images, videos and multi-page works, organised by - artist, tag, post and series. A Showcase front page, a filterable gallery, a - similarity-driven Explore view, and a page-turning reader for series. + artist, tag, post and series. A newest-first feed of what just arrived as the + front page, a random Showcase, a filterable gallery, a similarity-driven + Explore view, and a page-turning reader for series. - **Subscriptions.** Follows creators on Patreon, SubscribeStar, Pixiv and anything `gallery-dl` supports, on a schedule. Handles paywalled posts using your own logged-in session. diff --git a/frontend/src/router.js b/frontend/src/router.js index 6f188fa..3de94dd 100644 --- a/frontend/src/router.js +++ b/frontend/src/router.js @@ -9,15 +9,34 @@ import SeriesView from './views/SeriesView.vue' import SeriesManageView from './views/SeriesManageView.vue' import SeriesReaderView from './views/SeriesReaderView.vue' import SubscriptionsView from './views/SubscriptionsView.vue' +import PostsView from './views/PostsView.vue' // The application's front door. `/` redirects here. Changing the front door // is a one-line edit (e.g. '/gallery' or '/tags'). -export const FRONT_DOOR = '/showcase' +// +// Moved from '/showcase' to '/latest' (milestone #387 B1). Showcase answers +// "show me something" — a random TABLESAMPLE, lean-back, and it can never tell +// you anything is wrong. The feed answers "what arrived?", which is a question +// the operator has every day, and it is the only view where a failing source +// shows up on its own as a creator who has gone quiet. The per-artist "new +// since last visit" badges (#597) were a workaround for this view not being +// the door. Showcase is demoted to a nav entry, not removed. +export const FRONT_DOOR = '/latest' const routes = [ // Root is a redirect only — no meta.title so it stays out of the nav. { path: '/', redirect: FRONT_DOOR }, + // The front door (#387 B1): the post feed as its own surface. Reuses + // PostsView unchanged — it is already a self-contained feed (own container, + // own store, infinite scroll, deep-link anchoring), and Browse only ever + // wrapped it in a tab strip. Mounting it directly IS the difference the + // promotion was after: a door you arrive at, not a hub you navigate out of. + // + // No stickyChrome: unlike Browse/Gallery/Settings this view has no sticky + // sub-header for the nav to butt against, so the nav keeps its normal fade. + { path: '/latest', name: 'latest', component: PostsView, meta: { title: 'Latest', navOrder: 5 } }, + // FC-2: image backbone { path: '/showcase', name: 'showcase', component: ShowcaseView, meta: { title: 'Showcase', navOrder: 10 } }, { path: '/gallery', name: 'gallery', component: GalleryView, meta: { title: 'Gallery', navOrder: 20, stickyChrome: true } }, diff --git a/frontend/src/views/PostsView.vue b/frontend/src/views/PostsView.vue index 1f78372..30bbb96 100644 --- a/frontend/src/views/PostsView.vue +++ b/frontend/src/views/PostsView.vue @@ -3,9 +3,14 @@