wip
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
use gpui::{
|
||||
AnyElement, App, IntoElement, ParentElement, SharedString, Styled, WeakEntity, Window, div, px,
|
||||
AnyElement, App, IntoElement, ParentElement, SharedString, Styled, WeakEntity, Window, div,
|
||||
rems,
|
||||
};
|
||||
use gpui_kit::base::StyledExt as _;
|
||||
use gpui_kit::component::description_list::{DescriptionItem, DescriptionList};
|
||||
@@ -10,9 +11,9 @@ use ui::Avatar;
|
||||
|
||||
pub(crate) fn open(group: WeakEntity<Group>, window: &mut Window, cx: &mut App) {
|
||||
window.open_dialog(cx, move |this, _window, cx| {
|
||||
this.max_h(px(600.))
|
||||
this.max_h(rems(37.5))
|
||||
.close_button(true)
|
||||
.title("About Group")
|
||||
.title("About group")
|
||||
.child(body(&group, cx))
|
||||
});
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ use common::TimestampExt;
|
||||
use gpui::prelude::FluentBuilder;
|
||||
use gpui::{
|
||||
App, AppContext, ClipboardItem, Entity, IntoElement, ParentElement, SharedString, Styled,
|
||||
WeakEntity, Window, div, px,
|
||||
WeakEntity, Window, div, px, rems,
|
||||
};
|
||||
use gpui_kit::component::button::{Button, ButtonVariant, ButtonVariants};
|
||||
use gpui_kit::component::dialog::DialogButtonProps;
|
||||
@@ -25,7 +25,7 @@ pub(crate) fn open(group: WeakEntity<Group>, window: &mut Window, cx: &mut App)
|
||||
});
|
||||
|
||||
window.open_dialog(cx, move |this, _window, cx| {
|
||||
this.max_h(px(600.))
|
||||
this.max_h(rems(37.5))
|
||||
.close_button(true)
|
||||
.title("Invites")
|
||||
.child(body(group.clone(), input.clone(), cx))
|
||||
|
||||
+18
-20
@@ -8,7 +8,7 @@ use gpui::{
|
||||
Action, Anchor, AnyElement, App, AppContext, ClipboardItem, Context, Entity, EventEmitter,
|
||||
FocusHandle, Focusable, FollowMode, InteractiveElement, IntoElement, ListAlignment,
|
||||
ListScrollEvent, ListState, ParentElement, Render, SharedString, Styled, Subscription, Task,
|
||||
WeakEntity, Window, div, list, px,
|
||||
WeakEntity, Window, div, list, px, rems,
|
||||
};
|
||||
use gpui_kit::assets::IconName;
|
||||
use gpui_kit::base::StyledExt as _;
|
||||
@@ -167,7 +167,7 @@ pub fn actions(group: WeakEntity<Group>, cx: &App) -> AnyElement {
|
||||
)
|
||||
.child(
|
||||
Button::new("group-delete")
|
||||
.icon(IconName::CircleX)
|
||||
.icon(IconName::Trash)
|
||||
.tooltip("Delete group")
|
||||
.ghost()
|
||||
.small()
|
||||
@@ -965,16 +965,11 @@ impl GroupPanel {
|
||||
.py_1p5()
|
||||
.border_b_1()
|
||||
.border_color(cx.theme().border)
|
||||
.children(pins.iter().map(|pin| {
|
||||
div()
|
||||
.px_1p5()
|
||||
.py_0p5()
|
||||
.rounded(cx.theme().radius)
|
||||
.bg(cx.theme().primary)
|
||||
.text_xs()
|
||||
.text_color(cx.theme().muted_foreground)
|
||||
.child(pin_label(group, pin))
|
||||
}))
|
||||
.children(
|
||||
pins.iter().map(|pin| {
|
||||
gpui_kit::component::tag::Tag::secondary().child(pin_label(group, pin))
|
||||
}),
|
||||
)
|
||||
.into_any_element()
|
||||
}
|
||||
|
||||
@@ -1025,7 +1020,7 @@ impl GroupPanel {
|
||||
.child(
|
||||
Button::new("load-older")
|
||||
.label(if loading {
|
||||
"Loading earlier messages…"
|
||||
"Loading earlier messages"
|
||||
} else {
|
||||
"Load earlier messages"
|
||||
})
|
||||
@@ -1083,7 +1078,7 @@ impl GroupPanel {
|
||||
row.child("You're in preview mode. Join this group to talk.")
|
||||
.child(
|
||||
Button::new("join")
|
||||
.label("Request to Join")
|
||||
.label("Request to join")
|
||||
.small()
|
||||
.ghost()
|
||||
.on_click(cx.listener(move |this, _event, _window, cx| {
|
||||
@@ -1152,7 +1147,11 @@ impl GroupPanel {
|
||||
cx,
|
||||
)
|
||||
})
|
||||
.element(ix.into(), window, cx),
|
||||
.element(
|
||||
SharedString::from(format!("text-{}", message.id.to_hex())).into(),
|
||||
window,
|
||||
cx,
|
||||
),
|
||||
};
|
||||
|
||||
let admin = nostr
|
||||
@@ -1378,7 +1377,7 @@ impl GroupPanel {
|
||||
.child(
|
||||
div()
|
||||
.flex_shrink_0()
|
||||
.max_w(px(140.))
|
||||
.max_w(rems(8.75))
|
||||
.truncate()
|
||||
.font_semibold()
|
||||
.text_color(cx.theme().foreground)
|
||||
@@ -1408,8 +1407,7 @@ impl GroupPanel {
|
||||
fn render_attachments(&self, cx: &mut Context<Self>) -> Vec<AnyElement> {
|
||||
self.attachments
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(ix, url)| {
|
||||
.map(|url| {
|
||||
let url = url.clone();
|
||||
|
||||
h_flex()
|
||||
@@ -1425,12 +1423,12 @@ impl GroupPanel {
|
||||
.child(Icon::new(IconName::Link).xsmall())
|
||||
.child(
|
||||
div()
|
||||
.max_w(px(200.))
|
||||
.max_w(rems(12.5))
|
||||
.truncate()
|
||||
.child(attachment_name(&url)),
|
||||
)
|
||||
.child(
|
||||
Button::new(SharedString::from(format!("remove-attachment-{ix}")))
|
||||
Button::new(SharedString::from(format!("remove-attachment-{}", url)))
|
||||
.icon(IconName::Close)
|
||||
.tooltip("Remove")
|
||||
.ghost()
|
||||
|
||||
@@ -33,7 +33,7 @@ pub(crate) struct Actions {
|
||||
}
|
||||
|
||||
pub(crate) fn render(
|
||||
ix: usize,
|
||||
_ix: usize,
|
||||
message: &Message,
|
||||
content: AnyElement,
|
||||
show_author: bool,
|
||||
@@ -58,33 +58,36 @@ pub(crate) fn render(
|
||||
nostr.read(cx).current_user(),
|
||||
);
|
||||
|
||||
let row = MessageRow::new(ix)
|
||||
.show_author(show_author)
|
||||
.hide_avatar(hide_avatar)
|
||||
.avatar(
|
||||
Avatar::new(author.avatar())
|
||||
.seed(author.avatar_seed())
|
||||
.small()
|
||||
.flex_shrink_0(),
|
||||
)
|
||||
.author(author.name())
|
||||
.timestamp(message.created_at.to_human_time())
|
||||
.when(!message.replies_to.is_empty(), |this| {
|
||||
this.children(replies(
|
||||
&message.replies_to,
|
||||
&persons,
|
||||
&actions.group,
|
||||
&actions.panel,
|
||||
cx,
|
||||
))
|
||||
})
|
||||
.child(content)
|
||||
.when(!message.media.is_empty(), |this| {
|
||||
this.child(MessageMedia::new(&message.media))
|
||||
})
|
||||
.when(!reaction_groups.is_empty(), |this| {
|
||||
this.child(ReactionBar::new(reaction_groups))
|
||||
});
|
||||
let row = MessageRow::new(SharedString::from(format!(
|
||||
"message-{}",
|
||||
message.id.to_hex()
|
||||
)))
|
||||
.show_author(show_author)
|
||||
.hide_avatar(hide_avatar)
|
||||
.avatar(
|
||||
Avatar::new(author.avatar())
|
||||
.seed(author.avatar_seed())
|
||||
.small()
|
||||
.flex_shrink_0(),
|
||||
)
|
||||
.author(author.name())
|
||||
.timestamp(message.created_at.to_human_time())
|
||||
.when(!message.replies_to.is_empty(), |this| {
|
||||
this.children(replies(
|
||||
&message.replies_to,
|
||||
&persons,
|
||||
&actions.group,
|
||||
&actions.panel,
|
||||
cx,
|
||||
))
|
||||
})
|
||||
.child(content)
|
||||
.when(!message.media.is_empty(), |this| {
|
||||
this.child(MessageMedia::new(&message.media))
|
||||
})
|
||||
.when(!reaction_groups.is_empty(), |this| {
|
||||
this.child(ReactionBar::new(reaction_groups))
|
||||
});
|
||||
|
||||
let id = message.id;
|
||||
let admin = actions.admin;
|
||||
@@ -249,7 +252,7 @@ pub(crate) fn render(
|
||||
}
|
||||
|
||||
pub(crate) fn render_activity(
|
||||
ix: usize,
|
||||
_ix: usize,
|
||||
activity: &Activity,
|
||||
persons: &Entity<Directory>,
|
||||
cx: &App,
|
||||
@@ -258,12 +261,14 @@ pub(crate) fn render_activity(
|
||||
let hide_avatar = AppSettings::get_hide_avatar(cx);
|
||||
|
||||
h_flex()
|
||||
.id(ix)
|
||||
.id(SharedString::from(format!(
|
||||
"activity-{}",
|
||||
activity.id.to_hex()
|
||||
)))
|
||||
.w_full()
|
||||
.gap_2()
|
||||
.py_1()
|
||||
.px_3()
|
||||
.hover(|this| this.bg(cx.theme().list_hover))
|
||||
.child(badge(activity, cx))
|
||||
.when(!hide_avatar, |this| {
|
||||
this.child(
|
||||
@@ -340,7 +345,7 @@ fn replies(
|
||||
|
||||
let mut items = Vec::with_capacity(targets.len());
|
||||
|
||||
for (ix, id) in targets.iter().enumerate() {
|
||||
for id in targets.iter() {
|
||||
let context = entity.read_with(cx, |group, cx| {
|
||||
let message = group.message(*id)?;
|
||||
let author = persons.read(cx).person(&message.author, cx);
|
||||
@@ -359,15 +364,19 @@ fn replies(
|
||||
let panel = panel.clone();
|
||||
|
||||
items.push(
|
||||
ReplyPreview::new(ix, author, preview)
|
||||
.on_click(move |_event, _window, cx| {
|
||||
if let Err(error) = panel.update(cx, |panel, cx| {
|
||||
panel.scroll_to(&id, cx);
|
||||
}) {
|
||||
log::warn!("nip29: scrolling to message failed: {error}");
|
||||
}
|
||||
})
|
||||
.into_any_element(),
|
||||
ReplyPreview::new(
|
||||
SharedString::from(format!("reply-{}", id.to_hex())),
|
||||
author,
|
||||
preview,
|
||||
)
|
||||
.on_click(move |_event, _window, cx| {
|
||||
if let Err(error) = panel.update(cx, |panel, cx| {
|
||||
panel.scroll_to(&id, cx);
|
||||
}) {
|
||||
log::warn!("nip29: scrolling to message failed: {error}");
|
||||
}
|
||||
})
|
||||
.into_any_element(),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ use gpui_kit::component::dialog::DialogButtonProps;
|
||||
use gpui_kit::component::input::InputState;
|
||||
use gpui_kit::component::notification::Notification;
|
||||
use gpui_kit::component::switch::Switch;
|
||||
use gpui_kit::component::{ActiveTheme, Sizable, WindowExt, h_flex, v_flex};
|
||||
use gpui_kit::component::{ActiveTheme, Disableable, Sizable, WindowExt, h_flex, v_flex};
|
||||
use nip29::{Group, GroupId, GroupMetadata};
|
||||
use nostr_sdk::prelude::RelayUrl;
|
||||
use ui::settings_row;
|
||||
@@ -100,7 +100,7 @@ pub(crate) fn open(group: WeakEntity<Group>, window: &mut Window, cx: &mut App)
|
||||
let supported = *livekit.read(cx) != Some(false);
|
||||
|
||||
this.close_button(true)
|
||||
.title("Edit Group")
|
||||
.title("Edit group")
|
||||
.button_props(
|
||||
DialogButtonProps::default()
|
||||
.cancel_text("Cancel")
|
||||
@@ -161,24 +161,27 @@ pub(crate) fn open(group: WeakEntity<Group>, window: &mut Window, cx: &mut App)
|
||||
.child(settings_row(
|
||||
"LiveKit",
|
||||
if supported {
|
||||
"Announce audio and video support."
|
||||
"Announce audio and video support"
|
||||
} else {
|
||||
"The relay doesn't announce LiveKit support."
|
||||
},
|
||||
Switch::new("livekit").checked(current.livekit).on_click({
|
||||
let flags = flags.clone();
|
||||
let livekit = livekit.clone();
|
||||
Switch::new("livekit")
|
||||
.checked(current.livekit)
|
||||
.disabled(!supported)
|
||||
.on_click({
|
||||
let flags = flags.clone();
|
||||
let livekit = livekit.clone();
|
||||
|
||||
move |next, _window, cx| {
|
||||
if *next && *livekit.read(cx) == Some(false) {
|
||||
return;
|
||||
move |next, _window, cx| {
|
||||
if *next && *livekit.read(cx) == Some(false) {
|
||||
return;
|
||||
}
|
||||
flags.update(cx, |flags, cx| {
|
||||
flags.livekit = *next;
|
||||
cx.notify();
|
||||
});
|
||||
}
|
||||
flags.update(cx, |flags, cx| {
|
||||
flags.livekit = *next;
|
||||
cx.notify();
|
||||
});
|
||||
}
|
||||
}),
|
||||
}),
|
||||
cx,
|
||||
)),
|
||||
),
|
||||
@@ -293,10 +296,10 @@ fn children_section(children: &Entity<Vec<GroupId>>, cx: &App) -> AnyElement {
|
||||
.flex_shrink_0()
|
||||
.gap_1()
|
||||
.when(ix > 0, |this| {
|
||||
this.child(move_button(children.clone(), ix, ix - 1, "up"))
|
||||
this.child(move_button(children.clone(), child, ix, ix - 1, "up"))
|
||||
})
|
||||
.when(ix + 1 < list.len(), |this| {
|
||||
this.child(move_button(children.clone(), ix, ix + 1, "down"))
|
||||
this.child(move_button(children.clone(), child, ix, ix + 1, "down"))
|
||||
});
|
||||
|
||||
section = section.child(
|
||||
@@ -319,11 +322,12 @@ fn children_section(children: &Entity<Vec<GroupId>>, cx: &App) -> AnyElement {
|
||||
|
||||
fn move_button(
|
||||
children: Entity<Vec<GroupId>>,
|
||||
child: &GroupId,
|
||||
ix: usize,
|
||||
target: usize,
|
||||
direction: &'static str,
|
||||
) -> Button {
|
||||
Button::new(SharedString::from(format!("child-{direction}-{ix}")))
|
||||
Button::new(SharedString::from(format!("child-{direction}-{child}")))
|
||||
.label(if direction == "up" { "Up" } else { "Down" })
|
||||
.ghost()
|
||||
.small()
|
||||
|
||||
Reference in New Issue
Block a user