@@ -7,35 +7,56 @@ use gpui::{Context, Task};
use util::{ResultExt as _, maybe};
pub struct CloudUserStore {
- authenticated_user: Option<AuthenticatedUser>,
- _fetch_authenticated_user_task: Task<()>,
+ authenticated_user: Option<Arc<AuthenticatedUser>>,
+ _maintain_authenticated_user_task: Task<()>,
}
impl CloudUserStore {
pub fn new(cloud_client: Arc<CloudApiClient>, cx: &mut Context<Self>) -> Self {
Self {
authenticated_user: None,
- _fetch_authenticated_user_task: cx.spawn(async move |this, cx| {
+ _maintain_authenticated_user_task: cx.spawn(async move |this, cx| {
maybe!(async move {
loop {
+ let Some(this) = this.upgrade() else {
+ return anyhow::Ok(());
+ };
+
if cloud_client.has_credentials() {
- break;
+ if let Some(response) = cloud_client
+ .get_authenticated_user()
+ .await
+ .context("failed to fetch authenticated user")
+ .log_err()
+ {
+ this.update(cx, |this, _cx| {
+ this.authenticated_user = Some(Arc::new(response.user));
+ })
+ .ok();
+ }
+ } else {
+ this.update(cx, |this, _cx| {
+ this.authenticated_user = None;
+ })
+ .ok();
}
cx.background_executor()
.timer(Duration::from_millis(100))
.await;
}
-
- let response = cloud_client.get_authenticated_user().await?;
- this.update(cx, |this, _cx| {
- this.authenticated_user = Some(response.user);
- })
})
.await
- .context("failed to fetch authenticated user")
.log_err();
}),
}
}
+
+ pub fn is_authenticated(&self) -> bool {
+ self.authenticated_user.is_some()
+ }
+
+ pub fn authenticated_user(&self) -> Option<Arc<AuthenticatedUser>> {
+ self.authenticated_user.clone()
+ }
}
@@ -20,7 +20,7 @@ use crate::application_menu::{
use auto_update::AutoUpdateStatus;
use call::ActiveCall;
-use client::{Client, UserStore, zed_urls};
+use client::{Client, CloudUserStore, UserStore, zed_urls};
use gpui::{
Action, AnyElement, App, Context, Corner, Element, Entity, Focusable, InteractiveElement,
IntoElement, MouseButton, ParentElement, Render, StatefulInteractiveElement, Styled,
@@ -126,6 +126,7 @@ pub struct TitleBar {
platform_titlebar: Entity<PlatformTitleBar>,
project: Entity<Project>,
user_store: Entity<UserStore>,
+ cloud_user_store: Entity<CloudUserStore>,
client: Arc<Client>,
workspace: WeakEntity<Workspace>,
application_menu: Option<Entity<ApplicationMenu>>,
@@ -179,24 +180,25 @@ impl Render for TitleBar {
children.push(self.banner.clone().into_any_element())
}
+ let is_authenticated = self.cloud_user_store.read(cx).is_authenticated();
+ let status = self.client.status();
+ let status = &*status.borrow();
+
+ let show_sign_in = !is_authenticated || !matches!(status, client::Status::Connected { .. });
+
children.push(
h_flex()
.gap_1()
.pr_1()
.on_mouse_down(MouseButton::Left, |_, _, cx| cx.stop_propagation())
.children(self.render_call_controls(window, cx))
- .map(|el| {
- let status = self.client.status();
- let status = &*status.borrow();
- if matches!(status, client::Status::Connected { .. }) {
- el.child(self.render_user_menu_button(cx))
- } else {
- el.children(self.render_connection_status(status, cx))
- .when(TitleBarSettings::get_global(cx).show_sign_in, |el| {
- el.child(self.render_sign_in_button(cx))
- })
- .child(self.render_user_menu_button(cx))
- }
+ .children(self.render_connection_status(status, cx))
+ .when(
+ show_sign_in && TitleBarSettings::get_global(cx).show_sign_in,
+ |el| el.child(self.render_sign_in_button(cx)),
+ )
+ .when(is_authenticated, |parent| {
+ parent.child(self.render_user_menu_button(cx))
})
.into_any_element(),
);
@@ -246,6 +248,7 @@ impl TitleBar {
) -> Self {
let project = workspace.project().clone();
let user_store = workspace.app_state().user_store.clone();
+ let cloud_user_store = workspace.app_state().cloud_user_store.clone();
let client = workspace.app_state().client.clone();
let active_call = ActiveCall::global(cx);
@@ -293,6 +296,7 @@ impl TitleBar {
workspace: workspace.weak_handle(),
project,
user_store,
+ cloud_user_store,
client,
_subscriptions: subscriptions,
banner,
@@ -628,15 +632,15 @@ impl TitleBar {
}
pub fn render_user_menu_button(&mut self, cx: &mut Context<Self>) -> impl Element {
- let user_store = self.user_store.read(cx);
- if let Some(user) = user_store.current_user() {
+ let cloud_user_store = self.cloud_user_store.read(cx);
+ if let Some(user) = cloud_user_store.authenticated_user() {
let has_subscription_period = self.user_store.read(cx).subscription_period().is_some();
let plan = self.user_store.read(cx).current_plan().filter(|_| {
// Since the user might be on the legacy free plan we filter based on whether we have a subscription period.
has_subscription_period
});
- let user_avatar = user.avatar_uri.clone();
+ let user_avatar = user.avatar_url.clone();
let free_chip_bg = cx
.theme()
.colors()