History

Refine messages on waiting to join screen and include host avatar

Nathan Sobo committed 4 years ago

Commit 7c3eebf1 parent 91257f313 files · +125 −29Browse files

Unified · Split

13 files
  1. assets/themes/cave-dark.json +4 −0
  2. assets/themes/cave-light.json +4 −0
  3. assets/themes/dark.json +4 −0
  4. assets/themes/light.json +4 −0
  5. assets/themes/solarized-dark.json +4 −0
  6. assets/themes/solarized-light.json +4 −0
  7. assets/themes/sulphurpool-dark.json +4 −0
  8. assets/themes/sulphurpool-light.json +4 −0
  9. crates/contacts_panel/src/contacts_panel.rs +9 −8
  10. crates/theme/src/theme.rs +1 −0
  11. crates/workspace/src/workspace.rs +72 −21
  12. script/watch-themes +7 −0
  13. styles/src/styleTree/workspace.ts +4 −0
assets/themes/cave-dark.json+4−0
@@ -90,6 +90,10 @@ · 89 unmodified lines
9090 },
9191 "workspace": {
9292 "background": "#26232a",
93+ "joining_project_avatar": {
94+ "corner_radius": 40,
95+ "width": 80
96+ },
9397 "joining_project_message": {
9498 "padding": 12,
9599 "family": "Zed Sans",
assets/themes/cave-light.json+4−0
@@ -90,6 +90,10 @@ · 89 unmodified lines
9090 },
9191 "workspace": {
9292 "background": "#e2dfe7",
93+ "joining_project_avatar": {
94+ "corner_radius": 40,
95+ "width": 80
96+ },
9397 "joining_project_message": {
9498 "padding": 12,
9599 "family": "Zed Sans",
assets/themes/dark.json+4−0
@@ -90,6 +90,10 @@ · 89 unmodified lines
9090 },
9191 "workspace": {
9292 "background": "#1c1c1c",
93+ "joining_project_avatar": {
94+ "corner_radius": 40,
95+ "width": 80
96+ },
9397 "joining_project_message": {
9498 "padding": 12,
9599 "family": "Zed Sans",
assets/themes/light.json+4−0
@@ -90,6 +90,10 @@ · 89 unmodified lines
9090 },
9191 "workspace": {
9292 "background": "#f8f8f8",
93+ "joining_project_avatar": {
94+ "corner_radius": 40,
95+ "width": 80
96+ },
9397 "joining_project_message": {
9498 "padding": 12,
9599 "family": "Zed Sans",
assets/themes/solarized-dark.json+4−0
@@ -90,6 +90,10 @@ · 89 unmodified lines
9090 },
9191 "workspace": {
9292 "background": "#073642",
93+ "joining_project_avatar": {
94+ "corner_radius": 40,
95+ "width": 80
96+ },
9397 "joining_project_message": {
9498 "padding": 12,
9599 "family": "Zed Sans",
assets/themes/solarized-light.json+4−0
@@ -90,6 +90,10 @@ · 89 unmodified lines
9090 },
9191 "workspace": {
9292 "background": "#eee8d5",
93+ "joining_project_avatar": {
94+ "corner_radius": 40,
95+ "width": 80
96+ },
9397 "joining_project_message": {
9498 "padding": 12,
9599 "family": "Zed Sans",
assets/themes/sulphurpool-dark.json+4−0
@@ -90,6 +90,10 @@ · 89 unmodified lines
9090 },
9191 "workspace": {
9292 "background": "#293256",
93+ "joining_project_avatar": {
94+ "corner_radius": 40,
95+ "width": 80
96+ },
9397 "joining_project_message": {
9498 "padding": 12,
9599 "family": "Zed Sans",
assets/themes/sulphurpool-light.json+4−0
@@ -90,6 +90,10 @@ · 89 unmodified lines
9090 },
9191 "workspace": {
9292 "background": "#dfe2f1",
93+ "joining_project_avatar": {
94+ "corner_radius": 40,
95+ "width": 80
96+ },
9397 "joining_project_message": {
9498 "padding": 12,
9599 "family": "Zed Sans",
crates/contacts_panel/src/contacts_panel.rs+9−8
@@ -336,14 +336,14 @@ impl ContactsPanel { · 335 unmodified lines
336336 fn render_contact_project(
337337 contact: Arc<Contact>,
338338 current_user_id: Option<u64>,
339− project_ix: usize,
339+ project_index: usize,
340340 app_state: Arc<AppState>,
341341 theme: &theme::ContactsPanel,
342342 is_last_project: bool,
343343 is_selected: bool,
344344 cx: &mut LayoutContext,
345345 ) -> ElementBox {
346− let project = &contact.projects[project_ix];
346+ let project = &contact.projects[project_index];
347347 let project_id = project.id;
348348 let is_host = Some(contact.user.id) == current_user_id;
349349 let is_guest = !is_host
@@ -445,7 +445,8 @@ impl ContactsPanel { · 95 unmodified lines
445445 .on_click(move |_, cx| {
446446 if !is_host && !is_guest {
447447 cx.dispatch_global_action(JoinProject {
448− project_id,
448+ contact: contact.clone(),
449+ project_index,
449450 app_state: app_state.clone(),
450451 });
451452 }
@@ -768,12 +769,12 @@ impl ContactsPanel { · 316 unmodified lines
768769 let section = *section;
769770 self.toggle_expanded(&ToggleExpanded(section), cx);
770771 }
771− ContactEntry::ContactProject(contact, project_ix) => {
772− cx.dispatch_global_action(JoinProject {
773− project_id: contact.projects[*project_ix].id,
772+ ContactEntry::ContactProject(contact, project_index) => cx
773+ .dispatch_global_action(JoinProject {
774+ contact: contact.clone(),
775+ project_index: *project_index,
774776 app_state: self.app_state.clone(),
775− })
776− }
777+ }),
777778 _ => {}
778779 }
779780 }
crates/theme/src/theme.rs+1−0
@@ -48,6 +48,7 @@ pub struct Workspace { · 47 unmodified lines
4848 pub modal: ContainerStyle,
4949 pub notification: ContainerStyle,
5050 pub notifications: Notifications,
51+ pub joining_project_avatar: ImageStyle,
5152 pub joining_project_message: ContainedText,
5253 }
5354
crates/workspace/src/workspace.rs+72−21
@@ -8,7 +8,8 @@ mod toolbar; · 7 unmodified lines
88
99 use anyhow::{anyhow, Context, Result};
1010 use client::{
11− proto, Authenticate, ChannelList, Client, PeerId, Subscription, TypedEnvelope, User, UserStore,
11+ proto, Authenticate, ChannelList, Client, Contact, PeerId, Subscription, TypedEnvelope, User,
12+ UserStore,
1213 };
1314 use clock::ReplicaId;
1415 use collections::{hash_map, HashMap, HashSet};
@@ -97,7 +98,8 @@ pub struct ToggleFollow(pub PeerId); · 82 unmodified lines
9798
9899 #[derive(Clone)]
99100 pub struct JoinProject {
100− pub project_id: u64,
101+ pub contact: Arc<Contact>,
102+ pub project_index: usize,
101103 pub app_state: Arc<AppState>,
102104 }
103105
@@ -117,7 +119,13 @@ pub fn init(client: &Arc<Client>, cx: &mut MutableAppContext) { · 13 unmodified lines
117119 open_new(&action.0, cx)
118120 });
119121 cx.add_global_action(move |action: &JoinProject, cx: &mut MutableAppContext| {
120− join_project(action.project_id, &action.app_state, cx).detach();
122+ join_project(
123+ action.contact.clone(),
124+ action.project_index,
125+ &action.app_state,
126+ cx,
127+ )
128+ .detach();
121129 });
122130
123131 cx.add_async_action(Workspace::toggle_follow);
@@ -2268,12 +2276,16 @@ pub fn open_paths( · 2144 unmodified lines
22682276 }
22692277
22702278 pub fn join_project(
2271− project_id: u64,
2279+ contact: Arc<Contact>,
2280+ project_index: usize,
22722281 app_state: &Arc<AppState>,
22732282 cx: &mut MutableAppContext,
22742283 ) -> Task<Result<ViewHandle<Workspace>>> {
2284+ let project_id = contact.projects[project_index].id;
2285+
22752286 struct JoiningNotice {
2276− message: &'static str,
2287+ avatar: Option<Arc<ImageData>>,
2288+ message: String,
22772289 }
22782290
22792291 impl Entity for JoiningNotice {
@@ -2287,16 +2299,28 @@ pub fn join_project( · 7 unmodified lines
22872299
22882300 fn render(&mut self, cx: &mut RenderContext<Self>) -> ElementBox {
22892301 let theme = &cx.global::<Settings>().theme.workspace;
2290− Text::new(
2291− self.message.to_string(),
2292− theme.joining_project_message.text.clone(),
2293− )
2294− .contained()
2295− .with_style(theme.joining_project_message.container)
2296− .aligned()
2297− .contained()
2298− .with_background_color(theme.background)
2299− .boxed()
2302+
2303+ Flex::column()
2304+ .with_children(self.avatar.clone().map(|avatar| {
2305+ Image::new(avatar)
2306+ .with_style(theme.joining_project_avatar)
2307+ .aligned()
2308+ .boxed()
2309+ }))
2310+ .with_child(
2311+ Text::new(
2312+ self.message.clone(),
2313+ theme.joining_project_message.text.clone(),
2314+ )
2315+ .contained()
2316+ .with_style(theme.joining_project_message.container)
2317+ .aligned()
2318+ .boxed(),
2319+ )
2320+ .aligned()
2321+ .contained()
2322+ .with_background_color(theme.background)
2323+ .boxed()
23002324 }
23012325 }
23022326
@@ -2312,7 +2336,12 @@ pub fn join_project( · 9 unmodified lines
23122336 cx.spawn(|mut cx| async move {
23132337 let (window, joining_notice) = cx.update(|cx| {
23142338 cx.add_window((app_state.build_window_options)(), |_| JoiningNotice {
2315− message: "Loading remote project...",
2339+ avatar: contact.user.avatar.clone(),
2340+ message: format!(
2341+ "Asking to join @{}'s copy of {}...",
2342+ contact.user.github_login,
2343+ humanize_list(&contact.projects[project_index].worktree_root_names)
2344+ ),
23162345 })
23172346 });
23182347 let project = Project::remote(
@@ -2338,15 +2367,22 @@ pub fn join_project( · 19 unmodified lines
23382367 workspace
23392368 })),
23402369 Err(error @ _) => {
2370+ let login = &contact.user.github_login;
23412371 let message = match error {
23422372 project::JoinProjectError::HostDeclined => {
2343− "The host declined your request to join."
2373+ format!("@{} declined your request.", login)
2374+ }
2375+ project::JoinProjectError::HostClosedProject => {
2376+ format!(
2377+ "@{} closed their copy of {}.",
2378+ login,
2379+ humanize_list(&contact.projects[project_index].worktree_root_names)
2380+ )
23442381 }
2345− project::JoinProjectError::HostClosedProject => "The host closed the project.",
2346− project::JoinProjectError::HostWentOffline => "The host went offline.",
2347− project::JoinProjectError::Other(_) => {
2348− "An error occurred when attempting to join the project."
2382+ project::JoinProjectError::HostWentOffline => {
2383+ format!("@{} went offline.", login)
23492384 }
2385+ project::JoinProjectError::Other(_) => "An error occurred.".to_string(),
23502386 };
23512387 joining_notice.update(cx, |notice, cx| {
23522388 notice.message = message;
@@ -2372,3 +2408,18 @@ fn open_new(app_state: &Arc<AppState>, cx: &mut MutableAppContext) { · 19 unmodified lines
23722408 });
23732409 cx.dispatch_action(window_id, vec![workspace.id()], &OpenNew(app_state.clone()));
23742410 }
2411+
2412+fn humanize_list<'a>(items: impl IntoIterator<Item = &'a String>) -> String {
2413+ let mut list = String::new();
2414+ let mut items = items.into_iter().enumerate().peekable();
2415+ while let Some((ix, item)) = items.next() {
2416+ if ix > 0 {
2417+ list.push_str(", ");
2418+ }
2419+ if items.peek().is_none() {
2420+ list.push_str("and ");
2421+ }
2422+ list.push_str(item);
2423+ }
2424+ list
2425+}
script/watch-themes+7−0
@@ -0,0 +1,7 @@
1+#!/bin/bash
2+
3+set -e
4+
5+cd styles
6+npm install
7+npm run watch
styles/src/styleTree/workspace.ts+4−0
@@ -41,6 +41,10 @@ export default function workspace(theme: Theme) { · 40 unmodified lines
4141
4242 return {
4343 background: backgroundColor(theme, 300),
44+ joiningProjectAvatar: {
45+ cornerRadius: 40,
46+ width: 80,
47+ },
4448 joiningProjectMessage: {
4549 padding: 12,
4650 ...text(theme, "sans", "primary", { size: "lg" })