diff --git a/CHANGELOG.md b/CHANGELOG.md index 3694cb0..b143dc7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,8 @@ Das Format folgt [Keep a Changelog](https://keepachangelog.com/de/1.1.0/), die V - PWA Web Share Target: Text, Links und Bilder können über den nativen Teilen-Dialog des Smartphones direkt in den MindSift-Posteingang geteilt werden (`share_target` im Manifest, Abfangen im Service Worker via IndexedDB und Übernahme beim App-Start; Fallback-Route `POST /share-target` im Server). ### Changed +- Code-Blöcke ohne Rahmen und Kopfleiste: oben links nur die Sprache, Kopieren als runder Symbol-Knopf unten rechts (erscheint beim Überfahren, am Handy immer). „In normalen Text umwandeln“ steht für Code-Blöcke (und nummerierte Punkte) in der Aktionsblase des Punkts. +- Code-, Audio- und Diktat-Blöcke haben unabhängig vom Theme runde Ecken; Callouts bleiben eckig. - Inline-Code ist einfarbig (Text in Haupttextfarbe auf dem Code-Hintergrund des Themes) statt in Akzentfarbe, für bessere Lesbarkeit. - Notizen: Enter in einem leeren eingerückten Punkt rückt ihn nur noch aus, wenn danach kein Punkt mehr auf derselben Ebene folgt; sonst entsteht wie gewohnt ein neuer Punkt darunter (auch nummerierte Listen werden dann nicht beendet). - Workspace-Leiste: Live, Geteilt und Speicherstatus ohne Rahmen im gleichen Stil, ein senkrechter Trennstrich vor den Notiz-Knöpfen. Footer ohne Linie darüber. diff --git a/frontend/src/features/workspace/AudioBlock.tsx b/frontend/src/features/workspace/AudioBlock.tsx index 9a07df2..adaa899 100644 --- a/frontend/src/features/workspace/AudioBlock.tsx +++ b/frontend/src/features/workspace/AudioBlock.tsx @@ -87,7 +87,7 @@ export const AudioBlock: React.FC = ({ content, canEdit, onCapt return (
{failed ? ( -
+
Aufnahme nicht verfügbar (offline oder gelöscht)
) : src ? ( @@ -99,7 +99,7 @@ export const AudioBlock: React.FC = ({ content, canEdit, onCapt onClick={() => void transcribe()} disabled={transcribing} title="In Text umwandeln (eigene Spracherkennung)" - className="btn-secondary h-11 sm:h-8 px-2.5 text-xs flex items-center gap-1.5 shrink-0 disabled:opacity-40" + className="btn-secondary !rounded-full h-11 sm:h-8 px-3 text-xs flex items-center gap-1.5 shrink-0 disabled:opacity-40" > {transcribing ? : } {transcribing ? 'Wird erkannt…' : 'Transkribieren'} @@ -107,7 +107,7 @@ export const AudioBlock: React.FC = ({ content, canEdit, onCapt )}
) : ( -
+
)} diff --git a/frontend/src/features/workspace/AudioRecorderPicker.tsx b/frontend/src/features/workspace/AudioRecorderPicker.tsx index ebe4b08..24f3e0e 100644 --- a/frontend/src/features/workspace/AudioRecorderPicker.tsx +++ b/frontend/src/features/workspace/AudioRecorderPicker.tsx @@ -108,7 +108,7 @@ export const AudioRecorderPicker: React.FC = ({ docId, cancel(); } }} - className="my-1 inline-flex max-w-full flex-col gap-2 rounded-card border border-border bg-panel-elevated px-3 py-2 focus:outline-none" + className="my-1 inline-flex max-w-full flex-col gap-2 rounded-3xl border border-border bg-panel-elevated px-4 py-2 focus:outline-none" >
{state === 'recording' && ( @@ -162,7 +162,7 @@ export const AudioRecorderPicker: React.FC = ({ docId, onClick={cancel} disabled={state === 'uploading'} title="Abbrechen (Esc)" - className="w-11 h-11 sm:w-7 sm:h-7 flex items-center justify-center rounded-btn text-muted hover:text-main hover:bg-panel shrink-0 disabled:opacity-40" + className="w-11 h-11 sm:w-7 sm:h-7 flex items-center justify-center rounded-full text-muted hover:text-main hover:bg-panel shrink-0 disabled:opacity-40" > diff --git a/frontend/src/features/workspace/CodeBlockEditor.tsx b/frontend/src/features/workspace/CodeBlockEditor.tsx index c4e436b..655a9b5 100644 --- a/frontend/src/features/workspace/CodeBlockEditor.tsx +++ b/frontend/src/features/workspace/CodeBlockEditor.tsx @@ -1,6 +1,6 @@ import React, { useState, useEffect, useLayoutEffect, useMemo, useRef, useCallback } from 'react'; import Prism from 'prismjs'; -import { Code, Copy, Check } from 'lucide-react'; +import { Copy, Check } from 'lucide-react'; import { DocumentBlock } from '../../lib/types'; Prism.manual = true; @@ -311,6 +311,7 @@ export interface CodeBlockEditorProps { registerTextareaRef?: (blockId: string, el: HTMLTextAreaElement | null) => void; onChangeContent?: (content: string) => void; onChangeLang?: (lang: string) => void; + /** Kept for callers; converting back to text lives in the bullet's action bubble now */ onConvertToText?: () => void; handleFocus?: (e: React.FocusEvent) => void; handleBlur?: (e: React.FocusEvent) => void; @@ -326,7 +327,6 @@ export const CodeBlockEditor: React.FC = ({ registerTextareaRef, onChangeContent, onChangeLang, - onConvertToText, handleFocus, handleBlur, handleContentChange, @@ -542,73 +542,50 @@ export const CodeBlockEditor: React.FC = ({ const hasCustomUnknownLang = Boolean(selectValue && !KNOWN_OPTION_IDS.has(selectValue)); return ( -
- {/* Code Block Header */} -
-
- - {canEdit ? ( - - ) : ( - {block.lang || 'Text'} - )} -
- -
- + {/* Live Highlighted Overlay + Textarea with Line Numbers */}
{/* Line Numbers Column */} @@ -618,7 +595,7 @@ export const CodeBlockEditor: React.FC = ({ onScroll={handleLineNumbersScroll} onWheel={handleLineNumbersWheel} data-testid="code-line-numbers" - className="select-none py-2 pl-2.5 pr-2 font-mono text-xs text-faint leading-relaxed text-right border-r border-border/40 shrink-0 overflow-hidden" + className="select-none py-2 pl-2.5 pr-2 font-mono text-xs text-faint leading-relaxed text-right shrink-0 overflow-hidden" > {Array.from({ length: lineCount }, (_, i) => (
diff --git a/frontend/src/features/workspace/DictationBlock.tsx b/frontend/src/features/workspace/DictationBlock.tsx index d8bf720..d6cbd84 100644 --- a/frontend/src/features/workspace/DictationBlock.tsx +++ b/frontend/src/features/workspace/DictationBlock.tsx @@ -85,7 +85,7 @@ export const DictationBlock: React.FC = ({ onDone, onCancel }} disabled={transcribing || !!error} aria-label="Diktat beenden" - className="relative w-full min-h-[56px] sm:min-h-[44px] my-1 px-3 py-2 rounded-card border border-accent bg-accent-dim overflow-hidden flex flex-col gap-1.5 text-left cursor-pointer disabled:cursor-default focus:outline-none" + className="relative w-full min-h-[56px] sm:min-h-[44px] my-1 px-4 py-2 rounded-3xl border border-accent bg-accent-dim overflow-hidden flex flex-col gap-1.5 text-left cursor-pointer disabled:cursor-default focus:outline-none" > {(interim || chunkBusy) && !error && (
diff --git a/frontend/src/features/workspace/OutlinerBlock.tsx b/frontend/src/features/workspace/OutlinerBlock.tsx index 5db0903..aede07b 100644 --- a/frontend/src/features/workspace/OutlinerBlock.tsx +++ b/frontend/src/features/workspace/OutlinerBlock.tsx @@ -1613,8 +1613,8 @@ export const OutlinerBlock: React.FC = ({ : 'opacity-0 group-hover:opacity-100 focus-within:opacity-100 pointer-events-none group-hover:pointer-events-auto focus-within:pointer-events-auto' }`} > - {/* Convert back to bullet for headings, callouts, divider */} - {canEdit && ['callout', 'h1', 'h2', 'h3', 'divider'].includes(block.type) && ( + {/* Convert back to bullet for headings, callouts, dividers, code and numbered items */} + {canEdit && ['callout', 'h1', 'h2', 'h3', 'divider', 'code', 'numbered'].includes(block.type) && (