refactor(comments): streamline input — Enter to send, no buttons
Some checks failed
CI / Unit & Component Tests (push) Has been cancelled
CI / Backend Unit Tests (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
CI / Unit & Component Tests (pull_request) Has been cancelled
CI / Backend Unit Tests (pull_request) Has been cancelled
CI / E2E Tests (pull_request) Has been cancelled

- MentionEditor: Enter sends (Shift+Enter for newline), remove @ button
- CommentThread: remove send button, full-width input, always show
  input when comments exist (no need to click Kommentieren first)
- TranscriptionBlock: remove border-t above comment section (orange
  background provides enough visual separation)
- Update placeholder in all languages to hint @mention and Enter to send

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-04-05 22:25:46 +02:00
parent f09b605752
commit e384c87eef
6 changed files with 16 additions and 61 deletions

View File

@@ -315,7 +315,7 @@
"comp_expandable_show_less": "Weniger anzeigen",
"error_comment_not_found": "Der Kommentar wurde nicht gefunden.",
"comment_section_title": "Diskussion",
"comment_placeholder": "Kommentar schreiben…",
"comment_placeholder": "Kommentar schreiben… (@Name erwähnen · Enter senden)",
"comment_btn_post": "Senden",
"comment_btn_reply": "Antworten",
"comment_edited_label": "(Bearbeitet)",

View File

@@ -315,7 +315,7 @@
"comp_expandable_show_less": "Show less",
"error_comment_not_found": "The comment could not be found.",
"comment_section_title": "Discussion",
"comment_placeholder": "Write a comment…",
"comment_placeholder": "Write a comment… (@name to mention · Enter to send)",
"comment_btn_post": "Send",
"comment_btn_reply": "Reply",
"comment_edited_label": "(Edited)",

View File

@@ -315,7 +315,7 @@
"comp_expandable_show_less": "Mostrar menos",
"error_comment_not_found": "El comentario no pudo encontrarse.",
"comment_section_title": "Discusión",
"comment_placeholder": "Escribe un comentario…",
"comment_placeholder": "Escribe un comentario… (@nombre para mencionar · Enter para enviar)",
"comment_btn_post": "Enviar",
"comment_btn_reply": "Responder",
"comment_edited_label": "(Editado)",

View File

@@ -196,24 +196,15 @@ onMount(() => {
</div>
{/if}
{#if canComment && showCompose}
<div class="mt-2 flex gap-2">
<div class="flex-1">
<MentionEditor
bind:value={newText}
bind:mentionCandidates={newMentionCandidates}
rows={1}
placeholder={m.comment_placeholder()}
disabled={posting}
onsubmit={postComment}
/>
</div>
<button
class="self-end rounded bg-primary px-2.5 py-1.5 font-sans text-xs font-medium text-primary-fg hover:bg-primary/80 disabled:opacity-40"
disabled={posting || !newText.trim()}
onclick={postComment}
>
{m.comment_btn_post()}
</button>
{#if canComment && (showCompose || flatMessages.length > 0)}
<div class="mt-2">
<MentionEditor
bind:value={newText}
bind:mentionCandidates={newMentionCandidates}
rows={1}
placeholder={m.comment_placeholder()}
disabled={posting}
onsubmit={postComment}
/>
</div>
{/if}

View File

@@ -115,7 +115,8 @@ function closePopup() {
}
function handleKeydown(e: KeyboardEvent) {
if (e.ctrlKey && e.key === 'Enter') {
// Enter sends, Shift+Enter adds newline
if (e.key === 'Enter' && !e.shiftKey && query === null) {
e.preventDefault();
onsubmit?.();
return;
@@ -152,33 +153,6 @@ function handleKeydown(e: KeyboardEvent) {
}
}
async function handleAtButtonClick() {
if (!textarea) return;
const pos = textarea.selectionStart;
const before = value.slice(0, pos);
const after = value.slice(pos);
// Ensure @ is preceded by whitespace or is at the start
const needsSpace = before.length > 0 && !/\s$/.test(before);
const insertion = needsSpace ? ' @' : '@';
value = before + insertion + after;
await tick();
if (!textarea) return;
const newPos = pos + insertion.length;
textarea.selectionStart = newPos;
textarea.selectionEnd = newPos;
textarea.focus();
// Trigger mention detection after inserting @
const detected = detectMention(value, newPos);
if (detected !== null) {
mentionStart = newPos - 1;
query = detected;
highlightedIndex = 0;
scheduleSearch(detected);
}
}
onDestroy(() => clearTimeout(debounceTimer));
const popupOpen = $derived(query !== null);
@@ -224,14 +198,4 @@ const popupOpen = $derived(query !== null);
{/if}
</div>
{/if}
<button
type="button"
aria-label={m.mention_btn_label()}
disabled={disabled}
class="mt-1 rounded border border-line px-2 py-0.5 font-sans text-xs font-medium text-ink-3 transition-colors hover:border-ink hover:text-ink disabled:opacity-40"
onclick={handleAtButtonClick}
>
@
</button>
</div>

View File

@@ -196,7 +196,7 @@ function captureSelectionAndOpenComments() {
</div>
<!-- Comment thread — list always visible, compose toggled by Kommentieren -->
<div class="mt-3 border-t border-line pt-3">
<div class="mt-3">
<CommentThread
documentId={documentId}
blockId={blockId}