@@ -2,6 +2,7 @@ mod dev_servers;
2
2
pub mod disconnected_overlay;
3
3
mod ssh_connections;
4
4
mod ssh_remotes;
5
+ use remote:: SshConnectionOptions ;
5
6
pub use ssh_connections:: open_ssh_project;
6
7
7
8
use client:: { DevServerProjectId , ProjectId } ;
@@ -32,8 +33,8 @@ use ui::{
32
33
} ;
33
34
use util:: { paths:: PathExt , ResultExt } ;
34
35
use workspace:: {
35
- AppState , CloseIntent , ModalView , SerializedWorkspaceLocation , Workspace , WorkspaceId ,
36
- WORKSPACE_DB ,
36
+ AppState , CloseIntent , ModalView , OpenOptions , SerializedWorkspaceLocation , Workspace ,
37
+ WorkspaceId , WORKSPACE_DB ,
37
38
} ;
38
39
39
40
#[ derive( PartialEq , Clone , Deserialize , Default ) ]
@@ -172,7 +173,7 @@ pub struct RecentProjectsDelegate {
172
173
create_new_window : bool ,
173
174
// Flag to reset index when there is a new query vs not reset index when user delete an item
174
175
reset_selected_match_index : bool ,
175
- has_any_dev_server_projects : bool ,
176
+ has_any_non_local_projects : bool ,
176
177
}
177
178
178
179
impl RecentProjectsDelegate {
@@ -185,16 +186,16 @@ impl RecentProjectsDelegate {
185
186
create_new_window,
186
187
render_paths,
187
188
reset_selected_match_index : true ,
188
- has_any_dev_server_projects : false ,
189
+ has_any_non_local_projects : false ,
189
190
}
190
191
}
191
192
192
193
pub fn set_workspaces ( & mut self , workspaces : Vec < ( WorkspaceId , SerializedWorkspaceLocation ) > ) {
193
194
self . workspaces = workspaces;
194
- self . has_any_dev_server_projects = self
195
+ self . has_any_non_local_projects = ! self
195
196
. workspaces
196
197
. iter ( )
197
- . any ( |( _, location) | matches ! ( location, SerializedWorkspaceLocation :: DevServer ( _) ) ) ;
198
+ . all ( |( _, location) | matches ! ( location, SerializedWorkspaceLocation :: Local ( _ , _) ) ) ;
198
199
}
199
200
}
200
201
impl EventEmitter < DismissEvent > for RecentProjectsDelegate { }
@@ -258,6 +259,23 @@ impl PickerDelegate for RecentProjectsDelegate {
258
259
dev_server_project. paths. join( "" )
259
260
)
260
261
}
262
+ SerializedWorkspaceLocation :: Ssh ( ssh_project) => {
263
+ format ! (
264
+ "{}{}{}{}" ,
265
+ ssh_project. host,
266
+ ssh_project
267
+ . port
268
+ . as_ref( )
269
+ . map( |port| port. to_string( ) )
270
+ . unwrap_or_default( ) ,
271
+ ssh_project. path,
272
+ ssh_project
273
+ . user
274
+ . as_ref( )
275
+ . map( |user| user. to_string( ) )
276
+ . unwrap_or_default( )
277
+ )
278
+ }
261
279
} ;
262
280
263
281
StringMatchCandidate :: new ( id, combined_string)
@@ -364,6 +382,33 @@ impl PickerDelegate for RecentProjectsDelegate {
364
382
} ;
365
383
open_dev_server_project ( replace_current_window, dev_server_project. id , project_id, cx)
366
384
}
385
+ SerializedWorkspaceLocation :: Ssh ( ssh_project) => {
386
+ let app_state = workspace. app_state ( ) . clone ( ) ;
387
+
388
+ let replace_window = if replace_current_window {
389
+ cx. window_handle ( ) . downcast :: < Workspace > ( )
390
+ } else {
391
+ None
392
+ } ;
393
+
394
+ let open_options = OpenOptions {
395
+ replace_window,
396
+ ..Default :: default ( )
397
+ } ;
398
+
399
+ let connection_options = SshConnectionOptions {
400
+ host : ssh_project. host . clone ( ) ,
401
+ username : ssh_project. user . clone ( ) ,
402
+ port : ssh_project. port ,
403
+ password : None ,
404
+ } ;
405
+
406
+ let paths = vec ! [ PathBuf :: from( ssh_project. path. clone( ) ) ] ;
407
+
408
+ cx. spawn ( |_, mut cx| async move {
409
+ open_ssh_project ( connection_options, paths, app_state, open_options, & mut cx) . await
410
+ } )
411
+ }
367
412
}
368
413
}
369
414
} )
@@ -392,7 +437,6 @@ impl PickerDelegate for RecentProjectsDelegate {
392
437
393
438
let ( _, location) = self . workspaces . get ( hit. candidate_id ) ?;
394
439
395
- let is_remote = matches ! ( location, SerializedWorkspaceLocation :: DevServer ( _) ) ;
396
440
let dev_server_status =
397
441
if let SerializedWorkspaceLocation :: DevServer ( dev_server_project) = location {
398
442
let store = dev_server_projects:: Store :: global ( cx) . read ( cx) ;
@@ -416,6 +460,9 @@ impl PickerDelegate for RecentProjectsDelegate {
416
460
. filter_map ( |i| paths. paths ( ) . get ( * i) . cloned ( ) )
417
461
. collect ( ) ,
418
462
) ,
463
+ SerializedWorkspaceLocation :: Ssh ( ssh_project) => {
464
+ Arc :: new ( vec ! [ PathBuf :: from( ssh_project. ssh_url( ) ) ] )
465
+ }
419
466
SerializedWorkspaceLocation :: DevServer ( dev_server_project) => {
420
467
Arc :: new ( vec ! [ PathBuf :: from( format!(
421
468
"{}:{}" ,
@@ -457,29 +504,34 @@ impl PickerDelegate for RecentProjectsDelegate {
457
504
h_flex ( )
458
505
. flex_grow ( )
459
506
. gap_3 ( )
460
- . when ( self . has_any_dev_server_projects , |this| {
461
- this. child ( if is_remote {
462
- // if disabled, Color::Disabled
463
- let indicator_color = match dev_server_status {
464
- Some ( DevServerStatus :: Online ) => Color :: Created ,
465
- Some ( DevServerStatus :: Offline ) => Color :: Hidden ,
466
- _ => unreachable ! ( ) ,
467
- } ;
468
- IconWithIndicator :: new (
469
- Icon :: new ( IconName :: Server ) . color ( Color :: Muted ) ,
470
- Some ( Indicator :: dot ( ) ) ,
471
- )
472
- . indicator_color ( indicator_color)
473
- . indicator_border_color ( if selected {
474
- Some ( cx. theme ( ) . colors ( ) . element_selected )
475
- } else {
476
- None
477
- } )
478
- . into_any_element ( )
479
- } else {
480
- Icon :: new ( IconName :: Screen )
507
+ . when ( self . has_any_non_local_projects , |this| {
508
+ this. child ( match location {
509
+ SerializedWorkspaceLocation :: Local ( _, _) => {
510
+ Icon :: new ( IconName :: Screen )
511
+ . color ( Color :: Muted )
512
+ . into_any_element ( )
513
+ }
514
+ SerializedWorkspaceLocation :: Ssh ( _) => Icon :: new ( IconName :: Screen )
481
515
. color ( Color :: Muted )
516
+ . into_any_element ( ) ,
517
+ SerializedWorkspaceLocation :: DevServer ( _) => {
518
+ let indicator_color = match dev_server_status {
519
+ Some ( DevServerStatus :: Online ) => Color :: Created ,
520
+ Some ( DevServerStatus :: Offline ) => Color :: Hidden ,
521
+ _ => unreachable ! ( ) ,
522
+ } ;
523
+ IconWithIndicator :: new (
524
+ Icon :: new ( IconName :: Server ) . color ( Color :: Muted ) ,
525
+ Some ( Indicator :: dot ( ) ) ,
526
+ )
527
+ . indicator_color ( indicator_color)
528
+ . indicator_border_color ( if selected {
529
+ Some ( cx. theme ( ) . colors ( ) . element_selected )
530
+ } else {
531
+ None
532
+ } )
482
533
. into_any_element ( )
534
+ }
483
535
} )
484
536
} )
485
537
. child ( {
0 commit comments