Get communication working between extension and webview; add shared data types

This commit is contained in:
Saoud Rizwan
2024-07-07 06:22:00 -04:00
parent 08effc4799
commit 991ea6bd4e
10 changed files with 105 additions and 80 deletions

View File

@@ -1,42 +1,28 @@
import React, { useState } from "react"
import logo from "./logo.svg"
import React, { useEffect, useState } from "react"
import "./App.css"
import { vscode } from "./utilities/vscode"
import {
VSCodeBadge,
VSCodeButton,
VSCodeCheckbox,
VSCodeDataGrid,
VSCodeDataGridCell,
VSCodeDataGridRow,
VSCodeDivider,
VSCodeDropdown,
VSCodeLink,
VSCodeOption,
VSCodePanels,
VSCodePanelTab,
VSCodePanelView,
VSCodeProgressRing,
VSCodeRadio,
VSCodeRadioGroup,
VSCodeTag,
VSCodeTextArea,
VSCodeTextField,
} from "@vscode/webview-ui-toolkit/react"
import ChatSidebar from "./components/ChatSidebar"
import Demo from "./components/Demo"
import SettingsView from "./components/SettingsView"
import { ExtensionMessage } from "@shared/ExtensionMessage"
const App: React.FC = () => {
const [showSettings, setShowSettings] = useState(true)
const [showSettings, setShowSettings] = useState(false)
const handleHowdyClick = () => {
vscode.postMessage({
command: "hello",
text: "Hey there partner! 🤠",
useEffect(() => {
window.addEventListener("message", (e: MessageEvent) => {
const message: ExtensionMessage = e.data
if (message.type === "action") {
switch (message.action!) {
case "settingsButtonTapped":
setShowSettings(true)
break
case "plusButtonTapped":
setShowSettings(false)
break
}
}
})
}
}, [])
return <>{showSettings ? <SettingsView /> : <ChatSidebar />}</>
}

View File

@@ -2,9 +2,10 @@ import React, { useState, useRef, useEffect, useCallback, KeyboardEvent } from "
import { VSCodeButton, VSCodeTextArea, VSCodeDivider, VSCodeTextField } from "@vscode/webview-ui-toolkit/react"
import { vscode } from "../utilities/vscode"
import DynamicTextArea from "react-textarea-autosize"
import { ExtensionMessage } from "@shared/ExtensionMessage"
interface Message {
id: number
id: string
text: string
sender: "user" | "assistant"
}
@@ -26,17 +27,14 @@ const ChatSidebar = () => {
const handleSendMessage = () => {
if (inputValue.trim()) {
const newMessage: Message = {
id: Date.now(),
id: `${Date.now()}-user`,
text: inputValue.trim(),
sender: "user",
}
setMessages([...messages, newMessage])
setMessages(currentMessages => [...currentMessages, newMessage])
setInputValue("")
// Here you would typically send the message to your extension's backend
vscode.postMessage({
command: "sendMessage",
text: newMessage.text,
})
vscode.postMessage({ type: "text", text: newMessage.text})
}
}
const handleKeyDown = (event: KeyboardEvent<HTMLTextAreaElement>) => {
@@ -52,10 +50,24 @@ const ChatSidebar = () => {
}
}, [])
useEffect(() => {
window.addEventListener("message", (e: MessageEvent) => {
const message: ExtensionMessage = e.data
if (message.type === "text") {
const newMessage: Message = {
id: `${Date.now()}-assistant`,
text: message.text!.trim(),
sender: "assistant",
}
setMessages(currentMessages => [...currentMessages, newMessage])
}
})
}, [])
return (
<div style={{ display: "flex", flexDirection: "column", height: "100vh", backgroundColor: "gray", overflow: "hidden" }}>
<div style={{ display: "flex", flexDirection: "column", height: "100vh", overflow: "hidden" }}>
<div style={{ flexGrow: 1, overflowY: "scroll", scrollbarWidth: "none" }}>
{messages.map((message) => (
{messages.map((message, index) => (
<div
key={message.id}
style={{

View File

@@ -1,34 +1,33 @@
import { vscode } from "../utilities/vscode"
import {
VSCodeBadge,
VSCodeButton,
VSCodeCheckbox,
VSCodeDataGrid,
VSCodeDataGridCell,
VSCodeDataGridRow,
VSCodeDivider,
VSCodeDropdown,
VSCodeLink,
VSCodeOption,
VSCodePanels,
VSCodePanelTab,
VSCodePanelView,
VSCodeProgressRing,
VSCodeRadio,
VSCodeRadioGroup,
VSCodeTag,
VSCodeTextArea,
VSCodeTextField,
VSCodeBadge,
VSCodeButton,
VSCodeCheckbox,
VSCodeDataGrid,
VSCodeDataGridCell,
VSCodeDataGridRow,
VSCodeDivider,
VSCodeDropdown,
VSCodeLink,
VSCodeOption,
VSCodePanels,
VSCodePanelTab,
VSCodePanelView,
VSCodeProgressRing,
VSCodeRadio,
VSCodeRadioGroup,
VSCodeTag,
VSCodeTextArea,
VSCodeTextField,
} from "@vscode/webview-ui-toolkit/react"
function Demo() {
function handleHowdyClick() {
vscode.postMessage({
command: "hello",
text: "Hey there partner! 🤠",
})
}
// function handleHowdyClick() {
// vscode.postMessage({
// command: "hello",
// text: "Hey there partner! 🤠",
// })
// }
const rowData = [
{
@@ -54,7 +53,7 @@ function Demo() {
return (
<main>
<h1>Hello World!</h1>
<VSCodeButton onClick={handleHowdyClick}>Howdy!</VSCodeButton>
<VSCodeButton>Howdy!</VSCodeButton>
<div className="grid gap-3 p-2 place-items-start">
<VSCodeDataGrid>

View File

@@ -61,13 +61,13 @@ const SettingsView = () => {
color: "var(--vscode-descriptionForeground)",
fontSize: "12px",
lineHeight: "1.5",
fontStyle: "italic"
fontStyle: "italic",
}}>
<p>Made possible by the latest breakthroughs in Claude 3.5 Sonnet's agentic coding capabilities.</p>
<p>
This project was submitted to Anthropic's "Build with Claude June 2024 contest".
This project was submitted to Anthropic's<br/>"Build with Claude June 2024 contest"
<VSCodeLink href="https://github.com/saoudrizwan/claude-dev">
github.com/saoudrizwan/claude-dev
https://github.com/saoudrizwan/claude-dev
</VSCodeLink>
</p>
</div>

View File

@@ -1,3 +1,4 @@
import { WebviewMessage } from "@shared/WebviewMessage"
import type { WebviewApi } from "vscode-webview"
/**
@@ -28,7 +29,7 @@ class VSCodeAPIWrapper {
*
* @param message Abitrary data (must be JSON serializable) to send to the extension context.
*/
public postMessage(message: unknown) {
public postMessage(message: WebviewMessage) {
if (this.vsCodeApi) {
this.vsCodeApi.postMessage(message)
} else {

View File

@@ -14,7 +14,10 @@
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx"
"jsx": "react-jsx",
"paths": {
"@shared/*": ["../src/shared/*"]
}
},
"include": ["src"]
"include": ["src", "../src/shared"]
}