Show current user in active call

Antonio Scandurra created

Change summary

crates/collab_ui/src/contacts_popover.rs | 138 ++++++++++++++++---------
crates/theme/src/theme.rs                |  19 ---
styles/src/styleTree/contactsPopover.ts  |  52 ---------
3 files changed, 89 insertions(+), 120 deletions(-)

Detailed changes

crates/collab_ui/src/contacts_popover.rs 🔗

@@ -165,7 +165,12 @@ impl ContactsPopover {
                     )
                 }
                 ContactEntry::CallParticipant { user, is_pending } => {
-                    Self::render_call_participant(user, *is_pending, &theme.contacts_popover)
+                    Self::render_call_participant(
+                        user,
+                        *is_pending,
+                        is_selected,
+                        &theme.contacts_popover,
+                    )
                 }
                 ContactEntry::IncomingRequest(user) => Self::render_contact_request(
                     user.clone(),
@@ -303,21 +308,16 @@ impl ContactsPopover {
 
         if let Some(room) = ActiveCall::global(cx).read(cx).room() {
             let room = room.read(cx);
+            let mut call_participants = Vec::new();
 
-            self.entries.push(ContactEntry::Header(Section::ActiveCall));
-            if !self.collapsed_sections.contains(&Section::ActiveCall) {
-                // Populate remote participants.
+            // Populate the active user.
+            if let Some(user) = user_store.current_user() {
                 self.match_candidates.clear();
-                self.match_candidates
-                    .extend(
-                        room.remote_participants()
-                            .iter()
-                            .map(|(peer_id, participant)| StringMatchCandidate {
-                                id: peer_id.0 as usize,
-                                string: participant.user.github_login.clone(),
-                                char_bag: participant.user.github_login.chars().collect(),
-                            }),
-                    );
+                self.match_candidates.push(StringMatchCandidate {
+                    id: 0,
+                    string: user.github_login.clone(),
+                    char_bag: user.github_login.chars().collect(),
+                });
                 let matches = executor.block(match_strings(
                     &self.match_candidates,
                     &query,
@@ -326,38 +326,74 @@ impl ContactsPopover {
                     &Default::default(),
                     executor.clone(),
                 ));
-                self.entries.extend(matches.iter().map(|mat| {
-                    ContactEntry::CallParticipant {
-                        user: room.remote_participants()[&PeerId(mat.candidate_id as u32)]
-                            .user
-                            .clone(),
+                if !matches.is_empty() {
+                    call_participants.push(ContactEntry::CallParticipant {
+                        user,
                         is_pending: false,
-                    }
-                }));
+                    });
+                }
+            }
 
-                // Populate pending participants.
-                self.match_candidates.clear();
-                self.match_candidates
-                    .extend(room.pending_participants().iter().enumerate().map(
-                        |(id, participant)| StringMatchCandidate {
+            // Populate remote participants.
+            self.match_candidates.clear();
+            self.match_candidates
+                .extend(
+                    room.remote_participants()
+                        .iter()
+                        .map(|(peer_id, participant)| StringMatchCandidate {
+                            id: peer_id.0 as usize,
+                            string: participant.user.github_login.clone(),
+                            char_bag: participant.user.github_login.chars().collect(),
+                        }),
+                );
+            let matches = executor.block(match_strings(
+                &self.match_candidates,
+                &query,
+                true,
+                usize::MAX,
+                &Default::default(),
+                executor.clone(),
+            ));
+            call_participants.extend(matches.iter().map(|mat| {
+                ContactEntry::CallParticipant {
+                    user: room.remote_participants()[&PeerId(mat.candidate_id as u32)]
+                        .user
+                        .clone(),
+                    is_pending: false,
+                }
+            }));
+
+            // Populate pending participants.
+            self.match_candidates.clear();
+            self.match_candidates
+                .extend(
+                    room.pending_participants()
+                        .iter()
+                        .enumerate()
+                        .map(|(id, participant)| StringMatchCandidate {
                             id,
                             string: participant.github_login.clone(),
                             char_bag: participant.github_login.chars().collect(),
-                        },
-                    ));
-                let matches = executor.block(match_strings(
-                    &self.match_candidates,
-                    &query,
-                    true,
-                    usize::MAX,
-                    &Default::default(),
-                    executor.clone(),
-                ));
-                self.entries
-                    .extend(matches.iter().map(|mat| ContactEntry::CallParticipant {
-                        user: room.pending_participants()[mat.candidate_id].clone(),
-                        is_pending: true,
-                    }));
+                        }),
+                );
+            let matches = executor.block(match_strings(
+                &self.match_candidates,
+                &query,
+                true,
+                usize::MAX,
+                &Default::default(),
+                executor.clone(),
+            ));
+            call_participants.extend(matches.iter().map(|mat| ContactEntry::CallParticipant {
+                user: room.pending_participants()[mat.candidate_id].clone(),
+                is_pending: true,
+            }));
+
+            if !call_participants.is_empty() {
+                self.entries.push(ContactEntry::Header(Section::ActiveCall));
+                if !self.collapsed_sections.contains(&Section::ActiveCall) {
+                    self.entries.extend(call_participants);
+                }
             }
         }
 
@@ -495,6 +531,7 @@ impl ContactsPopover {
     fn render_call_participant(
         user: &User,
         is_pending: bool,
+        is_selected: bool,
         theme: &theme::ContactsPopover,
     ) -> ElementBox {
         Flex::row()
@@ -512,25 +549,26 @@ impl ContactsPopover {
                 )
                 .contained()
                 .with_style(theme.contact_username.container)
+                .aligned()
+                .left()
+                .flex(1., true)
                 .boxed(),
             )
             .with_children(if is_pending {
                 Some(
-                    Label::new(
-                        "Calling...".to_string(),
-                        theme.calling_indicator.text.clone(),
-                    )
-                    .contained()
-                    .with_style(theme.calling_indicator.container)
-                    .aligned()
-                    .flex_float()
-                    .boxed(),
+                    Label::new("Calling".to_string(), theme.calling_indicator.text.clone())
+                        .contained()
+                        .with_style(theme.calling_indicator.container)
+                        .aligned()
+                        .boxed(),
                 )
             } else {
                 None
             })
             .constrained()
             .with_height(theme.row_height)
+            .contained()
+            .with_style(*theme.contact_row.style_for(Default::default(), is_selected))
             .boxed()
     }
 

crates/theme/src/theme.rs 🔗

@@ -92,7 +92,6 @@ pub struct ContactsPopover {
     pub add_contact_button: IconButton,
     pub header_row: Interactive<ContainedText>,
     pub contact_row: Interactive<ContainerStyle>,
-    pub project_row: Interactive<ProjectRow>,
     pub row_height: f32,
     pub contact_avatar: ImageStyle,
     pub contact_status_free: ContainerStyle,
@@ -101,8 +100,6 @@ pub struct ContactsPopover {
     pub contact_button: Interactive<IconButton>,
     pub contact_button_spacing: f32,
     pub disabled_button: IconButton,
-    pub tree_branch: Interactive<TreeBranch>,
-    pub private_button: Interactive<IconButton>,
     pub section_icon_size: f32,
     pub invite_row: Interactive<ContainedLabel>,
     pub calling_indicator: ContainedText,
@@ -356,12 +353,6 @@ pub struct InviteLink {
     pub icon: Icon,
 }
 
-#[derive(Deserialize, Default, Clone, Copy)]
-pub struct TreeBranch {
-    pub width: f32,
-    pub color: Color,
-}
-
 #[derive(Deserialize, Default)]
 pub struct ContactFinder {
     pub row_height: f32,
@@ -389,16 +380,6 @@ pub struct IconButton {
     pub button_width: f32,
 }
 
-#[derive(Deserialize, Default)]
-pub struct ProjectRow {
-    #[serde(flatten)]
-    pub container: ContainerStyle,
-    pub name: ContainedText,
-    pub guests: ContainerStyle,
-    pub guest_avatar: ImageStyle,
-    pub guest_avatar_spacing: f32,
-}
-
 #[derive(Deserialize, Default)]
 pub struct ChatMessage {
     #[serde(flatten)]

styles/src/styleTree/contactsPopover.ts 🔗

@@ -5,32 +5,6 @@ export default function contactsPopover(theme: Theme) {
   const nameMargin = 8;
   const sidePadding = 12;
 
-  const projectRow = {
-    guestAvatarSpacing: 4,
-    height: 24,
-    guestAvatar: {
-      cornerRadius: 8,
-      width: 14,
-    },
-    name: {
-      ...text(theme, "mono", "placeholder", { size: "sm" }),
-      margin: {
-        left: nameMargin,
-        right: 6,
-      },
-    },
-    guests: {
-      margin: {
-        left: nameMargin,
-        right: nameMargin,
-      },
-    },
-    padding: {
-      left: sidePadding,
-      right: sidePadding,
-    },
-  };
-
   const contactButton = {
     background: backgroundColor(theme, 100),
     color: iconColor(theme, "primary"),
@@ -102,16 +76,6 @@ export default function contactsPopover(theme: Theme) {
         background: backgroundColor(theme, 100, "active"),
       },
     },
-    treeBranch: {
-      color: borderColor(theme, "active"),
-      width: 1,
-      hover: {
-        color: borderColor(theme, "active"),
-      },
-      active: {
-        color: borderColor(theme, "active"),
-      },
-    },
     contactAvatar: {
       cornerRadius: 10,
       width: 18,
@@ -146,20 +110,6 @@ export default function contactsPopover(theme: Theme) {
       background: backgroundColor(theme, 100),
       color: iconColor(theme, "muted"),
     },
-    projectRow: {
-      ...projectRow,
-      background: backgroundColor(theme, 300),
-      name: {
-        ...projectRow.name,
-        ...text(theme, "mono", "secondary", { size: "sm" }),
-      },
-      hover: {
-        background: backgroundColor(theme, 300, "hovered"),
-      },
-      active: {
-        background: backgroundColor(theme, 300, "active"),
-      },
-    },
     inviteRow: {
       padding: {
         left: sidePadding,
@@ -172,7 +122,7 @@ export default function contactsPopover(theme: Theme) {
       },
     },
     callingIndicator: {
-      ...text(theme, "mono", "primary", { size: "xs" }),
+      ...text(theme, "mono", "muted", { size: "xs" })
     }
   }
 }