@@ -2,6 +2,7 @@ mod dev_servers;
22pub mod disconnected_overlay;
33mod ssh_connections;
44mod ssh_remotes;
5+ use remote:: SshConnectionOptions ;
56pub use ssh_connections:: open_ssh_project;
67
78use client:: { DevServerProjectId , ProjectId } ;
@@ -32,8 +33,8 @@ use ui::{
3233} ;
3334use util:: { paths:: PathExt , ResultExt } ;
3435use workspace:: {
35- AppState , CloseIntent , ModalView , SerializedWorkspaceLocation , Workspace , WorkspaceId ,
36- WORKSPACE_DB ,
36+ AppState , CloseIntent , ModalView , OpenOptions , SerializedWorkspaceLocation , Workspace ,
37+ WorkspaceId , WORKSPACE_DB ,
3738} ;
3839
3940#[ derive( PartialEq , Clone , Deserialize , Default ) ]
@@ -172,7 +173,7 @@ pub struct RecentProjectsDelegate {
172173 create_new_window : bool ,
173174 // Flag to reset index when there is a new query vs not reset index when user delete an item
174175 reset_selected_match_index : bool ,
175- has_any_dev_server_projects : bool ,
176+ has_any_non_local_projects : bool ,
176177}
177178
178179impl RecentProjectsDelegate {
@@ -185,16 +186,16 @@ impl RecentProjectsDelegate {
185186 create_new_window,
186187 render_paths,
187188 reset_selected_match_index : true ,
188- has_any_dev_server_projects : false ,
189+ has_any_non_local_projects : false ,
189190 }
190191 }
191192
192193 pub fn set_workspaces ( & mut self , workspaces : Vec < ( WorkspaceId , SerializedWorkspaceLocation ) > ) {
193194 self . workspaces = workspaces;
194- self . has_any_dev_server_projects = self
195+ self . has_any_non_local_projects = ! self
195196 . workspaces
196197 . iter ( )
197- . any ( |( _, location) | matches ! ( location, SerializedWorkspaceLocation :: DevServer ( _) ) ) ;
198+ . all ( |( _, location) | matches ! ( location, SerializedWorkspaceLocation :: Local ( _ , _) ) ) ;
198199 }
199200}
200201impl EventEmitter < DismissEvent > for RecentProjectsDelegate { }
@@ -258,6 +259,23 @@ impl PickerDelegate for RecentProjectsDelegate {
258259 dev_server_project. paths. join( "" )
259260 )
260261 }
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+ }
261279 } ;
262280
263281 StringMatchCandidate :: new ( id, combined_string)
@@ -364,6 +382,33 @@ impl PickerDelegate for RecentProjectsDelegate {
364382 } ;
365383 open_dev_server_project ( replace_current_window, dev_server_project. id , project_id, cx)
366384 }
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+ }
367412 }
368413 }
369414 } )
@@ -392,7 +437,6 @@ impl PickerDelegate for RecentProjectsDelegate {
392437
393438 let ( _, location) = self . workspaces . get ( hit. candidate_id ) ?;
394439
395- let is_remote = matches ! ( location, SerializedWorkspaceLocation :: DevServer ( _) ) ;
396440 let dev_server_status =
397441 if let SerializedWorkspaceLocation :: DevServer ( dev_server_project) = location {
398442 let store = dev_server_projects:: Store :: global ( cx) . read ( cx) ;
@@ -416,6 +460,9 @@ impl PickerDelegate for RecentProjectsDelegate {
416460 . filter_map ( |i| paths. paths ( ) . get ( * i) . cloned ( ) )
417461 . collect ( ) ,
418462 ) ,
463+ SerializedWorkspaceLocation :: Ssh ( ssh_project) => {
464+ Arc :: new ( vec ! [ PathBuf :: from( ssh_project. ssh_url( ) ) ] )
465+ }
419466 SerializedWorkspaceLocation :: DevServer ( dev_server_project) => {
420467 Arc :: new ( vec ! [ PathBuf :: from( format!(
421468 "{}:{}" ,
@@ -457,29 +504,34 @@ impl PickerDelegate for RecentProjectsDelegate {
457504 h_flex ( )
458505 . flex_grow ( )
459506 . 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 )
481515 . 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+ } )
482533 . into_any_element ( )
534+ }
483535 } )
484536 } )
485537 . child ( {
0 commit comments