From 2a0c40918039ff06b137b566f66e129addfe145c Mon Sep 17 00:00:00 2001 From: Jared Vititoe Date: Sat, 19 Sep 2026 23:09:25 -0400 Subject: [PATCH] feat(messages): code blocks get a Wrap toggle next to Copy (#131) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Verified upstream first: the Copy chip (with a 'Copied' state) already exists on every code block. Added the missing half: a Wrap chip that switches long lines to pre-wrap (default stays no-wrap + horizontal scroll); the choice is remembered for the session, not persisted. Markdown/HTML output, layout widths and the syntax theme are untouched. Verified headless: scrollWidth 1016 → 612 px with wrapping on, 'Copied' state on copy. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA --- src/app/plugins/react-custom-html-parser.tsx | 34 +++++++++++++++----- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/src/app/plugins/react-custom-html-parser.tsx b/src/app/plugins/react-custom-html-parser.tsx index 76bcc6622..f1ce4d83e 100644 --- a/src/app/plugins/react-custom-html-parser.tsx +++ b/src/app/plugins/react-custom-html-parser.tsx @@ -333,13 +333,10 @@ const extractTextFromChildren = (nodes: ChildNode[]): string => { return text; }; -export function CodeBlock({ - children, - opts, -}: { - children: ChildNode[]; - opts: HTMLReactParserOptions; -}) { +export // Session memory for the code-block Wrap toggle (#131). +const codeWrapPreference = { value: false }; + +function CodeBlock({ children, opts }: { children: ChildNode[]; opts: HTMLReactParserOptions }) { const code = children[0]; const attribs = code instanceof Element && code.name === 'code' ? code.attribs : undefined; const languageClass = attribs?.class; @@ -357,6 +354,13 @@ export function CodeBlock({ const [expanded, setExpand] = useState(false); const [copied, setCopied] = useTimeoutToggle(); + // [Gitea #131] Line-wrap toggle for long lines; the choice is remembered for + // the session (module-level), not persisted. + const [wrap, setWrap] = useState(codeWrapPreference.value); + const toggleWrap = () => { + codeWrapPreference.value = !wrap; + setWrap(!wrap); + }; const handleCopy = () => { copyToClipboard(extractTextFromChildren(children)); @@ -376,6 +380,16 @@ export function CodeBlock({ + + Wrap + -
+
{domToReact(children as unknown as DOMNode[], opts)}