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 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);
|
||||
|
|
|
@ -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
|
@ -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 });
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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),
|
||||
};
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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: {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue