Refine GPUI shell UX surfaces
This commit is contained in:
1 parent
22ba7a9004
commit
6809df15de
7 files changed
+617
-122
No files matched your search
@@ -1,4 +1,10 @@
|
||||
use super::*;
|
||||
use super::{
|
||||
messages_parts::{
|
||||
compact_message_card, composer_chip, composer_subject, filter_shell, message_section_label,
|
||||
search_shell, secondary_message, selected_message_card, selected_recipient,
|
||||
},
|
||||
*,
|
||||
};
|
||||
|
||||
impl AppRoot {
|
||||
pub(super) fn render_messages(&self, cx: &mut Context<Self>) -> impl IntoElement + '_ {
|
||||
@@ -8,36 +14,60 @@ impl AppRoot {
|
||||
.iter()
|
||||
.find(|item| &item.id == id)
|
||||
});
|
||||
let selected_subject = selected
|
||||
.map(|item| item.subject.clone())
|
||||
.unwrap_or_else(|| "Select a thread".to_string());
|
||||
let selected_body = selected
|
||||
.map(|item| item.body.clone())
|
||||
.unwrap_or_else(|| "No message selected.".to_string());
|
||||
let company_wide = self
|
||||
.snapshot
|
||||
.agent_messages
|
||||
.iter()
|
||||
.filter(|item| item.channel == "company")
|
||||
.collect::<Vec<_>>();
|
||||
let department = self
|
||||
.snapshot
|
||||
.agent_messages
|
||||
.iter()
|
||||
.filter(|item| item.channel == "department")
|
||||
.collect::<Vec<_>>();
|
||||
let direct = self
|
||||
.snapshot
|
||||
.agent_messages
|
||||
.iter()
|
||||
.filter(|item| item.channel == "direct")
|
||||
.collect::<Vec<_>>();
|
||||
let task_threads = self
|
||||
.snapshot
|
||||
.agent_messages
|
||||
.iter()
|
||||
.filter(|item| {
|
||||
item.channel != "company"
|
||||
&& item.channel != "department"
|
||||
&& item.channel != "direct"
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
div()
|
||||
.flex()
|
||||
.gap_4()
|
||||
.child(
|
||||
div()
|
||||
.id("messages-list")
|
||||
.w(px(320.0))
|
||||
.p_4()
|
||||
.gap_2()
|
||||
.w(px(356.0))
|
||||
.p_5()
|
||||
.gap_4()
|
||||
.border_1()
|
||||
.rounded_md()
|
||||
.rounded_lg()
|
||||
.border_color(theme::panel_border())
|
||||
.bg(theme::panel())
|
||||
.overflow_scroll()
|
||||
.child(div().text_lg().child("Channels"))
|
||||
.children(self.snapshot.agent_messages.iter().map(|item| {
|
||||
.child(message_section_label("COMPANY-WIDE"))
|
||||
.children(company_wide.iter().map(|message| {
|
||||
let active =
|
||||
self.state.selected_message_id.as_deref() == Some(item.id.as_str());
|
||||
let message_id = item.id.clone();
|
||||
self.state.selected_message_id.as_deref() == Some(message.id.as_str());
|
||||
let message_id = message.id.clone();
|
||||
div()
|
||||
.id(SharedString::from(format!("message-{}", item.id)))
|
||||
.px_3()
|
||||
.py_2()
|
||||
.rounded_md()
|
||||
.id(SharedString::from(format!("message-{}", message.id)))
|
||||
.flex()
|
||||
.justify_between()
|
||||
.items_center()
|
||||
.px_4()
|
||||
.py_3()
|
||||
.rounded_lg()
|
||||
.cursor_pointer()
|
||||
.bg(if active {
|
||||
theme::selection_fill()
|
||||
@@ -49,46 +79,247 @@ impl AppRoot {
|
||||
this.state.selected_message_id = Some(message_id.clone());
|
||||
cx.notify();
|
||||
}))
|
||||
.child(format!("{} · {}", item.subject, item.priority))
|
||||
})),
|
||||
.child(
|
||||
div()
|
||||
.text_sm()
|
||||
.text_color(if active {
|
||||
theme::sidebar_text_active()
|
||||
} else {
|
||||
theme::text_secondary()
|
||||
})
|
||||
.truncate()
|
||||
.child(message.subject.clone()),
|
||||
)
|
||||
.when(message.priority == "urgent", |container| {
|
||||
container.child(
|
||||
div()
|
||||
.w(px(10.0))
|
||||
.h(px(10.0))
|
||||
.rounded_full()
|
||||
.bg(theme::danger()),
|
||||
)
|
||||
})
|
||||
}))
|
||||
.child(message_section_label("DEPARTMENT"))
|
||||
.children(department.iter().map(|message| {
|
||||
let active =
|
||||
self.state.selected_message_id.as_deref() == Some(message.id.as_str());
|
||||
let message_id = message.id.clone();
|
||||
div()
|
||||
.id(SharedString::from(format!("message-{}", message.id)))
|
||||
.flex()
|
||||
.justify_between()
|
||||
.items_center()
|
||||
.px_4()
|
||||
.py_3()
|
||||
.rounded_lg()
|
||||
.cursor_pointer()
|
||||
.bg(if active {
|
||||
theme::selection_fill()
|
||||
} else {
|
||||
theme::panel()
|
||||
})
|
||||
.hover(|style| style.bg(theme::panel_hover()))
|
||||
.on_click(cx.listener(move |this, _, _, cx| {
|
||||
this.state.selected_message_id = Some(message_id.clone());
|
||||
cx.notify();
|
||||
}))
|
||||
.child(
|
||||
div()
|
||||
.text_sm()
|
||||
.text_color(if active {
|
||||
theme::sidebar_text_active()
|
||||
} else {
|
||||
theme::text_secondary()
|
||||
})
|
||||
.truncate()
|
||||
.child(message.subject.clone()),
|
||||
)
|
||||
}))
|
||||
.child(message_section_label("DIRECT MESSAGES"))
|
||||
.children(direct.iter().map(|message| {
|
||||
let active =
|
||||
self.state.selected_message_id.as_deref() == Some(message.id.as_str());
|
||||
let message_id = message.id.clone();
|
||||
div()
|
||||
.id(SharedString::from(format!("message-{}", message.id)))
|
||||
.flex()
|
||||
.justify_between()
|
||||
.items_center()
|
||||
.px_4()
|
||||
.py_3()
|
||||
.rounded_lg()
|
||||
.cursor_pointer()
|
||||
.bg(if active {
|
||||
theme::selection_fill()
|
||||
} else {
|
||||
theme::panel()
|
||||
})
|
||||
.hover(|style| style.bg(theme::panel_hover()))
|
||||
.on_click(cx.listener(move |this, _, _, cx| {
|
||||
this.state.selected_message_id = Some(message_id.clone());
|
||||
cx.notify();
|
||||
}))
|
||||
.child(
|
||||
div()
|
||||
.text_sm()
|
||||
.text_color(if active {
|
||||
theme::sidebar_text_active()
|
||||
} else {
|
||||
theme::text_secondary()
|
||||
})
|
||||
.truncate()
|
||||
.child(message.subject.clone()),
|
||||
)
|
||||
.when(message.read_at.is_none(), |container| {
|
||||
container.child(
|
||||
div()
|
||||
.w(px(10.0))
|
||||
.h(px(10.0))
|
||||
.rounded_full()
|
||||
.bg(theme::danger()),
|
||||
)
|
||||
})
|
||||
}))
|
||||
.child(message_section_label("TASK DISCUSSIONS"))
|
||||
.children(task_threads.iter().map(|message| {
|
||||
let active =
|
||||
self.state.selected_message_id.as_deref() == Some(message.id.as_str());
|
||||
let message_id = message.id.clone();
|
||||
div()
|
||||
.id(SharedString::from(format!("message-{}", message.id)))
|
||||
.flex()
|
||||
.justify_between()
|
||||
.items_center()
|
||||
.px_4()
|
||||
.py_3()
|
||||
.rounded_lg()
|
||||
.cursor_pointer()
|
||||
.bg(if active {
|
||||
theme::selection_fill()
|
||||
} else {
|
||||
theme::panel()
|
||||
})
|
||||
.hover(|style| style.bg(theme::panel_hover()))
|
||||
.on_click(cx.listener(move |this, _, _, cx| {
|
||||
this.state.selected_message_id = Some(message_id.clone());
|
||||
cx.notify();
|
||||
}))
|
||||
.child(
|
||||
div()
|
||||
.text_sm()
|
||||
.text_color(if active {
|
||||
theme::sidebar_text_active()
|
||||
} else {
|
||||
theme::text_secondary()
|
||||
})
|
||||
.truncate()
|
||||
.child(message.subject.clone()),
|
||||
)
|
||||
}))
|
||||
.child(div().flex_1())
|
||||
.child(
|
||||
div()
|
||||
.flex()
|
||||
.justify_between()
|
||||
.text_xs()
|
||||
.text_color(theme::text_muted())
|
||||
.child(format!("{} channels", self.snapshot.agent_messages.len()))
|
||||
.child(format!("{} agents", self.snapshot.agents.len())),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.flex_1()
|
||||
.p_4()
|
||||
.gap_3()
|
||||
.border_1()
|
||||
.rounded_md()
|
||||
.rounded_lg()
|
||||
.border_color(theme::panel_border())
|
||||
.bg(theme::panel())
|
||||
.child(div().text_lg().child("Conversation"))
|
||||
.child(
|
||||
div()
|
||||
.text_sm()
|
||||
.text_color(theme::text_muted())
|
||||
.child(selected_subject),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.min_h(px(220.0))
|
||||
.p_3()
|
||||
.border_1()
|
||||
.border_color(theme::panel_inset_border())
|
||||
.rounded_md()
|
||||
.bg(theme::panel_inset())
|
||||
.child(selected_body),
|
||||
)
|
||||
.child(self.message_input.clone())
|
||||
.child(
|
||||
div()
|
||||
.flex()
|
||||
.gap_2()
|
||||
.child(primary_button("Send update", cx, |this, cx| {
|
||||
this.send_message(cx)
|
||||
}))
|
||||
.child(secondary_button("Mark read", cx, |this, cx| {
|
||||
this.mark_selected_message_read(cx)
|
||||
})),
|
||||
.justify_between()
|
||||
.items_center()
|
||||
.px_5()
|
||||
.py_4()
|
||||
.border_b_1()
|
||||
.border_color(theme::panel_border())
|
||||
.child(
|
||||
div().text_lg().text_color(theme::text_primary()).child(
|
||||
selected
|
||||
.map(|message| message.subject.clone())
|
||||
.unwrap_or_else(|| "Select a conversation".to_string()),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.flex()
|
||||
.gap_3()
|
||||
.child(search_shell("Search messages"))
|
||||
.child(filter_shell()),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.id("messages-stream")
|
||||
.flex_1()
|
||||
.p_4()
|
||||
.overflow_scroll()
|
||||
.child(selected_message_card(selected))
|
||||
.when_some(secondary_message(selected), |container, message| {
|
||||
container.child(compact_message_card(message))
|
||||
}),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.px_4()
|
||||
.py_3()
|
||||
.border_t_1()
|
||||
.border_color(theme::panel_border())
|
||||
.bg(theme::panel())
|
||||
.child(
|
||||
div()
|
||||
.flex()
|
||||
.gap_3()
|
||||
.child(composer_chip(selected_recipient(selected).as_str()))
|
||||
.child(composer_subject(selected)),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.mt(px(12.0))
|
||||
.p_3()
|
||||
.rounded_lg()
|
||||
.bg(theme::panel_inset())
|
||||
.border_1()
|
||||
.border_color(theme::panel_inset_border())
|
||||
.child(self.message_input.clone()),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.mt(px(10.0))
|
||||
.flex()
|
||||
.justify_between()
|
||||
.items_center()
|
||||
.child(
|
||||
div()
|
||||
.text_xs()
|
||||
.text_color(theme::text_muted())
|
||||
.child("Press Cmd+Enter to send"),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.flex()
|
||||
.gap_2()
|
||||
.child(primary_button("Send update", cx, |this, cx| {
|
||||
this.send_message(cx)
|
||||
}))
|
||||
.child(secondary_button(
|
||||
"Mark read",
|
||||
cx,
|
||||
|this, cx| this.mark_selected_message_read(cx),
|
||||
)),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user