From 4469b14512ec69168356b21db424da9f327066e3 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Thu, 28 Aug 2025 14:15:08 -0400 Subject: [PATCH] collab_ui: Show channel list while reconnecting (#37107) This PR makes it so the channel list will still be shown while reconnecting to Collab instead of showing the signed-out state. In order to model the transitional states that occur while reconnecting, we needed to introduce a new `Status::Reauthenticated` state that we go through when signing in as part of a reconnect. This is because we cannot tell from `Status::Authenticated` alone if we're authenticating for the first time or reauthenticating. Release Notes: - N/A --- crates/client/src/client.rs | 32 +++++++++++++++++++++++++--- crates/client/src/user.rs | 4 +++- crates/collab_ui/src/collab_panel.rs | 2 +- crates/workspace/src/workspace.rs | 3 ++- 4 files changed, 35 insertions(+), 6 deletions(-) diff --git a/crates/client/src/client.rs b/crates/client/src/client.rs index 2bbe7dd1b5a838c1f4e3bace2d91c396692983f4..bdbf049b75ef1e0de351c65be7382a94d73448e6 100644 --- a/crates/client/src/client.rs +++ b/crates/client/src/client.rs @@ -287,6 +287,7 @@ pub enum Status { }, ConnectionLost, Reauthenticating, + Reauthenticated, Reconnecting, ReconnectionError { next_reconnection: Instant, @@ -298,6 +299,21 @@ impl Status { matches!(self, Self::Connected { .. }) } + pub fn was_connected(&self) -> bool { + matches!( + self, + Self::ConnectionLost + | Self::Reauthenticating + | Self::Reauthenticated + | Self::Reconnecting + ) + } + + /// Returns whether the client is currently connected or was connected at some point. + pub fn is_or_was_connected(&self) -> bool { + self.is_connected() || self.was_connected() + } + pub fn is_signing_in(&self) -> bool { matches!( self, @@ -857,11 +873,13 @@ impl Client { try_provider: bool, cx: &AsyncApp, ) -> Result { - if self.status().borrow().is_signed_out() { + let is_reauthenticating = if self.status().borrow().is_signed_out() { self.set_status(Status::Authenticating, cx); + false } else { self.set_status(Status::Reauthenticating, cx); - } + true + }; let mut credentials = None; @@ -919,7 +937,14 @@ impl Client { self.cloud_client .set_credentials(credentials.user_id as u32, credentials.access_token.clone()); self.state.write().credentials = Some(credentials.clone()); - self.set_status(Status::Authenticated, cx); + self.set_status( + if is_reauthenticating { + Status::Reauthenticated + } else { + Status::Authenticated + }, + cx, + ); Ok(credentials) } @@ -1034,6 +1059,7 @@ impl Client { | Status::Authenticating | Status::AuthenticationError | Status::Reauthenticating + | Status::Reauthenticated | Status::ReconnectionError { .. } => false, Status::Connected { .. } | Status::Connecting | Status::Reconnecting => { return ConnectionResult::Result(Ok(())); diff --git a/crates/client/src/user.rs b/crates/client/src/user.rs index d23eb37519c00c2567683e5417aa2d82f10a2f58..a4c66e582c34e468432747d580e13c86b3ec33c8 100644 --- a/crates/client/src/user.rs +++ b/crates/client/src/user.rs @@ -216,7 +216,9 @@ impl UserStore { return Ok(()); }; match status { - Status::Authenticated | Status::Connected { .. } => { + Status::Authenticated + | Status::Reauthenticated + | Status::Connected { .. } => { if let Some(user_id) = client.user_id() { let response = client .cloud_client() diff --git a/crates/collab_ui/src/collab_panel.rs b/crates/collab_ui/src/collab_panel.rs index d85a6610a5b2fadde46f27be2602f62c6b8b7d62..90096542942e18ff9a0355d6319e5dcf590a870c 100644 --- a/crates/collab_ui/src/collab_panel.rs +++ b/crates/collab_ui/src/collab_panel.rs @@ -3047,7 +3047,7 @@ impl Render for CollabPanel { .on_action(cx.listener(CollabPanel::move_channel_down)) .track_focus(&self.focus_handle) .size_full() - .child(if !self.client.status().borrow().is_connected() { + .child(if !self.client.status().borrow().is_or_was_connected() { self.render_signed_out(cx) } else { self.render_signed_in(window, cx) diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 1fee2793f0c50efee9f2fd8040d3bcf8df2af08a..76693e716e3cafe31e60eeecfcaeeb5bb267fb77 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -6890,7 +6890,8 @@ async fn join_channel_internal( | Status::Authenticating | Status::Authenticated | Status::Reconnecting - | Status::Reauthenticating => continue, + | Status::Reauthenticating + | Status::Reauthenticated => continue, Status::Connected { .. } => break 'outer, Status::SignedOut | Status::AuthenticationError => { return Err(ErrorCode::SignedOut.into());