diff --git a/src/common/chatService/index.ts b/src/common/chatService/index.ts index 6fbc8b6..803d468 100644 --- a/src/common/chatService/index.ts +++ b/src/common/chatService/index.ts @@ -5,3 +5,9 @@ export const CHAT_SERVICE_NAME = "chat"; export interface IChatService extends IService { confirmPrompt(prompt: string): Promise; } + +export const CHAT_VIEW_SERVICE_NAME = "chat_view"; + +export interface IChatViewService extends IService { + setHasSelection(hasSelection: boolean): Promise; +} diff --git a/src/extension/chat/chatPanelProvider.ts b/src/extension/chat/chatPanelProvider.ts index 45bcc07..bb98048 100644 --- a/src/extension/chat/chatPanelProvider.ts +++ b/src/extension/chat/chatPanelProvider.ts @@ -3,6 +3,10 @@ import * as vscode from "vscode"; import { getNonce } from "../utils"; import { sharedChatServiceImpl } from "./chatServiceImpl"; import { ExtensionHostServiceManager } from "../../common/ipc/extensionHost"; +import { + IChatViewService, + CHAT_VIEW_SERVICE_NAME, +} from "../../common/chatService"; export class ChatPanelProvider implements vscode.WebviewViewProvider { static readonly viewType = "chat"; @@ -35,7 +39,20 @@ export class ChatPanelProvider implements vscode.WebviewViewProvider { const serviceManager = new ExtensionHostServiceManager(webview); serviceManager.registerService(sharedChatServiceImpl()); + + const eventDisposable = vscode.window.onDidChangeTextEditorSelection( + async (e) => { + const hasSelection = !e.selections[0].isEmpty; + const chatViewService = + await serviceManager.getService( + CHAT_VIEW_SERVICE_NAME + ); + await chatViewService.setHasSelection(hasSelection); + } + ); + webviewView.onDidDispose(() => { + eventDisposable.dispose(); serviceManager.dispose(); }); } diff --git a/src/webview/chat/chatViewServiceImpl.ts b/src/webview/chat/chatViewServiceImpl.ts new file mode 100644 index 0000000..fe65029 --- /dev/null +++ b/src/webview/chat/chatViewServiceImpl.ts @@ -0,0 +1,16 @@ +import { + IChatViewService, + CHAT_VIEW_SERVICE_NAME, +} from "../../common/chatService"; + +export class ChatViewServiceImpl implements IChatViewService { + setHasSelectionAction: ((hasSelection: boolean) => void) | null = null; + + get name(): string { + return CHAT_VIEW_SERVICE_NAME; + } + + async setHasSelection(hasSelection: boolean): Promise { + this.setHasSelectionAction?.call(null, hasSelection); + } +} diff --git a/src/webview/chat/index.tsx b/src/webview/chat/index.tsx index 3fff1be..91af702 100644 --- a/src/webview/chat/index.tsx +++ b/src/webview/chat/index.tsx @@ -4,11 +4,13 @@ import { VSCodeButton, VSCodeTextArea } from "@vscode/webview-ui-toolkit/react"; import "./style.css"; import { MessageItem, MessageItemModel } from "./MessageItem"; +import { ChatViewServiceImpl } from "./chatViewServiceImpl"; import { getServiceManager } from "../../common/ipc/webview"; import { IChatService, CHAT_SERVICE_NAME } from "../../common/chatService"; export function ChatPage() { const [messages, setMessages] = useState([] as MessageItemModel[]); + const [hasSelection, setHasSelection] = useState(false); const [prompt, setPrompt] = useState(""); useEffect(() => { setMessages( @@ -23,6 +25,10 @@ export function ChatPage() { }; }) ); + + const viewServiceImpl = new ChatViewServiceImpl(); + viewServiceImpl.setHasSelectionAction = setHasSelection; + getServiceManager().registerService(viewServiceImpl); }, []); const handleAskAction = useCallback(async () => { @@ -55,7 +61,9 @@ export function ChatPage() { ) => { setPrompt(e.target.value);