user_store.rs

 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                            let already_fetched_authenticated_user = this
27                                .read_with(cx, |this, _cx| this.authenticated_user().is_some())
28                                .unwrap_or(false);
29
30                            if already_fetched_authenticated_user {
31                                // We already fetched the authenticated user; nothing to do.
32                            } else {
33                                let authenticated_user_result = cloud_client
34                                    .get_authenticated_user()
35                                    .await
36                                    .context("failed to fetch authenticated user");
37                                if let Some(response) = authenticated_user_result.log_err() {
38                                    this.update(cx, |this, _cx| {
39                                        this.authenticated_user = Some(Arc::new(response.user));
40                                    })
41                                    .ok();
42                                }
43                            }
44                        } else {
45                            this.update(cx, |this, _cx| {
46                                this.authenticated_user = None;
47                            })
48                            .ok();
49                        }
50
51                        cx.background_executor()
52                            .timer(Duration::from_millis(100))
53                            .await;
54                    }
55                })
56                .await
57                .log_err();
58            }),
59        }
60    }
61
62    pub fn is_authenticated(&self) -> bool {
63        self.authenticated_user.is_some()
64    }
65
66    pub fn authenticated_user(&self) -> Option<Arc<AuthenticatedUser>> {
67        self.authenticated_user.clone()
68    }
69}