mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-08-28 05:27:24 +00:00
153 lines
4.6 KiB
TypeScript
153 lines
4.6 KiB
TypeScript
import { useCallback, useEffect, useRef, useState } from "react"
|
|
import { useEvent } from "react-use"
|
|
|
|
import { ExtensionMessage } from "../../src/shared/ExtensionMessage"
|
|
import { ShowHumanRelayDialogMessage } from "../../src/shared/ExtensionMessage"
|
|
|
|
import { vscode } from "./utils/vscode"
|
|
import { telemetryClient } from "./utils/TelemetryClient"
|
|
import { ExtensionStateContextProvider, useExtensionState } from "./context/ExtensionStateContext"
|
|
import ChatView from "./components/chat/ChatView"
|
|
import HistoryView from "./components/history/HistoryView"
|
|
import SettingsView, { SettingsViewRef } from "./components/settings/SettingsView"
|
|
import WelcomeView from "./components/welcome/WelcomeView"
|
|
import McpView from "./components/mcp/McpView"
|
|
import PromptsView from "./components/prompts/PromptsView"
|
|
import { HumanRelayDialog } from "./components/human-relay/HumanRelayDialog"
|
|
|
|
type Tab = "settings" | "history" | "mcp" | "prompts" | "chat"
|
|
|
|
const tabsByMessageAction: Partial<Record<NonNullable<ExtensionMessage["action"]>, Tab>> = {
|
|
chatButtonClicked: "chat",
|
|
settingsButtonClicked: "settings",
|
|
promptsButtonClicked: "prompts",
|
|
mcpButtonClicked: "mcp",
|
|
historyButtonClicked: "history",
|
|
}
|
|
const App = () => {
|
|
const { didHydrateState, showWelcome, shouldShowAnnouncement, telemetrySetting, telemetryKey, machineId } =
|
|
useExtensionState()
|
|
const [showAnnouncement, setShowAnnouncement] = useState(false)
|
|
const [tab, setTab] = useState<Tab>("chat")
|
|
const settingsRef = useRef<SettingsViewRef>(null)
|
|
|
|
// Human Relay Dialog Status
|
|
const [humanRelayDialogState, setHumanRelayDialogState] = useState<{
|
|
isOpen: boolean
|
|
requestId: string
|
|
promptText: string
|
|
}>({
|
|
isOpen: false,
|
|
requestId: "",
|
|
promptText: "",
|
|
})
|
|
|
|
const switchTab = useCallback((newTab: Tab) => {
|
|
if (settingsRef.current?.checkUnsaveChanges) {
|
|
settingsRef.current.checkUnsaveChanges(() => setTab(newTab))
|
|
} else {
|
|
setTab(newTab)
|
|
}
|
|
}, [])
|
|
|
|
const onMessage = useCallback(
|
|
(e: MessageEvent) => {
|
|
const message: ExtensionMessage = e.data
|
|
|
|
if (message.type === "action" && message.action) {
|
|
const newTab = tabsByMessageAction[message.action]
|
|
|
|
if (newTab) {
|
|
switchTab(newTab)
|
|
}
|
|
}
|
|
const mes: ShowHumanRelayDialogMessage = message as ShowHumanRelayDialogMessage
|
|
// Processing displays human relay dialog messages
|
|
if (mes.type === "showHumanRelayDialog" && mes.requestId && mes.promptText) {
|
|
setHumanRelayDialogState({
|
|
isOpen: true,
|
|
requestId: mes.requestId,
|
|
promptText: mes.promptText,
|
|
})
|
|
}
|
|
},
|
|
[switchTab],
|
|
)
|
|
|
|
// Processing Human Relay Dialog Submission
|
|
const handleHumanRelaySubmit = (requestId: string, text: string) => {
|
|
vscode.postMessage({
|
|
type: "humanRelayResponse",
|
|
requestId,
|
|
text,
|
|
})
|
|
}
|
|
|
|
// Handle Human Relay dialog box cancel
|
|
const handleHumanRelayCancel = (requestId: string) => {
|
|
vscode.postMessage({
|
|
type: "humanRelayCancel",
|
|
requestId,
|
|
})
|
|
}
|
|
|
|
useEvent("message", onMessage)
|
|
|
|
useEffect(() => {
|
|
if (shouldShowAnnouncement) {
|
|
setShowAnnouncement(true)
|
|
vscode.postMessage({ type: "didShowAnnouncement" })
|
|
}
|
|
}, [shouldShowAnnouncement])
|
|
|
|
useEffect(() => {
|
|
if (didHydrateState) {
|
|
telemetryClient.updateTelemetryState(telemetrySetting, telemetryKey, machineId)
|
|
}
|
|
}, [telemetrySetting, telemetryKey, machineId, didHydrateState])
|
|
|
|
// Tell Extension that we are ready to receive messages
|
|
useEffect(() => {
|
|
vscode.postMessage({ type: "webviewDidLaunch" })
|
|
}, [])
|
|
|
|
if (!didHydrateState) {
|
|
return null
|
|
}
|
|
|
|
// Do not conditionally load ChatView, it's expensive and there's state we
|
|
// don't want to lose (user input, disableInput, askResponse promise, etc.)
|
|
return showWelcome ? (
|
|
<WelcomeView />
|
|
) : (
|
|
<>
|
|
{tab === "settings" && <SettingsView ref={settingsRef} onDone={() => setTab("chat")} />}
|
|
{tab === "history" && <HistoryView onDone={() => switchTab("chat")} />}
|
|
{tab === "mcp" && <McpView onDone={() => switchTab("chat")} />}
|
|
{tab === "prompts" && <PromptsView onDone={() => switchTab("chat")} />}
|
|
<ChatView
|
|
isHidden={tab !== "chat"}
|
|
showAnnouncement={showAnnouncement}
|
|
hideAnnouncement={() => setShowAnnouncement(false)}
|
|
showHistoryView={() => switchTab("history")}
|
|
/>
|
|
{/* Human Relay Dialog */}
|
|
<HumanRelayDialog
|
|
isOpen={humanRelayDialogState.isOpen}
|
|
requestId={humanRelayDialogState.requestId}
|
|
promptText={humanRelayDialogState.promptText}
|
|
onClose={() => setHumanRelayDialogState((prev) => ({ ...prev, isOpen: false }))}
|
|
onSubmit={handleHumanRelaySubmit}
|
|
onCancel={handleHumanRelayCancel}
|
|
/>
|
|
</>
|
|
)
|
|
}
|
|
|
|
const AppWithProviders = () => (
|
|
<ExtensionStateContextProvider>
|
|
<App />
|
|
</ExtensionStateContextProvider>
|
|
)
|
|
|
|
export default AppWithProviders
|