simple-web-app

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit 7b5699384059ded1d87419a226c3ab577988bc30
parent e0e3d681a922eb0b6d85130a144e150eae226f34
Author: Silas Brack <silasbrack@gmail.com>
Date:   Wed, 10 Jun 2026 22:40:30 +0200

refactor: consolidate comments fragment into story handler

Sub-route via ?fragment=comments query param instead of a separate
/story/{id}/comments endpoint, keeping the story page as one logical unit.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Diffstat:
Msrc/handlers/story.rs | 41++++++++++++++++++-----------------------
Msrc/routes.rs | 1-
Mtemplates/story.html | 2+-
3 files changed, 19 insertions(+), 25 deletions(-)

diff --git a/src/handlers/story.rs b/src/handlers/story.rs @@ -1,6 +1,6 @@ use askama::Template; use axum::{ - extract::{Path, State}, + extract::{Path, Query, State}, response::{Html, Redirect}, Form, }; @@ -68,10 +68,16 @@ async fn fetch_enriched_comments( Ok(enriched) } +#[derive(Debug, Deserialize)] +pub struct StoryQuery { + pub fragment: Option<String>, +} + pub async fn show_story( State(state): State<AppState>, jar: CookieJar, Path(id): Path<i64>, + Query(query): Query<StoryQuery>, ) -> Result<Html<String>, AppError> { let tokens = get_tokens_from_cookies(&jar); let client = match &tokens { @@ -79,6 +85,17 @@ pub async fn show_story( None => trailbase::new_client(&state.trailbase_url)?, }; + // Return just the comments fragment if requested + if query.fragment.as_deref() == Some("comments") { + let enriched_comments = fetch_enriched_comments(&state, &tokens, &client, id).await?; + let is_logged_in = tokens.is_some(); + let template = CommentsTemplate { + comments: enriched_comments, + is_logged_in, + }; + return Ok(Html(template.render()?)); + } + // Fetch the story let story = trailbase::get_story(&client, id) .await? @@ -135,28 +152,6 @@ pub async fn show_story( Ok(Html(app.render()?)) } -/// Returns just the comments HTML fragment for a story (used by SSE refresh) -pub async fn story_comments_fragment( - State(state): State<AppState>, - jar: CookieJar, - Path(id): Path<i64>, -) -> Result<Html<String>, AppError> { - let tokens = get_tokens_from_cookies(&jar); - let client = match &tokens { - Some(t) => trailbase::client_with_tokens(&state.trailbase_url, t)?, - None => trailbase::new_client(&state.trailbase_url)?, - }; - - let enriched_comments = fetch_enriched_comments(&state, &tokens, &client, id).await?; - let is_logged_in = tokens.is_some(); - - let template = CommentsTemplate { - comments: enriched_comments, - is_logged_in, - }; - Ok(Html(template.render()?)) -} - pub async fn show_submit( State(state): State<AppState>, jar: CookieJar, diff --git a/src/routes.rs b/src/routes.rs @@ -71,7 +71,6 @@ pub fn create_router(state: AppState) -> Router { .route("/story/{id}/edit", post(handlers::edit_story)) // Comments - .route("/story/{id}/comments", get(handlers::story_comments_fragment)) .route("/story/{id}/comment", post(handlers::create_comment)) .route("/comment/{id}/reply", get(handlers::show_reply_form)) .route("/comment/{id}/reply", post(handlers::submit_reply)) diff --git a/templates/story.html b/templates/story.html @@ -88,7 +88,7 @@ (function() { var evtSource = new EventSource('/api/records/v1/comment/subscribe/*?filter[story_id]={{ story.id }}'); evtSource.onmessage = function(event) { - fetch('/story/{{ story.id }}/comments') + fetch('/story/{{ story.id }}?fragment=comments') .then(function(r) { return r.text(); }) .then(function(html) { document.getElementById('comments-section').innerHTML = html;