feat: add support for NIP-29 #56
+31
-27
@@ -33,10 +33,18 @@ mod invite;
|
|||||||
mod message;
|
mod message;
|
||||||
mod metadata;
|
mod metadata;
|
||||||
|
|
||||||
/// Ask the shell to show or hide the sidebar's information for a group.
|
/// Ask the shell to show the sidebar's information for a group.
|
||||||
#[derive(Action, Clone, PartialEq, Eq, Deserialize)]
|
#[derive(Action, Clone, PartialEq, Eq, Deserialize)]
|
||||||
#[action(namespace = nip29_ui, no_json)]
|
#[action(namespace = nip29_ui, no_json)]
|
||||||
pub struct ToggleGroupMeta {
|
pub struct ShowGroupMeta {
|
||||||
|
pub relay: RelayUrl,
|
||||||
|
pub group: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Ask the shell to hide the sidebar's information for a group.
|
||||||
|
#[derive(Action, Clone, PartialEq, Eq, Deserialize)]
|
||||||
|
#[action(namespace = nip29_ui, no_json)]
|
||||||
|
pub struct HideGroupMeta {
|
||||||
pub relay: RelayUrl,
|
pub relay: RelayUrl,
|
||||||
pub group: String,
|
pub group: String,
|
||||||
}
|
}
|
||||||
@@ -870,15 +878,6 @@ impl GroupPanel {
|
|||||||
supports_text && writable
|
supports_text && writable
|
||||||
});
|
});
|
||||||
|
|
||||||
let meta = self.group.upgrade().map(|group| {
|
|
||||||
let group = group.read(cx);
|
|
||||||
|
|
||||||
(
|
|
||||||
group.key().relay().clone(),
|
|
||||||
group.key().id().as_str().to_owned(),
|
|
||||||
)
|
|
||||||
});
|
|
||||||
|
|
||||||
v_flex()
|
v_flex()
|
||||||
.flex_shrink_0()
|
.flex_shrink_0()
|
||||||
.w_full()
|
.w_full()
|
||||||
@@ -889,22 +888,6 @@ impl GroupPanel {
|
|||||||
h_flex()
|
h_flex()
|
||||||
.gap_1()
|
.gap_1()
|
||||||
.items_end()
|
.items_end()
|
||||||
.child(
|
|
||||||
Button::new("info")
|
|
||||||
.icon(IconName::Group)
|
|
||||||
.tooltip("Toggle group information in the sidebar")
|
|
||||||
.ghost()
|
|
||||||
.large()
|
|
||||||
.on_click(move |_event, window, cx| {
|
|
||||||
let Some((relay, group)) = meta.clone() else {
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
window.dispatch_action(
|
|
||||||
Box::new(ToggleGroupMeta { relay, group }),
|
|
||||||
cx,
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
.child(
|
.child(
|
||||||
Button::new("upload")
|
Button::new("upload")
|
||||||
.icon(IconName::Upload)
|
.icon(IconName::Upload)
|
||||||
@@ -1000,6 +983,27 @@ impl Panel for GroupPanel {
|
|||||||
fn toolbar_buttons(&self, _window: &Window, _cx: &App) -> Vec<Button> {
|
fn toolbar_buttons(&self, _window: &Window, _cx: &App) -> Vec<Button> {
|
||||||
Vec::new()
|
Vec::new()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_active(&self, active: bool, window: &mut Window, cx: &mut App) {
|
||||||
|
let Some(group) = self.group.upgrade() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
let (relay, id) = {
|
||||||
|
let group = group.read(cx);
|
||||||
|
|
||||||
|
(
|
||||||
|
group.key().relay().clone(),
|
||||||
|
group.key().id().as_str().to_owned(),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
if active {
|
||||||
|
window.dispatch_action(Box::new(ShowGroupMeta { relay, group: id }), cx);
|
||||||
|
} else {
|
||||||
|
window.dispatch_action(Box::new(HideGroupMeta { relay, group: id }), cx);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EventEmitter<PanelEvent> for GroupPanel {}
|
impl EventEmitter<PanelEvent> for GroupPanel {}
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ pub trait Panel: EventEmitter<PanelEvent> + Render + Focusable {
|
|||||||
/// This method will be called when the panel is active or inactive.
|
/// This method will be called when the panel is active or inactive.
|
||||||
///
|
///
|
||||||
/// The last_active_panel and current_active_panel will be touched when the panel is active.
|
/// The last_active_panel and current_active_panel will be touched when the panel is active.
|
||||||
fn set_active(&self, _active: bool, _cx: &mut App) {}
|
fn set_active(&self, _active: bool, _window: &mut Window, _cx: &mut App) {}
|
||||||
|
|
||||||
/// Set zoomed state of the panel.
|
/// Set zoomed state of the panel.
|
||||||
///
|
///
|
||||||
@@ -74,7 +74,7 @@ pub trait PanelView: 'static + Send + Sync {
|
|||||||
fn closable(&self, cx: &App) -> bool;
|
fn closable(&self, cx: &App) -> bool;
|
||||||
fn zoomable(&self, cx: &App) -> bool;
|
fn zoomable(&self, cx: &App) -> bool;
|
||||||
fn visible(&self, cx: &App) -> bool;
|
fn visible(&self, cx: &App) -> bool;
|
||||||
fn set_active(&self, active: bool, cx: &mut App);
|
fn set_active(&self, active: bool, window: &mut Window, cx: &mut App);
|
||||||
fn set_zoomed(&self, zoomed: bool, cx: &mut App);
|
fn set_zoomed(&self, zoomed: bool, cx: &mut App);
|
||||||
fn popup_menu(&self, menu: PopupMenu, cx: &App) -> PopupMenu;
|
fn popup_menu(&self, menu: PopupMenu, cx: &App) -> PopupMenu;
|
||||||
fn toolbar_buttons(&self, window: &Window, cx: &App) -> Vec<Button>;
|
fn toolbar_buttons(&self, window: &Window, cx: &App) -> Vec<Button>;
|
||||||
@@ -103,9 +103,9 @@ impl<T: Panel> PanelView for Entity<T> {
|
|||||||
self.read(cx).visible(cx)
|
self.read(cx).visible(cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_active(&self, active: bool, cx: &mut App) {
|
fn set_active(&self, active: bool, window: &mut Window, cx: &mut App) {
|
||||||
self.update(cx, |this, cx| {
|
self.update(cx, |this, cx| {
|
||||||
this.set_active(active, cx);
|
this.set_active(active, window, cx);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,8 +196,8 @@ impl gpui_base::dock::PanelView for PanelHandle {
|
|||||||
self.panel.visible(cx)
|
self.panel.visible(cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_active(&self, active: bool, _: &mut Window, cx: &mut App) {
|
fn set_active(&self, active: bool, window: &mut Window, cx: &mut App) {
|
||||||
self.panel.set_active(active, cx);
|
self.panel.set_active(active, window, cx);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_zoomed(&self, zoomed: bool, _: &mut Window, cx: &mut App) {
|
fn set_zoomed(&self, zoomed: bool, _: &mut Window, cx: &mut App) {
|
||||||
|
|||||||
@@ -204,15 +204,27 @@ impl Workspace {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Listen app-wide, so a group panel can toggle the sidebar without holding it.
|
// Listen app-wide, so a group panel can show or hide the sidebar without holding it.
|
||||||
let workspace = cx.entity().downgrade();
|
let workspace = cx.entity().downgrade();
|
||||||
|
|
||||||
App::on_action(cx, move |action: &nip29_ui::ToggleGroupMeta, cx| {
|
App::on_action(cx, {
|
||||||
|
let workspace = workspace.clone();
|
||||||
|
|
||||||
|
move |action: &nip29_ui::ShowGroupMeta, cx| {
|
||||||
|
let Some(workspace) = workspace.upgrade() else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
workspace.update(cx, |this, cx| this.show_group_meta(action, cx));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
App::on_action(cx, move |action: &nip29_ui::HideGroupMeta, cx| {
|
||||||
let Some(workspace) = workspace.upgrade() else {
|
let Some(workspace) = workspace.upgrade() else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
workspace.update(cx, |this, cx| this.toggle_group_meta(action, cx));
|
workspace.update(cx, |this, cx| this.hide_group_meta(action, cx));
|
||||||
});
|
});
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
@@ -397,8 +409,8 @@ impl Workspace {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Show or hide the sidebar's information for the group a panel belongs to.
|
/// Show the sidebar's information for the group a panel belongs to.
|
||||||
fn toggle_group_meta(&mut self, action: &nip29_ui::ToggleGroupMeta, cx: &mut Context<Self>) {
|
fn show_group_meta(&mut self, action: &nip29_ui::ShowGroupMeta, cx: &mut Context<Self>) {
|
||||||
let Ok(id) = GroupId::new(action.group.clone()) else {
|
let Ok(id) = GroupId::new(action.group.clone()) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
@@ -406,7 +418,20 @@ impl Workspace {
|
|||||||
let key = GroupKey::new(action.relay.clone(), id);
|
let key = GroupKey::new(action.relay.clone(), id);
|
||||||
|
|
||||||
self.sidebar.update(cx, |sidebar, cx| {
|
self.sidebar.update(cx, |sidebar, cx| {
|
||||||
sidebar.toggle_group(&key, cx);
|
sidebar.show_group_meta(&key, cx);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Hide the sidebar's information for the group a panel belongs to.
|
||||||
|
fn hide_group_meta(&mut self, action: &nip29_ui::HideGroupMeta, cx: &mut Context<Self>) {
|
||||||
|
let Ok(id) = GroupId::new(action.group.clone()) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
let key = GroupKey::new(action.relay.clone(), id);
|
||||||
|
|
||||||
|
self.sidebar.update(cx, |sidebar, cx| {
|
||||||
|
sidebar.hide_group_meta(&key, cx);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -190,28 +190,28 @@ impl Sidebar {
|
|||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Show or hide the group view depending on which group is being viewed.
|
/// Show the group view without toggling it closed.
|
||||||
pub(crate) fn toggle_group(&mut self, key: &GroupKey, cx: &mut Context<Self>) {
|
pub(crate) fn show_group_meta(&mut self, key: &GroupKey, cx: &mut Context<Self>) {
|
||||||
let groups = GroupsRegistry::global(cx);
|
let groups = GroupsRegistry::global(cx);
|
||||||
|
|
||||||
let Some(entity) = groups.read(cx).group(key, cx) else {
|
let Some(group) = groups.read(cx).group(key, cx) else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let open = self
|
self.show_group(&group, cx);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Hide the group view if the sidebar is showing the given group.
|
||||||
|
pub(crate) fn hide_group_meta(&mut self, key: &GroupKey, cx: &mut Context<Self>) {
|
||||||
|
let showing = self
|
||||||
.group
|
.group
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.and_then(|group| group.upgrade())
|
.and_then(|group| group.upgrade())
|
||||||
.is_some_and(|current| current.entity_id() == entity.entity_id());
|
.is_some_and(|group| group.read(cx).key() == key);
|
||||||
|
|
||||||
if open {
|
if showing {
|
||||||
self.group_open = !self.group_open;
|
self.hide_group(cx);
|
||||||
} else {
|
|
||||||
self.group = Some(entity.downgrade());
|
|
||||||
self.group_open = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cx.notify();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Leave the group view, returning the sidebar to its tab list.
|
/// Leave the group view, returning the sidebar to its tab list.
|
||||||
|
|||||||
Reference in New Issue
Block a user