Compare commits

...

2 Commits

Author SHA1 Message Date
Elephant Lumps bc686deb1f merge conflicts 2025-06-03 23:53:18 -07:00
Elephant Lumps c13b1a9c4c migrate accountButtonClicked 2025-06-03 12:37:30 -07:00
5 changed files with 94 additions and 16 deletions
+3
View File
@@ -37,4 +37,7 @@ service UiService {
// Subscribe to chat button clicked events (when the chat button is clicked in VSCode)
rpc subscribeToChatButtonClicked(EmptyRequest) returns (stream Empty);
// Subscribe to account button click events
rpc subscribeToAccountButtonClicked(EmptyRequest) returns (stream Empty);
}
@@ -0,0 +1,55 @@
import { Controller } from "../index"
import { Empty, EmptyRequest } from "@shared/proto/common"
import { StreamingResponseHandler, getRequestRegistry } from "../grpc-handler"
// Track subscriptions by controller ID
const activeSubscriptions = new Map<string, StreamingResponseHandler>()
/**
* Subscribe to account button clicked events
* @param controller The controller instance
* @param request The empty request
* @param responseStream The streaming response handler
* @param requestId The request ID for cleanup
*/
export async function subscribeToAccountButtonClicked(
controller: Controller,
request: EmptyRequest,
responseStream: StreamingResponseHandler,
requestId?: string,
): Promise<void> {
const controllerId = controller.id
// Store subscription with controller ID
activeSubscriptions.set(controllerId, responseStream)
// Register cleanup
const cleanup = () => {
activeSubscriptions.delete(controllerId)
}
if (requestId) {
getRequestRegistry().registerRequest(requestId, cleanup, { type: "account_button_subscription" }, responseStream)
}
}
/**
* Send account button clicked event to a specific controller
* @param controllerId The ID of the controller to send the event to
*/
export async function sendAccountButtonClickedEvent(controllerId: string): Promise<void> {
const responseStream = activeSubscriptions.get(controllerId)
if (!responseStream) {
console.log(`No active subscription for controller ${controllerId}`)
return
}
try {
const event: Empty = {}
await responseStream(event, false)
} catch (error) {
console.error(`Error sending account button clicked event to controller ${controllerId}:`, error)
activeSubscriptions.delete(controllerId)
}
}
+15 -12
View File
@@ -20,6 +20,7 @@ import { v4 as uuidv4 } from "uuid"
import { WebviewProviderType as WebviewProviderTypeEnum } from "@shared/proto/ui"
import { WebviewProviderType } from "./shared/webview/types"
import { sendHistoryButtonClickedEvent } from "./core/controller/ui/subscribeToHistoryButtonClicked"
import { sendAccountButtonClickedEvent } from "./core/controller/ui/subscribeToAccountButtonClicked"
/*
Built using https://github.com/microsoft/vscode-webview-ui-toolkit
@@ -199,20 +200,22 @@ export async function activate(context: vscode.ExtensionContext) {
context.subscriptions.push(
vscode.commands.registerCommand("cline.accountButtonClicked", (webview: any) => {
WebviewProvider.getAllInstances().forEach((instance) => {
const openAccount = async (instance?: WebviewProvider) => {
instance?.controller.postMessageToWebview({
type: "action",
action: "accountButtonClicked",
})
console.log("[DEBUG] accountButtonClicked", webview)
const isSidebar = !webview
if (isSidebar) {
const sidebarInstance = WebviewProvider.getSidebarInstance()
if (sidebarInstance) {
// Send event to sidebar controller
sendAccountButtonClickedEvent(sidebarInstance.controller.id)
}
const isSidebar = !webview
if (isSidebar) {
openAccount(WebviewProvider.getSidebarInstance())
} else {
WebviewProvider.getTabInstances().forEach(openAccount)
} else {
// Send to all tab instances
const tabInstances = WebviewProvider.getTabInstances()
for (const instance of tabInstances) {
sendAccountButtonClickedEvent(instance.controller.id)
}
})
}
}),
)
+1 -1
View File
@@ -38,7 +38,7 @@ export interface ExtensionMessage {
| "fileSearchResults"
| "grpc_response" // New type for gRPC responses
text?: string
action?: "settingsButtonClicked" | "didBecomeVisible" | "accountLogoutClicked" | "accountButtonClicked" | "focusChatInput"
action?: "settingsButtonClicked" | "didBecomeVisible" | "accountLogoutClicked" | "focusChatInput"
state?: ExtensionState
images?: string[]
files?: string[]
@@ -196,9 +196,6 @@ export const ExtensionStateContextProvider: React.FC<{
case "settingsButtonClicked":
navigateToSettings()
break
case "accountButtonClicked":
navigateToAccount()
break
}
break
}
@@ -268,6 +265,7 @@ export const ExtensionStateContextProvider: React.FC<{
const mcpButtonUnsubscribeRef = useRef<(() => void) | null>(null)
const historyButtonClickedSubscriptionRef = useRef<(() => void) | null>(null)
const chatButtonUnsubscribeRef = useRef<(() => void) | null>(null)
const accountButtonClickedSubscriptionRef = useRef<(() => void) | null>(null)
// Subscribe to state updates and UI events using the gRPC streaming API
useEffect(() => {
@@ -400,6 +398,21 @@ export const ExtensionStateContextProvider: React.FC<{
// Still send the webviewDidLaunch message for other initialization
vscode.postMessage({ type: "webviewDidLaunch" })
// Set up account button clicked subscription
accountButtonClickedSubscriptionRef.current = UiServiceClient.subscribeToAccountButtonClicked(EmptyRequest.create(), {
onResponse: () => {
// When account button is clicked, navigate to account view
console.log("[DEBUG] Received account button clicked event from gRPC stream")
navigateToAccount()
},
onError: (error) => {
console.error("Error in account button clicked subscription:", error)
},
onComplete: () => {
console.log("Account button clicked subscription completed")
},
})
// Clean up subscriptions when component unmounts
return () => {
if (stateSubscriptionRef.current) {
@@ -418,6 +431,10 @@ export const ExtensionStateContextProvider: React.FC<{
chatButtonUnsubscribeRef.current()
chatButtonUnsubscribeRef.current = null
}
if (accountButtonClickedSubscriptionRef.current) {
accountButtonClickedSubscriptionRef.current()
accountButtonClickedSubscriptionRef.current = null
}
}
}, [])