title_bar: Show the plan from the CloudUserStore
(#35401)
This PR updates the user menu in the title bar to show the plan from the `CloudUserStore` instead of the `UserStore`. We're still leveraging the RPC connection to listen for `UpdateUserPlan` messages so that we can get live-updates from the server, but we are merely using this as a signal to re-fetch the information from Cloud. Release Notes: - N/A
This commit is contained in:
parent
89ed0b9601
commit
558bbfffae
8 changed files with 94 additions and 19 deletions
|
@ -2,19 +2,36 @@ use std::sync::Arc;
|
|||
use std::time::Duration;
|
||||
|
||||
use anyhow::Context as _;
|
||||
use cloud_api_client::{AuthenticatedUser, CloudApiClient};
|
||||
use gpui::{Context, Task};
|
||||
use chrono::{DateTime, Utc};
|
||||
use cloud_api_client::{AuthenticatedUser, CloudApiClient, GetAuthenticatedUserResponse, PlanInfo};
|
||||
use cloud_llm_client::Plan;
|
||||
use gpui::{Context, Entity, Subscription, Task};
|
||||
use util::{ResultExt as _, maybe};
|
||||
|
||||
use crate::UserStore;
|
||||
use crate::user::Event as RpcUserStoreEvent;
|
||||
|
||||
pub struct CloudUserStore {
|
||||
cloud_client: Arc<CloudApiClient>,
|
||||
authenticated_user: Option<Arc<AuthenticatedUser>>,
|
||||
plan_info: Option<Arc<PlanInfo>>,
|
||||
_maintain_authenticated_user_task: Task<()>,
|
||||
_rpc_plan_updated_subscription: Subscription,
|
||||
}
|
||||
|
||||
impl CloudUserStore {
|
||||
pub fn new(cloud_client: Arc<CloudApiClient>, cx: &mut Context<Self>) -> Self {
|
||||
pub fn new(
|
||||
cloud_client: Arc<CloudApiClient>,
|
||||
rpc_user_store: Entity<UserStore>,
|
||||
cx: &mut Context<Self>,
|
||||
) -> Self {
|
||||
let rpc_plan_updated_subscription =
|
||||
cx.subscribe(&rpc_user_store, Self::handle_rpc_user_store_event);
|
||||
|
||||
Self {
|
||||
cloud_client: cloud_client.clone(),
|
||||
authenticated_user: None,
|
||||
plan_info: None,
|
||||
_maintain_authenticated_user_task: cx.spawn(async move |this, cx| {
|
||||
maybe!(async move {
|
||||
loop {
|
||||
|
@ -36,14 +53,15 @@ impl CloudUserStore {
|
|||
.context("failed to fetch authenticated user");
|
||||
if let Some(response) = authenticated_user_result.log_err() {
|
||||
this.update(cx, |this, _cx| {
|
||||
this.authenticated_user = Some(Arc::new(response.user));
|
||||
this.update_authenticated_user(response);
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.update(cx, |this, _cx| {
|
||||
this.authenticated_user = None;
|
||||
this.authenticated_user.take();
|
||||
this.plan_info.take();
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
|
@ -56,6 +74,7 @@ impl CloudUserStore {
|
|||
.await
|
||||
.log_err();
|
||||
}),
|
||||
_rpc_plan_updated_subscription: rpc_plan_updated_subscription,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,4 +85,56 @@ impl CloudUserStore {
|
|||
pub fn authenticated_user(&self) -> Option<Arc<AuthenticatedUser>> {
|
||||
self.authenticated_user.clone()
|
||||
}
|
||||
|
||||
pub fn plan(&self) -> Option<Plan> {
|
||||
self.plan_info.as_ref().map(|plan| plan.plan)
|
||||
}
|
||||
|
||||
pub fn subscription_period(&self) -> Option<(DateTime<Utc>, DateTime<Utc>)> {
|
||||
self.plan_info
|
||||
.as_ref()
|
||||
.and_then(|plan| plan.subscription_period)
|
||||
.map(|subscription_period| {
|
||||
(
|
||||
subscription_period.started_at.0,
|
||||
subscription_period.ended_at.0,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fn update_authenticated_user(&mut self, response: GetAuthenticatedUserResponse) {
|
||||
self.authenticated_user = Some(Arc::new(response.user));
|
||||
self.plan_info = Some(Arc::new(response.plan));
|
||||
}
|
||||
|
||||
fn handle_rpc_user_store_event(
|
||||
&mut self,
|
||||
_: Entity<UserStore>,
|
||||
event: &RpcUserStoreEvent,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
match event {
|
||||
RpcUserStoreEvent::PlanUpdated => {
|
||||
cx.spawn(async move |this, cx| {
|
||||
let cloud_client =
|
||||
cx.update(|cx| this.read_with(cx, |this, _cx| this.cloud_client.clone()))??;
|
||||
|
||||
let response = cloud_client
|
||||
.get_authenticated_user()
|
||||
.await
|
||||
.context("failed to fetch authenticated user")?;
|
||||
|
||||
cx.update(|cx| {
|
||||
this.update(cx, |this, _cx| {
|
||||
this.update_authenticated_user(response);
|
||||
})
|
||||
})??;
|
||||
|
||||
anyhow::Ok(())
|
||||
})
|
||||
.detach_and_log_err(cx);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -145,6 +145,7 @@ pub enum Event {
|
|||
ShowContacts,
|
||||
ParticipantIndicesChanged,
|
||||
PrivateUserInfoUpdated,
|
||||
PlanUpdated,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
|
@ -388,6 +389,7 @@ impl UserStore {
|
|||
.map(EditPredictionUsage);
|
||||
}
|
||||
|
||||
cx.emit(Event::PlanUpdated);
|
||||
cx.notify();
|
||||
})?;
|
||||
Ok(())
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue