From bf85894093de7738a2b9975e7b73d726ebbbc843 Mon Sep 17 00:00:00 2001 From: lashman Date: Fri, 16 Jan 2026 01:13:43 +0200 Subject: [PATCH] theme and markdown helpers --- frontend/src/markdown.ts | 53 +++++++++++++++++++++++++++++++++++ frontend/src/settingsApply.ts | 13 +++++++++ 2 files changed, 66 insertions(+) create mode 100644 frontend/src/markdown.ts create mode 100644 frontend/src/settingsApply.ts diff --git a/frontend/src/markdown.ts b/frontend/src/markdown.ts new file mode 100644 index 0000000..c418e6a --- /dev/null +++ b/frontend/src/markdown.ts @@ -0,0 +1,53 @@ +function applyInline(text: string): string { + text = text.replace(/\*\*(.+?)\*\*/g, '$1') + text = text.replace(/\*(.+?)\*/g, '$1') + return text +} + +export function renderSimpleMarkdown(raw: string): string { + // escape HTML first + const text = raw + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + + // split into blocks by double newlines + const blocks = text.split(/\n\n+/) + const rendered = blocks.map(block => { + const lines = block.split('\n') + // check if block is a list + const isList = lines.every(l => l.match(/^\s*- /)) + if (isList) { + const items = lines.map(l => { + let item = l.replace(/^\s*- /, '') + item = applyInline(item) + return `
  • ${item}
  • ` + }) + return `` + } + // process each line + const processed = lines.map(line => { + // headings + if (line.match(/^## /)) return `

    ${applyInline(line.slice(3))}

    ` + if (line.match(/^# /)) return `

    ${applyInline(line.slice(2))}

    ` + // single list item within a paragraph block + if (line.match(/^\s*- /)) return `
  • ${applyInline(line.replace(/^\s*- /, ''))}
  • ` + return applyInline(line) + }) + // wrap non-heading lines in

    + const out: string[] = [] + let buf: string[] = [] + for (const p of processed) { + if (p.startsWith('

    ') || p.startsWith('

    ') || p.startsWith('
  • ') || p.startsWith('
      ')) { + if (buf.length) { out.push(`

      ${buf.join('
      ')}

      `); buf = [] } + out.push(p) + } else { + buf.push(p) + } + } + if (buf.length) out.push(`

      ${buf.join('
      ')}

      `) + return out.join('') + }) + return rendered.join('') +} \ No newline at end of file diff --git a/frontend/src/settingsApply.ts b/frontend/src/settingsApply.ts new file mode 100644 index 0000000..45745c9 --- /dev/null +++ b/frontend/src/settingsApply.ts @@ -0,0 +1,13 @@ +import type { ServerSettings } from './api' + +export function applySettings(settings: ServerSettings) { + const root = document.documentElement + root.removeAttribute('data-theme') + if (settings.theme === 'light') root.setAttribute('data-theme', 'light') + if (settings.theme === 'dark') root.setAttribute('data-theme', 'dark') + root.removeAttribute('data-colorblind') + if (settings.colorblind !== 'none') root.setAttribute('data-colorblind', String(settings.colorblind)) + root.style.fontSize = `${String(settings.textScale)}%` + if (settings.torFriendly) root.classList.add('tor-friendly') + else root.classList.remove('tor-friendly') +} \ No newline at end of file