1use std::sync::Arc;
2use std::time::Duration;
3
4use anyhow::Context as _;
5use cloud_api_client::{AuthenticatedUser, CloudApiClient};
6use gpui::{Context, Task};
7use util::{ResultExt as _, maybe};
8
9pub struct CloudUserStore {
10 authenticated_user: Option<Arc<AuthenticatedUser>>,
11 _maintain_authenticated_user_task: Task<()>,
12}
13
14impl CloudUserStore {
15 pub fn new(cloud_client: Arc<CloudApiClient>, cx: &mut Context<Self>) -> Self {
16 Self {
17 authenticated_user: None,
18 _maintain_authenticated_user_task: cx.spawn(async move |this, cx| {
19 maybe!(async move {
20 loop {
21 let Some(this) = this.upgrade() else {
22 return anyhow::Ok(());
23 };
24
25 if cloud_client.has_credentials() {
26 if let Some(response) = cloud_client
27 .get_authenticated_user()
28 .await
29 .context("failed to fetch authenticated user")
30 .log_err()
31 {
32 this.update(cx, |this, _cx| {
33 this.authenticated_user = Some(Arc::new(response.user));
34 })
35 .ok();
36 }
37 } else {
38 this.update(cx, |this, _cx| {
39 this.authenticated_user = None;
40 })
41 .ok();
42 }
43
44 cx.background_executor()
45 .timer(Duration::from_millis(100))
46 .await;
47 }
48 })
49 .await
50 .log_err();
51 }),
52 }
53 }
54
55 pub fn is_authenticated(&self) -> bool {
56 self.authenticated_user.is_some()
57 }
58
59 pub fn authenticated_user(&self) -> Option<Arc<AuthenticatedUser>> {
60 self.authenticated_user.clone()
61 }
62}