diff --git a/src/components/editor/MentionEditor.tsx b/src/components/editor/MentionEditor.tsx index d301565..7fadd8a 100644 --- a/src/components/editor/MentionEditor.tsx +++ b/src/components/editor/MentionEditor.tsx @@ -584,6 +584,9 @@ export const MentionEditor = forwardRef< node.content?.forEach((child: any) => { if (child.type === "text") { text += child.text; + } else if (child.type === "hardBreak") { + // Preserve newlines from Shift+Enter + text += "\n"; } else if (child.type === "mention") { const pubkey = child.attrs?.id; if (pubkey) { @@ -664,6 +667,9 @@ export const MentionEditor = forwardRef< // Build extensions array const extensions = useMemo(() => { + // Detect mobile devices (touch support) + const isMobile = "ontouchstart" in window || navigator.maxTouchPoints > 0; + // Custom extension for keyboard shortcuts (runs before suggestion plugins) const SubmitShortcut = Extension.create({ name: "submitShortcut", @@ -674,10 +680,16 @@ export const MentionEditor = forwardRef< handleSubmitRef.current(editor); return true; }, - // Plain Enter submits (Shift+Enter handled by hardBreak for newlines) + // Plain Enter behavior depends on device Enter: ({ editor }) => { - handleSubmitRef.current(editor); - return true; + if (isMobile) { + // On mobile, Enter inserts a newline (hardBreak) + return editor.commands.setHardBreak(); + } else { + // On desktop, Enter submits the message + handleSubmitRef.current(editor); + return true; + } }, }; }, diff --git a/src/components/nostr/RichText/Text.tsx b/src/components/nostr/RichText/Text.tsx index 12a03eb..7ac4823 100644 --- a/src/components/nostr/RichText/Text.tsx +++ b/src/components/nostr/RichText/Text.tsx @@ -1,5 +1,4 @@ import { CommonData } from "applesauce-content/nast"; -import { useMemo } from "react"; interface TextNodeProps { node: { @@ -11,23 +10,22 @@ interface TextNodeProps { export function Text({ node }: TextNodeProps) { const text = node.value; - const lines = useMemo(() => text.split("\n"), [text]); - if (text.includes("\n")) { - return ( - <> - {lines.map((line, idx) => - line.trim().length === 0 ? ( -
- ) : idx === 0 || idx === lines.length - 1 ? ( - {line} // FIXME: this should be span or div depnding on context - ) : ( -
- {line} -
- ), - )} - - ); + + // If no newlines, render as simple span + if (!text.includes("\n")) { + return {text}; } - return {text}; + + // Multi-line text: split and render with
between lines + const lines = text.split("\n"); + return ( + <> + {lines.map((line, idx) => ( + + {line} + {idx < lines.length - 1 &&
} +
+ ))} + + ); }