Move contact finder into contacts popover
This commit is contained in:
parent
34cb742db1
commit
6f4edf6df5
9 changed files with 138 additions and 976 deletions
|
@ -1,6 +1,7 @@
|
||||||
mod active_call_popover;
|
mod active_call_popover;
|
||||||
mod collab_titlebar_item;
|
mod collab_titlebar_item;
|
||||||
mod contact_finder;
|
mod contact_finder;
|
||||||
|
mod contact_list;
|
||||||
mod contact_notification;
|
mod contact_notification;
|
||||||
mod contacts_popover;
|
mod contacts_popover;
|
||||||
mod incoming_call_notification;
|
mod incoming_call_notification;
|
||||||
|
@ -18,6 +19,7 @@ use workspace::{AppState, JoinProject, ToggleFollow, Workspace};
|
||||||
pub fn init(app_state: Arc<AppState>, cx: &mut MutableAppContext) {
|
pub fn init(app_state: Arc<AppState>, cx: &mut MutableAppContext) {
|
||||||
collab_titlebar_item::init(cx);
|
collab_titlebar_item::init(cx);
|
||||||
contact_notification::init(cx);
|
contact_notification::init(cx);
|
||||||
|
contact_list::init(cx);
|
||||||
contact_finder::init(cx);
|
contact_finder::init(cx);
|
||||||
contacts_popover::init(cx);
|
contacts_popover::init(cx);
|
||||||
incoming_call_notification::init(cx);
|
incoming_call_notification::init(cx);
|
||||||
|
|
|
@ -1,19 +1,15 @@
|
||||||
use client::{ContactRequestStatus, User, UserStore};
|
use client::{ContactRequestStatus, User, UserStore};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
actions, elements::*, AnyViewHandle, Entity, ModelHandle, MouseState, MutableAppContext,
|
elements::*, AnyViewHandle, Entity, ModelHandle, MouseState, MutableAppContext, RenderContext,
|
||||||
RenderContext, Task, View, ViewContext, ViewHandle,
|
Task, View, ViewContext, ViewHandle,
|
||||||
};
|
};
|
||||||
use picker::{Picker, PickerDelegate};
|
use picker::{Picker, PickerDelegate};
|
||||||
use settings::Settings;
|
use settings::Settings;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use util::TryFutureExt;
|
use util::TryFutureExt;
|
||||||
use workspace::Workspace;
|
|
||||||
|
|
||||||
actions!(contact_finder, [Toggle]);
|
|
||||||
|
|
||||||
pub fn init(cx: &mut MutableAppContext) {
|
pub fn init(cx: &mut MutableAppContext) {
|
||||||
Picker::<ContactFinder>::init(cx);
|
Picker::<ContactFinder>::init(cx);
|
||||||
cx.add_action(ContactFinder::toggle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ContactFinder {
|
pub struct ContactFinder {
|
||||||
|
@ -166,34 +162,16 @@ impl PickerDelegate for ContactFinder {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl 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 {
|
pub fn new(user_store: ModelHandle<UserStore>, cx: &mut ViewContext<Self>) -> Self {
|
||||||
let this = cx.weak_handle();
|
let this = cx.weak_handle();
|
||||||
Self {
|
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([]),
|
potential_contacts: Arc::from([]),
|
||||||
user_store,
|
user_store,
|
||||||
selected_index: 0,
|
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
|
@ -82,20 +82,22 @@ impl IncomingCallNotification {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_caller(&self, cx: &mut RenderContext<Self>) -> ElementBox {
|
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()
|
Flex::row()
|
||||||
.with_children(
|
.with_children(
|
||||||
self.call
|
self.call
|
||||||
.caller
|
.caller
|
||||||
.avatar
|
.avatar
|
||||||
.clone()
|
.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(
|
.with_child(
|
||||||
Label::new(
|
Label::new(
|
||||||
self.call.caller.github_login.clone(),
|
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(),
|
||||||
)
|
)
|
||||||
.boxed()
|
.boxed()
|
||||||
|
@ -108,8 +110,11 @@ impl IncomingCallNotification {
|
||||||
Flex::row()
|
Flex::row()
|
||||||
.with_child(
|
.with_child(
|
||||||
MouseEventHandler::<Accept>::new(0, cx, |_, cx| {
|
MouseEventHandler::<Accept>::new(0, cx, |_, cx| {
|
||||||
let theme = &cx.global::<Settings>().theme.contacts_popover;
|
let theme = &cx.global::<Settings>().theme.incoming_call_notification;
|
||||||
Label::new("Accept".to_string(), theme.contact_username.text.clone()).boxed()
|
Label::new("Accept".to_string(), theme.accept_button.text.clone())
|
||||||
|
.contained()
|
||||||
|
.with_style(theme.accept_button.container)
|
||||||
|
.boxed()
|
||||||
})
|
})
|
||||||
.on_click(MouseButton::Left, |_, cx| {
|
.on_click(MouseButton::Left, |_, cx| {
|
||||||
cx.dispatch_action(RespondToCall { accept: true });
|
cx.dispatch_action(RespondToCall { accept: true });
|
||||||
|
@ -118,8 +123,11 @@ impl IncomingCallNotification {
|
||||||
)
|
)
|
||||||
.with_child(
|
.with_child(
|
||||||
MouseEventHandler::<Decline>::new(0, cx, |_, cx| {
|
MouseEventHandler::<Decline>::new(0, cx, |_, cx| {
|
||||||
let theme = &cx.global::<Settings>().theme.contacts_popover;
|
let theme = &cx.global::<Settings>().theme.incoming_call_notification;
|
||||||
Label::new("Decline".to_string(), theme.contact_username.text.clone()).boxed()
|
Label::new("Decline".to_string(), theme.decline_button.text.clone())
|
||||||
|
.contained()
|
||||||
|
.with_style(theme.decline_button.container)
|
||||||
|
.boxed()
|
||||||
})
|
})
|
||||||
.on_click(MouseButton::Left, |_, cx| {
|
.on_click(MouseButton::Left, |_, cx| {
|
||||||
cx.dispatch_action(RespondToCall { accept: false });
|
cx.dispatch_action(RespondToCall { accept: false });
|
||||||
|
|
|
@ -19,6 +19,7 @@ pub struct Picker<D: PickerDelegate> {
|
||||||
query_editor: ViewHandle<Editor>,
|
query_editor: ViewHandle<Editor>,
|
||||||
list_state: UniformListState,
|
list_state: UniformListState,
|
||||||
max_size: Vector2F,
|
max_size: Vector2F,
|
||||||
|
theme: Box<dyn FnMut(&AppContext) -> &theme::Picker>,
|
||||||
confirmed: bool,
|
confirmed: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,8 +52,8 @@ impl<D: PickerDelegate> View for Picker<D> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render(&mut self, cx: &mut RenderContext<Self>) -> gpui::ElementBox {
|
fn render(&mut self, cx: &mut RenderContext<Self>) -> gpui::ElementBox {
|
||||||
let settings = cx.global::<Settings>();
|
let theme = (self.theme)(cx);
|
||||||
let container_style = settings.theme.picker.container;
|
let container_style = theme.container;
|
||||||
let delegate = self.delegate.clone();
|
let delegate = self.delegate.clone();
|
||||||
let match_count = if let Some(delegate) = delegate.upgrade(cx.app) {
|
let match_count = if let Some(delegate) = delegate.upgrade(cx.app) {
|
||||||
delegate.read(cx).match_count()
|
delegate.read(cx).match_count()
|
||||||
|
@ -64,17 +65,14 @@ impl<D: PickerDelegate> View for Picker<D> {
|
||||||
.with_child(
|
.with_child(
|
||||||
ChildView::new(&self.query_editor)
|
ChildView::new(&self.query_editor)
|
||||||
.contained()
|
.contained()
|
||||||
.with_style(settings.theme.picker.input_editor.container)
|
.with_style(theme.input_editor.container)
|
||||||
.boxed(),
|
.boxed(),
|
||||||
)
|
)
|
||||||
.with_child(
|
.with_child(
|
||||||
if match_count == 0 {
|
if match_count == 0 {
|
||||||
Label::new(
|
Label::new("No matches".into(), theme.empty.label.clone())
|
||||||
"No matches".into(),
|
.contained()
|
||||||
settings.theme.picker.empty.label.clone(),
|
.with_style(theme.empty.container)
|
||||||
)
|
|
||||||
.contained()
|
|
||||||
.with_style(settings.theme.picker.empty.container)
|
|
||||||
} else {
|
} else {
|
||||||
UniformList::new(
|
UniformList::new(
|
||||||
self.list_state.clone(),
|
self.list_state.clone(),
|
||||||
|
@ -147,6 +145,7 @@ impl<D: PickerDelegate> Picker<D> {
|
||||||
list_state: Default::default(),
|
list_state: Default::default(),
|
||||||
delegate,
|
delegate,
|
||||||
max_size: vec2f(540., 420.),
|
max_size: vec2f(540., 420.),
|
||||||
|
theme: Box::new(|cx| &cx.global::<Settings>().theme.picker),
|
||||||
confirmed: false,
|
confirmed: false,
|
||||||
};
|
};
|
||||||
cx.defer(|this, cx| {
|
cx.defer(|this, cx| {
|
||||||
|
@ -163,6 +162,14 @@ impl<D: PickerDelegate> Picker<D> {
|
||||||
self
|
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 {
|
pub fn query(&self, cx: &AppContext) -> String {
|
||||||
self.query_editor.read(cx).text(cx)
|
self.query_editor.read(cx).text(cx)
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ pub struct Theme {
|
||||||
pub context_menu: ContextMenu,
|
pub context_menu: ContextMenu,
|
||||||
pub chat_panel: ChatPanel,
|
pub chat_panel: ChatPanel,
|
||||||
pub contacts_popover: ContactsPopover,
|
pub contacts_popover: ContactsPopover,
|
||||||
|
pub contact_list: ContactList,
|
||||||
pub contact_finder: ContactFinder,
|
pub contact_finder: ContactFinder,
|
||||||
pub project_panel: ProjectPanel,
|
pub project_panel: ProjectPanel,
|
||||||
pub command_palette: CommandPalette,
|
pub command_palette: CommandPalette,
|
||||||
|
@ -31,6 +32,7 @@ pub struct Theme {
|
||||||
pub contact_notification: ContactNotification,
|
pub contact_notification: ContactNotification,
|
||||||
pub update_notification: UpdateNotification,
|
pub update_notification: UpdateNotification,
|
||||||
pub project_shared_notification: ProjectSharedNotification,
|
pub project_shared_notification: ProjectSharedNotification,
|
||||||
|
pub incoming_call_notification: IncomingCallNotification,
|
||||||
pub tooltip: TooltipStyle,
|
pub tooltip: TooltipStyle,
|
||||||
pub terminal: TerminalStyle,
|
pub terminal: TerminalStyle,
|
||||||
}
|
}
|
||||||
|
@ -87,6 +89,10 @@ pub struct ContactsPopover {
|
||||||
pub container: ContainerStyle,
|
pub container: ContainerStyle,
|
||||||
pub height: f32,
|
pub height: f32,
|
||||||
pub width: f32,
|
pub width: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Default)]
|
||||||
|
pub struct ContactList {
|
||||||
pub user_query_editor: FieldEditor,
|
pub user_query_editor: FieldEditor,
|
||||||
pub user_query_editor_height: f32,
|
pub user_query_editor_height: f32,
|
||||||
pub add_contact_button: IconButton,
|
pub add_contact_button: IconButton,
|
||||||
|
@ -105,6 +111,16 @@ pub struct ContactsPopover {
|
||||||
pub calling_indicator: ContainedText,
|
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)]
|
#[derive(Clone, Deserialize, Default)]
|
||||||
pub struct TabBar {
|
pub struct TabBar {
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
|
@ -353,15 +369,6 @@ pub struct InviteLink {
|
||||||
pub icon: Icon,
|
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)]
|
#[derive(Deserialize, Default)]
|
||||||
pub struct Icon {
|
pub struct Icon {
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
|
@ -469,6 +476,14 @@ pub struct ProjectSharedNotification {
|
||||||
pub dismiss_button: ContainedText,
|
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)]
|
#[derive(Clone, Deserialize, Default)]
|
||||||
pub struct Editor {
|
pub struct Editor {
|
||||||
pub text_color: Color,
|
pub text_color: Color,
|
||||||
|
|
|
@ -16,6 +16,8 @@ import updateNotification from "./updateNotification";
|
||||||
import projectSharedNotification from "./projectSharedNotification";
|
import projectSharedNotification from "./projectSharedNotification";
|
||||||
import tooltip from "./tooltip";
|
import tooltip from "./tooltip";
|
||||||
import terminal from "./terminal";
|
import terminal from "./terminal";
|
||||||
|
import contactList from "./contactList";
|
||||||
|
import incomingCallNotification from "./incomingCallNotification";
|
||||||
|
|
||||||
export const panel = {
|
export const panel = {
|
||||||
padding: { top: 12, bottom: 12 },
|
padding: { top: 12, bottom: 12 },
|
||||||
|
@ -36,6 +38,7 @@ export default function app(theme: Theme): Object {
|
||||||
projectPanel: projectPanel(theme),
|
projectPanel: projectPanel(theme),
|
||||||
chatPanel: chatPanel(theme),
|
chatPanel: chatPanel(theme),
|
||||||
contactsPopover: contactsPopover(theme),
|
contactsPopover: contactsPopover(theme),
|
||||||
|
contactList: contactList(theme),
|
||||||
contactFinder: contactFinder(theme),
|
contactFinder: contactFinder(theme),
|
||||||
search: search(theme),
|
search: search(theme),
|
||||||
breadcrumbs: {
|
breadcrumbs: {
|
||||||
|
@ -47,6 +50,7 @@ export default function app(theme: Theme): Object {
|
||||||
contactNotification: contactNotification(theme),
|
contactNotification: contactNotification(theme),
|
||||||
updateNotification: updateNotification(theme),
|
updateNotification: updateNotification(theme),
|
||||||
projectSharedNotification: projectSharedNotification(theme),
|
projectSharedNotification: projectSharedNotification(theme),
|
||||||
|
incomingCallNotification: incomingCallNotification(theme),
|
||||||
tooltip: tooltip(theme),
|
tooltip: tooltip(theme),
|
||||||
terminal: terminal(theme),
|
terminal: terminal(theme),
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import Theme from "../themes/common/theme";
|
import Theme from "../themes/common/theme";
|
||||||
import picker from "./picker";
|
import picker from "./picker";
|
||||||
import { backgroundColor, iconColor } from "./components";
|
import { backgroundColor, border, iconColor, player, text } from "./components";
|
||||||
|
|
||||||
export default function contactFinder(theme: Theme) {
|
export default function contactFinder(theme: Theme) {
|
||||||
const contactButton = {
|
const contactButton = {
|
||||||
|
@ -12,7 +12,28 @@ export default function contactFinder(theme: Theme) {
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
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,
|
rowHeight: 28,
|
||||||
contactAvatar: {
|
contactAvatar: {
|
||||||
cornerRadius: 10,
|
cornerRadius: 10,
|
||||||
|
|
|
@ -19,7 +19,6 @@ export default function contactsPopover(theme: Theme) {
|
||||||
padding: { top: 6 },
|
padding: { top: 6 },
|
||||||
shadow: popoverShadow(theme),
|
shadow: popoverShadow(theme),
|
||||||
border: border(theme, "primary"),
|
border: border(theme, "primary"),
|
||||||
margin: { top: -5 },
|
|
||||||
width: 250,
|
width: 250,
|
||||||
height: 300,
|
height: 300,
|
||||||
userQueryEditor: {
|
userQueryEditor: {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue