Checkpoint

This commit is contained in:
Antonio Scandurra 2023-10-22 18:25:24 +02:00
parent db6a3e1783
commit ce75be91e1
9 changed files with 111 additions and 244 deletions

View file

@ -14,8 +14,8 @@ use futures::{
future::BoxFuture, AsyncReadExt, FutureExt, SinkExt, StreamExt, TryFutureExt as _, TryStreamExt, future::BoxFuture, AsyncReadExt, FutureExt, SinkExt, StreamExt, TryFutureExt as _, TryStreamExt,
}; };
use gpui2::{ use gpui2::{
serde_json, AnyHandle, AnyWeakHandle, AnyWindowHandle, AppContext, AsyncAppContext, Handle, serde_json, AnyHandle, AnyWeakHandle, AppContext, AsyncAppContext, Handle, SemanticVersion,
SemanticVersion, Task, ViewContext, WeakHandle, Task, WeakHandle,
}; };
use lazy_static::lazy_static; use lazy_static::lazy_static;
use parking_lot::RwLock; use parking_lot::RwLock;
@ -235,7 +235,7 @@ struct ClientState {
dyn Send dyn Send
+ Sync + Sync
+ Fn( + Fn(
Subscriber, AnyHandle,
Box<dyn AnyTypedEnvelope>, Box<dyn AnyTypedEnvelope>,
&Arc<Client>, &Arc<Client>,
AsyncAppContext, AsyncAppContext,
@ -245,18 +245,10 @@ struct ClientState {
} }
enum WeakSubscriber { enum WeakSubscriber {
Entity { Entity { handle: AnyWeakHandle },
handle: AnyWeakHandle,
window_handle: Option<AnyWindowHandle>,
},
Pending(Vec<Box<dyn AnyTypedEnvelope>>), Pending(Vec<Box<dyn AnyTypedEnvelope>>),
} }
struct Subscriber {
handle: AnyHandle,
window_handle: Option<AnyWindowHandle>,
}
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Credentials { pub struct Credentials {
pub user_id: u64, pub user_id: u64,
@ -310,7 +302,7 @@ impl Drop for Subscription {
} }
} }
pub struct PendingEntitySubscription<T> { pub struct PendingEntitySubscription<T: 'static> {
client: Arc<Client>, client: Arc<Client>,
remote_id: u64, remote_id: u64,
_entity_type: PhantomData<T>, _entity_type: PhantomData<T>,
@ -335,7 +327,6 @@ where
id, id,
WeakSubscriber::Entity { WeakSubscriber::Entity {
handle: model.downgrade().into(), handle: model.downgrade().into(),
window_handle: None,
}, },
); );
drop(state); drop(state);
@ -349,7 +340,10 @@ where
} }
} }
impl<T> Drop for PendingEntitySubscription<T> { impl<T> Drop for PendingEntitySubscription<T>
where
T: 'static,
{
fn drop(&mut self) { fn drop(&mut self) {
if !self.consumed { if !self.consumed {
let mut state = self.client.state.write(); let mut state = self.client.state.write();
@ -494,7 +488,7 @@ impl Client {
Status::ConnectionLost => { Status::ConnectionLost => {
let this = self.clone(); let this = self.clone();
let reconnect_interval = state.reconnect_interval; let reconnect_interval = state.reconnect_interval;
state._reconnect_task = Some(cx.spawn(|cx| async move { state._reconnect_task = Some(cx.spawn(move |cx| async move {
#[cfg(any(test, feature = "test-support"))] #[cfg(any(test, feature = "test-support"))]
let mut rng = StdRng::seed_from_u64(0); let mut rng = StdRng::seed_from_u64(0);
#[cfg(not(any(test, feature = "test-support")))] #[cfg(not(any(test, feature = "test-support")))]
@ -521,39 +515,21 @@ impl Client {
})); }));
} }
Status::SignedOut | Status::UpgradeRequired => { Status::SignedOut | Status::UpgradeRequired => {
cx.update(|cx| self.telemetry.set_authenticated_user_info(None, false, cx)); cx.update(|cx| self.telemetry.set_authenticated_user_info(None, false, cx))
.log_err();
state._reconnect_task.take(); state._reconnect_task.take();
} }
_ => {} _ => {}
} }
} }
pub fn add_view_for_remote_entity<T>(
self: &Arc<Self>,
remote_id: u64,
cx: &mut ViewContext<T>,
) -> Subscription
where
T: 'static + Send + Sync,
{
let id = (TypeId::of::<T>(), remote_id);
self.state.write().entities_by_type_and_remote_id.insert(
id,
WeakSubscriber::Entity {
handle: cx.handle().into(),
window_handle: Some(cx.window_handle()),
},
);
Subscription::Entity {
client: Arc::downgrade(self),
id,
}
}
pub fn subscribe_to_entity<T>( pub fn subscribe_to_entity<T>(
self: &Arc<Self>, self: &Arc<Self>,
remote_id: u64, remote_id: u64,
) -> Result<PendingEntitySubscription<T>> { ) -> Result<PendingEntitySubscription<T>>
where
T: 'static + Send + Sync,
{
let id = (TypeId::of::<T>(), remote_id); let id = (TypeId::of::<T>(), remote_id);
let mut state = self.state.write(); let mut state = self.state.write();
@ -594,7 +570,7 @@ impl Client {
let prev_handler = state.message_handlers.insert( let prev_handler = state.message_handlers.insert(
message_type_id, message_type_id,
Arc::new(move |subscriber, envelope, client, cx| { Arc::new(move |subscriber, envelope, client, cx| {
let subscriber = subscriber.handle.downcast::<E>().unwrap(); let subscriber = subscriber.downcast::<E>().unwrap();
let envelope = envelope.into_any().downcast::<TypedEnvelope<M>>().unwrap(); let envelope = envelope.into_any().downcast::<TypedEnvelope<M>>().unwrap();
handler(subscriber, *envelope, client.clone(), cx).boxed() handler(subscriber, *envelope, client.clone(), cx).boxed()
}), }),
@ -643,22 +619,15 @@ impl Client {
F: 'static + Future<Output = Result<()>> + Send, F: 'static + Future<Output = Result<()>> + Send,
{ {
self.add_entity_message_handler::<M, E, _, _>(move |subscriber, message, client, cx| { self.add_entity_message_handler::<M, E, _, _>(move |subscriber, message, client, cx| {
handler( handler(subscriber.downcast::<E>().unwrap(), message, client, cx)
subscriber.handle.downcast::<E>().unwrap(),
message,
client,
cx,
)
}) })
} }
fn add_entity_message_handler<M, E, H, F>(self: &Arc<Self>, handler: H) fn add_entity_message_handler<M, E, H, F>(self: &Arc<Self>, handler: H)
where where
M: EntityMessage, M: EntityMessage,
H: 'static E: 'static + Send + Sync,
+ Send H: 'static + Send + Sync + Fn(AnyHandle, TypedEnvelope<M>, Arc<Self>, AsyncAppContext) -> F,
+ Sync
+ Fn(Subscriber, TypedEnvelope<M>, Arc<Self>, AsyncAppContext) -> F,
F: 'static + Future<Output = Result<()>> + Send, F: 'static + Future<Output = Result<()>> + Send,
{ {
let model_type_id = TypeId::of::<E>(); let model_type_id = TypeId::of::<E>();
@ -1079,7 +1048,7 @@ impl Client {
write!(&mut url, "&impersonate={}", impersonate_login).unwrap(); write!(&mut url, "&impersonate={}", impersonate_login).unwrap();
} }
cx.run_on_main(|cx| cx.open_url(&url))?.await; cx.run_on_main(move |cx| cx.open_url(&url))?.await;
// Receive the HTTP request from the user's browser. Retrieve the user id and encrypted // Receive the HTTP request from the user's browser. Retrieve the user id and encrypted
// access token from the query params. // access token from the query params.
@ -1269,10 +1238,7 @@ impl Client {
.get(&payload_type_id) .get(&payload_type_id)
.and_then(|handle| handle.upgrade()) .and_then(|handle| handle.upgrade())
{ {
subscriber = Some(Subscriber { subscriber = Some(handle);
handle,
window_handle: None,
});
} else if let Some((extract_entity_id, entity_type_id)) = } else if let Some((extract_entity_id, entity_type_id)) =
state.entity_id_extractors.get(&payload_type_id).zip( state.entity_id_extractors.get(&payload_type_id).zip(
state state
@ -1292,14 +1258,8 @@ impl Client {
return; return;
} }
Some(weak_subscriber @ _) => match weak_subscriber { Some(weak_subscriber @ _) => match weak_subscriber {
WeakSubscriber::Entity { WeakSubscriber::Entity { handle } => {
handle, subscriber = handle.upgrade();
window_handle,
} => {
subscriber = handle.upgrade().map(|handle| Subscriber {
handle,
window_handle: window_handle.clone(),
});
} }
WeakSubscriber::Pending(_) => {} WeakSubscriber::Pending(_) => {}
@ -1331,7 +1291,7 @@ impl Client {
sender_id, sender_id,
type_name type_name
); );
cx.spawn_on_main(|_| async move { cx.spawn_on_main(move |_| async move {
match future.await { match future.await {
Ok(()) => { Ok(()) => {
log::debug!( log::debug!(

View file

@ -159,7 +159,7 @@ impl Telemetry {
} }
let this = self.clone(); let this = self.clone();
cx.spawn(|mut cx| async move { cx.spawn(|cx| async move {
let mut system = System::new_all(); let mut system = System::new_all();
system.refresh_all(); system.refresh_all();

View file

@ -1,7 +1,7 @@
use super::{proto, Client, Status, TypedEnvelope}; use super::{proto, Client, Status, TypedEnvelope};
use anyhow::{anyhow, Context, Result}; use anyhow::{anyhow, Context, Result};
use collections::{hash_map::Entry, HashMap, HashSet}; use collections::{hash_map::Entry, HashMap, HashSet};
use feature_flags::FeatureFlagAppExt; use feature_flags2::FeatureFlagAppExt;
use futures::{channel::mpsc, future, AsyncReadExt, Future, StreamExt}; use futures::{channel::mpsc, future, AsyncReadExt, Future, StreamExt};
use gpui2::{AsyncAppContext, EventEmitter, Handle, ImageData, ModelContext, Task}; use gpui2::{AsyncAppContext, EventEmitter, Handle, ImageData, ModelContext, Task};
use postage::{sink::Sink, watch}; use postage::{sink::Sink, watch};
@ -78,7 +78,7 @@ pub struct UserStore {
client: Weak<Client>, client: Weak<Client>,
http: Arc<dyn HttpClient>, http: Arc<dyn HttpClient>,
_maintain_contacts: Task<()>, _maintain_contacts: Task<()>,
_maintain_current_user: Task<()>, _maintain_current_user: Task<Result<()>>,
} }
#[derive(Clone)] #[derive(Clone)]
@ -167,28 +167,20 @@ impl UserStore {
client.request(proto::GetPrivateUserInfo {}).log_err(); client.request(proto::GetPrivateUserInfo {}).log_err();
let (user, info) = futures::join!(fetch_user, fetch_metrics_id); let (user, info) = futures::join!(fetch_user, fetch_metrics_id);
if let Some(info) = info { cx.update(|cx| {
cx.update(|cx| { if let Some(info) = info {
cx.update_flags(info.staff, info.flags); cx.update_flags(info.staff, info.flags);
client.telemetry.set_authenticated_user_info( client.telemetry.set_authenticated_user_info(
Some(info.metrics_id.clone()), Some(info.metrics_id.clone()),
info.staff, info.staff,
cx, cx,
) )
}); }
} else { })?;
cx.read(|cx| {
client
.telemetry
.set_authenticated_user_info(None, false, cx)
});
}
current_user_tx.send(user).await.ok(); current_user_tx.send(user).await.ok();
this.update(&mut cx, |_, cx| { this.update(&mut cx, |_, cx| cx.notify())?;
cx.notify();
});
} }
} }
Status::SignedOut => { Status::SignedOut => {
@ -196,21 +188,20 @@ impl UserStore {
this.update(&mut cx, |this, cx| { this.update(&mut cx, |this, cx| {
cx.notify(); cx.notify();
this.clear_contacts() this.clear_contacts()
}) })?
.await; .await;
} }
Status::ConnectionLost => { Status::ConnectionLost => {
if let Some(this) = this.upgrade() { this.update(&mut cx, |this, cx| {
this.update(&mut cx, |this, cx| { cx.notify();
cx.notify(); this.clear_contacts()
this.clear_contacts() })?
}) .await;
.await;
}
} }
_ => {} _ => {}
} }
} }
Ok(())
}), }),
pending_contact_requests: Default::default(), pending_contact_requests: Default::default(),
} }
@ -233,7 +224,7 @@ impl UserStore {
count: message.payload.count, count: message.payload.count,
}); });
cx.notify(); cx.notify();
}); })?;
Ok(()) Ok(())
} }
@ -243,7 +234,7 @@ impl UserStore {
_: Arc<Client>, _: Arc<Client>,
mut cx: AsyncAppContext, mut cx: AsyncAppContext,
) -> Result<()> { ) -> Result<()> {
this.update(&mut cx, |_, cx| cx.emit(Event::ShowContacts)); this.update(&mut cx, |_, cx| cx.emit(Event::ShowContacts))?;
Ok(()) Ok(())
} }
@ -261,7 +252,7 @@ impl UserStore {
this.update_contacts_tx this.update_contacts_tx
.unbounded_send(UpdateContacts::Update(message.payload)) .unbounded_send(UpdateContacts::Update(message.payload))
.unwrap(); .unwrap();
}); })?;
Ok(()) Ok(())
} }
@ -297,6 +288,9 @@ impl UserStore {
// Users are fetched in parallel above and cached in call to get_users // Users are fetched in parallel above and cached in call to get_users
// No need to paralellize here // No need to paralellize here
let mut updated_contacts = Vec::new(); let mut updated_contacts = Vec::new();
let this = this
.upgrade()
.ok_or_else(|| anyhow!("can't upgrade user store handle"))?;
for contact in message.contacts { for contact in message.contacts {
let should_notify = contact.should_notify; let should_notify = contact.should_notify;
updated_contacts.push(( updated_contacts.push((
@ -309,7 +303,9 @@ impl UserStore {
for request in message.incoming_requests { for request in message.incoming_requests {
incoming_requests.push({ incoming_requests.push({
let user = this let user = this
.update(&mut cx, |this, cx| this.get_user(request.requester_id, cx)) .update(&mut cx, |this, cx| {
this.get_user(request.requester_id, cx)
})?
.await?; .await?;
(user, request.should_notify) (user, request.should_notify)
}); });
@ -318,7 +314,7 @@ impl UserStore {
let mut outgoing_requests = Vec::new(); let mut outgoing_requests = Vec::new();
for requested_user_id in message.outgoing_requests { for requested_user_id in message.outgoing_requests {
outgoing_requests.push( outgoing_requests.push(
this.update(&mut cx, |this, cx| this.get_user(requested_user_id, cx)) this.update(&mut cx, |this, cx| this.get_user(requested_user_id, cx))?
.await?, .await?,
); );
} }
@ -398,7 +394,7 @@ impl UserStore {
} }
cx.notify(); cx.notify();
}); })?;
Ok(()) Ok(())
}) })
@ -494,7 +490,7 @@ impl UserStore {
cx: &mut ModelContext<Self>, cx: &mut ModelContext<Self>,
) -> Task<Result<()>> { ) -> Task<Result<()>> {
let client = self.client.upgrade(); let client = self.client.upgrade();
cx.spawn_weak(|_, _| async move { cx.spawn(move |_, _| async move {
client client
.ok_or_else(|| anyhow!("can't upgrade client reference"))? .ok_or_else(|| anyhow!("can't upgrade client reference"))?
.request(proto::RespondToContactRequest { .request(proto::RespondToContactRequest {
@ -516,7 +512,7 @@ impl UserStore {
*self.pending_contact_requests.entry(user_id).or_insert(0) += 1; *self.pending_contact_requests.entry(user_id).or_insert(0) += 1;
cx.notify(); cx.notify();
cx.spawn(|this, mut cx| async move { cx.spawn(move |this, mut cx| async move {
let response = client let response = client
.ok_or_else(|| anyhow!("can't upgrade client reference"))? .ok_or_else(|| anyhow!("can't upgrade client reference"))?
.request(request) .request(request)
@ -531,7 +527,7 @@ impl UserStore {
} }
} }
cx.notify(); cx.notify();
}); })?;
response?; response?;
Ok(()) Ok(())
}) })
@ -574,11 +570,11 @@ impl UserStore {
}, },
cx, cx,
) )
}) })?
.await?; .await?;
} }
this.read_with(&cx, |this, _| { this.update(&mut cx, |this, _| {
user_ids user_ids
.iter() .iter()
.map(|user_id| { .map(|user_id| {
@ -588,7 +584,7 @@ impl UserStore {
.ok_or_else(|| anyhow!("user {} not found", user_id)) .ok_or_else(|| anyhow!("user {} not found", user_id))
}) })
.collect() .collect()
}) })?
}) })
} }
@ -614,7 +610,7 @@ impl UserStore {
} }
let load_users = self.get_users(vec![user_id], cx); let load_users = self.get_users(vec![user_id], cx);
cx.spawn(|this, mut cx| async move { cx.spawn(move |this, mut cx| async move {
load_users.await?; load_users.await?;
this.update(&mut cx, |this, _| { this.update(&mut cx, |this, _| {
this.users this.users
@ -700,7 +696,7 @@ impl Contact {
let user = user_store let user = user_store
.update(cx, |user_store, cx| { .update(cx, |user_store, cx| {
user_store.get_user(contact.user_id, cx) user_store.get_user(contact.user_id, cx)
}) })?
.await?; .await?;
Ok(Self { Ok(Self {
user, user,

View file

@ -430,7 +430,6 @@ impl<'a, 'w> WindowContext<'a, 'w> {
where where
G: 'static + Send + Sync, G: 'static + Send + Sync,
{ {
let global_type = TypeId::of::<G>();
let mut global = self.app.lease_global::<G>(); let mut global = self.app.lease_global::<G>();
let result = f(global.as_mut(), self); let result = f(global.as_mut(), self);
self.app.set_global(global); self.app.set_global(global);

View file

@ -2,7 +2,7 @@ use crate::{settings_store::SettingsStore, Setting};
use anyhow::Result; use anyhow::Result;
use fs::Fs; use fs::Fs;
use futures::{channel::mpsc, StreamExt}; use futures::{channel::mpsc, StreamExt};
use gpui2::{AppContext, Context, Executor}; use gpui2::{AppContext, Executor};
use std::{ use std::{
io::ErrorKind, io::ErrorKind,
path::{Path, PathBuf}, path::{Path, PathBuf},

View file

@ -10,14 +10,13 @@ use std::sync::Arc;
use clap::Parser; use clap::Parser;
use gpui2::{ use gpui2::{
div, px, size, view, AnyView, BorrowAppContext, Bounds, Context, Element, ViewContext, div, px, size, view, AnyView, Bounds, Context, Element, ViewContext, WindowBounds,
WindowBounds, WindowOptions, WindowOptions,
}; };
use log::LevelFilter; use log::LevelFilter;
use simplelog::SimpleLogger; use simplelog::SimpleLogger;
use story_selector::ComponentStory; use story_selector::ComponentStory;
use ui::prelude::*; use ui::{prelude::*, themed};
use ui::{themed, with_settings, FakeSettings};
use crate::assets::Assets; use crate::assets::Assets;
use crate::story_selector::StorySelector; use crate::story_selector::StorySelector;
@ -67,13 +66,7 @@ fn main() {
}, },
move |cx| { move |cx| {
view( view(
cx.entity(|cx| { cx.entity(|cx| StoryWrapper::new(selector.story(cx), theme)),
cx.with_global(FakeSettings::default(), |cx| {
cx.with_global(theme.clone(), |cx| {
StoryWrapper::new(selector.story(cx), theme)
})
})
}),
StoryWrapper::render, StoryWrapper::render,
) )
}, },
@ -87,27 +80,20 @@ fn main() {
pub struct StoryWrapper { pub struct StoryWrapper {
story: AnyView, story: AnyView,
theme: Theme, theme: Theme,
settings: FakeSettings,
} }
impl StoryWrapper { impl StoryWrapper {
pub(crate) fn new(story: AnyView, theme: Theme) -> Self { pub(crate) fn new(story: AnyView, theme: Theme) -> Self {
Self { Self { story, theme }
story,
theme,
settings: FakeSettings::default(),
}
} }
fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Element<ViewState = Self> { fn render(&mut self, cx: &mut ViewContext<Self>) -> impl Element<ViewState = Self> {
with_settings(self.settings.clone(), cx, |cx| { themed(self.theme.clone(), cx, |cx| {
themed(self.theme.clone(), cx, |cx| { div()
div() .flex()
.flex() .flex_col()
.flex_col() .size_full()
.size_full() .child(self.story.clone())
.child(self.story.clone())
})
}) })
} }
} }

View file

@ -1,8 +1,6 @@
use std::ops::Deref; use std::ops::Deref;
use gpui2::{ use gpui2::{rems, AbsoluteLength, WindowContext};
rems, AbsoluteLength, AnyElement, BorrowAppContext, Bounds, LayoutId, Pixels, WindowContext,
};
use crate::prelude::*; use crate::prelude::*;
@ -72,78 +70,3 @@ impl Default for FakeSettings {
} }
impl FakeSettings {} impl FakeSettings {}
pub fn with_settings<E, F>(
settings: FakeSettings,
cx: &mut ViewContext<E::ViewState>,
build_child: F,
) -> WithSettings<E>
where
E: Element,
F: FnOnce(&mut ViewContext<E::ViewState>) -> E,
{
let child = cx.with_global(settings.clone(), |cx| build_child(cx));
WithSettings { settings, child }
}
pub struct WithSettings<E> {
pub(crate) settings: FakeSettings,
pub(crate) child: E,
}
impl<E> IntoAnyElement<E::ViewState> for WithSettings<E>
where
E: Element,
{
fn into_any(self) -> AnyElement<E::ViewState> {
AnyElement::new(self)
}
}
impl<E: Element> Element for WithSettings<E> {
type ViewState = E::ViewState;
type ElementState = E::ElementState;
fn id(&self) -> Option<gpui2::ElementId> {
None
}
fn initialize(
&mut self,
view_state: &mut Self::ViewState,
element_state: Option<Self::ElementState>,
cx: &mut ViewContext<Self::ViewState>,
) -> Self::ElementState {
cx.with_global(self.settings.clone(), |cx| {
self.child.initialize(view_state, element_state, cx)
})
}
fn layout(
&mut self,
view_state: &mut E::ViewState,
element_state: &mut Self::ElementState,
cx: &mut ViewContext<E::ViewState>,
) -> LayoutId
where
Self: Sized,
{
cx.with_global(self.settings.clone(), |cx| {
self.child.layout(view_state, element_state, cx)
})
}
fn paint(
&mut self,
bounds: Bounds<Pixels>,
view_state: &mut Self::ViewState,
frame_state: &mut Self::ElementState,
cx: &mut ViewContext<Self::ViewState>,
) where
Self: Sized,
{
cx.with_global(self.settings.clone(), |cx| {
self.child.paint(bounds, view_state, frame_state, cx);
});
}
}

View file

@ -1,13 +1,12 @@
use gpui2::{
AnyElement, Bounds, Element, Hsla, IntoAnyElement, LayoutId, Pixels, Result, ViewContext,
WindowContext,
};
use serde::{de::Visitor, Deserialize, Deserializer};
use std::collections::HashMap; use std::collections::HashMap;
use std::fmt; use std::fmt;
use std::sync::Arc; use std::sync::Arc;
use gpui2::{
AnyElement, BorrowAppContext, Bounds, Element, Hsla, IntoAnyElement, LayoutId, Pixels, Result,
ViewContext, WindowContext,
};
use serde::{de::Visitor, Deserialize, Deserializer};
#[derive(Deserialize, Clone, Default, Debug)] #[derive(Deserialize, Clone, Default, Debug)]
pub struct Theme { pub struct Theme {
pub name: String, pub name: String,
@ -138,7 +137,9 @@ where
E: Element, E: Element,
F: FnOnce(&mut ViewContext<E::ViewState>) -> E, F: FnOnce(&mut ViewContext<E::ViewState>) -> E,
{ {
let child = cx.with_global(theme.clone(), |cx| build_child(cx)); cx.default_global::<ThemeStack>().0.push(theme.clone());
let child = build_child(cx);
cx.default_global::<ThemeStack>().0.pop();
Themed { theme, child } Themed { theme, child }
} }
@ -156,6 +157,9 @@ where
} }
} }
#[derive(Default)]
struct ThemeStack(Vec<Theme>);
impl<E: Element> Element for Themed<E> { impl<E: Element> Element for Themed<E> {
type ViewState = E::ViewState; type ViewState = E::ViewState;
type ElementState = E::ElementState; type ElementState = E::ElementState;
@ -170,9 +174,10 @@ impl<E: Element> Element for Themed<E> {
element_state: Option<Self::ElementState>, element_state: Option<Self::ElementState>,
cx: &mut ViewContext<Self::ViewState>, cx: &mut ViewContext<Self::ViewState>,
) -> Self::ElementState { ) -> Self::ElementState {
cx.with_global(self.theme.clone(), |cx| { cx.default_global::<ThemeStack>().0.push(self.theme.clone());
self.child.initialize(view_state, element_state, cx) let element_state = self.child.initialize(view_state, element_state, cx);
}) cx.default_global::<ThemeStack>().0.pop();
element_state
} }
fn layout( fn layout(
@ -184,9 +189,10 @@ impl<E: Element> Element for Themed<E> {
where where
Self: Sized, Self: Sized,
{ {
cx.with_global(self.theme.clone(), |cx| { cx.default_global::<ThemeStack>().0.push(self.theme.clone());
self.child.layout(view_state, element_state, cx) let layout_id = self.child.layout(view_state, element_state, cx);
}) cx.default_global::<ThemeStack>().0.pop();
layout_id
} }
fn paint( fn paint(
@ -198,9 +204,9 @@ impl<E: Element> Element for Themed<E> {
) where ) where
Self: Sized, Self: Sized,
{ {
cx.with_global(self.theme.clone(), |cx| { cx.default_global::<ThemeStack>().0.push(self.theme.clone());
self.child.paint(bounds, view_state, frame_state, cx); self.child.paint(bounds, view_state, frame_state, cx);
}); cx.default_global::<ThemeStack>().0.pop();
} }
} }

View file

@ -38,6 +38,7 @@ use util::{
http::HttpClient, http::HttpClient,
paths, ResultExt, paths, ResultExt,
}; };
use uuid::Uuid;
use zed2::{ensure_only_instance, AppState, Assets, IsOnlyInstance}; use zed2::{ensure_only_instance, AppState, Assets, IsOnlyInstance};
// use zed2::{ // use zed2::{
// assets::Assets, // assets::Assets,
@ -59,7 +60,7 @@ fn main() {
log::info!("========== starting zed =========="); log::info!("========== starting zed ==========");
let app = App::production(Arc::new(Assets)); let app = App::production(Arc::new(Assets));
// let installation_id = app.background().block(installation_id()).ok(); // let installation_id = app.executor().block(installation_id()).ok();
// let session_id = Uuid::new_v4().to_string(); // let session_id = Uuid::new_v4().to_string();
// init_panic_hook(&app, installation_id.clone(), session_id.clone()); // init_panic_hook(&app, installation_id.clone(), session_id.clone());
@ -259,15 +260,10 @@ fn main() {
} }
OpenRequest::CliConnection { connection } => { OpenRequest::CliConnection { connection } => {
let app_state = app_state.clone(); let app_state = app_state.clone();
if cx cx.spawn(move |cx| {
.spawn(move |cx| { handle_cli_connection(connection, app_state.clone(), cx)
handle_cli_connection(connection, app_state.clone(), cx) })
}) .detach();
.map(Task::detach)
.is_err()
{
break;
}
} }
OpenRequest::JoinChannel { channel_id: _ } => { OpenRequest::JoinChannel { channel_id: _ } => {
// cx // cx
@ -404,9 +400,7 @@ static PANIC_COUNT: AtomicU32 = AtomicU32::new(0);
fn init_panic_hook(app: &App, installation_id: Option<String>, session_id: String) { fn init_panic_hook(app: &App, installation_id: Option<String>, session_id: String) {
let is_pty = stdout_is_a_pty(); let is_pty = stdout_is_a_pty();
let app_version = app.app_version().ok(); let app_metadata = app.metadata();
let os_name = app.os_name();
let os_version = app.os_version().ok();
panic::set_hook(Box::new(move |info| { panic::set_hook(Box::new(move |info| {
let prior_panic_count = PANIC_COUNT.fetch_add(1, Ordering::SeqCst); let prior_panic_count = PANIC_COUNT.fetch_add(1, Ordering::SeqCst);
@ -442,8 +436,8 @@ fn init_panic_hook(app: &App, installation_id: Option<String>, session_id: Strin
std::process::exit(-1); std::process::exit(-1);
} }
let app_version = client::ZED_APP_VERSION let app_version = client2::ZED_APP_VERSION
.or(app_version) .or(app_metadata.app_version)
.map_or("dev".to_string(), |v| v.to_string()); .map_or("dev".to_string(), |v| v.to_string());
let backtrace = Backtrace::new(); let backtrace = Backtrace::new();
@ -470,8 +464,11 @@ fn init_panic_hook(app: &App, installation_id: Option<String>, session_id: Strin
}), }),
app_version: app_version.clone(), app_version: app_version.clone(),
release_channel: RELEASE_CHANNEL.display_name().into(), release_channel: RELEASE_CHANNEL.display_name().into(),
os_name: os_name.into(), os_name: app_metadata.os_name.into(),
os_version: os_version.as_ref().map(SemanticVersion::to_string), os_version: app_metadata
.os_version
.as_ref()
.map(SemanticVersion::to_string),
architecture: env::consts::ARCH.into(), architecture: env::consts::ARCH.into(),
panicked_on: SystemTime::now() panicked_on: SystemTime::now()
.duration_since(UNIX_EPOCH) .duration_since(UNIX_EPOCH)
@ -507,11 +504,11 @@ fn init_panic_hook(app: &App, installation_id: Option<String>, session_id: Strin
} }
fn upload_previous_panics(http: Arc<dyn HttpClient>, cx: &mut AppContext) { fn upload_previous_panics(http: Arc<dyn HttpClient>, cx: &mut AppContext) {
let telemetry_settings = *settings2::get::<client::TelemetrySettings>(cx); let telemetry_settings = *settings2::get::<client2::TelemetrySettings>(cx);
cx.executor() cx.executor()
.spawn(async move { .spawn(async move {
let panic_report_url = format!("{}/api/panic", &*client::ZED_SERVER_URL); let panic_report_url = format!("{}/api/panic", &*client2::ZED_SERVER_URL);
let mut children = smol::fs::read_dir(&*paths::LOGS_DIR).await?; let mut children = smol::fs::read_dir(&*paths::LOGS_DIR).await?;
while let Some(child) = children.next().await { while let Some(child) = children.next().await {
let child = child?; let child = child?;
@ -554,7 +551,7 @@ fn upload_previous_panics(http: Arc<dyn HttpClient>, cx: &mut AppContext) {
if let Some(panic) = panic { if let Some(panic) = panic {
let body = serde_json::to_string(&PanicRequest { let body = serde_json::to_string(&PanicRequest {
panic, panic,
token: client::ZED_SECRET_CLIENT_TOKEN.into(), token: client2::ZED_SECRET_CLIENT_TOKEN.into(),
}) })
.unwrap(); .unwrap();