Detailed changes
@@ -345,7 +345,7 @@ async fn test_channel_messages(cx: &mut TestAppContext) {
fn init_test(cx: &mut AppContext) -> Model<ChannelStore> {
let http = FakeHttpClient::with_404_response();
let client = Client::new(http.clone(), cx);
- let user_store = cx.build_model(|cx| UserStore::new(client.clone(), http, cx));
+ let user_store = cx.build_model(|cx| UserStore::new(client.clone(), cx));
let settings_store = SettingsStore::test(cx);
cx.set_global(settings_store);
@@ -8,7 +8,6 @@ use rpc::{
ConnectionId, Peer, Receipt, TypedEnvelope,
};
use std::sync::Arc;
-use util::http::FakeHttpClient;
pub struct FakeServer {
peer: Arc<Peer>,
@@ -195,8 +194,7 @@ impl FakeServer {
client: Arc<Client>,
cx: &mut TestAppContext,
) -> Model<UserStore> {
- let http_client = FakeHttpClient::with_404_response();
- let user_store = cx.build_model(|cx| UserStore::new(client, http_client, cx));
+ let user_store = cx.build_model(|cx| UserStore::new(client, cx));
assert_eq!(
self.receive::<proto::GetUsers>()
.await
@@ -2,8 +2,8 @@ use super::{proto, Client, Status, TypedEnvelope};
use anyhow::{anyhow, Context, Result};
use collections::{hash_map::Entry, HashMap, HashSet};
use feature_flags::FeatureFlagAppExt;
-use futures::{channel::mpsc, future, AsyncReadExt, Future, StreamExt};
-use gpui::{AsyncAppContext, EventEmitter, ImageData, Model, ModelContext, Task};
+use futures::{channel::mpsc, AsyncReadExt, Future, StreamExt};
+use gpui::{AsyncAppContext, EventEmitter, ImageData, Model, ModelContext, SharedString, Task};
use postage::{sink::Sink, watch};
use rpc::proto::{RequestMessage, UsersResponse};
use std::sync::{Arc, Weak};
@@ -20,7 +20,7 @@ pub struct ParticipantIndex(pub u32);
pub struct User {
pub id: UserId,
pub github_login: String,
- pub avatar: Option<Arc<ImageData>>,
+ pub avatar_uri: SharedString,
}
#[derive(Clone, Debug, PartialEq, Eq)]
@@ -76,7 +76,6 @@ pub struct UserStore {
pending_contact_requests: HashMap<u64, usize>,
invite_info: Option<InviteInfo>,
client: Weak<Client>,
- http: Arc<dyn HttpClient>,
_maintain_contacts: Task<()>,
_maintain_current_user: Task<Result<()>>,
}
@@ -114,7 +113,6 @@ enum UpdateContacts {
impl UserStore {
pub fn new(
client: Arc<Client>,
- http: Arc<dyn HttpClient>,
cx: &mut ModelContext<Self>,
) -> Self {
let (mut current_user_tx, current_user_rx) = watch::channel();
@@ -134,7 +132,6 @@ impl UserStore {
invite_info: None,
client: Arc::downgrade(&client),
update_contacts_tx,
- http,
_maintain_contacts: cx.spawn(|this, mut cx| async move {
let _subscriptions = rpc_subscriptions;
while let Some(message) = update_contacts_rx.next().await {
@@ -445,6 +442,12 @@ impl UserStore {
self.perform_contact_request(user_id, proto::RemoveContact { user_id }, cx)
}
+ pub fn has_incoming_contact_request(&self, user_id: u64) -> bool {
+ self.incoming_contact_requests
+ .iter()
+ .any(|user| user.id == user_id)
+ }
+
pub fn respond_to_contact_request(
&mut self,
requester_id: u64,
@@ -616,17 +619,14 @@ impl UserStore {
cx: &mut ModelContext<Self>,
) -> Task<Result<Vec<Arc<User>>>> {
let client = self.client.clone();
- let http = self.http.clone();
cx.spawn(|this, mut cx| async move {
if let Some(rpc) = client.upgrade() {
let response = rpc.request(request).await.context("error loading users")?;
- let users = future::join_all(
- response
- .users
- .into_iter()
- .map(|user| User::new(user, http.as_ref())),
- )
- .await;
+ let users = response
+ .users
+ .into_iter()
+ .map(|user| User::new(user))
+ .collect::<Vec<_>>();
this.update(&mut cx, |this, _| {
for user in &users {
@@ -659,11 +659,11 @@ impl UserStore {
}
impl User {
- async fn new(message: proto::User, http: &dyn HttpClient) -> Arc<Self> {
+ fn new(message: proto::User) -> Arc<Self> {
Arc::new(User {
id: message.id,
github_login: message.github_login,
- avatar: fetch_avatar(http, &message.avatar_url).warn_on_err().await,
+ avatar_uri: message.avatar_url.into(),
})
}
}
@@ -1823,7 +1823,7 @@ async fn test_active_call_events(
owner: Arc::new(User {
id: client_a.user_id().unwrap(),
github_login: "user_a".to_string(),
- avatar: None,
+ avatar_uri: "avatar_a".into(),
}),
project_id: project_a_id,
worktree_root_names: vec!["a".to_string()],
@@ -1841,7 +1841,7 @@ async fn test_active_call_events(
owner: Arc::new(User {
id: client_b.user_id().unwrap(),
github_login: "user_b".to_string(),
- avatar: None,
+ avatar_uri: "avatar_b".into(),
}),
project_id: project_b_id,
worktree_root_names: vec!["b".to_string()]
@@ -209,7 +209,7 @@ impl TestServer {
});
let fs = FakeFs::new(cx.executor());
- let user_store = cx.build_model(|cx| UserStore::new(client.clone(), http, cx));
+ let user_store = cx.build_model(|cx| UserStore::new(client.clone(), cx));
let workspace_store = cx.build_model(|cx| WorkspaceStore::new(client.clone(), cx));
let mut language_registry = LanguageRegistry::test();
language_registry.set_executor(cx.executor());
@@ -364,13 +364,7 @@ impl ChatPanel {
if !is_continuation {
result = result.child(
h_stack()
- .children(
- message
- .sender
- .avatar
- .clone()
- .map(|avatar| Avatar::data(avatar)),
- )
+ .child(Avatar::new(message.sender.avatar_uri.clone()))
.child(Label::new(message.sender.github_login.clone()))
.child(Label::new(format_timestamp(
message.timestamp,
@@ -659,7 +653,7 @@ mod tests {
timestamp: OffsetDateTime::now_utc(),
sender: Arc::new(client::User {
github_login: "fgh".into(),
- avatar: None,
+ avatar_uri: "avatar_fgh".into(),
id: 103,
}),
nonce: 5,
@@ -234,7 +234,7 @@ mod tests {
user: Arc::new(User {
github_login: "a-b".into(),
id: 101,
- avatar: None,
+ avatar_uri: "avatar_a-b".into(),
}),
kind: proto::channel_member::Kind::Member,
role: proto::ChannelRole::Member,
@@ -243,7 +243,7 @@ mod tests {
user: Arc::new(User {
github_login: "C_D".into(),
id: 102,
- avatar: None,
+ avatar_uri: "avatar_C_D".into(),
}),
kind: proto::channel_member::Kind::Member,
role: proto::ChannelRole::Member,
@@ -275,7 +275,7 @@ mod tests {
cx.update(|cx| {
let http = FakeHttpClient::with_404_response();
let client = Client::new(http.clone(), cx);
- let user_store = cx.build_model(|cx| UserStore::new(client.clone(), http, cx));
+ let user_store = cx.build_model(|cx| UserStore::new(client.clone(), cx));
let settings = SettingsStore::test(cx);
cx.set_global(settings);
theme::init(theme::LoadThemes::JustBase, cx);
@@ -1155,7 +1155,7 @@ impl CollabPanel {
let tooltip = format!("Follow {}", user.github_login);
ListItem::new(SharedString::from(user.github_login.clone()))
- .left_child(Avatar::data(user.avatar.clone().unwrap()))
+ .left_child(Avatar::new(user.avatar_uri.clone()))
.child(
h_stack()
.w_full()
@@ -2365,44 +2365,45 @@ impl CollabPanel {
let busy = contact.busy || calling;
let user_id = contact.user.id;
let github_login = SharedString::from(contact.user.github_login.clone());
- let mut item = ListItem::new(github_login.clone())
- .on_click(cx.listener(move |this, _, cx| this.call(user_id, cx)))
- .child(
- h_stack()
- .w_full()
- .justify_between()
- .child(Label::new(github_login.clone()))
- .when(calling, |el| {
- el.child(Label::new("Calling").color(Color::Muted))
- })
- .when(!calling, |el| {
- el.child(
- div()
- .id("remove_contact")
- .invisible()
- .group_hover("", |style| style.visible())
- .child(
- IconButton::new("remove_contact", Icon::Close)
- .icon_color(Color::Muted)
- .tooltip(|cx| Tooltip::text("Remove Contact", cx))
- .on_click(cx.listener({
- let github_login = github_login.clone();
- move |this, _, cx| {
- this.remove_contact(user_id, &github_login, cx);
- }
- })),
- ),
- )
- }),
- )
- .left_child(
- // todo!() handle contacts with no avatar
- Avatar::data(contact.user.avatar.clone().unwrap())
- .availability_indicator(if online { Some(!busy) } else { None }),
- )
- .when(online && !busy, |el| {
- el.on_click(cx.listener(move |this, _, cx| this.call(user_id, cx)))
- });
+ let mut item =
+ ListItem::new(github_login.clone())
+ .on_click(cx.listener(move |this, _, cx| this.call(user_id, cx)))
+ .child(
+ h_stack()
+ .w_full()
+ .justify_between()
+ .child(Label::new(github_login.clone()))
+ .when(calling, |el| {
+ el.child(Label::new("Calling").color(Color::Muted))
+ })
+ .when(!calling, |el| {
+ el.child(
+ div()
+ .id("remove_contact")
+ .invisible()
+ .group_hover("", |style| style.visible())
+ .child(
+ IconButton::new("remove_contact", Icon::Close)
+ .icon_color(Color::Muted)
+ .tooltip(|cx| Tooltip::text("Remove Contact", cx))
+ .on_click(cx.listener({
+ let github_login = github_login.clone();
+ move |this, _, cx| {
+ this.remove_contact(user_id, &github_login, cx);
+ }
+ })),
+ ),
+ )
+ }),
+ )
+ .left_child(
+ // todo!() handle contacts with no avatar
+ Avatar::new(contact.user.avatar_uri.clone())
+ .availability_indicator(if online { Some(!busy) } else { None }),
+ )
+ .when(online && !busy, |el| {
+ el.on_click(cx.listener(move |this, _, cx| this.call(user_id, cx)))
+ });
div()
.id(github_login.clone())
@@ -2474,7 +2475,7 @@ impl CollabPanel {
.child(Label::new(github_login.clone()))
.child(h_stack().children(controls)),
)
- .when_some(user.avatar.clone(), |el, avatar| el.left_avatar(avatar))
+ .left_avatar(user.avatar_uri.clone())
}
fn render_contact_placeholder(
@@ -2532,7 +2533,9 @@ impl CollabPanel {
let result = FacePile {
faces: participants
.iter()
- .filter_map(|user| Some(Avatar::data(user.avatar.clone()?).into_any_element()))
+ .filter_map(|user| {
+ Some(Avatar::new(user.avatar_uri.clone()).into_any_element())
+ })
.take(FACEPILE_LIMIT)
.chain(if extra_count > 0 {
// todo!() @nate - this label looks wrong.
@@ -7,7 +7,7 @@ use gpui::{
use picker::{Picker, PickerDelegate};
use std::sync::Arc;
use theme::ActiveTheme as _;
-use ui::prelude::*;
+use ui::{prelude::*, Avatar};
use util::{ResultExt as _, TryFutureExt};
use workspace::ModalView;
@@ -187,7 +187,7 @@ impl PickerDelegate for ContactFinderDelegate {
div()
.flex_1()
.justify_between()
- .children(user.avatar.clone().map(|avatar| img(avatar)))
+ .child(Avatar::new(user.avatar_uri.clone()))
.child(Label::new(user.github_login.clone()))
.children(icon_path.map(|icon_path| svg().path(icon_path))),
)
@@ -232,43 +232,41 @@ impl Render for CollabTitlebarItem {
})
.child(h_stack().px_1p5().map(|this| {
if let Some(user) = current_user {
- this.when_some(user.avatar.clone(), |this, avatar| {
- // TODO: Finish implementing user menu popover
- //
- this.child(
- popover_menu("user-menu")
- .menu(|cx| {
- ContextMenu::build(cx, |menu, _| menu.header("ADADA"))
- })
- .trigger(
- ButtonLike::new("user-menu")
- .child(
- h_stack()
- .gap_0p5()
- .child(Avatar::data(avatar))
- .child(
- IconElement::new(Icon::ChevronDown)
- .color(Color::Muted),
- ),
- )
- .style(ButtonStyle::Subtle)
- .tooltip(move |cx| {
- Tooltip::text("Toggle User Menu", cx)
- }),
- )
- .anchor(gpui::AnchorCorner::TopRight),
- )
- // this.child(
- // ButtonLike::new("user-menu")
- // .child(
- // h_stack().gap_0p5().child(Avatar::data(avatar)).child(
- // IconElement::new(Icon::ChevronDown).color(Color::Muted),
- // ),
- // )
- // .style(ButtonStyle::Subtle)
- // .tooltip(move |cx| Tooltip::text("Toggle User Menu", cx)),
- // )
- })
+ // TODO: Finish implementing user menu popover
+ //
+ this.child(
+ popover_menu("user-menu")
+ .menu(|cx| {
+ ContextMenu::build(cx, |menu, _| menu.header("ADADA"))
+ })
+ .trigger(
+ ButtonLike::new("user-menu")
+ .child(
+ h_stack()
+ .gap_0p5()
+ .child(Avatar::new(user.avatar_uri.clone()))
+ .child(
+ IconElement::new(Icon::ChevronDown)
+ .color(Color::Muted),
+ ),
+ )
+ .style(ButtonStyle::Subtle)
+ .tooltip(move |cx| {
+ Tooltip::text("Toggle User Menu", cx)
+ }),
+ )
+ .anchor(gpui::AnchorCorner::TopRight),
+ )
+ // this.child(
+ // ButtonLike::new("user-menu")
+ // .child(
+ // h_stack().gap_0p5().child(Avatar::data(avatar)).child(
+ // IconElement::new(Icon::ChevronDown).color(Color::Muted),
+ // ),
+ // )
+ // .style(ButtonStyle::Subtle)
+ // .tooltip(move |cx| Tooltip::text("Toggle User Menu", cx)),
+ // )
} else {
this.child(Button::new("sign_in", "Sign in").on_click(move |_, cx| {
let client = client.clone();
@@ -425,26 +423,20 @@ impl CollabTitlebarItem {
) -> Option<FacePile> {
let followers = project_id.map_or(&[] as &[_], |id| room.followers_for(peer_id, id));
let mut pile = FacePile::default();
- pile.extend(
- user.avatar
- .clone()
- .map(|avatar| {
- div()
- .child(
- Avatar::data(avatar.clone())
- .grayscale(!is_present)
- .border_color(if is_speaking {
- gpui::blue()
- } else if is_muted {
- gpui::red()
- } else {
- Hsla::default()
- }),
- )
- .into_any_element()
- })
- .into_iter()
- .chain(followers.iter().filter_map(|follower_peer_id| {
+ pile.child(
+ div()
+ .child(
+ Avatar::new(user.avatar_uri.clone())
+ .grayscale(!is_present)
+ .border_color(if is_speaking {
+ gpui::blue()
+ } else if is_muted {
+ gpui::red()
+ } else {
+ Hsla::default()
+ }),
+ )
+ .children(followers.iter().filter_map(|follower_peer_id| {
let follower = room
.remote_participants()
.values()
@@ -454,10 +446,8 @@ impl CollabTitlebarItem {
.then_some(current_user)
})?
.clone();
- follower
- .avatar
- .clone()
- .map(|avatar| div().child(Avatar::data(avatar.clone())).into_any_element())
+
+ Some(div().child(Avatar::new(follower.avatar_uri.clone())))
})),
);
Some(pile)
@@ -1,11 +1,12 @@
use gpui::{
- div, AnyElement, Div, ElementId, IntoElement, ParentElement as _, RenderOnce, Styled,
- WindowContext,
+ div, AnyElement, Div, ElementId, IntoElement, ParentElement as _, ParentElement, RenderOnce,
+ Styled, WindowContext,
};
+use smallvec::SmallVec;
#[derive(Default, IntoElement)]
pub struct FacePile {
- pub faces: Vec<AnyElement>,
+ pub faces: SmallVec<[AnyElement; 2]>,
}
impl RenderOnce for FacePile {
@@ -25,8 +26,8 @@ impl RenderOnce for FacePile {
}
}
-impl Extend<AnyElement> for FacePile {
- fn extend<T: IntoIterator<Item = AnyElement>>(&mut self, children: T) {
- self.faces.extend(children);
+impl ParentElement for FacePile {
+ fn children_mut(&mut self) -> &mut SmallVec<[AnyElement; 2]> {
+ &mut self.faces
}
}
@@ -6,11 +6,11 @@ use collections::HashMap;
use db::kvp::KEY_VALUE_STORE;
use futures::StreamExt;
use gpui::{
- actions, div, img, serde_json, svg, AnyElement, AnyView, AppContext, AsyncAppContext, Context,
- CursorStyle, Div, Entity, EventEmitter, Flatten, FocusHandle, FocusableView,
- InteractiveElement, IntoElement, ListAlignment, ListState, Model, MouseButton, ParentElement,
- Render, Stateful, StatefulInteractiveElement, Task, View, ViewContext, VisualContext, WeakView,
- WindowContext,
+ actions, div, img, px, serde_json, svg, AnyElement, AnyView, AppContext, AsyncAppContext,
+ AsyncWindowContext, Context, CursorStyle, Div, Element, Entity, EventEmitter, Flatten,
+ FocusHandle, FocusableView, InteractiveElement, IntoElement, ListAlignment, ListScrollEvent,
+ ListState, Model, MouseButton, ParentElement, Render, Stateful, StatefulInteractiveElement,
+ Task, View, ViewContext, VisualContext, WeakView, WindowContext,
};
use notifications::{NotificationEntry, NotificationEvent, NotificationStore};
use project::Fs;
@@ -80,7 +80,9 @@ impl NotificationPanel {
let user_store = workspace.app_state().user_store.clone();
let workspace_handle = workspace.weak_handle();
- cx.build_view(|cx| {
+ cx.build_view(|cx: &mut ViewContext<Self>| {
+ let view = cx.view().clone();
+
let mut status = client.status();
cx.spawn(|this, mut cx| async move {
while let Some(_) = status.next().await {
@@ -97,25 +99,30 @@ impl NotificationPanel {
.detach();
let mut notification_list =
- ListState::new(0, ListAlignment::Top, 1000., move |this, ix, cx| {
- this.render_notification(ix, cx).unwrap_or_else(|| div())
+ ListState::new(0, ListAlignment::Top, px(1000.), move |ix, cx| {
+ view.update(cx, |this, cx| {
+ this.render_notification(ix, cx)
+ .unwrap_or_else(|| div().into_any())
+ })
});
- notification_list.set_scroll_handler(|visible_range, count, this, cx| {
- if count.saturating_sub(visible_range.end) < LOADING_THRESHOLD {
- if let Some(task) = this
- .notification_store
- .update(cx, |store, cx| store.load_more_notifications(false, cx))
- {
- task.detach();
+ notification_list.set_scroll_handler(cx.listener(
+ |this, event: &ListScrollEvent, cx| {
+ if event.count.saturating_sub(event.visible_range.end) < LOADING_THRESHOLD {
+ if let Some(task) = this
+ .notification_store
+ .update(cx, |store, cx| store.load_more_notifications(false, cx))
+ {
+ task.detach();
+ }
}
- }
- });
+ },
+ ));
let mut this = Self {
fs,
client,
user_store,
- local_timezone: cx.platform().local_timezone(),
+ local_timezone: cx.local_timezone(),
channel_store: ChannelStore::global(cx),
notification_store: NotificationStore::global(cx),
notification_list,
@@ -146,7 +153,10 @@ impl NotificationPanel {
})
}
- pub fn load(workspace: WeakView<Workspace>, cx: AsyncAppContext) -> Task<Result<View<Self>>> {
+ pub fn load(
+ workspace: WeakView<Workspace>,
+ cx: AsyncWindowContext,
+ ) -> Task<Result<View<Self>>> {
cx.spawn(|mut cx| async move {
let serialized_panel = if let Some(panel) = cx
.background_executor()
@@ -160,24 +170,22 @@ impl NotificationPanel {
None
};
- Flatten::flatten(cx.update(|cx| {
- workspace.update(cx, |workspace, cx| {
- let panel = Self::new(workspace, cx);
- if let Some(serialized_panel) = serialized_panel {
- panel.update(cx, |panel, cx| {
- panel.width = serialized_panel.width;
- cx.notify();
- });
- }
- panel
- })
- }))
+ workspace.update(&mut cx, |workspace, cx| {
+ let panel = Self::new(workspace, cx);
+ if let Some(serialized_panel) = serialized_panel {
+ panel.update(cx, |panel, cx| {
+ panel.width = serialized_panel.width;
+ cx.notify();
+ });
+ }
+ panel
+ })
})
}
fn serialize(&mut self, cx: &mut ViewContext<Self>) {
let width = self.width;
- self.pending_serialization = cx.background().spawn(
+ self.pending_serialization = cx.background_executor().spawn(
async move {
KEY_VALUE_STORE
.write_kvp(
@@ -217,17 +225,17 @@ impl NotificationPanel {
.child(
v_stack().child(Label::new(text)).child(
h_stack()
- .child(Label::from(format_timestamp(
+ .child(Label::new(format_timestamp(
timestamp,
now,
self.local_timezone,
)))
.children(if let Some(is_accepted) = response {
- Some(Label::new(if is_accepted {
+ Some(div().child(Label::new(if is_accepted {
"You accepted"
} else {
"You declined"
- }))
+ })))
} else if needs_response {
Some(
h_stack()
@@ -262,7 +270,8 @@ impl NotificationPanel {
None
}),
),
- ),
+ )
+ .into_any(),
)
}
@@ -355,7 +364,7 @@ impl NotificationPanel {
.or_insert_with(|| {
let client = self.client.clone();
cx.spawn(|this, mut cx| async move {
- cx.background().timer(MARK_AS_READ_DELAY).await;
+ cx.background_executor().timer(MARK_AS_READ_DELAY).await;
client
.request(proto::MarkNotificationRead { notification_id })
.await?;
@@ -867,7 +867,7 @@ impl Project {
languages.set_executor(cx.executor());
let http_client = util::http::FakeHttpClient::with_404_response();
let client = cx.update(|cx| client::Client::new(http_client.clone(), cx));
- let user_store = cx.build_model(|cx| UserStore::new(client.clone(), http_client, cx));
+ let user_store = cx.build_model(|cx| UserStore::new(client.clone(), cx));
let project = cx.update(|cx| {
Project::local(
client,
@@ -58,16 +58,8 @@ impl RenderOnce for Avatar {
}
impl Avatar {
- pub fn uri(src: impl Into<SharedString>) -> Self {
- Self::source(src.into().into())
- }
-
- pub fn data(src: Arc<ImageData>) -> Self {
- Self::source(src.into())
- }
-
- pub fn source(src: ImageSource) -> Self {
- Self {
+ pub fn new(src: impl Into<ImageSource>) -> Self {
+ Avatar {
image: img(src),
is_available: None,
border_color: None,
@@ -107,7 +107,7 @@ impl ListItem {
}
pub fn left_avatar(mut self, left_avatar: impl Into<ImageSource>) -> Self {
- self.left_slot = Some(Avatar::source(left_avatar.into()).into_any_element());
+ self.left_slot = Some(Avatar::new(left_avatar).into_any_element());
self
}
}
@@ -13,18 +13,18 @@ impl Render for AvatarStory {
Story::container()
.child(Story::title_for::<Avatar>())
.child(Story::label("Default"))
- .child(Avatar::uri(
+ .child(Avatar::new(
"https://avatars.githubusercontent.com/u/1714999?v=4",
))
- .child(Avatar::uri(
+ .child(Avatar::new(
"https://avatars.githubusercontent.com/u/326587?v=4",
))
.child(
- Avatar::uri("https://avatars.githubusercontent.com/u/326587?v=4")
+ Avatar::new("https://avatars.githubusercontent.com/u/326587?v=4")
.availability_indicator(true),
)
.child(
- Avatar::uri("https://avatars.githubusercontent.com/u/326587?v=4")
+ Avatar::new("https://avatars.githubusercontent.com/u/326587?v=4")
.availability_indicator(false),
)
}
@@ -360,7 +360,7 @@ impl AppState {
let languages = Arc::new(LanguageRegistry::test());
let http_client = util::http::FakeHttpClient::with_404_response();
let client = Client::new(http_client.clone(), cx);
- let user_store = cx.build_model(|cx| UserStore::new(client.clone(), http_client, cx));
+ let user_store = cx.build_model(|cx| UserStore::new(client.clone(), cx));
let workspace_store = cx.build_model(|cx| WorkspaceStore::new(client.clone(), cx));
theme::init(theme::LoadThemes::JustBase, cx);
@@ -143,7 +143,7 @@ fn main() {
language::init(cx);
languages::init(languages.clone(), node_runtime.clone(), cx);
- let user_store = cx.build_model(|cx| UserStore::new(client.clone(), http.clone(), cx));
+ let user_store = cx.build_model(|cx| UserStore::new(client.clone(), cx));
let workspace_store = cx.build_model(|cx| WorkspaceStore::new(client.clone(), cx));
cx.set_global(client.clone());
@@ -165,10 +165,10 @@ pub fn initialize_workspace(app_state: Arc<AppState>, cx: &mut AppContext) {
collab_ui::collab_panel::CollabPanel::load(workspace_handle.clone(), cx.clone());
let chat_panel =
collab_ui::chat_panel::ChatPanel::load(workspace_handle.clone(), cx.clone());
- // let notification_panel = collab_ui::notification_panel::NotificationPanel::load(
- // workspace_handle.clone(),
- // cx.clone(),
- // );
+ let notification_panel = collab_ui::notification_panel::NotificationPanel::load(
+ workspace_handle.clone(),
+ cx.clone(),
+ );
let (
project_panel,
terminal_panel,