Release Notes: - Added the ability to set settings per-release stage - Added a `"server_url"` setting
Unified · Split
| @@ -9025,6 +9025,7 @@ dependencies = [ · 9024 unmodified lines | |||
| 9025 | "isahc", | 9025 | "isahc", |
| 9026 | "lazy_static", | 9026 | "lazy_static", |
| 9027 | "log", | 9027 | "log", |
| 9028 | "parking_lot 0.11.2", | ||
| 9028 | "rand 0.8.5", | 9029 | "rand 0.8.5", |
| 9029 | "rust-embed", | 9030 | "rust-embed", |
| 9030 | "serde", | 9031 | "serde", |
| @@ -503,5 +503,28 @@ · 502 unmodified lines | |||
| 503 | // } | 503 | // } |
| 504 | // } | 504 | // } |
| 505 | // } | 505 | // } |
| 506 | }, | ||
| 507 | // The server to connect to. If the environment variable | ||
| 508 | // ZED_SERVER_URL is set, it will override this setting. | ||
| 509 | "server_url": "https://zed.dev", | ||
| 510 | // Settings overrides to use when using Zed Preview. | ||
| 511 | // Mostly useful for developers who are managing multiple instances of Zed. | ||
| 512 | "preview": { | ||
| 513 | // "theme": "Andromeda" | ||
| 514 | }, | ||
| 515 | // Settings overrides to use when using Zed Nightly. | ||
| 516 | // Mostly useful for developers who are managing multiple instances of Zed. | ||
| 517 | "nightly": { | ||
| 518 | // "theme": "Andromeda" | ||
| 519 | }, | ||
| 520 | // Settings overrides to use when using Zed Stable. | ||
| 521 | // Mostly useful for developers who are managing multiple instances of Zed. | ||
| 522 | "stable": { | ||
| 523 | // "theme": "Andromeda" | ||
| 524 | }, | ||
| 525 | // Settings overrides to use when using Zed Stable. | ||
| 526 | // Mostly useful for developers who are managing multiple instances of Zed. | ||
| 527 | "dev": { | ||
| 528 | // "theme": "Andromeda" | ||
| 506 | } | 529 | } |
| 507 | } | 530 | } |
| @@ -25,8 +25,11 @@ use std::{ · 24 unmodified lines | |||
| 25 | time::Duration, | 25 | time::Duration, |
| 26 | }; | 26 | }; |
| 27 | use update_notification::UpdateNotification; | 27 | use update_notification::UpdateNotification; |
| 28 | use util::channel::{AppCommitSha, ReleaseChannel}; | ||
| 29 | use util::http::HttpClient; | 28 | use util::http::HttpClient; |
| 29 | use util::{ | ||
| 30 | channel::{AppCommitSha, ReleaseChannel}, | ||
| 31 | http::ZedHttpClient, | ||
| 32 | }; | ||
| 30 | use workspace::Workspace; | 33 | use workspace::Workspace; |
| 31 | 34 | ||
| 32 | const SHOULD_SHOW_UPDATE_NOTIFICATION_KEY: &str = "auto-updater-should-show-updated-notification"; | 35 | const SHOULD_SHOW_UPDATE_NOTIFICATION_KEY: &str = "auto-updater-should-show-updated-notification"; |
| @@ -54,9 +57,8 @@ pub enum AutoUpdateStatus { · 21 unmodified lines | |||
| 54 | pub struct AutoUpdater { | 57 | pub struct AutoUpdater { |
| 55 | status: AutoUpdateStatus, | 58 | status: AutoUpdateStatus, |
| 56 | current_version: SemanticVersion, | 59 | current_version: SemanticVersion, |
| 57 | http_client: Arc<dyn HttpClient>, | 60 | http_client: Arc<ZedHttpClient>, |
| 58 | pending_poll: Option<Task<Option<()>>>, | 61 | pending_poll: Option<Task<Option<()>>>, |
| 59 | server_url: String, | ||
| 60 | } | 62 | } |
| 61 | 63 | ||
| 62 | #[derive(Deserialize)] | 64 | #[derive(Deserialize)] |
| @@ -92,7 +94,7 @@ impl Settings for AutoUpdateSetting { · 29 unmodified lines | |||
| 92 | } | 94 | } |
| 93 | } | 95 | } |
| 94 | 96 | ||
| 95 | pub fn init(http_client: Arc<dyn HttpClient>, server_url: String, cx: &mut AppContext) { | 97 | pub fn init(http_client: Arc<ZedHttpClient>, cx: &mut AppContext) { |
| 96 | AutoUpdateSetting::register(cx); | 98 | AutoUpdateSetting::register(cx); |
| 97 | 99 | ||
| 98 | cx.observe_new_views(|workspace: &mut Workspace, _cx| { | 100 | cx.observe_new_views(|workspace: &mut Workspace, _cx| { |
| @@ -106,7 +108,7 @@ pub fn init(http_client: Arc<dyn HttpClient>, server_url: String, cx: &mut AppCo · 7 unmodified lines | |||
| 106 | 108 | ||
| 107 | if let Some(version) = ZED_APP_VERSION.or_else(|| cx.app_metadata().app_version) { | 109 | if let Some(version) = ZED_APP_VERSION.or_else(|| cx.app_metadata().app_version) { |
| 108 | let auto_updater = cx.new_model(|cx| { | 110 | let auto_updater = cx.new_model(|cx| { |
| 109 | let updater = AutoUpdater::new(version, http_client, server_url); | 111 | let updater = AutoUpdater::new(version, http_client); |
| 110 | 112 | ||
| 111 | let mut update_subscription = AutoUpdateSetting::get_global(cx) | 113 | let mut update_subscription = AutoUpdateSetting::get_global(cx) |
| 112 | .0 | 114 | .0 |
| @@ -151,10 +153,11 @@ pub fn view_release_notes(_: &ViewReleaseNotes, cx: &mut AppContext) -> Option<( · 38 unmodified lines | |||
| 151 | ReleaseChannel::Stable | ReleaseChannel::Preview | 153 | ReleaseChannel::Stable | ReleaseChannel::Preview |
| 152 | ) { | 154 | ) { |
| 153 | let auto_updater = auto_updater.read(cx); | 155 | let auto_updater = auto_updater.read(cx); |
| 154 | let server_url = &auto_updater.server_url; | ||
| 155 | let release_channel = release_channel.dev_name(); | 156 | let release_channel = release_channel.dev_name(); |
| 156 | let current_version = auto_updater.current_version; | 157 | let current_version = auto_updater.current_version; |
| 157 | let url = format!("{server_url}/releases/{release_channel}/{current_version}"); | 158 | let url = &auto_updater |
| 159 | .http_client | ||
| 160 | .zed_url(&format!("/releases/{release_channel}/{current_version}")); | ||
| 158 | cx.open_url(&url); | 161 | cx.open_url(&url); |
| 159 | } | 162 | } |
| 160 | 163 | ||
| @@ -191,16 +194,11 @@ impl AutoUpdater { · 30 unmodified lines | |||
| 191 | cx.default_global::<Option<Model<Self>>>().clone() | 194 | cx.default_global::<Option<Model<Self>>>().clone() |
| 192 | } | 195 | } |
| 193 | 196 | ||
| 194 | fn new( | 197 | fn new(current_version: SemanticVersion, http_client: Arc<ZedHttpClient>) -> Self { |
| 195 | current_version: SemanticVersion, | ||
| 196 | http_client: Arc<dyn HttpClient>, | ||
| 197 | server_url: String, | ||
| 198 | ) -> Self { | ||
| 199 | Self { | 198 | Self { |
| 200 | status: AutoUpdateStatus::Idle, | 199 | status: AutoUpdateStatus::Idle, |
| 201 | current_version, | 200 | current_version, |
| 202 | http_client, | 201 | http_client, |
| 203 | server_url, | ||
| 204 | pending_poll: None, | 202 | pending_poll: None, |
| 205 | } | 203 | } |
| 206 | } | 204 | } |
| @@ -246,18 +244,14 @@ impl AutoUpdater { · 39 unmodified lines | |||
| 246 | } | 244 | } |
| 247 | 245 | ||
| 248 | async fn update(this: Model<Self>, mut cx: AsyncAppContext) -> Result<()> { | 246 | async fn update(this: Model<Self>, mut cx: AsyncAppContext) -> Result<()> { |
| 249 | let (client, server_url, current_version) = this.read_with(&cx, |this, _| { | 247 | let (client, current_version) = this.read_with(&cx, |this, _| { |
| 250 | ( | 248 | (this.http_client.clone(), this.current_version) |
| 251 | this.http_client.clone(), | ||
| 252 | this.server_url.clone(), | ||
| 253 | this.current_version, | ||
| 254 | ) | ||
| 255 | })?; | 249 | })?; |
| 256 | 250 | ||
| 257 | let mut url_string = format!( | 251 | let mut url_string = client.zed_url(&format!( |
| 258 | "{server_url}/api/releases/latest?asset=Zed.dmg&os={}&arch={}", | 252 | "/api/releases/latest?asset=Zed.dmg&os={}&arch={}", |
| 259 | OS, ARCH | 253 | OS, ARCH |
| 260 | ); | 254 | )); |
| 261 | cx.update(|cx| { | 255 | cx.update(|cx| { |
| 262 | if let Some(param) = cx | 256 | if let Some(param) = cx |
| 263 | .try_global::<ReleaseChannel>() | 257 | .try_global::<ReleaseChannel>() |
| @@ -329,6 +329,7 @@ async fn test_channel_messages(cx: &mut TestAppContext) { · 328 unmodified lines | |||
| 329 | fn init_test(cx: &mut AppContext) -> Model<ChannelStore> { | 329 | fn init_test(cx: &mut AppContext) -> Model<ChannelStore> { |
| 330 | let settings_store = SettingsStore::test(cx); | 330 | let settings_store = SettingsStore::test(cx); |
| 331 | cx.set_global(settings_store); | 331 | cx.set_global(settings_store); |
| 332 | client::init_settings(cx); | ||
| 332 | 333 | ||
| 333 | let http = FakeHttpClient::with_404_response(); | 334 | let http = FakeHttpClient::with_404_response(); |
| 334 | let client = Client::new(http.clone(), cx); | 335 | let client = Client::new(http.clone(), cx); |
| @@ -26,7 +26,7 @@ use rpc::proto::{AnyTypedEnvelope, EntityMessage, EnvelopedMessage, PeerId, Requ · 25 unmodified lines | |||
| 26 | use schemars::JsonSchema; | 26 | use schemars::JsonSchema; |
| 27 | use serde::{Deserialize, Serialize}; | 27 | use serde::{Deserialize, Serialize}; |
| 28 | use serde_json; | 28 | use serde_json; |
| 29 | use settings::Settings; | 29 | use settings::{Settings, SettingsStore}; |
| 30 | use std::{ | 30 | use std::{ |
| 31 | any::TypeId, | 31 | any::TypeId, |
| 32 | collections::HashMap, | 32 | collections::HashMap, |
| @@ -41,8 +41,8 @@ use std::{ · 8 unmodified lines | |||
| 41 | use telemetry::Telemetry; | 41 | use telemetry::Telemetry; |
| 42 | use thiserror::Error; | 42 | use thiserror::Error; |
| 43 | use url::Url; | 43 | use url::Url; |
| 44 | use util::channel::ReleaseChannel; | ||
| 45 | use util::http::HttpClient; | 44 | use util::http::HttpClient; |
| 45 | use util::{channel::ReleaseChannel, http::ZedHttpClient}; | ||
| 46 | use util::{ResultExt, TryFutureExt}; | 46 | use util::{ResultExt, TryFutureExt}; |
| 47 | 47 | ||
| 48 | pub use rpc::*; | 48 | pub use rpc::*; |
| @@ -50,9 +50,8 @@ pub use telemetry::Event; · 1 unmodified line | |||
| 50 | pub use user::*; | 50 | pub use user::*; |
| 51 | 51 | ||
| 52 | lazy_static! { | 52 | lazy_static! { |
| 53 | pub static ref ZED_SERVER_URL: String = | 53 | static ref ZED_SERVER_URL: Option<String> = std::env::var("ZED_SERVER_URL").ok(); |
| 54 | std::env::var("ZED_SERVER_URL").unwrap_or_else(|_| "https://zed.dev".to_string()); | 54 | static ref ZED_RPC_URL: Option<String> = std::env::var("ZED_RPC_URL").ok(); |
| 55 | pub static ref ZED_RPC_URL: Option<String> = std::env::var("ZED_RPC_URL").ok(); | ||
| 56 | pub static ref IMPERSONATE_LOGIN: Option<String> = std::env::var("ZED_IMPERSONATE") | 55 | pub static ref IMPERSONATE_LOGIN: Option<String> = std::env::var("ZED_IMPERSONATE") |
| 57 | .ok() | 56 | .ok() |
| 58 | .and_then(|s| if s.is_empty() { None } else { Some(s) }); | 57 | .and_then(|s| if s.is_empty() { None } else { Some(s) }); |
| @@ -73,13 +72,45 @@ pub const CONNECTION_TIMEOUT: Duration = Duration::from_secs(5); · 14 unmodified lines | |||
| 73 | 72 | ||
| 74 | actions!(client, [SignIn, SignOut, Reconnect]); | 73 | actions!(client, [SignIn, SignOut, Reconnect]); |
| 75 | 74 | ||
| 75 | #[derive(Clone, Default, Serialize, Deserialize, JsonSchema)] | ||
| 76 | pub struct ClientSettingsContent { | ||
| 77 | server_url: Option<String>, | ||
| 78 | } | ||
| 79 | |||
| 80 | #[derive(Deserialize)] | ||
| 81 | pub struct ClientSettings { | ||
| 82 | pub server_url: String, | ||
| 83 | } | ||
| 84 | |||
| 85 | impl Settings for ClientSettings { | ||
| 86 | const KEY: Option<&'static str> = None; | ||
| 87 | |||
| 88 | type FileContent = ClientSettingsContent; | ||
| 89 | |||
| 90 | fn load( | ||
| 91 | default_value: &Self::FileContent, | ||
| 92 | user_values: &[&Self::FileContent], | ||
| 93 | _: &mut AppContext, | ||
| 94 | ) -> Result<Self> | ||
| 95 | where | ||
| 96 | Self: Sized, | ||
| 97 | { | ||
| 98 | let mut result = Self::load_via_json_merge(default_value, user_values)?; | ||
| 99 | if let Some(server_url) = &*ZED_SERVER_URL { | ||
| 100 | result.server_url = server_url.clone() | ||
| 101 | } | ||
| 102 | Ok(result) | ||
| 103 | } | ||
| 104 | } | ||
| 105 | |||
| 76 | pub fn init_settings(cx: &mut AppContext) { | 106 | pub fn init_settings(cx: &mut AppContext) { |
| 77 | TelemetrySettings::register(cx); | 107 | TelemetrySettings::register(cx); |
| 108 | cx.update_global(|store: &mut SettingsStore, cx| { | ||
| 109 | store.register_setting::<ClientSettings>(cx); | ||
| 110 | }); | ||
| 78 | } | 111 | } |
| 79 | 112 | ||
| 80 | pub fn init(client: &Arc<Client>, cx: &mut AppContext) { | 113 | pub fn init(client: &Arc<Client>, cx: &mut AppContext) { |
| 81 | init_settings(cx); | ||
| 82 | |||
| 83 | let client = Arc::downgrade(client); | 114 | let client = Arc::downgrade(client); |
| 84 | cx.on_action({ | 115 | cx.on_action({ |
| 85 | let client = client.clone(); | 116 | let client = client.clone(); |
| @@ -121,7 +152,7 @@ pub fn init(client: &Arc<Client>, cx: &mut AppContext) { · 35 unmodified lines | |||
| 121 | pub struct Client { | 152 | pub struct Client { |
| 122 | id: AtomicU64, | 153 | id: AtomicU64, |
| 123 | peer: Arc<Peer>, | 154 | peer: Arc<Peer>, |
| 124 | http: Arc<dyn HttpClient>, | 155 | http: Arc<ZedHttpClient>, |
| 125 | telemetry: Arc<Telemetry>, | 156 | telemetry: Arc<Telemetry>, |
| 126 | state: RwLock<ClientState>, | 157 | state: RwLock<ClientState>, |
| 127 | 158 | ||
| @@ -390,8 +421,8 @@ impl settings::Settings for TelemetrySettings { · 262 unmodified lines | |||
| 390 | } | 421 | } |
| 391 | 422 | ||
| 392 | impl Client { | 423 | impl Client { |
| 393 | pub fn new(http: Arc<dyn HttpClient>, cx: &mut AppContext) -> Arc<Self> { | 424 | pub fn new(http: Arc<ZedHttpClient>, cx: &mut AppContext) -> Arc<Self> { |
| 394 | Arc::new(Self { | 425 | let client = Arc::new(Self { |
| 395 | id: AtomicU64::new(0), | 426 | id: AtomicU64::new(0), |
| 396 | peer: Peer::new(0), | 427 | peer: Peer::new(0), |
| 397 | telemetry: Telemetry::new(http.clone(), cx), | 428 | telemetry: Telemetry::new(http.clone(), cx), |
| @@ -402,14 +433,16 @@ impl Client { · 4 unmodified lines | |||
| 402 | authenticate: Default::default(), | 433 | authenticate: Default::default(), |
| 403 | #[cfg(any(test, feature = "test-support"))] | 434 | #[cfg(any(test, feature = "test-support"))] |
| 404 | establish_connection: Default::default(), | 435 | establish_connection: Default::default(), |
| 405 | }) | 436 | }); |
| 437 | |||
| 438 | client | ||
| 406 | } | 439 | } |
| 407 | 440 | ||
| 408 | pub fn id(&self) -> u64 { | 441 | pub fn id(&self) -> u64 { |
| 409 | self.id.load(std::sync::atomic::Ordering::SeqCst) | 442 | self.id.load(std::sync::atomic::Ordering::SeqCst) |
| 410 | } | 443 | } |
| 411 | 444 | ||
| 412 | pub fn http_client(&self) -> Arc<dyn HttpClient> { | 445 | pub fn http_client(&self) -> Arc<ZedHttpClient> { |
| 413 | self.http.clone() | 446 | self.http.clone() |
| 414 | } | 447 | } |
| 415 | 448 | ||
| @@ -925,14 +958,14 @@ impl Client { · 509 unmodified lines | |||
| 925 | } | 958 | } |
| 926 | 959 | ||
| 927 | async fn get_rpc_url( | 960 | async fn get_rpc_url( |
| 928 | http: Arc<dyn HttpClient>, | 961 | http: Arc<ZedHttpClient>, |
| 929 | release_channel: Option<ReleaseChannel>, | 962 | release_channel: Option<ReleaseChannel>, |
| 930 | ) -> Result<Url> { | 963 | ) -> Result<Url> { |
| 931 | if let Some(url) = &*ZED_RPC_URL { | 964 | if let Some(url) = &*ZED_RPC_URL { |
| 932 | return Url::parse(url).context("invalid rpc url"); | 965 | return Url::parse(url).context("invalid rpc url"); |
| 933 | } | 966 | } |
| 934 | 967 | ||
| 935 | let mut url = format!("{}/rpc", *ZED_SERVER_URL); | 968 | let mut url = http.zed_url("/rpc"); |
| 936 | if let Some(preview_param) = | 969 | if let Some(preview_param) = |
| 937 | release_channel.and_then(|channel| channel.release_query_param()) | 970 | release_channel.and_then(|channel| channel.release_query_param()) |
| 938 | { | 971 | { |
| @@ -1053,10 +1086,10 @@ impl Client { · 114 unmodified lines | |||
| 1053 | 1086 | ||
| 1054 | // Open the Zed sign-in page in the user's browser, with query parameters that indicate | 1087 | // Open the Zed sign-in page in the user's browser, with query parameters that indicate |
| 1055 | // that the user is signing in from a Zed app running on the same device. | 1088 | // that the user is signing in from a Zed app running on the same device. |
| 1056 | let mut url = format!( | 1089 | let mut url = http.zed_url(&format!( |
| 1057 | "{}/native_app_signin?native_app_port={}&native_app_public_key={}", | 1090 | "/native_app_signin?native_app_port={}&native_app_public_key={}", |
| 1058 | *ZED_SERVER_URL, port, public_key_string | 1091 | port, public_key_string |
| 1059 | ); | 1092 | )); |
| 1060 | 1093 | ||
| 1061 | if let Some(impersonate_login) = IMPERSONATE_LOGIN.as_ref() { | 1094 | if let Some(impersonate_login) = IMPERSONATE_LOGIN.as_ref() { |
| 1062 | log::info!("impersonating user @{}", impersonate_login); | 1095 | log::info!("impersonating user @{}", impersonate_login); |
| @@ -1088,7 +1121,7 @@ impl Client { · 25 unmodified lines | |||
| 1088 | } | 1121 | } |
| 1089 | 1122 | ||
| 1090 | let post_auth_url = | 1123 | let post_auth_url = |
| 1091 | format!("{}/native_app_signin_succeeded", *ZED_SERVER_URL); | 1124 | http.zed_url("/native_app_signin_succeeded"); |
| 1092 | req.respond( | 1125 | req.respond( |
| 1093 | tiny_http::Response::empty(302).with_header( | 1126 | tiny_http::Response::empty(302).with_header( |
| 1094 | tiny_http::Header::from_bytes( | 1127 | tiny_http::Header::from_bytes( |
| @@ -1130,7 +1163,7 @@ impl Client { · 35 unmodified lines | |||
| 1130 | } | 1163 | } |
| 1131 | 1164 | ||
| 1132 | async fn authenticate_as_admin( | 1165 | async fn authenticate_as_admin( |
| 1133 | http: Arc<dyn HttpClient>, | 1166 | http: Arc<ZedHttpClient>, |
| 1134 | login: String, | 1167 | login: String, |
| 1135 | mut api_token: String, | 1168 | mut api_token: String, |
| 1136 | ) -> Result<Credentials> { | 1169 | ) -> Result<Credentials> { |
| @@ -1351,7 +1384,7 @@ async fn read_credentials_from_keychain(cx: &AsyncAppContext) -> Option<Credenti · 214 unmodified lines | |||
| 1351 | } | 1384 | } |
| 1352 | 1385 | ||
| 1353 | let (user_id, access_token) = cx | 1386 | let (user_id, access_token) = cx |
| 1354 | .update(|cx| cx.read_credentials(&ZED_SERVER_URL)) | 1387 | .update(|cx| cx.read_credentials(&ClientSettings::get_global(cx).server_url)) |
| 1355 | .log_err()? | 1388 | .log_err()? |
| 1356 | .await | 1389 | .await |
| 1357 | .log_err()??; | 1390 | .log_err()??; |
| @@ -1368,7 +1401,7 @@ async fn write_credentials_to_keychain( · 10 unmodified lines | |||
| 1368 | ) -> Result<()> { | 1401 | ) -> Result<()> { |
| 1369 | cx.update(move |cx| { | 1402 | cx.update(move |cx| { |
| 1370 | cx.write_credentials( | 1403 | cx.write_credentials( |
| 1371 | &ZED_SERVER_URL, | 1404 | &ClientSettings::get_global(cx).server_url, |
| 1372 | &credentials.user_id.to_string(), | 1405 | &credentials.user_id.to_string(), |
| 1373 | credentials.access_token.as_bytes(), | 1406 | credentials.access_token.as_bytes(), |
| 1374 | ) | 1407 | ) |
| @@ -1377,7 +1410,7 @@ async fn write_credentials_to_keychain( · 2 unmodified lines | |||
| 1377 | } | 1410 | } |
| 1378 | 1411 | ||
| 1379 | async fn delete_credentials_from_keychain(cx: &AsyncAppContext) -> Result<()> { | 1412 | async fn delete_credentials_from_keychain(cx: &AsyncAppContext) -> Result<()> { |
| 1380 | cx.update(move |cx| cx.delete_credentials(&ZED_SERVER_URL))? | 1413 | cx.update(move |cx| cx.delete_credentials(&ClientSettings::get_global(cx).server_url))? |
| 1381 | .await | 1414 | .await |
| 1382 | } | 1415 | } |
| 1383 | 1416 | ||
| @@ -1684,6 +1717,7 @@ mod tests { · 300 unmodified lines | |||
| 1684 | cx.update(|cx| { | 1717 | cx.update(|cx| { |
| 1685 | let settings_store = SettingsStore::test(cx); | 1718 | let settings_store = SettingsStore::test(cx); |
| 1686 | cx.set_global(settings_store); | 1719 | cx.set_global(settings_store); |
| 1720 | init_settings(cx); | ||
| 1687 | }); | 1721 | }); |
| 1688 | } | 1722 | } |
| 1689 | } | 1723 | } |
| @@ -1,10 +1,9 @@ | |||
| 1 | mod event_coalescer; | 1 | mod event_coalescer; |
| 2 | 2 | ||
| 3 | use crate::{TelemetrySettings, ZED_SERVER_URL}; | 3 | use crate::TelemetrySettings; |
| 4 | use chrono::{DateTime, Utc}; | 4 | use chrono::{DateTime, Utc}; |
| 5 | use futures::Future; | 5 | use futures::Future; |
| 6 | use gpui::{AppContext, AppMetadata, BackgroundExecutor, Task}; | 6 | use gpui::{AppContext, AppMetadata, BackgroundExecutor, Task}; |
| 7 | use lazy_static::lazy_static; | ||
| 8 | use parking_lot::Mutex; | 7 | use parking_lot::Mutex; |
| 9 | use serde::Serialize; | 8 | use serde::Serialize; |
| 10 | use settings::{Settings, SettingsStore}; | 9 | use settings::{Settings, SettingsStore}; |
| @@ -13,7 +12,7 @@ use sysinfo::{ · 2 unmodified lines | |||
| 13 | CpuRefreshKind, Pid, PidExt, ProcessExt, ProcessRefreshKind, RefreshKind, System, SystemExt, | 12 | CpuRefreshKind, Pid, PidExt, ProcessExt, ProcessRefreshKind, RefreshKind, System, SystemExt, |
| 14 | }; | 13 | }; |
| 15 | use tempfile::NamedTempFile; | 14 | use tempfile::NamedTempFile; |
| 16 | use util::http::HttpClient; | 15 | use util::http::{HttpClient, ZedHttpClient}; |
| 17 | #[cfg(not(debug_assertions))] | 16 | #[cfg(not(debug_assertions))] |
| 18 | use util::ResultExt; | 17 | use util::ResultExt; |
| 19 | use util::{channel::ReleaseChannel, TryFutureExt}; | 18 | use util::{channel::ReleaseChannel, TryFutureExt}; |
| @@ -21,7 +20,7 @@ use util::{channel::ReleaseChannel, TryFutureExt}; · 1 unmodified line | |||
| 21 | use self::event_coalescer::EventCoalescer; | 20 | use self::event_coalescer::EventCoalescer; |
| 22 | 21 | ||
| 23 | pub struct Telemetry { | 22 | pub struct Telemetry { |
| 24 | http_client: Arc<dyn HttpClient>, | 23 | http_client: Arc<ZedHttpClient>, |
| 25 | executor: BackgroundExecutor, | 24 | executor: BackgroundExecutor, |
| 26 | state: Arc<Mutex<TelemetryState>>, | 25 | state: Arc<Mutex<TelemetryState>>, |
| 27 | } | 26 | } |
| @@ -43,12 +42,6 @@ struct TelemetryState { · 15 unmodified lines | |||
| 43 | max_queue_size: usize, | 42 | max_queue_size: usize, |
| 44 | } | 43 | } |
| 45 | 44 | ||
| 46 | const EVENTS_URL_PATH: &'static str = "/api/events"; | ||
| 47 | |||
| 48 | lazy_static! { | ||
| 49 | static ref EVENTS_URL: String = format!("{}{}", *ZED_SERVER_URL, EVENTS_URL_PATH); | ||
| 50 | } | ||
| 51 | |||
| 52 | #[derive(Serialize, Debug)] | 45 | #[derive(Serialize, Debug)] |
| 53 | struct EventRequestBody { | 46 | struct EventRequestBody { |
| 54 | installation_id: Option<Arc<str>>, | 47 | installation_id: Option<Arc<str>>, |
| @@ -149,7 +142,7 @@ const FLUSH_INTERVAL: Duration = Duration::from_secs(1); · 94 unmodified lines | |||
| 149 | const FLUSH_INTERVAL: Duration = Duration::from_secs(60 * 5); | 142 | const FLUSH_INTERVAL: Duration = Duration::from_secs(60 * 5); |
| 150 | 143 | ||
| 151 | impl Telemetry { | 144 | impl Telemetry { |
| 152 | pub fn new(client: Arc<dyn HttpClient>, cx: &mut AppContext) -> Arc<Self> { | 145 | pub fn new(client: Arc<ZedHttpClient>, cx: &mut AppContext) -> Arc<Self> { |
| 153 | let release_channel = cx | 146 | let release_channel = cx |
| 154 | .try_global::<ReleaseChannel>() | 147 | .try_global::<ReleaseChannel>() |
| 155 | .map(|release_channel| release_channel.display_name()); | 148 | .map(|release_channel| release_channel.display_name()); |
| @@ -548,7 +541,7 @@ impl Telemetry { · 392 unmodified lines | |||
| 548 | } | 541 | } |
| 549 | 542 | ||
| 550 | this.http_client | 543 | this.http_client |
| 551 | .post_json(EVENTS_URL.as_str(), json_bytes.into()) | 544 | .post_json(&this.http_client.zed_url("/api/events"), json_bytes.into()) |
| 552 | .await?; | 545 | .await?; |
| 553 | anyhow::Ok(()) | 546 | anyhow::Ok(()) |
| 554 | } | 547 | } |
| @@ -153,6 +153,7 @@ impl TestServer { · 152 unmodified lines | |||
| 153 | } | 153 | } |
| 154 | let settings = SettingsStore::test(cx); | 154 | let settings = SettingsStore::test(cx); |
| 155 | cx.set_global(settings); | 155 | cx.set_global(settings); |
| 156 | client::init_settings(cx); | ||
| 156 | }); | 157 | }); |
| 157 | 158 | ||
| 158 | let http = FakeHttpClient::with_404_response(); | 159 | let http = FakeHttpClient::with_404_response(); |
| @@ -2,7 +2,7 @@ use std::{ops::RangeInclusive, sync::Arc, time::Duration}; · 1 unmodified line | |||
| 2 | 2 | ||
| 3 | use anyhow::{anyhow, bail}; | 3 | use anyhow::{anyhow, bail}; |
| 4 | use bitflags::bitflags; | 4 | use bitflags::bitflags; |
| 5 | use client::{Client, ZED_SERVER_URL}; | 5 | use client::Client; |
| 6 | use db::kvp::KEY_VALUE_STORE; | 6 | use db::kvp::KEY_VALUE_STORE; |
| 7 | use editor::{Editor, EditorEvent}; | 7 | use editor::{Editor, EditorEvent}; |
| 8 | use futures::AsyncReadExt; | 8 | use futures::AsyncReadExt; |
| @@ -16,7 +16,7 @@ use project::Project; · 7 unmodified lines | |||
| 16 | use regex::Regex; | 16 | use regex::Regex; |
| 17 | use serde_derive::Serialize; | 17 | use serde_derive::Serialize; |
| 18 | use ui::{prelude::*, Button, ButtonStyle, IconPosition, Tooltip}; | 18 | use ui::{prelude::*, Button, ButtonStyle, IconPosition, Tooltip}; |
| 19 | use util::ResultExt; | 19 | use util::{http::HttpClient, ResultExt}; |
| 20 | use workspace::{ModalView, Toast, Workspace}; | 20 | use workspace::{ModalView, Toast, Workspace}; |
| 21 | 21 | ||
| 22 | use crate::{system_specs::SystemSpecs, GiveFeedback, OpenZedRepo}; | 22 | use crate::{system_specs::SystemSpecs, GiveFeedback, OpenZedRepo}; |
| @@ -293,12 +293,12 @@ impl FeedbackModal { · 270 unmodified lines | |||
| 293 | } | 293 | } |
| 294 | } | 294 | } |
| 295 | 295 | ||
| 296 | let feedback_endpoint = format!("{}/api/feedback", *ZED_SERVER_URL); | ||
| 297 | let telemetry = zed_client.telemetry(); | 296 | let telemetry = zed_client.telemetry(); |
| 298 | let metrics_id = telemetry.metrics_id(); | 297 | let metrics_id = telemetry.metrics_id(); |
| 299 | let installation_id = telemetry.installation_id(); | 298 | let installation_id = telemetry.installation_id(); |
| 300 | let is_staff = telemetry.is_staff(); | 299 | let is_staff = telemetry.is_staff(); |
| 301 | let http_client = zed_client.http_client(); | 300 | let http_client = zed_client.http_client(); |
| 301 | let feedback_endpoint = http_client.zed_url("/api/feedback"); | ||
| 302 | let request = FeedbackRequestBody { | 302 | let request = FeedbackRequestBody { |
| 303 | feedback_text: &feedback_text, | 303 | feedback_text: &feedback_text, |
| 304 | email, | 304 | email, |
| @@ -1,6 +1,6 @@ | |||
| 1 | use anyhow::{anyhow, Context, Result}; | 1 | use anyhow::{anyhow, Context, Result}; |
| 2 | use collections::{btree_map, hash_map, BTreeMap, HashMap}; | 2 | use collections::{btree_map, hash_map, BTreeMap, HashMap}; |
| 3 | use gpui::AppContext; | 3 | use gpui::{AppContext, AsyncAppContext}; |
| 4 | use lazy_static::lazy_static; | 4 | use lazy_static::lazy_static; |
| 5 | use schemars::{gen::SchemaGenerator, schema::RootSchema, JsonSchema}; | 5 | use schemars::{gen::SchemaGenerator, schema::RootSchema, JsonSchema}; |
| 6 | use serde::{de::DeserializeOwned, Deserialize as _, Serialize}; | 6 | use serde::{de::DeserializeOwned, Deserialize as _, Serialize}; |
| @@ -13,7 +13,9 @@ use std::{ · 6 unmodified lines | |||
| 13 | str, | 13 | str, |
| 14 | sync::Arc, | 14 | sync::Arc, |
| 15 | }; | 15 | }; |
| 16 | use util::{merge_non_null_json_value_into, RangeExt, ResultExt as _}; | 16 | use util::{ |
| 17 | channel::RELEASE_CHANNEL_NAME, merge_non_null_json_value_into, RangeExt, ResultExt as _, | ||
| 18 | }; | ||
| 17 | 19 | ||
| 18 | /// A value that can be defined as a user setting. | 20 | /// A value that can be defined as a user setting. |
| 19 | /// | 21 | /// |
| @@ -102,6 +104,14 @@ pub trait Settings: 'static + Send + Sync { · 82 unmodified lines | |||
| 102 | cx.global::<SettingsStore>().get(None) | 104 | cx.global::<SettingsStore>().get(None) |
| 103 | } | 105 | } |
| 104 | 106 | ||
| 107 | #[track_caller] | ||
| 108 | fn try_read_global<'a, R>(cx: &'a AsyncAppContext, f: impl FnOnce(&Self) -> R) -> Option<R> | ||
| 109 | where | ||
| 110 | Self: Sized, | ||
| 111 | { | ||
| 112 | cx.try_read_global(|s: &SettingsStore, _| f(s.get(None))) | ||
| 113 | } | ||
| 114 | |||
| 105 | #[track_caller] | 115 | #[track_caller] |
| 106 | fn override_global<'a>(settings: Self, cx: &'a mut AppContext) | 116 | fn override_global<'a>(settings: Self, cx: &'a mut AppContext) |
| 107 | where | 117 | where |
| @@ -197,6 +207,15 @@ impl SettingsStore { · 89 unmodified lines | |||
| 197 | user_values_stack = vec![user_settings]; | 207 | user_values_stack = vec![user_settings]; |
| 198 | } | 208 | } |
| 199 | 209 | ||
| 210 | if let Some(release_settings) = &self.raw_user_settings.get(&*RELEASE_CHANNEL_NAME) { | ||
| 211 | if let Some(release_settings) = setting_value | ||
| 212 | .deserialize_setting(&release_settings) | ||
| 213 | .log_err() | ||
| 214 | { | ||
| 215 | user_values_stack.push(release_settings); | ||
| 216 | } | ||
| 217 | } | ||
| 218 | |||
| 200 | if let Some(setting) = setting_value | 219 | if let Some(setting) = setting_value |
| 201 | .load_setting(&default_settings, &user_values_stack, cx) | 220 | .load_setting(&default_settings, &user_values_stack, cx) |
| 202 | .context("A default setting must be added to the `default.json` file") | 221 | .context("A default setting must be added to the `default.json` file") |
| @@ -484,6 +503,15 @@ impl SettingsStore { · 281 unmodified lines | |||
| 484 | } | 503 | } |
| 485 | } | 504 | } |
| 486 | 505 | ||
| 506 | for release_stage in ["dev", "nightly", "stable", "preview"] { | ||
| 507 | let schema = combined_schema.schema.clone(); | ||
| 508 | combined_schema | ||
| 509 | .schema | ||
| 510 | .object() | ||
| 511 | .properties | ||
| 512 | .insert(release_stage.to_string(), schema.into()); | ||
| 513 | } | ||
| 514 | |||
| 487 | serde_json::to_value(&combined_schema).unwrap() | 515 | serde_json::to_value(&combined_schema).unwrap() |
| 488 | } | 516 | } |
| 489 | 517 | ||
| @@ -509,6 +537,16 @@ impl SettingsStore { · 19 unmodified lines | |||
| 509 | paths_stack.push(None); | 537 | paths_stack.push(None); |
| 510 | } | 538 | } |
| 511 | 539 | ||
| 540 | if let Some(release_settings) = &self.raw_user_settings.get(&*RELEASE_CHANNEL_NAME) { | ||
| 541 | if let Some(release_settings) = setting_value | ||
| 542 | .deserialize_setting(&release_settings) | ||
| 543 | .log_err() | ||
| 544 | { | ||
| 545 | user_settings_stack.push(release_settings); | ||
| 546 | paths_stack.push(None); | ||
| 547 | } | ||
| 548 | } | ||
| 549 | |||
| 512 | // If the global settings file changed, reload the global value for the field. | 550 | // If the global settings file changed, reload the global value for the field. |
| 513 | if changed_local_path.is_none() { | 551 | if changed_local_path.is_none() { |
| 514 | if let Some(value) = setting_value | 552 | if let Some(value) = setting_value |
| @@ -30,6 +30,7 @@ serde_json.workspace = true · 29 unmodified lines | |||
| 30 | git2 = { workspace = true, optional = true } | 30 | git2 = { workspace = true, optional = true } |
| 31 | dirs = "3.0" | 31 | dirs = "3.0" |
| 32 | take-until = "0.2.0" | 32 | take-until = "0.2.0" |
| 33 | parking_lot.workspace = true | ||
| 33 | 34 | ||
| 34 | [target.'cfg(windows)'.dependencies] | 35 | [target.'cfg(windows)'.dependencies] |
| 35 | tendril = "0.4.3" | 36 | tendril = "0.4.3" |
| @@ -6,12 +6,49 @@ pub use isahc::{ · 5 unmodified lines | |||
| 6 | Error, | 6 | Error, |
| 7 | }; | 7 | }; |
| 8 | pub use isahc::{AsyncBody, Request, Response}; | 8 | pub use isahc::{AsyncBody, Request, Response}; |
| 9 | use parking_lot::Mutex; | ||
| 9 | use smol::future::FutureExt; | 10 | use smol::future::FutureExt; |
| 10 | #[cfg(feature = "test-support")] | 11 | #[cfg(feature = "test-support")] |
| 11 | use std::fmt; | 12 | use std::fmt; |
| 12 | use std::{sync::Arc, time::Duration}; | 13 | use std::{sync::Arc, time::Duration}; |
| 13 | pub use url::Url; | 14 | pub use url::Url; |
| 14 | 15 | ||
| 16 | pub struct ZedHttpClient { | ||
| 17 | pub zed_host: Mutex<String>, | ||
| 18 | client: Box<dyn HttpClient>, | ||
| 19 | } | ||
| 20 | |||
| 21 | impl ZedHttpClient { | ||
| 22 | pub fn zed_url(&self, path: &str) -> String { | ||
| 23 | format!("{}{}", self.zed_host.lock(), path) | ||
| 24 | } | ||
| 25 | } | ||
| 26 | |||
| 27 | impl HttpClient for Arc<ZedHttpClient> { | ||
| 28 | fn send(&self, req: Request<AsyncBody>) -> BoxFuture<Result<Response<AsyncBody>, Error>> { | ||
| 29 | self.client.send(req) | ||
| 30 | } | ||
| 31 | } | ||
| 32 | |||
| 33 | impl HttpClient for ZedHttpClient { | ||
| 34 | fn send(&self, req: Request<AsyncBody>) -> BoxFuture<Result<Response<AsyncBody>, Error>> { | ||
| 35 | self.client.send(req) | ||
| 36 | } | ||
| 37 | } | ||
| 38 | |||
| 39 | pub fn zed_client(zed_host: &str) -> Arc<ZedHttpClient> { | ||
| 40 | Arc::new(ZedHttpClient { | ||
| 41 | zed_host: Mutex::new(zed_host.to_string()), | ||
| 42 | client: Box::new( | ||
| 43 | isahc::HttpClient::builder() | ||
| 44 | .connect_timeout(Duration::from_secs(5)) | ||
| 45 | .low_speed_timeout(100, Duration::from_secs(5)) | ||
| 46 | .build() | ||
| 47 | .unwrap(), | ||
| 48 | ), | ||
| 49 | }) | ||
| 50 | } | ||
| 51 | |||
| 15 | pub trait HttpClient: Send + Sync { | 52 | pub trait HttpClient: Send + Sync { |
| 16 | fn send(&self, req: Request<AsyncBody>) -> BoxFuture<Result<Response<AsyncBody>, Error>>; | 53 | fn send(&self, req: Request<AsyncBody>) -> BoxFuture<Result<Response<AsyncBody>, Error>>; |
| 17 | 54 | ||
| @@ -81,17 +118,20 @@ pub struct FakeHttpClient { · 63 unmodified lines | |||
| 81 | 118 | ||
| 82 | #[cfg(feature = "test-support")] | 119 | #[cfg(feature = "test-support")] |
| 83 | impl FakeHttpClient { | 120 | impl FakeHttpClient { |
| 84 | pub fn create<Fut, F>(handler: F) -> Arc<dyn HttpClient> | 121 | pub fn create<Fut, F>(handler: F) -> Arc<ZedHttpClient> |
| 85 | where | 122 | where |
| 86 | Fut: 'static + Send + futures::Future<Output = Result<Response<AsyncBody>, Error>>, | 123 | Fut: 'static + Send + futures::Future<Output = Result<Response<AsyncBody>, Error>>, |
| 87 | F: 'static + Send + Sync + Fn(Request<AsyncBody>) -> Fut, | 124 | F: 'static + Send + Sync + Fn(Request<AsyncBody>) -> Fut, |
| 88 | { | 125 | { |
| 89 | Arc::new(Self { | 126 | Arc::new(ZedHttpClient { |
| 90 | handler: Box::new(move |req| Box::pin(handler(req))), | 127 | zed_host: Mutex::new("http://test.example".into()), |
| 128 | client: Box::new(Self { | ||
| 129 | handler: Box::new(move |req| Box::pin(handler(req))), | ||
| 130 | }), | ||
| 91 | }) | 131 | }) |
| 92 | } | 132 | } |
| 93 | 133 | ||
| 94 | pub fn with_404_response() -> Arc<dyn HttpClient> { | 134 | pub fn with_404_response() -> Arc<ZedHttpClient> { |
| 95 | Self::create(|_| async move { | 135 | Self::create(|_| async move { |
| 96 | Ok(Response::builder() | 136 | Ok(Response::builder() |
| 97 | .status(404) | 137 | .status(404) |
| @@ -100,7 +140,7 @@ impl FakeHttpClient { · 2 unmodified lines | |||
| 100 | }) | 140 | }) |
| 101 | } | 141 | } |
| 102 | 142 | ||
| 103 | pub fn with_200_response() -> Arc<dyn HttpClient> { | 143 | pub fn with_200_response() -> Arc<ZedHttpClient> { |
| 104 | Self::create(|_| async move { | 144 | Self::create(|_| async move { |
| 105 | Ok(Response::builder() | 145 | Ok(Response::builder() |
| 106 | .status(200) | 146 | .status(200) |
| @@ -42,7 +42,7 @@ use theme::{ActiveTheme, ThemeRegistry, ThemeSettings}; · 41 unmodified lines | |||
| 42 | use util::{ | 42 | use util::{ |
| 43 | async_maybe, | 43 | async_maybe, |
| 44 | channel::{parse_zed_link, AppCommitSha, ReleaseChannel, RELEASE_CHANNEL}, | 44 | channel::{parse_zed_link, AppCommitSha, ReleaseChannel, RELEASE_CHANNEL}, |
| 45 | http::{self, HttpClient}, | 45 | http::{self, HttpClient, ZedHttpClient}, |
| 46 | paths::{self, CRASHES_DIR, CRASHES_RETIRED_DIR}, | 46 | paths::{self, CRASHES_DIR, CRASHES_RETIRED_DIR}, |
| 47 | ResultExt, | 47 | ResultExt, |
| 48 | }; | 48 | }; |
| @@ -59,7 +59,6 @@ fn main() { · 10 unmodified lines | |||
| 59 | menu::init(); | 59 | menu::init(); |
| 60 | zed_actions::init(); | 60 | zed_actions::init(); |
| 61 | 61 | ||
| 62 | let http = http::client(); | ||
| 63 | init_paths(); | 62 | init_paths(); |
| 64 | init_logger(); | 63 | init_logger(); |
| 65 | 64 | ||
| @@ -132,6 +131,9 @@ fn main() { · 66 unmodified lines | |||
| 132 | cx.set_global(store); | 131 | cx.set_global(store); |
| 133 | handle_settings_file_changes(user_settings_file_rx, cx); | 132 | handle_settings_file_changes(user_settings_file_rx, cx); |
| 134 | handle_keymap_file_changes(user_keymap_file_rx, cx); | 133 | handle_keymap_file_changes(user_keymap_file_rx, cx); |
| 134 | client::init_settings(cx); | ||
| 135 | |||
| 136 | let http = http::zed_client(&client::ClientSettings::get_global(cx).server_url); | ||
| 135 | 137 | ||
| 136 | let client = client::Client::new(http.clone(), cx); | 138 | let client = client::Client::new(http.clone(), cx); |
| 137 | let mut languages = LanguageRegistry::new(login_shell_env_loaded); | 139 | let mut languages = LanguageRegistry::new(login_shell_env_loaded); |
| @@ -201,7 +203,20 @@ fn main() { · 63 unmodified lines | |||
| 201 | languages.set_theme(cx.theme().clone()); | 203 | languages.set_theme(cx.theme().clone()); |
| 202 | cx.observe_global::<SettingsStore>({ | 204 | cx.observe_global::<SettingsStore>({ |
| 203 | let languages = languages.clone(); | 205 | let languages = languages.clone(); |
| 204 | move |cx| languages.set_theme(cx.theme().clone()) | 206 | let http = http.clone(); |
| 207 | let client = client.clone(); | ||
| 208 | |||
| 209 | move |cx| { | ||
| 210 | languages.set_theme(cx.theme().clone()); | ||
| 211 | let new_host = &client::ClientSettings::get_global(cx).server_url; | ||
| 212 | let mut host = http.zed_host.lock(); | ||
| 213 | if &*host != new_host { | ||
| 214 | *host = new_host.clone(); | ||
| 215 | if client.status().borrow().is_connected() { | ||
| 216 | client.reconnect(&cx.to_async()); | ||
| 217 | } | ||
| 218 | } | ||
| 219 | } | ||
| 205 | }) | 220 | }) |
| 206 | .detach(); | 221 | .detach(); |
| 207 | 222 | ||
| @@ -230,7 +245,7 @@ fn main() { · 22 unmodified lines | |||
| 230 | cx.set_global(Arc::downgrade(&app_state)); | 245 | cx.set_global(Arc::downgrade(&app_state)); |
| 231 | 246 | ||
| 232 | audio::init(Assets, cx); | 247 | audio::init(Assets, cx); |
| 233 | auto_update::init(http.clone(), client::ZED_SERVER_URL.clone(), cx); | 248 | auto_update::init(http.clone(), cx); |
| 234 | 249 | ||
| 235 | workspace::init(app_state.clone(), cx); | 250 | workspace::init(app_state.clone(), cx); |
| 236 | recent_projects::init(cx); | 251 | recent_projects::init(cx); |
| @@ -634,7 +649,7 @@ fn init_panic_hook(app: &App, installation_id: Option<String>, session_id: Strin · 397 unmodified lines | |||
| 634 | })); | 649 | })); |
| 635 | } | 650 | } |
| 636 | 651 | ||
| 637 | fn upload_panics_and_crashes(http: Arc<dyn HttpClient>, cx: &mut AppContext) { | 652 | fn upload_panics_and_crashes(http: Arc<ZedHttpClient>, cx: &mut AppContext) { |
| 638 | let telemetry_settings = *client::TelemetrySettings::get_global(cx); | 653 | let telemetry_settings = *client::TelemetrySettings::get_global(cx); |
| 639 | cx.background_executor() | 654 | cx.background_executor() |
| 640 | .spawn(async move { | 655 | .spawn(async move { |
| @@ -650,10 +665,10 @@ fn upload_panics_and_crashes(http: Arc<dyn HttpClient>, cx: &mut AppContext) { · 9 unmodified lines | |||
| 650 | 665 | ||
| 651 | /// upload panics to us (via zed.dev) | 666 | /// upload panics to us (via zed.dev) |
| 652 | async fn upload_previous_panics( | 667 | async fn upload_previous_panics( |
| 653 | http: Arc<dyn HttpClient>, | 668 | http: Arc<ZedHttpClient>, |
| 654 | telemetry_settings: client::TelemetrySettings, | 669 | telemetry_settings: client::TelemetrySettings, |
| 655 | ) -> Result<()> { | 670 | ) -> Result<()> { |
| 656 | let panic_report_url = format!("{}/api/panic", &*client::ZED_SERVER_URL); | 671 | let panic_report_url = http.zed_url("/api/panic"); |
| 657 | let mut children = smol::fs::read_dir(&*paths::LOGS_DIR).await?; | 672 | let mut children = smol::fs::read_dir(&*paths::LOGS_DIR).await?; |
| 658 | while let Some(child) = children.next().await { | 673 | while let Some(child) = children.next().await { |
| 659 | let child = child?; | 674 | let child = child?; |
| @@ -717,7 +732,7 @@ static LAST_CRASH_UPLOADED: &'static str = "LAST_CRASH_UPLOADED"; · 57 unmodified lines | |||
| 717 | /// upload crashes from apple's diagnostic reports to our server. | 732 | /// upload crashes from apple's diagnostic reports to our server. |
| 718 | /// (only if telemetry is enabled) | 733 | /// (only if telemetry is enabled) |
| 719 | async fn upload_previous_crashes( | 734 | async fn upload_previous_crashes( |
| 720 | http: Arc<dyn HttpClient>, | 735 | http: Arc<ZedHttpClient>, |
| 721 | telemetry_settings: client::TelemetrySettings, | 736 | telemetry_settings: client::TelemetrySettings, |
| 722 | ) -> Result<()> { | 737 | ) -> Result<()> { |
| 723 | if !telemetry_settings.diagnostics { | 738 | if !telemetry_settings.diagnostics { |
| @@ -728,7 +743,7 @@ async fn upload_previous_crashes( · 4 unmodified lines | |||
| 728 | .unwrap_or("zed-2024-01-17-221900.ips".to_string()); // don't upload old crash reports from before we had this. | 743 | .unwrap_or("zed-2024-01-17-221900.ips".to_string()); // don't upload old crash reports from before we had this. |
| 729 | let mut uploaded = last_uploaded.clone(); | 744 | let mut uploaded = last_uploaded.clone(); |
| 730 | 745 | ||
| 731 | let crash_report_url = format!("{}/api/crash", &*client::ZED_SERVER_URL); | 746 | let crash_report_url = http.zed_url("/api/crash"); |
| 732 | 747 | ||
| 733 | for dir in [&*CRASHES_DIR, &*CRASHES_RETIRED_DIR] { | 748 | for dir in [&*CRASHES_DIR, &*CRASHES_RETIRED_DIR] { |
| 734 | let mut children = smol::fs::read_dir(&dir).await?; | 749 | let mut children = smol::fs::read_dir(&dir).await?; |