From 7e3a770a4ccf0bff5e0d82b45cd5d4cb41aa389c Mon Sep 17 00:00:00 2001 From: pashpashpash Date: Tue, 21 Jan 2025 19:39:40 -0800 Subject: [PATCH] Add account button to top nav bar --- package.json | 10 ++++++++++ src/core/webview/ClineProvider.ts | 20 +++++++++++++++++++ src/extension.ts | 16 +++++++++++++++ src/shared/ExtensionMessage.ts | 3 ++- src/shared/WebviewMessage.ts | 1 + .../src/context/ExtensionStateContext.tsx | 1 + 6 files changed, 50 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 915ffd67f..285f1693a 100644 --- a/package.json +++ b/package.json @@ -90,6 +90,11 @@ "title": "Settings", "icon": "$(settings-gear)" }, + { + "command": "cline.accountButtonClicked", + "title": "Account", + "icon": "$(account)" + }, { "command": "cline.openInNewTab", "title": "Open In New Tab", @@ -122,6 +127,11 @@ "command": "cline.settingsButtonClicked", "group": "navigation@5", "when": "view == claude-dev.SidebarProvider" + }, + { + "command": "cline.accountButtonClicked", + "group": "navigation@6", + "when": "view == claude-dev.SidebarProvider" } ] }, diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 81072c43b..1b427a82f 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -43,6 +43,7 @@ type SecretKey = | "openAiNativeApiKey" | "deepSeekApiKey" | "mistralApiKey" + | "authToken" type GlobalStateKey = | "apiProvider" | "apiModelId" @@ -594,6 +595,12 @@ export class ClineProvider implements vscode.WebviewViewProvider { case "getLatestState": await this.postStateToWebview() break + case "accountButtonClicked": + // Open browser for authentication + console.log("Account button clicked in top nav bar") + console.log("Opening auth page: https://cline.bot/auth") + vscode.env.openExternal(vscode.Uri.parse('https://cline.bot/auth')) + break case "openMcpSettings": { const mcpSettingsFilePath = await this.mcpHub?.getMcpSettingsFilePath() if (mcpSettingsFilePath) { @@ -740,6 +747,15 @@ export class ClineProvider implements vscode.WebviewViewProvider { } } + // Auth + + async handleAuthCallback(token: string) { + // Store the auth token securely + await this.storeSecret("authToken", token) + await this.postStateToWebview() + vscode.window.showInformationMessage("Successfully logged in to Cline") + } + // OpenRouter async handleOpenRouterCallback(code: string) { @@ -1014,6 +1030,8 @@ export class ClineProvider implements vscode.WebviewViewProvider { browserSettings, chatSettings, } = await this.getState() + + const authToken = await this.getSecret("authToken") return { version: this.context.extension?.packageJSON?.version ?? "", apiConfiguration, @@ -1027,6 +1045,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { autoApprovalSettings, browserSettings, chatSettings, + isLoggedIn: !!authToken, } } @@ -1279,6 +1298,7 @@ export class ClineProvider implements vscode.WebviewViewProvider { "openAiNativeApiKey", "deepSeekApiKey", "mistralApiKey", + "authToken", ] for (const key of secretKeys) { await this.storeSecret(key, undefined) diff --git a/src/extension.ts b/src/extension.ts index 35dda8b58..bed47c85f 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -110,6 +110,15 @@ export function activate(context: vscode.ExtensionContext) { }), ) + context.subscriptions.push( + vscode.commands.registerCommand("cline.accountButtonClicked", () => { + sidebarProvider.postMessageToWebview({ + type: "action", + action: "accountButtonClicked", + }) + }), + ) + /* We use the text document content provider API to show the left side for diff view by creating a virtual document for the original content. This makes it readonly so users know to edit the right side if they want to keep their changes. @@ -140,6 +149,13 @@ export function activate(context: vscode.ExtensionContext) { } break } + case "/auth": { + const token = query.get("token") + if (token) { + await visibleProvider.handleAuthCallback(token) + } + break + } default: break } diff --git a/src/shared/ExtensionMessage.ts b/src/shared/ExtensionMessage.ts index ce6502774..0f82186cc 100644 --- a/src/shared/ExtensionMessage.ts +++ b/src/shared/ExtensionMessage.ts @@ -25,7 +25,7 @@ export interface ExtensionMessage { | "vsCodeLmModels" | "requestVsCodeLmModels" text?: string - action?: "chatButtonClicked" | "mcpButtonClicked" | "settingsButtonClicked" | "historyButtonClicked" | "didBecomeVisible" + action?: "chatButtonClicked" | "mcpButtonClicked" | "settingsButtonClicked" | "historyButtonClicked" | "didBecomeVisible" | "accountButtonClicked" invoke?: "sendMessage" | "primaryButtonClick" | "secondaryButtonClick" state?: ExtensionState images?: string[] @@ -51,6 +51,7 @@ export interface ExtensionState { autoApprovalSettings: AutoApprovalSettings browserSettings: BrowserSettings chatSettings: ChatSettings + isLoggedIn: boolean } export interface ClineMessage { diff --git a/src/shared/WebviewMessage.ts b/src/shared/WebviewMessage.ts index 6783bc0d7..706c87832 100644 --- a/src/shared/WebviewMessage.ts +++ b/src/shared/WebviewMessage.ts @@ -37,6 +37,7 @@ export interface WebviewMessage { | "toggleToolAutoApprove" | "toggleMcpServer" | "getLatestState" + | "accountButtonClicked" // | "relaunchChromeDebugMode" text?: string disabled?: boolean diff --git a/webview-ui/src/context/ExtensionStateContext.tsx b/webview-ui/src/context/ExtensionStateContext.tsx index 75db746f0..d6211e3a7 100644 --- a/webview-ui/src/context/ExtensionStateContext.tsx +++ b/webview-ui/src/context/ExtensionStateContext.tsx @@ -35,6 +35,7 @@ export const ExtensionStateContextProvider: React.FC<{ autoApprovalSettings: DEFAULT_AUTO_APPROVAL_SETTINGS, browserSettings: DEFAULT_BROWSER_SETTINGS, chatSettings: DEFAULT_CHAT_SETTINGS, + isLoggedIn: false, }) const [didHydrateState, setDidHydrateState] = useState(false) const [showWelcome, setShowWelcome] = useState(false)