first pass of merging in warp (doesn't build)

This commit is contained in:
Ryan Ward
2026-07-01 16:08:58 -05:00
parent 2f64909469
commit 4770ac06b5
3662 changed files with 414574 additions and 89772 deletions
+18 -83
View File
@@ -1,32 +1,24 @@
use galaxy_core::ui::appearance::Appearance;
use galaxyui::{
elements::{
ConstrainedBox, Container, CrossAxisAlignment, Flex, FormattedTextElement,
HighlightedHyperlink, HyperlinkLens, MainAxisAlignment, MainAxisSize, ParentElement,
},
AppContext, Element, Entity, SingletonEntity, TypedActionView, View, ViewContext,
};
use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine};
use crate::{
ai::{blocklist::error_color, AIRequestUsageModel},
auth::AuthStateProvider,
network::NetworkStatus,
server::ids::ServerId,
settings::PrivacySettings,
settings_view::SettingsSection,
ui_components::icons::Icon,
workspace::WorkspaceAction,
workspaces::user_workspaces::UserWorkspaces,
};
use ai::api_keys::ApiKeyManager;
use markdown_parser::{FormattedText, FormattedTextFragment, FormattedTextLine};
use galaxy_core::ui::appearance::Appearance;
use galaxyui::elements::{
ConstrainedBox, Container, CrossAxisAlignment, Flex, FormattedTextElement,
HighlightedHyperlink, HyperlinkLens, MainAxisAlignment, MainAxisSize, ParentElement,
};
use galaxyui::{AppContext, Element, Entity, SingletonEntity, TypedActionView, View, ViewContext};
use crate::ai::blocklist::error_color;
use crate::ai::AIRequestUsageModel;
use crate::auth::AuthStateProvider;
use crate::network::NetworkStatus;
use crate::server::ids::ServerId;
use crate::settings_view::SettingsSection;
use crate::ui_components::icons::Icon;
use crate::workspace::WorkspaceAction;
use crate::workspaces::user_workspaces::UserWorkspaces;
const ANONYMOUS_USER_REQUEST_LIMIT_SOFT_GATE_PERCENTAGE: f32 = 0.5;
const TELEMETRY_DISABLED_PRIMARY_TEXT: &str = "To use AI features,";
const ENABLE_ANALYTICS_ACTION_TEXT: &str = "enable analytics";
const UPGRADE_TO_BUILD_ACTION_TEXT: &str = "upgrade";
const NO_CONNECTION_PRIMARY_TEXT: &str = "No internet connection";
const ANONYMOUS_USER_REQUEST_LIMIT_SOFT_GATE_PRIMARY_TEXT: &str = "";
const ANONYMOUS_USER_REQUEST_LIMIT_HARD_GATE_PRIMARY_TEXT: &str = "At Limit -";
@@ -49,7 +41,6 @@ const NON_ADMIN_ASK_ADMIN_TO_INCREASE_OVERAGES_TEXT: &str =
pub enum PromptAlertAction {
SignUpClickedForAnonymousUser,
OpenSettingsClicked,
OpenPrivacySettingsClicked,
ManageBillingClicked { team_uid: ServerId },
}
@@ -57,7 +48,6 @@ pub enum PromptAlertAction {
pub enum PromptAlertEvent {
SignupAnonymousUser,
OpenBillingAndUsagePage,
OpenPrivacyPage,
OpenBillingPortal { team_uid: ServerId },
}
@@ -66,9 +56,6 @@ pub enum PromptAlertEvent {
pub enum PromptAlertState {
/// The user is offline (no connection).
NoConnection,
/// Telemetry is disabled and the user is on a free tier.
/// Free tier users must enable telemetry or upgrade to use AI features.
TelemetryDisabledOnFreeTier,
/// An anonymous user has reached a certain percentage of requests used.
/// This doesn't use a primary text to avoid being too in-your-face.
AnonymousUserRequestLimitSoftGate,
@@ -96,7 +83,6 @@ impl PromptAlertView {
let request_usage_model = AIRequestUsageModel::handle(ctx);
let user_workspaces = UserWorkspaces::handle(ctx);
let network_status = NetworkStatus::handle(ctx);
let privacy_settings = PrivacySettings::handle(ctx);
let api_key_manager = ApiKeyManager::handle(ctx);
ctx.subscribe_to_model(&request_usage_model, |me, _, _, ctx| {
@@ -114,11 +100,6 @@ impl PromptAlertView {
ctx.notify();
});
ctx.subscribe_to_model(&privacy_settings, |me, _, _, ctx| {
me.state = Self::determine_state(ctx);
ctx.notify();
});
ctx.subscribe_to_model(&api_key_manager, |me, _, _, ctx| {
me.state = Self::determine_state(ctx);
ctx.notify();
@@ -136,21 +117,6 @@ impl PromptAlertView {
return PromptAlertState::NoConnection;
}
// Check if telemetry is disabled for free tier users.
// Free tier users must enable telemetry or upgrade to use AI features.
let privacy_settings = PrivacySettings::as_ref(app);
if !privacy_settings.is_telemetry_enabled {
// Fail safe: if billing status is unknown, assume paid to avoid showing confusing message to paying users
let is_on_paid_plan = UserWorkspaces::as_ref(app)
.current_workspace()
.map(|w| w.billing_metadata.is_user_on_paid_plan())
.unwrap_or(true);
if !is_on_paid_plan {
return PromptAlertState::TelemetryDisabledOnFreeTier;
}
}
let request_usage_model = AIRequestUsageModel::as_ref(app);
let has_requests_remaining = request_usage_model.has_requests_remaining();
let auth_state = AuthStateProvider::as_ref(app).get();
@@ -229,11 +195,6 @@ impl PromptAlertView {
NO_CONNECTION_PRIMARY_TEXT,
));
}
PromptAlertState::TelemetryDisabledOnFreeTier => {
text_fragments.push(FormattedTextFragment::plain_text(
TELEMETRY_DISABLED_PRIMARY_TEXT,
));
}
PromptAlertState::AnonymousUserRequestLimitSoftGate => {
text_fragments.push(FormattedTextFragment::plain_text(
ANONYMOUS_USER_REQUEST_LIMIT_SOFT_GATE_PRIMARY_TEXT,
@@ -274,28 +235,6 @@ impl PromptAlertView {
match state {
PromptAlertState::NoConnection => {}
PromptAlertState::TelemetryDisabledOnFreeTier => {
// Show "enable analytics" action link
text_fragments.push(FormattedTextFragment::plain_text(" "));
text_fragments.push(FormattedTextFragment::hyperlink_action(
ENABLE_ANALYTICS_ACTION_TEXT,
PromptAlertAction::OpenPrivacySettingsClicked,
));
// Show "or upgrade to Build" link
text_fragments.push(FormattedTextFragment::plain_text(" or "));
let upgrade_url = if let Some(team) = UserWorkspaces::as_ref(app).current_team() {
UserWorkspaces::upgrade_link_for_team(team.uid)
} else {
let user_id = auth_state.user_id().unwrap_or_default();
UserWorkspaces::upgrade_link(user_id)
};
text_fragments.push(FormattedTextFragment::hyperlink(
UPGRADE_TO_BUILD_ACTION_TEXT,
upgrade_url,
));
text_fragments.push(FormattedTextFragment::plain_text("."));
}
PromptAlertState::AnonymousUserRequestLimitSoftGate
| PromptAlertState::AnonymousUserRequestLimitHardGate => {
text_fragments.push(FormattedTextFragment::plain_text(" "));
@@ -385,7 +324,7 @@ impl PromptAlertView {
};
text_fragments.push(FormattedTextFragment::hyperlink(label, upgrade_url));
}
if UserWorkspaces::as_ref(app).is_byo_api_key_enabled() {
if UserWorkspaces::as_ref(app).is_byo_api_key_enabled(app) {
text_fragments.push(FormattedTextFragment::plain_text(" or "));
text_fragments.push(FormattedTextFragment::hyperlink_action(
"use your own API keys",
@@ -405,7 +344,6 @@ fn does_alert_block_ai_requests(state: &PromptAlertState) -> bool {
match state {
PromptAlertState::AnonymousUserRequestLimitSoftGate | PromptAlertState::NoAlert => false,
PromptAlertState::NoConnection
| PromptAlertState::TelemetryDisabledOnFreeTier
| PromptAlertState::AnonymousUserRequestLimitHardGate
| PromptAlertState::DelinquentDueToPaymentIssue
| PromptAlertState::OveragesToggleableButNotEnabled
@@ -527,9 +465,6 @@ impl TypedActionView for PromptAlertView {
PromptAlertAction::OpenSettingsClicked => {
ctx.emit(PromptAlertEvent::OpenBillingAndUsagePage);
}
PromptAlertAction::OpenPrivacySettingsClicked => {
ctx.emit(PromptAlertEvent::OpenPrivacyPage);
}
PromptAlertAction::ManageBillingClicked { team_uid } => {
ctx.emit(PromptAlertEvent::OpenBillingPortal {
team_uid: *team_uid,