diff --git a/packages/kilo-vscode/tests/unit/review-comments.test.ts b/packages/kilo-vscode/tests/unit/review-comments.test.ts index ca9b9353cfe..f1e75a3bc94 100644 --- a/packages/kilo-vscode/tests/unit/review-comments.test.ts +++ b/packages/kilo-vscode/tests/unit/review-comments.test.ts @@ -245,9 +245,7 @@ describe("markdownCommentBlocks", () => { describe("review annotation speech keys", () => { it("keeps draft keys scoped to the selected review location", () => { - expect(reviewDraftSpeechKey({ file: "src/a.ts", side: "additions", line: 4 })).toBe( - "draft:src/a.ts:additions:4:4", - ) + expect(reviewDraftSpeechKey({ file: "src/a.ts", side: "additions", line: 4 })).toBe("draft:src/a.ts:additions:4:4") expect(reviewDraftSpeechKey({ file: "src/a.ts", side: "deletions", line: 4, endLine: 8 })).toBe( "draft:src/a.ts:deletions:4:8", ) diff --git a/packages/kilo-vscode/webview-ui/agent-manager/review-annotation-speech.tsx b/packages/kilo-vscode/webview-ui/agent-manager/review-annotation-speech.tsx index ae8314e1b52..48c67f73d28 100644 --- a/packages/kilo-vscode/webview-ui/agent-manager/review-annotation-speech.tsx +++ b/packages/kilo-vscode/webview-ui/agent-manager/review-annotation-speech.tsx @@ -1,4 +1,4 @@ -import { createEffect, createSignal, onCleanup, Show, type Accessor } from "solid-js" +import { createEffect, createRoot, createSignal, onCleanup, Show, type Accessor } from "solid-js" import { render as renderSolid } from "solid-js/web" import { SpeechToTextButton } from "../src/components/speech-to-text/SpeechToTextButton" import { insertSpacedText } from "../src/components/chat/prompt-input-utils" @@ -19,7 +19,7 @@ type Node = { setTextarea: (textarea: HTMLTextAreaElement) => void } -export function insertReviewSpeechText(textarea: HTMLTextAreaElement, value: string): void { +function insertReviewSpeechText(textarea: HTMLTextAreaElement, value: string): void { const text = textarea.value const start = textarea.selectionStart ?? text.length const end = textarea.selectionEnd ?? start @@ -42,11 +42,18 @@ export function createReviewAnnotationSpeechRenderer(props: Props) { let field = textarea const mine = () => owner() === key const state = (): SpeechState => (mine() ? props.speech.state() : "idle") + const start = (model: string) => { + setOwner(key) + props.speech.start({ + model, + insert: (value) => insertReviewSpeechText(field, value), + }) + } const speech: SpeechToText = { state, error: () => (mine() ? props.speech.error() : undefined), active: () => mine() && props.speech.active(), - start: props.speech.start, + start: (opts) => start(opts.model), stop: () => { if (!mine()) return props.speech.stop() @@ -63,22 +70,24 @@ export function createReviewAnnotationSpeechRenderer(props: Props) { }, } const blocked = () => props.speech.active() && !mine() - const start = () => { - setOwner(key) - props.speech.start({ - model: props.model(), - insert: (value) => insertReviewSpeechText(field, value), - }) - } - const dispose = renderSolid( - () => ( - - - - ), - host, - ) + const dispose = createRoot((root) => { + const view = renderSolid( + () => ( + + start(props.model())} + label={props.label} + /> + + ), + host, + ) + onCleanup(view) + return root + }) const node = { host,