chore: better dropdown menu #11
@@ -18,7 +18,7 @@ use ui::button::{Button, ButtonVariants};
|
|||||||
use ui::dock_area::dock::DockPlacement;
|
use ui::dock_area::dock::DockPlacement;
|
||||||
use ui::dock_area::panel::PanelView;
|
use ui::dock_area::panel::PanelView;
|
||||||
use ui::dock_area::{ClosePanel, DockArea, DockItem};
|
use ui::dock_area::{ClosePanel, DockArea, DockItem};
|
||||||
use ui::menu::DropdownMenu;
|
use ui::menu::{DropdownMenu, PopupMenuItem};
|
||||||
use ui::{h_flex, v_flex, IconName, Root, Sizable, WindowExtension};
|
use ui::{h_flex, v_flex, IconName, Root, Sizable, WindowExtension};
|
||||||
|
|
||||||
use crate::dialogs::settings;
|
use crate::dialogs::settings;
|
||||||
@@ -382,17 +382,29 @@ impl Workspace {
|
|||||||
.when_some(current_user.as_ref(), |this, public_key| {
|
.when_some(current_user.as_ref(), |this, public_key| {
|
||||||
let persons = PersonRegistry::global(cx);
|
let persons = PersonRegistry::global(cx);
|
||||||
let profile = persons.read(cx).get(public_key, cx);
|
let profile = persons.read(cx).get(public_key, cx);
|
||||||
|
let avatar = profile.avatar();
|
||||||
|
let name = profile.name();
|
||||||
|
|
||||||
this.child(
|
this.child(
|
||||||
Button::new("current-user")
|
Button::new("current-user")
|
||||||
.child(Avatar::new(profile.avatar()).xsmall())
|
.child(Avatar::new(avatar.clone()).xsmall())
|
||||||
.small()
|
.small()
|
||||||
.caret()
|
.caret()
|
||||||
.compact()
|
.compact()
|
||||||
.transparent()
|
.transparent()
|
||||||
.dropdown_menu(move |this, _window, _cx| {
|
.dropdown_menu(move |this, _window, _cx| {
|
||||||
|
let avatar = avatar.clone();
|
||||||
|
let name = name.clone();
|
||||||
|
|
||||||
this.min_w(px(256.))
|
this.min_w(px(256.))
|
||||||
.label(profile.name())
|
.item(PopupMenuItem::element(move |_window, cx| {
|
||||||
|
h_flex()
|
||||||
|
.gap_1p5()
|
||||||
|
.text_xs()
|
||||||
|
.text_color(cx.theme().text_muted)
|
||||||
|
.child(Avatar::new(avatar.clone()).xsmall())
|
||||||
|
.child(name.clone())
|
||||||
|
}))
|
||||||
.separator()
|
.separator()
|
||||||
.menu_with_icon(
|
.menu_with_icon(
|
||||||
"Profile",
|
"Profile",
|
||||||
@@ -491,54 +503,35 @@ impl Workspace {
|
|||||||
.small()
|
.small()
|
||||||
.ghost()
|
.ghost()
|
||||||
.when(inbox_state.subscribing(), |this| this.indicator())
|
.when(inbox_state.subscribing(), |this| this.indicator())
|
||||||
.dropdown_menu(move |this, _window, _cx| {
|
.dropdown_menu(move |this, _window, cx| {
|
||||||
this.min_w(px(260.))
|
let persons = PersonRegistry::global(cx);
|
||||||
.label("Messaging Relays")
|
let profile = persons.read(cx).get(&pkey, cx);
|
||||||
.menu_element_with_disabled(
|
let urls: Vec<SharedString> = profile
|
||||||
Box::new(Command::ShowRelayList),
|
.messaging_relays()
|
||||||
true,
|
.iter()
|
||||||
move |_window, cx| {
|
.map(|url| SharedString::from(url.to_string()))
|
||||||
let persons = PersonRegistry::global(cx);
|
.collect();
|
||||||
let profile = persons.read(cx).get(&pkey, cx);
|
|
||||||
let urls = profile.messaging_relays();
|
|
||||||
|
|
||||||
v_flex()
|
// Header
|
||||||
.gap_1()
|
let menu = this.min_w(px(260.)).label("Messaging Relays");
|
||||||
.w_full()
|
|
||||||
.items_start()
|
|
||||||
.justify_start()
|
|
||||||
.children({
|
|
||||||
let mut items = vec![];
|
|
||||||
|
|
||||||
for url in urls.iter() {
|
// Content
|
||||||
items.push(
|
let menu = urls.into_iter().fold(menu, |this, url| {
|
||||||
h_flex()
|
this.item(PopupMenuItem::element(move |_window, _cx| {
|
||||||
.h_6()
|
h_flex()
|
||||||
.w_full()
|
.px_1()
|
||||||
.gap_2()
|
.w_full()
|
||||||
.px_2()
|
.gap_2()
|
||||||
.text_xs()
|
.text_sm()
|
||||||
.bg(cx
|
.child(
|
||||||
.theme()
|
div().size_1p5().rounded_full().bg(gpui::green()),
|
||||||
.elevated_surface_background)
|
)
|
||||||
.rounded(cx.theme().radius)
|
.child(url.clone())
|
||||||
.child(
|
}))
|
||||||
div()
|
});
|
||||||
.size_1()
|
|
||||||
.rounded_full()
|
|
||||||
.bg(gpui::green()),
|
|
||||||
)
|
|
||||||
.child(SharedString::from(
|
|
||||||
url.to_string(),
|
|
||||||
)),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
items
|
// Footer
|
||||||
})
|
menu.separator()
|
||||||
},
|
|
||||||
)
|
|
||||||
.separator()
|
|
||||||
.menu_with_icon(
|
.menu_with_icon(
|
||||||
"Reload",
|
"Reload",
|
||||||
IconName::Refresh,
|
IconName::Refresh,
|
||||||
@@ -579,51 +572,30 @@ impl Workspace {
|
|||||||
.small()
|
.small()
|
||||||
.ghost()
|
.ghost()
|
||||||
.when(relay_list.configured(), |this| this.indicator())
|
.when(relay_list.configured(), |this| this.indicator())
|
||||||
.dropdown_menu(move |this, _window, _cx| {
|
.dropdown_menu(move |this, _window, cx| {
|
||||||
this.min_w(px(260.))
|
let nostr = NostrRegistry::global(cx);
|
||||||
.label("Relays")
|
let urls = nostr.read(cx).read_only_relays(&pkey, cx);
|
||||||
.menu_element_with_disabled(
|
|
||||||
Box::new(Command::ShowRelayList),
|
|
||||||
true,
|
|
||||||
move |_window, cx| {
|
|
||||||
let nostr = NostrRegistry::global(cx);
|
|
||||||
let urls = nostr.read(cx).read_only_relays(&pkey, cx);
|
|
||||||
|
|
||||||
v_flex()
|
// Header
|
||||||
.gap_1()
|
let menu = this.min_w(px(260.)).label("Relays");
|
||||||
.w_full()
|
|
||||||
.items_start()
|
|
||||||
.justify_start()
|
|
||||||
.children({
|
|
||||||
let mut items = vec![];
|
|
||||||
|
|
||||||
for url in urls.into_iter() {
|
// Content
|
||||||
items.push(
|
let menu = urls.into_iter().fold(menu, |this, url| {
|
||||||
h_flex()
|
this.item(PopupMenuItem::element(move |_window, _cx| {
|
||||||
.h_6()
|
h_flex()
|
||||||
.w_full()
|
.px_1()
|
||||||
.gap_2()
|
.w_full()
|
||||||
.px_2()
|
.gap_2()
|
||||||
.text_xs()
|
.text_sm()
|
||||||
.bg(cx
|
.child(
|
||||||
.theme()
|
div().size_1p5().rounded_full().bg(gpui::green()),
|
||||||
.elevated_surface_background)
|
)
|
||||||
.rounded(cx.theme().radius)
|
.child(url.clone())
|
||||||
.child(
|
}))
|
||||||
div()
|
});
|
||||||
.size_1()
|
|
||||||
.rounded_full()
|
|
||||||
.bg(gpui::green()),
|
|
||||||
)
|
|
||||||
.child(url),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
items
|
// Footer
|
||||||
})
|
menu.separator()
|
||||||
},
|
|
||||||
)
|
|
||||||
.separator()
|
|
||||||
.menu_with_icon(
|
.menu_with_icon(
|
||||||
"Reload",
|
"Reload",
|
||||||
IconName::Refresh,
|
IconName::Refresh,
|
||||||
|
|||||||
@@ -1112,25 +1112,17 @@ impl PopupMenu {
|
|||||||
.border_color(cx.theme().border)
|
.border_color(cx.theme().border)
|
||||||
.disabled(true),
|
.disabled(true),
|
||||||
PopupMenuItem::Label(label) => this.disabled(true).cursor_default().child(
|
PopupMenuItem::Label(label) => this.disabled(true).cursor_default().child(
|
||||||
h_flex()
|
h_flex().cursor_default().items_center().gap_x_1().child(
|
||||||
.cursor_default()
|
div()
|
||||||
.items_center()
|
.flex_1()
|
||||||
.gap_x_1()
|
.text_xs()
|
||||||
.children(Self::render_icon(has_left_icon, false, None, window, cx))
|
.font_semibold()
|
||||||
.child(
|
.text_color(cx.theme().text_muted)
|
||||||
div()
|
.child(label.clone()),
|
||||||
.flex_1()
|
),
|
||||||
.text_xs()
|
|
||||||
.font_semibold()
|
|
||||||
.text_color(cx.theme().text_muted)
|
|
||||||
.child(label.clone()),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
PopupMenuItem::ElementItem {
|
PopupMenuItem::ElementItem {
|
||||||
render,
|
render, disabled, ..
|
||||||
icon,
|
|
||||||
disabled,
|
|
||||||
..
|
|
||||||
} => this
|
} => this
|
||||||
.when(!disabled, |this| {
|
.when(!disabled, |this| {
|
||||||
this.on_click(
|
this.on_click(
|
||||||
@@ -1144,13 +1136,6 @@ impl PopupMenu {
|
|||||||
.min_h(item_height)
|
.min_h(item_height)
|
||||||
.items_center()
|
.items_center()
|
||||||
.gap_x_2()
|
.gap_x_2()
|
||||||
.children(Self::render_icon(
|
|
||||||
has_left_icon,
|
|
||||||
is_left_check,
|
|
||||||
icon.clone(),
|
|
||||||
window,
|
|
||||||
cx,
|
|
||||||
))
|
|
||||||
.child((render)(window, cx))
|
.child((render)(window, cx))
|
||||||
.children(right_check_icon.map(|icon| icon.ml_3())),
|
.children(right_check_icon.map(|icon| icon.ml_3())),
|
||||||
),
|
),
|
||||||
|
|||||||
Reference in New Issue
Block a user