import { Hono } from "hono"; import { BaseLayout } from "../layouts/base.js"; import { PageHeader, ErrorDisplay } from "../components/index.js"; import { getSession } from "../lib/session.js"; import { fetchApi } from "../lib/api.js"; import { isProgrammingError, isNotFoundError, } from "../lib/errors.js"; import { logger } from "../lib/logger.js"; import { FALLBACK_THEME, type WebAppEnv } from "../lib/theme-resolution.js"; interface BoardResponse { id: string; did: string; uri: string; name: string; description: string | null; slug: string | null; sortOrder: number | null; categoryId: string; categoryUri: string | null; createdAt: string | null; indexedAt: string | null; } const CHAR_COUNTER_SCRIPT = ` function updateCharCount(el) { var seg = new Intl.Segmenter(); var n = Array.from(seg.segment(el.value)).length; var counter = document.getElementById("char-count"); counter.textContent = (300 - n) + " left"; counter.dataset.over = n > 300 ? "true" : "false"; } function updateTitleCharCount(el) { var seg = new Intl.Segmenter(); var n = Array.from(seg.segment(el.value)).length; var counter = document.getElementById("title-char-count"); counter.textContent = (120 - n) + " left"; counter.dataset.over = n > 120 ? "true" : "false"; } `; export function createNewTopicRoutes(appviewUrl: string) { return new Hono() .get("/new-topic", async (c) => { const resolvedTheme = c.get("theme") ?? FALLBACK_THEME; const boardIdParam = c.req.query("boardId"); // boardId required and must be numeric if (!boardIdParam || !/^\d+$/.test(boardIdParam)) { return c.redirect("/"); } const auth = await getSession(appviewUrl, c.req.header("cookie")); if (!auth.authenticated) { return c.html(

Log in to create a topic.

); } // Fetch board data — need the AT URI for the hidden form field let board: BoardResponse; try { board = await fetchApi(`/boards/${boardIdParam}`); } catch (error) { if (isProgrammingError(error)) throw error; if (isNotFoundError(error)) { return c.html( , 404 ); } logger.error("Failed to load board for new topic form", { operation: "GET /new-topic", boardId: boardIdParam, error: error instanceof Error ? error.message : String(error), }); return c.redirect("/"); } return c.html(
120 left