wip
This commit is contained in:
@@ -16,6 +16,9 @@ use ui::{Icon, IconName, Selectable, Sizable, StyledExt, WindowExtension, h_flex
|
|||||||
|
|
||||||
use crate::dialogs::screening;
|
use crate::dialogs::screening;
|
||||||
|
|
||||||
|
/// Group name callers can target from a `trailing` element to react to row hover.
|
||||||
|
pub const ROOM_ENTRY_GROUP: &str = "room-entry";
|
||||||
|
|
||||||
#[derive(IntoElement)]
|
#[derive(IntoElement)]
|
||||||
pub struct RoomEntry {
|
pub struct RoomEntry {
|
||||||
ix: usize,
|
ix: usize,
|
||||||
@@ -112,6 +115,7 @@ impl RenderOnce for RoomEntry {
|
|||||||
|
|
||||||
h_flex()
|
h_flex()
|
||||||
.id(self.ix)
|
.id(self.ix)
|
||||||
|
.group(ROOM_ENTRY_GROUP)
|
||||||
.h_8()
|
.h_8()
|
||||||
.w_full()
|
.w_full()
|
||||||
.pl(px(6. + self.depth as f32 * 14.))
|
.pl(px(6. + self.depth as f32 * 14.))
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ use crate::Command;
|
|||||||
mod entry;
|
mod entry;
|
||||||
mod tree;
|
mod tree;
|
||||||
|
|
||||||
|
use entry::ROOM_ENTRY_GROUP;
|
||||||
pub(crate) use entry::RoomEntry;
|
pub(crate) use entry::RoomEntry;
|
||||||
use tree::{SidebarRow, TreeRow, TreeRowKind, TreeSection, dummy_communities};
|
use tree::{SidebarRow, TreeRow, TreeRowKind, TreeSection, dummy_communities};
|
||||||
|
|
||||||
@@ -241,8 +242,10 @@ impl Sidebar {
|
|||||||
SidebarRow::Room {
|
SidebarRow::Room {
|
||||||
room,
|
room,
|
||||||
depth,
|
depth,
|
||||||
pinned: _pinned,
|
pinned,
|
||||||
} => {
|
} => {
|
||||||
|
let pinned = *pinned;
|
||||||
|
let room_id = room.read(cx).id;
|
||||||
let public_key = room.read(cx).display_member(cx).public_key();
|
let public_key = room.read(cx).display_member(cx).public_key();
|
||||||
let name = room.read(cx).display_name(cx);
|
let name = room.read(cx).display_name(cx);
|
||||||
let avatar = room.read(cx).display_image(cx);
|
let avatar = room.read(cx).display_image(cx);
|
||||||
@@ -255,6 +258,45 @@ impl Sidebar {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let sidebar = cx.entity().downgrade();
|
||||||
|
let trailing =
|
||||||
|
Button::new(ElementId::NamedInteger("room-menu".into(), index as u64))
|
||||||
|
.icon(IconName::Ellipsis)
|
||||||
|
.ghost_alt()
|
||||||
|
.xsmall()
|
||||||
|
.compact()
|
||||||
|
.invisible()
|
||||||
|
.group_hover(ROOM_ENTRY_GROUP, |style| style.visible())
|
||||||
|
.dropdown_menu(move |this, _window, _cx| {
|
||||||
|
let sidebar = sidebar.clone();
|
||||||
|
|
||||||
|
if pinned {
|
||||||
|
this.item(PopupMenuItem::new("Unpin").on_click(
|
||||||
|
move |_event, _window, cx| {
|
||||||
|
if let Err(error) =
|
||||||
|
sidebar.update(cx, |sidebar, cx| {
|
||||||
|
sidebar.unpin_room(room_id, cx);
|
||||||
|
})
|
||||||
|
{
|
||||||
|
log::error!("Failed to unpin room: {error}");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
this.item(PopupMenuItem::new("Pin").on_click(
|
||||||
|
move |_event, _window, cx| {
|
||||||
|
if let Err(error) =
|
||||||
|
sidebar.update(cx, |sidebar, cx| {
|
||||||
|
sidebar.pin_room(room_id, cx);
|
||||||
|
})
|
||||||
|
{
|
||||||
|
log::error!("Failed to pin room: {error}");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
))
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
RoomEntry::new(index)
|
RoomEntry::new(index)
|
||||||
.name(name)
|
.name(name)
|
||||||
.avatar(avatar)
|
.avatar(avatar)
|
||||||
@@ -262,6 +304,7 @@ impl Sidebar {
|
|||||||
.kind(kind)
|
.kind(kind)
|
||||||
.created_at(created_at)
|
.created_at(created_at)
|
||||||
.depth(*depth)
|
.depth(*depth)
|
||||||
|
.trailing(trailing)
|
||||||
.on_click(handler)
|
.on_click(handler)
|
||||||
.into_any_element()
|
.into_any_element()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
# Sidebar tree redesign
|
# Sidebar tree redesign
|
||||||
|
|
||||||
Status: steps 1-5 implemented. Search now lives in `panels/search.rs`; the
|
Status: steps 1-6 implemented. Search lives in `panels/search.rs`; the sidebar
|
||||||
sidebar renders the nav rail and the flattened tree. Remaining: step 6 (pin UI),
|
renders the nav rail, the flattened tree, and per-row pin/unpin menus. Remaining:
|
||||||
step 7 (community rows are already rendered from dummy data, tracked by the
|
step 7 (confirm the placeholder community names), optional step 8 (persistence),
|
||||||
`TODO(concord)`), optional step 8 (persistence), step 9 (cleanup of the step-6
|
step 9 (remove the unused `TreeRow::selected` and run the final cleanup).
|
||||||
dead code).
|
|
||||||
|
|
||||||
Scope: `crates/workspace/src/sidebar` (`mod.rs`, `entry.rs`, new `tree.rs`),
|
Scope: `crates/workspace/src/sidebar` (`mod.rs`, `entry.rs`, new `tree.rs`),
|
||||||
new panel shells in `crates/workspace/src/panels/`, and the `Command` wiring in
|
new panel shells in `crates/workspace/src/panels/`, and the `Command` wiring in
|
||||||
@@ -264,10 +263,10 @@ Search is now a panel, not a sidebar mode:
|
|||||||
- Pin state: `pinned_rooms: Vec<u64>` in `Sidebar`, order = pin order.
|
- Pin state: `pinned_rooms: Vec<u64>` in `Sidebar`, order = pin order.
|
||||||
- UI: hover ellipsis (`IconName::Ellipsis`, `ghost_alt`, `xsmall`, `compact`)
|
- UI: hover ellipsis (`IconName::Ellipsis`, `ghost_alt`, `xsmall`, `compact`)
|
||||||
on each room row, opening a `DropdownMenu` with `Pin` / `Unpin`
|
on each room row, opening a `DropdownMenu` with `Pin` / `Unpin`
|
||||||
(`PopupMenuItem::new(...).on_click(...)`). Verify the trigger click does not
|
(`PopupMenuItem::new(...).on_click(...)`). The ellipsis is a `RoomEntry`
|
||||||
also fire the row's `emit_room` click; if it does, `cx.stop_propagation()`
|
trailing element, hidden by default and revealed with `group_hover` against the
|
||||||
in the menu trigger's `on_click`. (There is no right-click menu pattern in
|
row's `ROOM_ENTRY_GROUP` group. (There is no right-click menu pattern in the
|
||||||
the codebase yet; a context menu is a follow-up.)
|
codebase yet; a context menu is a follow-up.)
|
||||||
- `Pinned` folder is hidden when no pinned room resolves to a live room;
|
- `Pinned` folder is hidden when no pinned room resolves to a live room;
|
||||||
otherwise expanded by default, showing pinned rooms in pin order.
|
otherwise expanded by default, showing pinned rooms in pin order.
|
||||||
- A pinned room remains listed under `Messages`.
|
- A pinned room remains listed under `Messages`.
|
||||||
@@ -335,8 +334,15 @@ unused until step 5 consumes them. Run the checks in §15 after each step.
|
|||||||
`uniform_list("sidebar-tree")`. `has_search`, `find_focused`, `set_input_focus`
|
`uniform_list("sidebar-tree")`. `has_search`, `find_focused`, `set_input_focus`
|
||||||
were dropped because they only existed to switch the sidebar between the room
|
were dropped because they only existed to switch the sidebar between the room
|
||||||
list and the search view.
|
list and the search view.
|
||||||
- [ ] **Step 6 — pin UI.** Build the per-row ellipsis dropdown, wire
|
- [x] **Step 6 — pin UI.** Per-row ellipsis (`IconName::Ellipsis`, `ghost_alt`,
|
||||||
`pin_room`/`unpin_room`.
|
`xsmall`, `compact`) passed to `RoomEntry::trailing`, revealed on row hover
|
||||||
|
through the `ROOM_ENTRY_GROUP` group name, opening a `DropdownMenu` with
|
||||||
|
Pin/Unpin; the handlers call `pin_room`/`unpin_room` through a
|
||||||
|
`WeakEntity<Sidebar>`. Click propagation: `gpui_base::Popover` registers the
|
||||||
|
trigger's `on_mouse_down` with `cx.stop_propagation()`, and GPUI only fires an
|
||||||
|
element's `on_click` when that element recorded the matching mouse-down, so the
|
||||||
|
row's `emit_room` click does not fire when the menu trigger is clicked. No extra
|
||||||
|
handling was needed.
|
||||||
- [ ] **Step 7 — community section.** Render dummy entries and hint; add the
|
- [ ] **Step 7 — community section.** Render dummy entries and hint; add the
|
||||||
`TODO(concord)` marker. The flattening and rendering landed with step 5
|
`TODO(concord)` marker. The flattening and rendering landed with step 5
|
||||||
(`SidebarRow::Community` -> `TreeRow`, dummy data from `dummy_communities()`),
|
(`SidebarRow::Community` -> `TreeRow`, dummy data from `dummy_communities()`),
|
||||||
|
|||||||
Reference in New Issue
Block a user