From 9c959f641227018bf4875540f90557419923a6aa Mon Sep 17 00:00:00 2001 From: Jocadbz Date: Thu, 15 Jan 2026 23:33:03 -0300 Subject: [PATCH] Revert "Chat: Add markdown preview toggle with client-side rendering and user preference" This reverts commit ffe9f30c0aa9ffb9c095b4daa218b448fb0d0808. --- handlers/chat.go | 26 ++---- static/app.js | 115 ------------------------ templates/pages/chat.html | 179 +------------------------------------- 3 files changed, 9 insertions(+), 311 deletions(-) diff --git a/handlers/chat.go b/handlers/chat.go index 6abfae4..5f2bda3 100644 --- a/handlers/chat.go +++ b/handlers/chat.go @@ -223,21 +223,12 @@ func ChatHandler(app *App) http.HandlerFunc { } allUsernamesJSON, _ := json.Marshal(allUsernames) - // Get user preferences for markdown preview default - prefs, err := models.GetUserPreferences(app.DB, userID) - if err != nil { - log.Printf("Error fetching user preferences: %v", err) - // Create default if not found - prefs, _ = models.CreateDefaultPreferences(app.DB, userID) - } - data := struct { PageData - Board models.Board - Messages []models.ChatMessage - AllUsernames template.JS - CurrentUsername string - MarkdownPreviewDefault string + Board models.Board + Messages []models.ChatMessage + AllUsernames template.JS + CurrentUsername string }{ PageData: PageData{ Title: "ThreadR Chat - " + board.Name, @@ -248,11 +239,10 @@ func ChatHandler(app *App) http.HandlerFunc { StaticPath: app.Config.ThreadrDir + "/static", CurrentURL: r.URL.Path, }, - Board: *board, - Messages: messages, - AllUsernames: template.JS(allUsernamesJSON), - CurrentUsername: currentUsername, - MarkdownPreviewDefault: prefs.MarkdownPreviewDefault, + Board: *board, + Messages: messages, + AllUsernames: template.JS(allUsernamesJSON), + CurrentUsername: currentUsername, } if err := app.Tmpl.ExecuteTemplate(w, "chat", data); err != nil { log.Printf("Error executing template in ChatHandler: %v", err) diff --git a/static/app.js b/static/app.js index aefdf51..3f374b0 100644 --- a/static/app.js +++ b/static/app.js @@ -371,118 +371,3 @@ function showDraftIndicator(content, timestamp, onRestore, onDiscard) { return indicator; } - -// ============================================ -// Markdown Preview Functions -// ============================================ - -// Escape HTML to prevent XSS -function escapeHTML(str) { - const div = document.createElement('div'); - div.textContent = str; - return div.innerHTML; -} - -// Process inline markdown (bold, italic, code, mentions) -function processInlineMarkdown(line) { - // Inline code first (to avoid processing markdown inside code) - line = line.replace(/`([^`]+)`/g, '$1'); - - // Bold: **text** or __text__ - line = line.replace(/\*\*([^\*]+)\*\*/g, '$1'); - line = line.replace(/__([^_]+)__/g, '$1'); - - // Italic: *text* or _text_ - line = line.replace(/\*([^\*]+)\*/g, '$1'); - line = line.replace(/_([^_]+)_/g, '$1'); - - // Mentions: @username - line = line.replace(/@(\w+)/g, '@$1'); - - return line; -} - -// Render markdown to HTML (matching Go implementation) -function renderMarkdownPreview(content) { - let html = ''; - - // Extract code blocks first and replace with placeholders - const codeBlocks = []; - let codeBlockCounter = 0; - - content = content.replace(/```(\w*)\n([\s\S]*?)\n```/g, (match, lang, code) => { - const escapedCode = escapeHTML(code); - let renderedBlock; - if (lang) { - renderedBlock = `
${escapedCode}
`; - } else { - renderedBlock = `
${escapedCode}
`; - } - const placeholder = ``; - codeBlocks[codeBlockCounter] = renderedBlock; - codeBlockCounter++; - return placeholder; - }); - - // Process lines - const lines = content.split('\n'); - let inList = false; - - for (const line of lines) { - const trimmedLine = line.trim(); - - // Headers - if (trimmedLine.startsWith('### ')) { - if (inList) { html += '\n'; inList = false; } - html += '

' + processInlineMarkdown(trimmedLine.substring(4)) + '

\n'; - continue; - } else if (trimmedLine.startsWith('## ')) { - if (inList) { html += '\n'; inList = false; } - html += '

' + processInlineMarkdown(trimmedLine.substring(3)) + '

\n'; - continue; - } else if (trimmedLine.startsWith('# ')) { - if (inList) { html += '\n'; inList = false; } - html += '

' + processInlineMarkdown(trimmedLine.substring(2)) + '

\n'; - continue; - } - - // Lists - if (trimmedLine.startsWith('* ') || trimmedLine.startsWith('- ')) { - if (!inList) { - html += '\n'; - inList = false; - } - - // Regular paragraphs - if (trimmedLine !== '') { - html += '

' + processInlineMarkdown(trimmedLine) + '

\n'; - } else { - html += '\n'; - } - } - - // Close list if still open - if (inList) { - html += '\n'; - } - - // Replace code block placeholders - codeBlocks.forEach((block, index) => { - html = html.replace(``, block); - }); - - // Clean up excessive newlines - html = html.replace(/\n{3,}/g, '\n\n'); - - return html; -} diff --git a/templates/pages/chat.html b/templates/pages/chat.html index 28eff8b..2adba73 100644 --- a/templates/pages/chat.html +++ b/templates/pages/chat.html @@ -247,99 +247,6 @@ padding: 6px 12px; font-size: 0.9em; } - .markdown-tabs { - display: flex; - gap: 0; - margin-bottom: 0; - border-bottom: 1px solid #001858; - } - .markdown-tab { - flex: 1; - padding: 8px 16px; - border: none; - background-color: #f3d2c1; - color: #001858; - font-family: monospace; - font-size: 0.9em; - cursor: pointer; - border-right: 1px solid #001858; - transition: background-color 0.2s ease; - } - .markdown-tab:last-child { - border-right: none; - } - .markdown-tab:hover { - background-color: #fef6e4; - } - .markdown-tab.active { - background-color: #8bd3dd; - color: #001858; - font-weight: bold; - } - .markdown-content-container { - position: relative; - min-height: 50px; - } - .chat-input textarea, - .markdown-preview { - display: none; - resize: none; - height: 50px; - margin-bottom: 8px; - font-size: 0.9em; - width: 100%; - box-sizing: border-box; - } - .chat-input textarea.markdown-visible, - .markdown-preview.markdown-visible { - display: block; - } - .markdown-preview { - border: 1px solid #001858; - border-radius: 5px; - padding: 8px; - background-color: #fef6e4; - color: #001858; - min-height: 50px; - max-height: 200px; - overflow-y: auto; - font-family: monospace; - } - .markdown-preview h1 { - font-size: 1.5em; - margin: 0.5em 0; - } - .markdown-preview h2 { - font-size: 1.3em; - margin: 0.5em 0; - } - .markdown-preview h3 { - font-size: 1.1em; - margin: 0.5em 0; - } - .markdown-preview p { - margin: 0.5em 0; - } - .markdown-preview ul { - margin: 0.5em 0; - padding-left: 2em; - } - .markdown-preview code { - background-color: #f3d2c1; - padding: 2px 4px; - border-radius: 3px; - } - .markdown-preview pre { - background-color: #f3d2c1; - padding: 8px; - border-radius: 5px; - overflow-x: auto; - margin: 0.5em 0; - } - .markdown-preview pre code { - background-color: transparent; - padding: 0; - } .post-actions { position: absolute; top: 5px; @@ -503,29 +410,6 @@ border-color: #f582ae; } } - .markdown-tab { - background-color: #555; - color: #fef6e4; - border-color: #fef6e4; - } - .markdown-tab:hover { - background-color: #666; - } - .markdown-tab.active { - background-color: #8bd3dd; - color: #001858; - } - .markdown-preview { - background-color: #333; - color: #fef6e4; - border-color: #fef6e4; - } - .markdown-preview code { - background-color: #555; - } - .markdown-preview pre { - background-color: #555; - } } @@ -582,14 +466,7 @@ Replying to -
- - -
-
- -
-
+ @@ -952,57 +829,6 @@ } }); - // Markdown preview functionality - let currentTab = '{{.MarkdownPreviewDefault}}' || 'edit'; - let previewUpdateTimeout; - - function switchMarkdownTab(tab) { - currentTab = tab; - const textarea = document.getElementById('chat-input-text'); - const preview = document.getElementById('chat-preview'); - const tabs = document.querySelectorAll('.markdown-tab'); - - // Update tab styling - tabs.forEach(t => { - if (t.dataset.tab === tab) { - t.classList.add('active'); - } else { - t.classList.remove('active'); - } - }); - - // Show/hide content - if (tab === 'edit') { - textarea.classList.add('markdown-visible'); - preview.classList.remove('markdown-visible'); - textarea.focus(); - } else { - textarea.classList.remove('markdown-visible'); - preview.classList.add('markdown-visible'); - updatePreview(); - } - } - - function updatePreview() { - const textarea = document.getElementById('chat-input-text'); - const preview = document.getElementById('chat-preview'); - const content = textarea.value; - - if (content.trim() === '') { - preview.innerHTML = '

Nothing to preview. Type some markdown in the Edit tab.

'; - } else { - preview.innerHTML = renderMarkdownPreview(content); - } - } - - // Update preview on input (debounced) - document.getElementById('chat-input-text').addEventListener('input', () => { - if (currentTab === 'preview') { - clearTimeout(previewUpdateTimeout); - previewUpdateTimeout = setTimeout(updatePreview, 300); - } - }); - window.onload = function() { connectWebSocket(); const messagesContainer = document.getElementById('chat-messages'); @@ -1080,9 +906,6 @@ originalSendMessage(); }; - // Initialize markdown preview tab based on user preference - switchMarkdownTab(currentTab); - // Initial check for scroll position checkScrollPosition(); };