Checkpoint
This commit is contained in:
parent
db6a3e1783
commit
ce75be91e1
9 changed files with 111 additions and 244 deletions
|
@ -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!(
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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},
|
||||||
|
|
|
@ -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())
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue