1
+ import React , { FC , PropsWithChildren , useState , useEffect } from "react"
1
2
import { getApiKey } from "api/api"
2
3
import { VSCodeIcon } from "components/Icons/VSCodeIcon"
3
- import { FC , PropsWithChildren , useState } from "react "
4
+ import { VSCodeInsidersIcon } from "components/Icons/VSCodeInsidersIcon "
4
5
import { PrimaryAgentButton } from "components/Resources/AgentButton"
5
6
6
7
export interface VSCodeDesktopButtonProps {
@@ -10,43 +11,118 @@ export interface VSCodeDesktopButtonProps {
10
11
folderPath ?: string
11
12
}
12
13
14
+ enum VSCodeVariant {
15
+ VSCode = "VSCode" ,
16
+ VSCodeInsiders = "VSCode Insiders" ,
17
+ }
18
+
19
+ const getSelectedVariantFromLocalStorage = ( ) : VSCodeVariant | null => {
20
+ const storedVariant = localStorage . getItem ( "selectedVariant" )
21
+ if (
22
+ storedVariant &&
23
+ Object . values ( VSCodeVariant ) . includes ( storedVariant as VSCodeVariant )
24
+ ) {
25
+ return storedVariant as VSCodeVariant
26
+ }
27
+ return null
28
+ }
29
+
13
30
export const VSCodeDesktopButton : FC <
14
31
PropsWithChildren < VSCodeDesktopButtonProps >
15
32
> = ( { userName, workspaceName, agentName, folderPath } ) => {
16
33
const [ loading , setLoading ] = useState ( false )
34
+ const [ selectedVariant , setSelectedVariant ] = useState < VSCodeVariant | null > (
35
+ getSelectedVariantFromLocalStorage ( ) ,
36
+ )
37
+ const [ dropdownOpen , setDropdownOpen ] = useState ( false )
38
+
39
+ useEffect ( ( ) => {
40
+ if ( selectedVariant ) {
41
+ localStorage . setItem ( "selectedVariant" , selectedVariant )
42
+ } else {
43
+ localStorage . removeItem ( "selectedVariant" )
44
+ }
45
+ } , [ selectedVariant ] )
46
+
47
+ const handleButtonClick = ( ) => {
48
+ setLoading ( true )
49
+ getApiKey ( )
50
+ . then ( ( { key } ) => {
51
+ const query = new URLSearchParams ( {
52
+ owner : userName ,
53
+ workspace : workspaceName ,
54
+ url : location . origin ,
55
+ token : key ,
56
+ } )
57
+ if ( agentName ) {
58
+ query . set ( "agent" , agentName )
59
+ }
60
+ if ( folderPath ) {
61
+ query . set ( "folder" , folderPath )
62
+ }
63
+
64
+ const vscodeCommand =
65
+ selectedVariant === VSCodeVariant . VSCode
66
+ ? "vscode://"
67
+ : "vscode-insiders://"
68
+
69
+ location . href = `${ vscodeCommand } coder.coder-remote/open?${ query . toString ( ) } `
70
+ } )
71
+ . catch ( ( ex ) => {
72
+ console . error ( ex )
73
+ } )
74
+ . finally ( ( ) => {
75
+ setLoading ( false )
76
+ } )
77
+ }
78
+
79
+ const handleVariantChange = ( variant : VSCodeVariant ) => {
80
+ setSelectedVariant ( variant )
81
+ setDropdownOpen ( false )
82
+ }
17
83
18
84
return (
19
- < PrimaryAgentButton
20
- startIcon = { < VSCodeIcon /> }
21
- disabled = { loading }
22
- onClick = { ( ) => {
23
- setLoading ( true )
24
- getApiKey ( )
25
- . then ( ( { key } ) => {
26
- const query = new URLSearchParams ( {
27
- owner : userName ,
28
- workspace : workspaceName ,
29
- url : location . origin ,
30
- token : key ,
31
- } )
32
- if ( agentName ) {
33
- query . set ( "agent" , agentName )
34
- }
35
- if ( folderPath ) {
36
- query . set ( "folder" , folderPath )
37
- }
38
-
39
- location . href = `vscode://coder.coder-remote/open?${ query . toString ( ) } `
40
- } )
41
- . catch ( ( ex ) => {
42
- console . error ( ex )
43
- } )
44
- . finally ( ( ) => {
45
- setLoading ( false )
46
- } )
47
- } }
48
- >
49
- VS Code Desktop
50
- </ PrimaryAgentButton >
85
+ < div >
86
+ < div style = { { position : "relative" } } >
87
+ < PrimaryAgentButton
88
+ startIcon = {
89
+ selectedVariant === VSCodeVariant . VSCode ? (
90
+ < VSCodeIcon />
91
+ ) : (
92
+ < VSCodeInsidersIcon />
93
+ )
94
+ }
95
+ disabled = { loading || dropdownOpen }
96
+ onClick = { ( ) => setDropdownOpen ( ! dropdownOpen ) }
97
+ >
98
+ { selectedVariant === VSCodeVariant . VSCode
99
+ ? "VS Code Desktop"
100
+ : "VS Code Insiders" }
101
+ </ PrimaryAgentButton >
102
+ { dropdownOpen && (
103
+ < div
104
+ style = { {
105
+ position : "absolute" ,
106
+ top : "100%" ,
107
+ left : 0 ,
108
+ marginTop : "4px" ,
109
+ } }
110
+ >
111
+ < PrimaryAgentButton
112
+ onClick = { ( ) => handleVariantChange ( VSCodeVariant . VSCode ) }
113
+ startIcon = { < VSCodeIcon /> }
114
+ >
115
+ VS Code Desktop
116
+ </ PrimaryAgentButton >
117
+ < PrimaryAgentButton
118
+ onClick = { ( ) => handleVariantChange ( VSCodeVariant . VSCodeInsiders ) }
119
+ startIcon = { < VSCodeInsidersIcon /> }
120
+ >
121
+ VS Code Insiders
122
+ </ PrimaryAgentButton >
123
+ </ div >
124
+ ) }
125
+ </ div >
126
+ </ div >
51
127
)
52
128
}
0 commit comments