From cb8b108d3cd6fc7209b366ae2a622182919841cd Mon Sep 17 00:00:00 2001 From: Ulas Date: Fri, 27 Mar 2026 15:31:50 +0100 Subject: [PATCH] =?UTF-8?q?fix:=20Notizen-Toolbar=20erweitert=20+=20Essen-?= =?UTF-8?q?Widget=202=C3=972-Grid=20auf=20Desktop?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pinnwand: Pflichtfeld-Stern entfernt, Markdown-Hinweis ergänzt, Formatierungs-Toolbar um Unterstreichen, Durchgestrichen, Überschrift, nummerierte Liste, Checkliste, Link, Code, Zitat und Trennlinie erweitert. Dashboard: Essen-Widget nutzt ab Desktop 2×2-Layout statt 4×1 für bessere Lesbarkeit der Mahlzeiten-Labels. Co-Authored-By: Claude Opus 4.6 --- public/pages/notes.js | 120 ++++++++++++++++++++++++++++++++++-- public/styles/dashboard.css | 23 +++++++ 2 files changed, 139 insertions(+), 4 deletions(-) diff --git a/public/pages/notes.js b/public/pages/notes.js index c9f032c..9006335 100644 --- a/public/pages/notes.js +++ b/public/pages/notes.js @@ -169,14 +169,49 @@ function applyFormat(textarea, format) { before = '*'; after = '*'; insert = sel || 'Text'; break; + case 'underline': + before = ''; after = ''; + insert = sel || 'Text'; + break; + case 'strikethrough': + before = '~~'; after = '~~'; + insert = sel || 'Text'; + break; + case 'code': + before = '`'; after = '`'; + insert = sel || 'Code'; + break; + case 'link': + if (sel) { + textarea.setRangeText(`[${sel}](url)`, start, end, 'select'); + textarea.selectionStart = start + sel.length + 3; + textarea.selectionEnd = start + sel.length + 6; + } else { + textarea.setRangeText('[Linktext](url)', start, end, 'select'); + textarea.selectionStart = start + 1; + textarea.selectionEnd = start + 9; + } + return; + case 'heading': { + const lineStart = text.lastIndexOf('\n', start - 1) + 1; + const lineEnd = text.indexOf('\n', start); + const line = text.slice(lineStart, lineEnd === -1 ? text.length : lineEnd); + const match = line.match(/^(#{1,3})\s/); + if (match && match[1].length < 3) { + textarea.setRangeText('#' + line, lineStart, lineEnd === -1 ? text.length : lineEnd, 'end'); + } else if (match && match[1].length >= 3) { + textarea.setRangeText(line.replace(/^#{1,3}\s/, ''), lineStart, lineEnd === -1 ? text.length : lineEnd, 'end'); + } else { + textarea.setRangeText('## ' + line, lineStart, lineEnd === -1 ? text.length : lineEnd, 'end'); + } + return; + } case 'list': { - // Jede Zeile mit "- " prefixen oder neuen Listenpunkt einfügen if (sel) { const lines = sel.split('\n').map((l) => l.startsWith('- ') ? l : `- ${l}`); textarea.setRangeText(lines.join('\n'), start, end, 'end'); return; } - before = ''; after = ''; const lineStart = text.lastIndexOf('\n', start - 1) + 1; const currentLine = text.slice(lineStart, start); if (currentLine.trim() === '') { @@ -186,6 +221,54 @@ function applyFormat(textarea, format) { } return; } + case 'ordered-list': { + if (sel) { + const lines = sel.split('\n').map((l, i) => `${i + 1}. ${l.replace(/^\d+\.\s/, '')}`); + textarea.setRangeText(lines.join('\n'), start, end, 'end'); + return; + } + const lineStart = text.lastIndexOf('\n', start - 1) + 1; + const currentLine = text.slice(lineStart, start); + if (currentLine.trim() === '') { + textarea.setRangeText('1. ', start, start, 'end'); + } else { + textarea.setRangeText('\n1. ', start, start, 'end'); + } + return; + } + case 'checklist': { + if (sel) { + const lines = sel.split('\n').map((l) => l.startsWith('- [ ] ') ? l : `- [ ] ${l}`); + textarea.setRangeText(lines.join('\n'), start, end, 'end'); + return; + } + const lineStart = text.lastIndexOf('\n', start - 1) + 1; + const currentLine = text.slice(lineStart, start); + if (currentLine.trim() === '') { + textarea.setRangeText('- [ ] ', start, start, 'end'); + } else { + textarea.setRangeText('\n- [ ] ', start, start, 'end'); + } + return; + } + case 'quote': { + if (sel) { + const lines = sel.split('\n').map((l) => l.startsWith('> ') ? l : `> ${l}`); + textarea.setRangeText(lines.join('\n'), start, end, 'end'); + return; + } + const lineStart = text.lastIndexOf('\n', start - 1) + 1; + const currentLine = text.slice(lineStart, start); + if (currentLine.trim() === '') { + textarea.setRangeText('> ', start, start, 'end'); + } else { + textarea.setRangeText('\n> ', start, start, 'end'); + } + return; + } + case 'divider': + textarea.setRangeText('\n\n---\n\n', start, end, 'end'); + return; default: return; } @@ -211,7 +294,7 @@ function openNoteModal({ mode, note = null }) { placeholder="Kein Titel" value="${escHtml(isEdit && note.title ? note.title : '')}">
- +
+ + - + + + + + + + +