Move contact finder into contacts popover

This commit is contained in:
Antonio Scandurra 2022-10-10 09:56:21 +02:00
parent 34cb742db1
commit 6f4edf6df5
9 changed files with 138 additions and 976 deletions

View file

@ -1,6 +1,7 @@
mod active_call_popover;
mod collab_titlebar_item;
mod contact_finder;
mod contact_list;
mod contact_notification;
mod contacts_popover;
mod incoming_call_notification;
@ -18,6 +19,7 @@ use workspace::{AppState, JoinProject, ToggleFollow, Workspace};
pub fn init(app_state: Arc<AppState>, cx: &mut MutableAppContext) {
collab_titlebar_item::init(cx);
contact_notification::init(cx);
contact_list::init(cx);
contact_finder::init(cx);
contacts_popover::init(cx);
incoming_call_notification::init(cx);

View file

@ -1,19 +1,15 @@
use client::{ContactRequestStatus, User, UserStore};
use gpui::{
actions, elements::*, AnyViewHandle, Entity, ModelHandle, MouseState, MutableAppContext,
RenderContext, Task, View, ViewContext, ViewHandle,
elements::*, AnyViewHandle, Entity, ModelHandle, MouseState, MutableAppContext, RenderContext,
Task, View, ViewContext, ViewHandle,
};
use picker::{Picker, PickerDelegate};
use settings::Settings;
use std::sync::Arc;
use util::TryFutureExt;
use workspace::Workspace;
actions!(contact_finder, [Toggle]);
pub fn init(cx: &mut MutableAppContext) {
Picker::<ContactFinder>::init(cx);
cx.add_action(ContactFinder::toggle);
}
pub struct ContactFinder {
@ -166,34 +162,16 @@ impl PickerDelegate for ContactFinder {
}
impl ContactFinder {
fn toggle(workspace: &mut Workspace, _: &Toggle, cx: &mut ViewContext<Workspace>) {
workspace.toggle_modal(cx, |workspace, cx| {
let finder = cx.add_view(|cx| Self::new(workspace.user_store().clone(), cx));
cx.subscribe(&finder, Self::on_event).detach();
finder
});
}
pub fn new(user_store: ModelHandle<UserStore>, cx: &mut ViewContext<Self>) -> Self {
let this = cx.weak_handle();
Self {
picker: cx.add_view(|cx| Picker::new(this, cx)),
picker: cx.add_view(|cx| {
Picker::new(this, cx)
.with_theme(|cx| &cx.global::<Settings>().theme.contact_finder.picker)
}),
potential_contacts: Arc::from([]),
user_store,
selected_index: 0,
}
}
fn on_event(
workspace: &mut Workspace,
_: ViewHandle<Self>,
event: &Event,
cx: &mut ViewContext<Workspace>,
) {
match event {
Event::Dismissed => {
workspace.dismiss_modal(cx);
}
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -82,20 +82,22 @@ impl IncomingCallNotification {
}
fn render_caller(&self, cx: &mut RenderContext<Self>) -> ElementBox {
let theme = &cx.global::<Settings>().theme.contacts_popover;
let theme = &cx.global::<Settings>().theme.incoming_call_notification;
Flex::row()
.with_children(
self.call
.caller
.avatar
.clone()
.map(|avatar| Image::new(avatar).with_style(theme.contact_avatar).boxed()),
.map(|avatar| Image::new(avatar).with_style(theme.caller_avatar).boxed()),
)
.with_child(
Label::new(
self.call.caller.github_login.clone(),
theme.contact_username.text.clone(),
theme.caller_username.text.clone(),
)
.contained()
.with_style(theme.caller_username.container)
.boxed(),
)
.boxed()
@ -108,8 +110,11 @@ impl IncomingCallNotification {
Flex::row()
.with_child(
MouseEventHandler::<Accept>::new(0, cx, |_, cx| {
let theme = &cx.global::<Settings>().theme.contacts_popover;
Label::new("Accept".to_string(), theme.contact_username.text.clone()).boxed()
let theme = &cx.global::<Settings>().theme.incoming_call_notification;
Label::new("Accept".to_string(), theme.accept_button.text.clone())
.contained()
.with_style(theme.accept_button.container)
.boxed()
})
.on_click(MouseButton::Left, |_, cx| {
cx.dispatch_action(RespondToCall { accept: true });
@ -118,8 +123,11 @@ impl IncomingCallNotification {
)
.with_child(
MouseEventHandler::<Decline>::new(0, cx, |_, cx| {
let theme = &cx.global::<Settings>().theme.contacts_popover;
Label::new("Decline".to_string(), theme.contact_username.text.clone()).boxed()
let theme = &cx.global::<Settings>().theme.incoming_call_notification;
Label::new("Decline".to_string(), theme.decline_button.text.clone())
.contained()
.with_style(theme.decline_button.container)
.boxed()
})
.on_click(MouseButton::Left, |_, cx| {
cx.dispatch_action(RespondToCall { accept: false });

View file

@ -19,6 +19,7 @@ pub struct Picker<D: PickerDelegate> {
query_editor: ViewHandle<Editor>,
list_state: UniformListState,
max_size: Vector2F,
theme: Box<dyn FnMut(&AppContext) -> &theme::Picker>,
confirmed: bool,
}
@ -51,8 +52,8 @@ impl<D: PickerDelegate> View for Picker<D> {
}
fn render(&mut self, cx: &mut RenderContext<Self>) -> gpui::ElementBox {
let settings = cx.global::<Settings>();
let container_style = settings.theme.picker.container;
let theme = (self.theme)(cx);
let container_style = theme.container;
let delegate = self.delegate.clone();
let match_count = if let Some(delegate) = delegate.upgrade(cx.app) {
delegate.read(cx).match_count()
@ -64,17 +65,14 @@ impl<D: PickerDelegate> View for Picker<D> {
.with_child(
ChildView::new(&self.query_editor)
.contained()
.with_style(settings.theme.picker.input_editor.container)
.with_style(theme.input_editor.container)
.boxed(),
)
.with_child(
if match_count == 0 {
Label::new(
"No matches".into(),
settings.theme.picker.empty.label.clone(),
)
.contained()
.with_style(settings.theme.picker.empty.container)
Label::new("No matches".into(), theme.empty.label.clone())
.contained()
.with_style(theme.empty.container)
} else {
UniformList::new(
self.list_state.clone(),
@ -147,6 +145,7 @@ impl<D: PickerDelegate> Picker<D> {
list_state: Default::default(),
delegate,
max_size: vec2f(540., 420.),
theme: Box::new(|cx| &cx.global::<Settings>().theme.picker),
confirmed: false,
};
cx.defer(|this, cx| {
@ -163,6 +162,14 @@ impl<D: PickerDelegate> Picker<D> {
self
}
pub fn with_theme<F>(mut self, theme: F) -> Self
where
F: 'static + FnMut(&AppContext) -> &theme::Picker,
{
self.theme = Box::new(theme);
self
}
pub fn query(&self, cx: &AppContext) -> String {
self.query_editor.read(cx).text(cx)
}

View file

@ -20,6 +20,7 @@ pub struct Theme {
pub context_menu: ContextMenu,
pub chat_panel: ChatPanel,
pub contacts_popover: ContactsPopover,
pub contact_list: ContactList,
pub contact_finder: ContactFinder,
pub project_panel: ProjectPanel,
pub command_palette: CommandPalette,
@ -31,6 +32,7 @@ pub struct Theme {
pub contact_notification: ContactNotification,
pub update_notification: UpdateNotification,
pub project_shared_notification: ProjectSharedNotification,
pub incoming_call_notification: IncomingCallNotification,
pub tooltip: TooltipStyle,
pub terminal: TerminalStyle,
}
@ -87,6 +89,10 @@ pub struct ContactsPopover {
pub container: ContainerStyle,
pub height: f32,
pub width: f32,
}
#[derive(Deserialize, Default)]
pub struct ContactList {
pub user_query_editor: FieldEditor,
pub user_query_editor_height: f32,
pub add_contact_button: IconButton,
@ -105,6 +111,16 @@ pub struct ContactsPopover {
pub calling_indicator: ContainedText,
}
#[derive(Deserialize, Default)]
pub struct ContactFinder {
pub picker: Picker,
pub row_height: f32,
pub contact_avatar: ImageStyle,
pub contact_username: ContainerStyle,
pub contact_button: IconButton,
pub disabled_contact_button: IconButton,
}
#[derive(Clone, Deserialize, Default)]
pub struct TabBar {
#[serde(flatten)]
@ -353,15 +369,6 @@ pub struct InviteLink {
pub icon: Icon,
}
#[derive(Deserialize, Default)]
pub struct ContactFinder {
pub row_height: f32,
pub contact_avatar: ImageStyle,
pub contact_username: ContainerStyle,
pub contact_button: IconButton,
pub disabled_contact_button: IconButton,
}
#[derive(Deserialize, Default)]
pub struct Icon {
#[serde(flatten)]
@ -469,6 +476,14 @@ pub struct ProjectSharedNotification {
pub dismiss_button: ContainedText,
}
#[derive(Deserialize, Default)]
pub struct IncomingCallNotification {
pub caller_avatar: ImageStyle,
pub caller_username: ContainedText,
pub accept_button: ContainedText,
pub decline_button: ContainedText,
}
#[derive(Clone, Deserialize, Default)]
pub struct Editor {
pub text_color: Color,

View file

@ -16,6 +16,8 @@ import updateNotification from "./updateNotification";
import projectSharedNotification from "./projectSharedNotification";
import tooltip from "./tooltip";
import terminal from "./terminal";
import contactList from "./contactList";
import incomingCallNotification from "./incomingCallNotification";
export const panel = {
padding: { top: 12, bottom: 12 },
@ -36,6 +38,7 @@ export default function app(theme: Theme): Object {
projectPanel: projectPanel(theme),
chatPanel: chatPanel(theme),
contactsPopover: contactsPopover(theme),
contactList: contactList(theme),
contactFinder: contactFinder(theme),
search: search(theme),
breadcrumbs: {
@ -47,6 +50,7 @@ export default function app(theme: Theme): Object {
contactNotification: contactNotification(theme),
updateNotification: updateNotification(theme),
projectSharedNotification: projectSharedNotification(theme),
incomingCallNotification: incomingCallNotification(theme),
tooltip: tooltip(theme),
terminal: terminal(theme),
};

View file

@ -1,6 +1,6 @@
import Theme from "../themes/common/theme";
import picker from "./picker";
import { backgroundColor, iconColor } from "./components";
import { backgroundColor, border, iconColor, player, text } from "./components";
export default function contactFinder(theme: Theme) {
const contactButton = {
@ -12,7 +12,28 @@ export default function contactFinder(theme: Theme) {
};
return {
...picker(theme),
picker: {
item: picker(theme).item,
empty: picker(theme).empty,
inputEditor: {
background: backgroundColor(theme, 500),
cornerRadius: 6,
text: text(theme, "mono", "primary"),
placeholderText: text(theme, "mono", "placeholder", { size: "sm" }),
selection: player(theme, 1).selection,
border: border(theme, "secondary"),
padding: {
bottom: 4,
left: 8,
right: 8,
top: 4,
},
margin: {
left: 12,
right: 12,
}
}
},
rowHeight: 28,
contactAvatar: {
cornerRadius: 10,

View file

@ -19,7 +19,6 @@ export default function contactsPopover(theme: Theme) {
padding: { top: 6 },
shadow: popoverShadow(theme),
border: border(theme, "primary"),
margin: { top: -5 },
width: 250,
height: 300,
userQueryEditor: {