inline_completion_button: Replace UserStore with CloudUserStore (#35456)

This PR replaces usages of the `UserStore` in the inline completion
button with the `CloudUserStore`.

Release Notes:

- N/A
This commit is contained in:
Marshall Bowers 2025-07-31 23:25:23 -04:00 committed by GitHub
parent 8be3f48f37
commit f7f90593ac
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 24 additions and 27 deletions

View file

@ -114,7 +114,6 @@ pub struct UserStore {
trial_started_at: Option<DateTime<Utc>>,
is_usage_based_billing_enabled: Option<bool>,
account_too_young: Option<bool>,
has_overdue_invoices: Option<bool>,
current_user: watch::Receiver<Option<Arc<User>>>,
accepted_tos_at: Option<Option<DateTime<Utc>>>,
contacts: Vec<Arc<Contact>>,
@ -190,7 +189,6 @@ impl UserStore {
trial_started_at: None,
is_usage_based_billing_enabled: None,
account_too_young: None,
has_overdue_invoices: None,
accepted_tos_at: None,
contacts: Default::default(),
incoming_contact_requests: Default::default(),
@ -358,7 +356,6 @@ impl UserStore {
.and_then(|trial_started_at| DateTime::from_timestamp(trial_started_at as i64, 0));
this.is_usage_based_billing_enabled = message.payload.is_usage_based_billing_enabled;
this.account_too_young = message.payload.account_too_young;
this.has_overdue_invoices = message.payload.has_overdue_invoices;
cx.emit(Event::PlanUpdated);
cx.notify();
@ -755,11 +752,6 @@ impl UserStore {
self.account_too_young.unwrap_or(false)
}
/// Returns whether the current user has overdue invoices and usage should be blocked.
pub fn has_overdue_invoices(&self) -> bool {
self.has_overdue_invoices.unwrap_or(false)
}
pub fn current_user_has_accepted_terms(&self) -> Option<bool> {
self.accepted_tos_at
.map(|accepted_tos_at| accepted_tos_at.is_some())

View file

@ -1,5 +1,5 @@
use anyhow::Result;
use client::{DisableAiSettings, UserStore, zed_urls};
use client::{CloudUserStore, DisableAiSettings, zed_urls};
use cloud_llm_client::UsageLimit;
use copilot::{Copilot, Status};
use editor::{
@ -59,7 +59,7 @@ pub struct InlineCompletionButton {
file: Option<Arc<dyn File>>,
edit_prediction_provider: Option<Arc<dyn inline_completion::InlineCompletionProviderHandle>>,
fs: Arc<dyn Fs>,
user_store: Entity<UserStore>,
cloud_user_store: Entity<CloudUserStore>,
popover_menu_handle: PopoverMenuHandle<ContextMenu>,
}
@ -245,13 +245,16 @@ impl Render for InlineCompletionButton {
IconName::ZedPredictDisabled
};
if zeta::should_show_upsell_modal(&self.user_store, cx) {
let tooltip_meta =
match self.user_store.read(cx).current_user_has_accepted_terms() {
Some(true) => "Choose a Plan",
Some(false) => "Accept the Terms of Service",
None => "Sign In",
};
if zeta::should_show_upsell_modal(&self.cloud_user_store, cx) {
let tooltip_meta = if self.cloud_user_store.read(cx).is_authenticated() {
if self.cloud_user_store.read(cx).has_accepted_tos() {
"Choose a Plan"
} else {
"Accept the Terms of Service"
}
} else {
"Sign In"
};
return div().child(
IconButton::new("zed-predict-pending-button", zeta_icon)
@ -368,7 +371,7 @@ impl Render for InlineCompletionButton {
impl InlineCompletionButton {
pub fn new(
fs: Arc<dyn Fs>,
user_store: Entity<UserStore>,
cloud_user_store: Entity<CloudUserStore>,
popover_menu_handle: PopoverMenuHandle<ContextMenu>,
cx: &mut Context<Self>,
) -> Self {
@ -389,7 +392,7 @@ impl InlineCompletionButton {
edit_prediction_provider: None,
popover_menu_handle,
fs,
user_store,
cloud_user_store,
}
}
@ -760,7 +763,7 @@ impl InlineCompletionButton {
})
})
.separator();
} else if self.user_store.read(cx).account_too_young() {
} else if self.cloud_user_store.read(cx).account_too_young() {
menu = menu
.custom_entry(
|_window, _cx| {
@ -775,7 +778,7 @@ impl InlineCompletionButton {
cx.open_url(&zed_urls::account_url(cx))
})
.separator();
} else if self.user_store.read(cx).has_overdue_invoices() {
} else if self.cloud_user_store.read(cx).has_overdue_invoices() {
menu = menu
.custom_entry(
|_window, _cx| {

View file

@ -336,7 +336,7 @@ pub fn initialize_workspace(
let edit_prediction_button = cx.new(|cx| {
inline_completion_button::InlineCompletionButton::new(
app_state.fs.clone(),
app_state.user_store.clone(),
app_state.cloud_user_store.clone(),
inline_completion_menu_handle.clone(),
cx,
)

View file

@ -16,7 +16,7 @@ pub use rate_completion_modal::*;
use anyhow::{Context as _, Result, anyhow};
use arrayvec::ArrayVec;
use client::{Client, CloudUserStore, EditPredictionUsage, UserStore};
use client::{Client, CloudUserStore, EditPredictionUsage};
use cloud_llm_client::{
AcceptEditPredictionBody, EXPIRED_LLM_TOKEN_HEADER_NAME, MINIMUM_REQUIRED_VERSION_HEADER_NAME,
PredictEditsBody, PredictEditsResponse, ZED_VERSION_HEADER_NAME,
@ -120,10 +120,11 @@ impl Dismissable for ZedPredictUpsell {
}
}
pub fn should_show_upsell_modal(user_store: &Entity<UserStore>, cx: &App) -> bool {
match user_store.read(cx).current_user_has_accepted_terms() {
Some(true) => !ZedPredictUpsell::dismissed(),
Some(false) | None => true,
pub fn should_show_upsell_modal(cloud_user_store: &Entity<CloudUserStore>, cx: &App) -> bool {
if cloud_user_store.read(cx).has_accepted_tos() {
!ZedPredictUpsell::dismissed()
} else {
true
}
}
@ -1804,6 +1805,7 @@ fn tokens_for_bytes(bytes: usize) -> usize {
#[cfg(test)]
mod tests {
use client::UserStore;
use client::test::FakeServer;
use clock::FakeSystemClock;
use cloud_api_types::{