Add settings page, model management, and chat UX improvements
- Settings infrastructure: key-value settings table, GET/PUT API, Pinia store - Configurable assistant name (default "Fable") in settings and LLM system prompt - Model catalog with 18 models in 3 categories (General Purpose, Coding, Uncensored / Creative Writing) with download/select/remove functionality - Move Ollama status indicator from chat views to global nav bar - Chat bubble layout: user messages right-aligned, assistant left-aligned - Floating dark input bar with auto-focus and circular send button - Fix HTML entity rendering (' apostrophe issue in marked/DOMPurify pipeline) - Fix new chat button navigation (fetchConversation before router.push) - Recent chats section on home page with "New Chat" button - Update summary.md with Phase 4.5 changes Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -2,20 +2,31 @@ import { marked } from "marked";
|
||||
import DOMPurify from "dompurify";
|
||||
import { linkifyTags, linkifyWikilinks } from "@/utils/tags";
|
||||
|
||||
function decodeEntities(text: string): string {
|
||||
const textarea = document.createElement("textarea");
|
||||
textarea.innerHTML = text;
|
||||
return textarea.value;
|
||||
}
|
||||
|
||||
export function renderMarkdown(text: string): string {
|
||||
const html = marked(text) as string;
|
||||
const decoded = decodeEntities(text);
|
||||
const html = marked(decoded) as string;
|
||||
const withTags = linkifyTags(html);
|
||||
const withLinks = linkifyWikilinks(withTags);
|
||||
return DOMPurify.sanitize(withLinks, {
|
||||
const sanitized = DOMPurify.sanitize(withLinks, {
|
||||
ADD_ATTR: ["data-tag", "data-title"],
|
||||
});
|
||||
// marked escapes ' to ' — replace after sanitization to ensure clean rendering
|
||||
return sanitized.replace(/'/g, "'");
|
||||
}
|
||||
|
||||
export function renderPreview(text: string): string {
|
||||
const html = marked(text) as string;
|
||||
const decoded = decodeEntities(text);
|
||||
const html = marked(decoded) as string;
|
||||
const withTags = linkifyTags(html);
|
||||
const withLinks = linkifyWikilinks(withTags);
|
||||
return DOMPurify.sanitize(withLinks, {
|
||||
const sanitized = DOMPurify.sanitize(withLinks, {
|
||||
FORBID_TAGS: ["a", "img"],
|
||||
});
|
||||
return sanitized.replace(/'/g, "'");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user