| 193 | : Math.min(slashIndex, slashMatches.length - 1); |
| 194 | |
| 195 | function insertSlashCommand(cmd: SlashCommand) { |
| 196 | // Catalog `name` is the command without the leading slash ("new", "clear"). |
| 197 | // Insert ends with a trailing space so the popover closes — a second |
| 198 | // Enter then submits. |
| 199 | const insert = cmd.insert ?? `/${cmd.name} `; |
| 200 | setInput(insert); |
| 201 | setSlashIndex(0); |
| 202 | requestAnimationFrame(() => { |
| 203 | const ta = textareaRef.current; |
| 204 | if (ta) { |
| 205 | ta.focus(); |
| 206 | ta.setSelectionRange(insert.length, insert.length); |
| 207 | } |
| 208 | }); |
| 209 | } |
| 210 | |
| 211 | // Optimistic state for the active /api/chat send. Rendered after committed |
| 212 | // events so the user sees their message + the streaming response before |