@@ -8,42 +8,85 @@ import { Remote } from "./remote"
88import  {  Storage  }  from  "./storage" 
99import  {  OpenableTreeItem  }  from  "./workspacesProvider" 
1010
11- // maybeAskUrl asks the user for the URL if it was not provided and normalizes 
12- // the returned URL. 
13- export  async  function  maybeAskUrl ( 
14-   providedUrl : string  |  undefined  |  null , 
15-   lastUsedUrl ?: string , 
16- ) : Promise < string  |  undefined >  { 
17-   let  url  = 
18-     providedUrl  || 
19-     ( await  vscode . window . showInputBox ( { 
20-       title : "Coder URL" , 
21-       prompt : "Enter the URL of your Coder deployment." , 
22-       placeHolder : "https://example.coder.com" , 
23-       value : lastUsedUrl , 
24-     } ) ) 
25-   if  ( ! url )  { 
26-     return  undefined 
27-   } 
28-   if  ( ! url . startsWith ( "http://" )  &&  ! url . startsWith ( "https://" ) )  { 
29-     // Default to HTTPS if not provided! 
30-     // https://github.com/coder/vscode-coder/issues/44 
31-     url  =  "https://"  +  url 
32-   } 
33-   while  ( url . endsWith ( "/" ) )  { 
34-     url  =  url . substring ( 0 ,  url . length  -  1 ) 
35-   } 
36-   return  url 
37- } 
38- 
3911export  class  Commands  { 
4012  public  constructor ( 
4113    private  readonly  vscodeProposed : typeof  vscode , 
4214    private  readonly  storage : Storage , 
4315  )  { } 
4416
17+   /** 
18+    * Ask the user for the URL, letting them choose from a list of recent URLs or 
19+    * CODER_URL or enter a new one.  Undefined means the user aborted. 
20+    */ 
21+   private  askURL ( selection ?: string ) : Promise < string  |  undefined >  { 
22+     const  quickPick  =  vscode . window . createQuickPick ( ) 
23+     quickPick . value  =  selection  ||  process . env . CODER_URL  ||  "" 
24+     quickPick . placeholder  =  "https://example.coder.com" , 
25+     quickPick . title  =  "Enter the URL of your Coder deployment." , 
26+ 
27+     // Initial items. 
28+     quickPick . items  =  this . storage . withUrlHistory ( process . env . CODER_URL ) 
29+       . map ( ( url )  =>  ( { 
30+         alwaysShow : true , 
31+         label : url 
32+       } ) ) 
33+ 
34+     // Quick picks do not allow arbitrary values, so we add the value itself as 
35+     // an option in case the user wants to connect to something that is not in 
36+     // the list. 
37+     quickPick . onDidChangeValue ( ( value )  =>  { 
38+       quickPick . items  =  this . storage . withUrlHistory ( process . env . CODER_URL ,  value ) 
39+         . map ( ( url )  =>  ( { 
40+           alwaysShow : true , 
41+           label : url , 
42+         } ) ) 
43+     } ) 
44+ 
45+     quickPick . show ( ) 
46+ 
47+     return  new  Promise < string  |  undefined > ( ( resolve )  =>  { 
48+       quickPick . onDidHide ( ( )  =>  resolve ( undefined ) ) 
49+       quickPick . onDidChangeSelection ( ( selected )  =>  resolve ( selected [ 0 ] ?. label ) ) 
50+     } ) 
51+   } 
52+ 
53+   /** 
54+    * Ask the user for the URL if it was not provided, letting them choose from a 
55+    * list of recent URLs or CODER_URL or enter a new one, and normalizes the 
56+    * returned URL.  Undefined means the user aborted. 
57+    */ 
58+   public  async  maybeAskUrl ( 
59+     providedUrl : string  |  undefined  |  null , 
60+     lastUsedUrl ?: string , 
61+   ) : Promise < string  |  undefined >  { 
62+     let  url  =  providedUrl  ||  await  askURL ( lastUsedUrl ) 
63+     if  ( ! url )  {  // User aborted. 
64+       return  undefined 
65+     } 
66+ 
67+     // Normalize URL. 
68+     if  ( ! url . startsWith ( "http://" )  &&  ! url . startsWith ( "https://" ) )  { 
69+       // Default to HTTPS if not provided! 
70+       // https://github.com/coder/vscode-coder/issues/44 
71+       url  =  "https://"  +  url 
72+     } 
73+     while  ( url . endsWith ( "/" ) )  { 
74+       url  =  url . substring ( 0 ,  url . length  -  1 ) 
75+     } 
76+     return  url 
77+   } 
78+ 
79+   /** 
80+    * Log into the provided deployment.  If the deployment URL is not specified, 
81+    * ask for it first with a menu showing recent URLs and CODER_URL, if set. 
82+    */ 
4583  public  async  login ( ...args : string [ ] ) : Promise < void >  { 
46-     const  url  =  await  maybeAskUrl ( args [ 0 ] ) 
84+     const  url  =  await  this . maybeAskUrl ( args [ 0 ] ) 
85+     if  ( ! url )  { 
86+       vscode . window . showWarningMessage ( "Aborting login because no URL was provided." ) 
87+       return 
88+     } 
89+ 
4790    let  token : string  |  undefined  =  args . length  >=  2  ? args [ 1 ]  : undefined 
4891    if  ( ! token )  { 
4992      const  opened  =  await  vscode . env . openExternal ( vscode . Uri . parse ( `${ url }  ) ) 
@@ -91,6 +134,7 @@ export class Commands {
91134      } ) 
92135    } 
93136    if  ( ! token )  { 
137+       vscode . window . showWarningMessage ( "Aborting login because no token was provided." ) 
94138      return 
95139    } 
96140
0 commit comments