Rework the contact panel's styling to allow keyboard navigation

Co-authored-by: Nathan Sobo <nathan@zed.dev>
This commit is contained in:
Max Brunsfeld 2022-05-11 16:50:51 -07:00
parent 4739c683af
commit 615319b2ab
12 changed files with 526 additions and 264 deletions

View File

@ -989,9 +989,7 @@
"chat_panel": {
"padding": {
"top": 12,
"left": 12,
"bottom": 12,
"right": 12
"bottom": 12
},
"channel_name": {
"family": "Zed Sans",
@ -1208,9 +1206,7 @@
"contacts_panel": {
"padding": {
"top": 12,
"left": 12,
"bottom": 12,
"right": 12
"bottom": 12
},
"user_query_editor": {
"background": "#19171c",
@ -1238,23 +1234,33 @@
"left": 8,
"right": 8,
"top": 4
},
"margin": {
"left": 12,
"right": 12
}
},
"user_query_editor_height": 32,
"add_contact_button": {
"margin": {
"left": 6
"left": 6,
"right": 12
},
"color": "#e2dfe7",
"button_width": 8,
"icon_width": 8
},
"row_height": 28,
"header_row": {
"family": "Zed Mono",
"color": "#8b8792",
"size": 14,
"margin": {
"top": 8
"top": 14
},
"padding": {
"left": 12,
"right": 12
},
"active": {
"family": "Zed Mono",
@ -1265,15 +1271,23 @@
},
"contact_row": {
"padding": {
"left": 8
"left": 12,
"right": 12
},
"active": {
"background": "#5852605c"
}
},
"row_height": 28,
"tree_branch_color": "#655f6d",
"tree_branch_width": 1,
"tree_branch": {
"color": "#655f6d",
"width": 1,
"hover": {
"color": "#655f6d"
},
"active": {
"color": "#655f6d"
}
},
"contact_avatar": {
"corner_radius": 10,
"width": 18
@ -1282,10 +1296,11 @@
"family": "Zed Mono",
"color": "#e2dfe7",
"size": 14,
"padding": {
"margin": {
"left": 8
}
},
"contact_button_spacing": 8,
"contact_button": {
"background": "#26232a",
"color": "#e2dfe7",
@ -1315,14 +1330,21 @@
"color": "#8b8792",
"size": 14,
"margin": {
"left": 8,
"right": 6
}
},
"guests": {
"margin": {
"left": 8,
"right": 8
}
},
"padding": {
"left": 8
"left": 12,
"right": 12
},
"background": "#26232a",
"corner_radius": 6,
"hover": {
"background": "#5852603d"
},
@ -1342,14 +1364,21 @@
"color": "#8b8792",
"size": 14,
"margin": {
"left": 8,
"right": 6
}
},
"guests": {
"margin": {
"left": 8,
"right": 8
}
},
"padding": {
"left": 8
"left": 12,
"right": 12
},
"background": "#26232a",
"corner_radius": 6,
"hover": {
"background": "#5852603d"
},

View File

@ -989,9 +989,7 @@
"chat_panel": {
"padding": {
"top": 12,
"left": 12,
"bottom": 12,
"right": 12
"bottom": 12
},
"channel_name": {
"family": "Zed Sans",
@ -1208,9 +1206,7 @@
"contacts_panel": {
"padding": {
"top": 12,
"left": 12,
"bottom": 12,
"right": 12
"bottom": 12
},
"user_query_editor": {
"background": "#efecf4",
@ -1238,23 +1234,33 @@
"left": 8,
"right": 8,
"top": 4
},
"margin": {
"left": 12,
"right": 12
}
},
"user_query_editor_height": 32,
"add_contact_button": {
"margin": {
"left": 6
"left": 6,
"right": 12
},
"color": "#26232a",
"button_width": 8,
"icon_width": 8
},
"row_height": 28,
"header_row": {
"family": "Zed Mono",
"color": "#585260",
"size": 14,
"margin": {
"top": 8
"top": 14
},
"padding": {
"left": 12,
"right": 12
},
"active": {
"family": "Zed Mono",
@ -1265,15 +1271,23 @@
},
"contact_row": {
"padding": {
"left": 8
"left": 12,
"right": 12
},
"active": {
"background": "#8b87922e"
}
},
"row_height": 28,
"tree_branch_color": "#7e7887",
"tree_branch_width": 1,
"tree_branch": {
"color": "#7e7887",
"width": 1,
"hover": {
"color": "#7e7887"
},
"active": {
"color": "#7e7887"
}
},
"contact_avatar": {
"corner_radius": 10,
"width": 18
@ -1282,10 +1296,11 @@
"family": "Zed Mono",
"color": "#26232a",
"size": 14,
"padding": {
"margin": {
"left": 8
}
},
"contact_button_spacing": 8,
"contact_button": {
"background": "#e2dfe7",
"color": "#26232a",
@ -1315,14 +1330,21 @@
"color": "#585260",
"size": 14,
"margin": {
"left": 8,
"right": 6
}
},
"guests": {
"margin": {
"left": 8,
"right": 8
}
},
"padding": {
"left": 8
"left": 12,
"right": 12
},
"background": "#e2dfe7",
"corner_radius": 6,
"hover": {
"background": "#8b87921f"
},
@ -1342,14 +1364,21 @@
"color": "#585260",
"size": 14,
"margin": {
"left": 8,
"right": 6
}
},
"guests": {
"margin": {
"left": 8,
"right": 8
}
},
"padding": {
"left": 8
"left": 12,
"right": 12
},
"background": "#e2dfe7",
"corner_radius": 6,
"hover": {
"background": "#8b87921f"
},

View File

@ -989,9 +989,7 @@
"chat_panel": {
"padding": {
"top": 12,
"left": 12,
"bottom": 12,
"right": 12
"bottom": 12
},
"channel_name": {
"family": "Zed Sans",
@ -1208,9 +1206,7 @@
"contacts_panel": {
"padding": {
"top": 12,
"left": 12,
"bottom": 12,
"right": 12
"bottom": 12
},
"user_query_editor": {
"background": "#000000",
@ -1238,23 +1234,33 @@
"left": 8,
"right": 8,
"top": 4
},
"margin": {
"left": 12,
"right": 12
}
},
"user_query_editor_height": 32,
"add_contact_button": {
"margin": {
"left": 6
"left": 6,
"right": 12
},
"color": "#c6c6c6",
"button_width": 8,
"icon_width": 8
},
"row_height": 28,
"header_row": {
"family": "Zed Mono",
"color": "#9c9c9c",
"size": 14,
"margin": {
"top": 8
"top": 14
},
"padding": {
"left": 12,
"right": 12
},
"active": {
"family": "Zed Mono",
@ -1265,15 +1271,23 @@
},
"contact_row": {
"padding": {
"left": 8
"left": 12,
"right": 12
},
"active": {
"background": "#1c1c1c"
}
},
"row_height": 28,
"tree_branch_color": "#404040",
"tree_branch_width": 1,
"tree_branch": {
"color": "#000000",
"width": 1,
"hover": {
"color": "#000000"
},
"active": {
"color": "#000000"
}
},
"contact_avatar": {
"corner_radius": 10,
"width": 18
@ -1282,10 +1296,11 @@
"family": "Zed Mono",
"color": "#f1f1f1",
"size": 14,
"padding": {
"margin": {
"left": 8
}
},
"contact_button_spacing": 8,
"contact_button": {
"background": "#2b2b2b",
"color": "#c6c6c6",
@ -1315,14 +1330,21 @@
"color": "#9c9c9c",
"size": 14,
"margin": {
"left": 8,
"right": 6
}
},
"guests": {
"margin": {
"left": 8,
"right": 8
}
},
"padding": {
"left": 8
"left": 12,
"right": 12
},
"background": "#1c1c1c",
"corner_radius": 6,
"hover": {
"background": "#232323"
},
@ -1342,14 +1364,21 @@
"color": "#9c9c9c",
"size": 14,
"margin": {
"left": 8,
"right": 6
}
},
"guests": {
"margin": {
"left": 8,
"right": 8
}
},
"padding": {
"left": 8
"left": 12,
"right": 12
},
"background": "#1c1c1c",
"corner_radius": 6,
"hover": {
"background": "#232323"
},

View File

@ -989,9 +989,7 @@
"chat_panel": {
"padding": {
"top": 12,
"left": 12,
"bottom": 12,
"right": 12
"bottom": 12
},
"channel_name": {
"family": "Zed Sans",
@ -1208,9 +1206,7 @@
"contacts_panel": {
"padding": {
"top": 12,
"left": 12,
"bottom": 12,
"right": 12
"bottom": 12
},
"user_query_editor": {
"background": "#ffffff",
@ -1238,23 +1234,33 @@
"left": 8,
"right": 8,
"top": 4
},
"margin": {
"left": 12,
"right": 12
}
},
"user_query_editor_height": 32,
"add_contact_button": {
"margin": {
"left": 6
"left": 6,
"right": 12
},
"color": "#393939",
"button_width": 8,
"icon_width": 8
},
"row_height": 28,
"header_row": {
"family": "Zed Mono",
"color": "#474747",
"size": 14,
"margin": {
"top": 8
"top": 14
},
"padding": {
"left": 12,
"right": 12
},
"active": {
"family": "Zed Mono",
@ -1265,15 +1271,23 @@
},
"contact_row": {
"padding": {
"left": 8
"left": 12,
"right": 12
},
"active": {
"background": "#d5d5d5"
}
},
"row_height": 28,
"tree_branch_color": "#e3e3e3",
"tree_branch_width": 1,
"tree_branch": {
"color": "#b8b8b8",
"width": 1,
"hover": {
"color": "#b8b8b8"
},
"active": {
"color": "#b8b8b8"
}
},
"contact_avatar": {
"corner_radius": 10,
"width": 18
@ -1282,10 +1296,11 @@
"family": "Zed Mono",
"color": "#2b2b2b",
"size": 14,
"padding": {
"margin": {
"left": 8
}
},
"contact_button_spacing": 8,
"contact_button": {
"background": "#eaeaea",
"color": "#393939",
@ -1315,14 +1330,21 @@
"color": "#474747",
"size": 14,
"margin": {
"left": 8,
"right": 6
}
},
"guests": {
"margin": {
"left": 8,
"right": 8
}
},
"padding": {
"left": 8
"left": 12,
"right": 12
},
"background": "#f8f8f8",
"corner_radius": 6,
"hover": {
"background": "#eaeaea"
},
@ -1342,14 +1364,21 @@
"color": "#474747",
"size": 14,
"margin": {
"left": 8,
"right": 6
}
},
"guests": {
"margin": {
"left": 8,
"right": 8
}
},
"padding": {
"left": 8
"left": 12,
"right": 12
},
"background": "#f8f8f8",
"corner_radius": 6,
"hover": {
"background": "#eaeaea"
},

View File

@ -989,9 +989,7 @@
"chat_panel": {
"padding": {
"top": 12,
"left": 12,
"bottom": 12,
"right": 12
"bottom": 12
},
"channel_name": {
"family": "Zed Sans",
@ -1208,9 +1206,7 @@
"contacts_panel": {
"padding": {
"top": 12,
"left": 12,
"bottom": 12,
"right": 12
"bottom": 12
},
"user_query_editor": {
"background": "#002b36",
@ -1238,23 +1234,33 @@
"left": 8,
"right": 8,
"top": 4
},
"margin": {
"left": 12,
"right": 12
}
},
"user_query_editor_height": 32,
"add_contact_button": {
"margin": {
"left": 6
"left": 6,
"right": 12
},
"color": "#eee8d5",
"button_width": 8,
"icon_width": 8
},
"row_height": 28,
"header_row": {
"family": "Zed Mono",
"color": "#93a1a1",
"size": 14,
"margin": {
"top": 8
"top": 14
},
"padding": {
"left": 12,
"right": 12
},
"active": {
"family": "Zed Mono",
@ -1265,15 +1271,23 @@
},
"contact_row": {
"padding": {
"left": 8
"left": 12,
"right": 12
},
"active": {
"background": "#586e755c"
}
},
"row_height": 28,
"tree_branch_color": "#657b83",
"tree_branch_width": 1,
"tree_branch": {
"color": "#657b83",
"width": 1,
"hover": {
"color": "#657b83"
},
"active": {
"color": "#657b83"
}
},
"contact_avatar": {
"corner_radius": 10,
"width": 18
@ -1282,10 +1296,11 @@
"family": "Zed Mono",
"color": "#eee8d5",
"size": 14,
"padding": {
"margin": {
"left": 8
}
},
"contact_button_spacing": 8,
"contact_button": {
"background": "#073642",
"color": "#eee8d5",
@ -1315,14 +1330,21 @@
"color": "#93a1a1",
"size": 14,
"margin": {
"left": 8,
"right": 6
}
},
"guests": {
"margin": {
"left": 8,
"right": 8
}
},
"padding": {
"left": 8
"left": 12,
"right": 12
},
"background": "#073642",
"corner_radius": 6,
"hover": {
"background": "#586e753d"
},
@ -1342,14 +1364,21 @@
"color": "#93a1a1",
"size": 14,
"margin": {
"left": 8,
"right": 6
}
},
"guests": {
"margin": {
"left": 8,
"right": 8
}
},
"padding": {
"left": 8
"left": 12,
"right": 12
},
"background": "#073642",
"corner_radius": 6,
"hover": {
"background": "#586e753d"
},

View File

@ -989,9 +989,7 @@
"chat_panel": {
"padding": {
"top": 12,
"left": 12,
"bottom": 12,
"right": 12
"bottom": 12
},
"channel_name": {
"family": "Zed Sans",
@ -1208,9 +1206,7 @@
"contacts_panel": {
"padding": {
"top": 12,
"left": 12,
"bottom": 12,
"right": 12
"bottom": 12
},
"user_query_editor": {
"background": "#fdf6e3",
@ -1238,23 +1234,33 @@
"left": 8,
"right": 8,
"top": 4
},
"margin": {
"left": 12,
"right": 12
}
},
"user_query_editor_height": 32,
"add_contact_button": {
"margin": {
"left": 6
"left": 6,
"right": 12
},
"color": "#073642",
"button_width": 8,
"icon_width": 8
},
"row_height": 28,
"header_row": {
"family": "Zed Mono",
"color": "#586e75",
"size": 14,
"margin": {
"top": 8
"top": 14
},
"padding": {
"left": 12,
"right": 12
},
"active": {
"family": "Zed Mono",
@ -1265,15 +1271,23 @@
},
"contact_row": {
"padding": {
"left": 8
"left": 12,
"right": 12
},
"active": {
"background": "#93a1a12e"
}
},
"row_height": 28,
"tree_branch_color": "#839496",
"tree_branch_width": 1,
"tree_branch": {
"color": "#839496",
"width": 1,
"hover": {
"color": "#839496"
},
"active": {
"color": "#839496"
}
},
"contact_avatar": {
"corner_radius": 10,
"width": 18
@ -1282,10 +1296,11 @@
"family": "Zed Mono",
"color": "#073642",
"size": 14,
"padding": {
"margin": {
"left": 8
}
},
"contact_button_spacing": 8,
"contact_button": {
"background": "#eee8d5",
"color": "#073642",
@ -1315,14 +1330,21 @@
"color": "#586e75",
"size": 14,
"margin": {
"left": 8,
"right": 6
}
},
"guests": {
"margin": {
"left": 8,
"right": 8
}
},
"padding": {
"left": 8
"left": 12,
"right": 12
},
"background": "#eee8d5",
"corner_radius": 6,
"hover": {
"background": "#93a1a11f"
},
@ -1342,14 +1364,21 @@
"color": "#586e75",
"size": 14,
"margin": {
"left": 8,
"right": 6
}
},
"guests": {
"margin": {
"left": 8,
"right": 8
}
},
"padding": {
"left": 8
"left": 12,
"right": 12
},
"background": "#eee8d5",
"corner_radius": 6,
"hover": {
"background": "#93a1a11f"
},

View File

@ -989,9 +989,7 @@
"chat_panel": {
"padding": {
"top": 12,
"left": 12,
"bottom": 12,
"right": 12
"bottom": 12
},
"channel_name": {
"family": "Zed Sans",
@ -1208,9 +1206,7 @@
"contacts_panel": {
"padding": {
"top": 12,
"left": 12,
"bottom": 12,
"right": 12
"bottom": 12
},
"user_query_editor": {
"background": "#202746",
@ -1238,23 +1234,33 @@
"left": 8,
"right": 8,
"top": 4
},
"margin": {
"left": 12,
"right": 12
}
},
"user_query_editor_height": 32,
"add_contact_button": {
"margin": {
"left": 6
"left": 6,
"right": 12
},
"color": "#dfe2f1",
"button_width": 8,
"icon_width": 8
},
"row_height": 28,
"header_row": {
"family": "Zed Mono",
"color": "#979db4",
"size": 14,
"margin": {
"top": 8
"top": 14
},
"padding": {
"left": 12,
"right": 12
},
"active": {
"family": "Zed Mono",
@ -1265,15 +1271,23 @@
},
"contact_row": {
"padding": {
"left": 8
"left": 12,
"right": 12
},
"active": {
"background": "#5e66875c"
}
},
"row_height": 28,
"tree_branch_color": "#6b7394",
"tree_branch_width": 1,
"tree_branch": {
"color": "#6b7394",
"width": 1,
"hover": {
"color": "#6b7394"
},
"active": {
"color": "#6b7394"
}
},
"contact_avatar": {
"corner_radius": 10,
"width": 18
@ -1282,10 +1296,11 @@
"family": "Zed Mono",
"color": "#dfe2f1",
"size": 14,
"padding": {
"margin": {
"left": 8
}
},
"contact_button_spacing": 8,
"contact_button": {
"background": "#293256",
"color": "#dfe2f1",
@ -1315,14 +1330,21 @@
"color": "#979db4",
"size": 14,
"margin": {
"left": 8,
"right": 6
}
},
"guests": {
"margin": {
"left": 8,
"right": 8
}
},
"padding": {
"left": 8
"left": 12,
"right": 12
},
"background": "#293256",
"corner_radius": 6,
"hover": {
"background": "#5e66873d"
},
@ -1342,14 +1364,21 @@
"color": "#979db4",
"size": 14,
"margin": {
"left": 8,
"right": 6
}
},
"guests": {
"margin": {
"left": 8,
"right": 8
}
},
"padding": {
"left": 8
"left": 12,
"right": 12
},
"background": "#293256",
"corner_radius": 6,
"hover": {
"background": "#5e66873d"
},

View File

@ -989,9 +989,7 @@
"chat_panel": {
"padding": {
"top": 12,
"left": 12,
"bottom": 12,
"right": 12
"bottom": 12
},
"channel_name": {
"family": "Zed Sans",
@ -1208,9 +1206,7 @@
"contacts_panel": {
"padding": {
"top": 12,
"left": 12,
"bottom": 12,
"right": 12
"bottom": 12
},
"user_query_editor": {
"background": "#f5f7ff",
@ -1238,23 +1234,33 @@
"left": 8,
"right": 8,
"top": 4
},
"margin": {
"left": 12,
"right": 12
}
},
"user_query_editor_height": 32,
"add_contact_button": {
"margin": {
"left": 6
"left": 6,
"right": 12
},
"color": "#293256",
"button_width": 8,
"icon_width": 8
},
"row_height": 28,
"header_row": {
"family": "Zed Mono",
"color": "#5e6687",
"size": 14,
"margin": {
"top": 8
"top": 14
},
"padding": {
"left": 12,
"right": 12
},
"active": {
"family": "Zed Mono",
@ -1265,15 +1271,23 @@
},
"contact_row": {
"padding": {
"left": 8
"left": 12,
"right": 12
},
"active": {
"background": "#979db42e"
}
},
"row_height": 28,
"tree_branch_color": "#898ea4",
"tree_branch_width": 1,
"tree_branch": {
"color": "#898ea4",
"width": 1,
"hover": {
"color": "#898ea4"
},
"active": {
"color": "#898ea4"
}
},
"contact_avatar": {
"corner_radius": 10,
"width": 18
@ -1282,10 +1296,11 @@
"family": "Zed Mono",
"color": "#293256",
"size": 14,
"padding": {
"margin": {
"left": 8
}
},
"contact_button_spacing": 8,
"contact_button": {
"background": "#dfe2f1",
"color": "#293256",
@ -1315,14 +1330,21 @@
"color": "#5e6687",
"size": 14,
"margin": {
"left": 8,
"right": 6
}
},
"guests": {
"margin": {
"left": 8,
"right": 8
}
},
"padding": {
"left": 8
"left": 12,
"right": 12
},
"background": "#dfe2f1",
"corner_radius": 6,
"hover": {
"background": "#979db41f"
},
@ -1342,14 +1364,21 @@
"color": "#5e6687",
"size": 14,
"margin": {
"left": 8,
"right": 6
}
},
"guests": {
"margin": {
"left": 8,
"right": 8
}
},
"padding": {
"left": 8
"left": 12,
"right": 12
},
"background": "#dfe2f1",
"corner_radius": 6,
"hover": {
"background": "#979db41f"
},

View File

@ -186,6 +186,7 @@ impl ContactsPanel {
.with_style(theme.contact_username.container)
.aligned()
.left()
.flex(1., true)
.boxed(),
)
.constrained()
@ -211,6 +212,13 @@ impl ContactsPanel {
) -> ElementBox {
let project = &contact.projects[project_ix];
let project_id = project.id;
let is_host = Some(contact.user.id) == current_user_id;
let is_guest = !is_host
&& project
.guests
.iter()
.any(|guest| Some(guest.id) == current_user_id);
let is_shared = project.is_shared;
let font_cache = cx.font_cache();
let host_avatar_height = theme
@ -219,120 +227,103 @@ impl ContactsPanel {
.or(theme.contact_avatar.height)
.unwrap_or(0.);
let row = &theme.unshared_project_row.default;
let tree_branch = theme.tree_branch.clone();
let line_height = row.name.text.line_height(font_cache);
let cap_height = row.name.text.cap_height(font_cache);
let baseline_offset =
row.name.text.baseline_offset(font_cache) + (row.height - line_height) / 2.;
let tree_branch_width = theme.tree_branch_width;
let tree_branch_color = theme.tree_branch_color;
row.name.text.baseline_offset(font_cache) + (theme.row_height - line_height) / 2.;
Flex::row()
.with_child(
Canvas::new(move |bounds, _, cx| {
let start_x = bounds.min_x() + (bounds.width() / 2.) - (tree_branch_width / 2.);
let end_x = bounds.max_x();
let start_y = bounds.min_y();
let end_y = bounds.min_y() + baseline_offset - (cap_height / 2.);
MouseEventHandler::new::<JoinProject, _, _>(project_id as usize, cx, |mouse_state, _| {
let tree_branch = *tree_branch.style_for(mouse_state, is_selected);
let row = if project.is_shared {
&theme.shared_project_row
} else {
&theme.unshared_project_row
}
.style_for(mouse_state, is_selected);
cx.scene.push_quad(gpui::Quad {
bounds: RectF::from_points(
vec2f(start_x, start_y),
vec2f(
start_x + tree_branch_width,
if is_last_project {
end_y
} else {
bounds.max_y()
},
Flex::row()
.with_child(
Canvas::new(move |bounds, _, cx| {
let start_x =
bounds.min_x() + (bounds.width() / 2.) - (tree_branch.width / 2.);
let end_x = bounds.max_x();
let start_y = bounds.min_y();
let end_y = bounds.min_y() + baseline_offset - (cap_height / 2.);
cx.scene.push_quad(gpui::Quad {
bounds: RectF::from_points(
vec2f(start_x, start_y),
vec2f(
start_x + tree_branch.width,
if is_last_project {
end_y
} else {
bounds.max_y()
},
),
),
),
background: Some(tree_branch_color),
border: gpui::Border::default(),
corner_radius: 0.,
});
cx.scene.push_quad(gpui::Quad {
bounds: RectF::from_points(
vec2f(start_x, end_y),
vec2f(end_x, end_y + tree_branch_width),
),
background: Some(tree_branch_color),
border: gpui::Border::default(),
corner_radius: 0.,
});
})
.constrained()
.with_width(host_avatar_height)
.boxed(),
)
.with_child({
let is_host = Some(contact.user.id) == current_user_id;
let is_guest = !is_host
&& project
.guests
.iter()
.any(|guest| Some(guest.id) == current_user_id);
let is_shared = project.is_shared;
let app_state = app_state.clone();
MouseEventHandler::new::<JoinProject, _, _>(
project_id as usize,
cx,
|mouse_state, _| {
let style = if project.is_shared {
&theme.shared_project_row
} else {
&theme.unshared_project_row
}
.style_for(mouse_state, is_selected);
Flex::row()
.with_child(
Label::new(
project.worktree_root_names.join(", "),
style.name.text.clone(),
)
.aligned()
.left()
.contained()
.with_style(style.name.container)
.boxed(),
)
.with_children(project.guests.iter().filter_map(|participant| {
participant.avatar.clone().map(|avatar| {
Image::new(avatar)
.with_style(style.guest_avatar)
.aligned()
.left()
.contained()
.with_margin_right(style.guest_avatar_spacing)
.boxed()
})
}))
.contained()
.with_style(style.container)
.constrained()
.with_height(style.height)
.boxed()
},
)
.with_cursor_style(if !is_host && is_shared {
CursorStyle::PointingHand
} else {
CursorStyle::Arrow
})
.on_click(move |_, cx| {
if !is_host && !is_guest {
cx.dispatch_global_action(JoinProject {
project_id,
app_state: app_state.clone(),
background: Some(tree_branch.color),
border: gpui::Border::default(),
corner_radius: 0.,
});
}
})
.flex(1., true)
cx.scene.push_quad(gpui::Quad {
bounds: RectF::from_points(
vec2f(start_x, end_y),
vec2f(end_x, end_y + tree_branch.width),
),
background: Some(tree_branch.color),
border: gpui::Border::default(),
corner_radius: 0.,
});
})
.constrained()
.with_width(host_avatar_height)
.boxed(),
)
.with_child(
Label::new(
project.worktree_root_names.join(", "),
row.name.text.clone(),
)
.aligned()
.left()
.contained()
.with_style(row.name.container)
.flex(1., false)
.boxed(),
)
.with_children(project.guests.iter().filter_map(|participant| {
participant.avatar.clone().map(|avatar| {
Image::new(avatar)
.with_style(row.guest_avatar)
.aligned()
.left()
.contained()
.with_margin_right(row.guest_avatar_spacing)
.boxed()
})
}))
.constrained()
.with_height(theme.row_height)
.contained()
.with_style(row.container)
.boxed()
})
.constrained()
.with_height(row.height)
.boxed()
})
.with_cursor_style(if !is_host && is_shared {
CursorStyle::PointingHand
} else {
CursorStyle::Arrow
})
.on_click(move |_, cx| {
if !is_host && !is_guest {
cx.dispatch_global_action(JoinProject {
project_id,
app_state: app_state.clone(),
});
}
})
.boxed()
}
fn render_contact_request(
@ -364,11 +355,13 @@ impl ContactsPanel {
.with_style(theme.contact_username.container)
.aligned()
.left()
.flex(1., true)
.boxed(),
);
let user_id = user.id;
let is_contact_request_pending = user_store.read(cx).is_contact_request_pending(&user);
let button_spacing = theme.contact_button_spacing;
if is_incoming {
row.add_children([
@ -380,7 +373,7 @@ impl ContactsPanel {
};
render_icon_button(button_style, "icons/reject.svg")
.aligned()
.flex_float()
// .flex_float()
.boxed()
})
.with_cursor_style(CursorStyle::PointingHand)
@ -390,7 +383,9 @@ impl ContactsPanel {
accept: false,
})
})
.flex_float()
// .flex_float()
.contained()
.with_margin_right(button_spacing)
.boxed(),
MouseEventHandler::new::<Accept, _, _>(user.id as usize, cx, |mouse_state, _| {
let button_style = if is_contact_request_pending {

View File

@ -246,9 +246,15 @@ pub struct ContactsPanel {
pub contact_avatar: ImageStyle,
pub contact_username: ContainedText,
pub contact_button: Interactive<IconButton>,
pub contact_button_spacing: f32,
pub disabled_contact_button: IconButton,
pub tree_branch_width: f32,
pub tree_branch_color: Color,
pub tree_branch: Interactive<TreeBranch>,
}
#[derive(Deserialize, Default, Clone, Copy)]
pub struct TreeBranch {
pub width: f32,
pub color: Color,
}
#[derive(Deserialize, Default)]
@ -273,8 +279,8 @@ pub struct IconButton {
pub struct ProjectRow {
#[serde(flatten)]
pub container: ContainerStyle,
pub height: f32,
pub name: ContainedText,
pub guests: ContainerStyle,
pub guest_avatar: ImageStyle,
pub guest_avatar_spacing: f32,
}

View File

@ -12,7 +12,7 @@ import workspace from "./workspace";
import projectDiagnostics from "./projectDiagnostics";
export const panel = {
padding: { top: 12, left: 12, bottom: 12, right: 12 },
padding: { top: 12, bottom: 12 },
};
export default function app(theme: Theme): Object {

View File

@ -3,7 +3,10 @@ import { panel } from "./app";
import { backgroundColor, border, borderColor, iconColor, player, text } from "./components";
export default function contactsPanel(theme: Theme) {
const project = {
const nameMargin = 8;
const sidePadding = 12;
const projectRow = {
guestAvatarSpacing: 4,
height: 24,
guestAvatar: {
@ -13,11 +16,19 @@ export default function contactsPanel(theme: Theme) {
name: {
...text(theme, "mono", "placeholder", { size: "sm" }),
margin: {
left: nameMargin,
right: 6,
},
},
guests: {
margin: {
left: nameMargin,
right: nameMargin,
}
},
padding: {
left: 8,
left: sidePadding,
right: sidePadding,
},
};
@ -44,41 +55,61 @@ export default function contactsPanel(theme: Theme) {
right: 8,
top: 4,
},
margin: {
left: sidePadding,
right: sidePadding,
}
},
userQueryEditorHeight: 32,
addContactButton: {
margin: { left: 6 },
margin: { left: 6, right: 12 },
color: iconColor(theme, "primary"),
buttonWidth: 8,
iconWidth: 8,
},
rowHeight: 28,
headerRow: {
...text(theme, "mono", "secondary", { size: "sm" }),
margin: { top: 8 },
margin: { top: 14 },
padding: {
left: sidePadding,
right: sidePadding,
},
active: {
...text(theme, "mono", "primary", { size: "sm" }),
background: backgroundColor(theme, 100, "active"),
}
},
contactRow: {
padding: { left: 8 },
padding: {
left: sidePadding,
right: sidePadding
},
active: {
background: backgroundColor(theme, 100, "active"),
}
},
rowHeight: 28,
treeBranchColor: borderColor(theme, "muted"),
treeBranchWidth: 1,
treeBranch: {
color: borderColor(theme, "active"),
width: 1,
hover: {
color: borderColor(theme, "active"),
},
active: {
color: borderColor(theme, "active"),
}
},
contactAvatar: {
cornerRadius: 10,
width: 18,
},
contactUsername: {
...text(theme, "mono", "primary", { size: "sm" }),
padding: {
left: 8,
margin: {
left: nameMargin,
},
},
contactButtonSpacing: nameMargin,
contactButton: {
...contactButton,
hover: {
@ -91,11 +122,10 @@ export default function contactsPanel(theme: Theme) {
color: iconColor(theme, "muted"),
},
sharedProjectRow: {
...project,
...projectRow,
background: backgroundColor(theme, 300),
cornerRadius: 6,
name: {
...project.name,
...projectRow.name,
...text(theme, "mono", "secondary", { size: "sm" }),
},
hover: {
@ -106,11 +136,10 @@ export default function contactsPanel(theme: Theme) {
}
},
unsharedProjectRow: {
...project,
...projectRow,
background: backgroundColor(theme, 300),
cornerRadius: 6,
name: {
...project.name,
...projectRow.name,
...text(theme, "mono", "secondary", { size: "sm" }),
},
hover: {