diff --git a/web/src/views/compose/Composer.tsx b/web/src/views/compose/Composer.tsx index b992f5f..99be5e5 100644 --- a/web/src/views/compose/Composer.tsx +++ b/web/src/views/compose/Composer.tsx @@ -38,6 +38,11 @@ export function Composer({ draft }: { draft: Draft }) { const [showToolbar, setShowToolbar] = useState(true); const d = draft; const key = d.key; + // Where the caret starts, decided once when the composer opens: a blank + // message starts in the recipients, a reply (already addressed and titled) + // starts in the body. Deriving this from live state would move the caret + // while the user types. + const [initialFocus] = useState(() => initialFocusTarget(draft)); const patch = useCallback((p: Partial) => update(key, p), [update, key]); const onHtml = useCallback((html: string) => update(key, { html }), [update, key]); @@ -138,7 +143,7 @@ export function Composer({ draft }: { draft: Draft }) { )}
- patch({ to })} placeholder="Recipients" autoFocus={!d.to.length} /> + patch({ to })} placeholder="Recipients" autoFocus={initialFocus === "to"} /> {!d.showCc && } {!d.showBcc && } @@ -165,13 +170,13 @@ export function Composer({ draft }: { draft: Draft }) { )}
- patch({ subject: e.target.value })} autoFocus={d.to.length > 0 && !d.subject} /> + patch({ subject: e.target.value })} autoFocus={initialFocus === "subject"} /> {d.priority !== "normal" && {d.priority === "high" ? "High priority" : "Low priority"}} {d.requestReceipt && }
{d.format === "html" ? ( - addFiles(key, files)} showToolbar={showToolbar} autoFocus={d.to.length > 0 && Boolean(d.subject)} /> + addFiles(key, files)} showToolbar={showToolbar} autoFocus={initialFocus === "body"} /> ) : (