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
This commit is contained in:
Marshall Bowers
2025-08-28 18:15:08 +00:00
committed by GitHub
parent 29fc324a78
commit 4469b14512
4 changed files with 35 additions and 6 deletions
+29 -3
View File
@@ -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<Credentials> {
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(()));
+3 -1
View File
@@ -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()
+1 -1
View File
@@ -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)
+2 -1
View File
@@ -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());