wip
This commit is contained in:
@@ -155,7 +155,7 @@ impl AutoUpdater {
|
|||||||
pub fn status(&self) -> SharedString {
|
pub fn status(&self) -> SharedString {
|
||||||
match &self.status {
|
match &self.status {
|
||||||
UpdateStatus::Idle | UpdateStatus::UpToDate => "Up to date".into(),
|
UpdateStatus::Idle | UpdateStatus::UpToDate => "Up to date".into(),
|
||||||
UpdateStatus::Checking => "Checking for updates…".into(),
|
UpdateStatus::Checking => "Checking for updates".into(),
|
||||||
UpdateStatus::Available(version) => format!("Version {version} available").into(),
|
UpdateStatus::Available(version) => format!("Version {version} available").into(),
|
||||||
UpdateStatus::Downloading { downloaded, total } => {
|
UpdateStatus::Downloading { downloaded, total } => {
|
||||||
let total_mb = total.map(|t| t as f64 / 1_048_576.0);
|
let total_mb = total.map(|t| t as f64 / 1_048_576.0);
|
||||||
@@ -165,7 +165,7 @@ impl AutoUpdater {
|
|||||||
None => format!("Downloading {downloaded_mb:.1} MB").into(),
|
None => format!("Downloading {downloaded_mb:.1} MB").into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
UpdateStatus::Installing => "Installing update…".into(),
|
UpdateStatus::Installing => "Installing update".into(),
|
||||||
UpdateStatus::Staged(version) => {
|
UpdateStatus::Staged(version) => {
|
||||||
format!("Version {version} ready — restart to apply").into()
|
format!("Version {version} ready — restart to apply").into()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -172,7 +172,7 @@
|
|||||||
|
|
||||||
<div id="nip07-status" class="status status--checking">
|
<div id="nip07-status" class="status status--checking">
|
||||||
<div class="status__dot"></div>
|
<div class="status__dot"></div>
|
||||||
<span id="nip07-status-text">Checking extension…</span>
|
<span id="nip07-status-text">Checking extension</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="hint">
|
<div class="hint">
|
||||||
|
|||||||
+29
-26
@@ -12,7 +12,7 @@ use gpui::{
|
|||||||
Focusable, InteractiveElement, IntoElement, ListAlignment, ListOffset, ListState, MouseButton,
|
Focusable, InteractiveElement, IntoElement, ListAlignment, ListOffset, ListState, MouseButton,
|
||||||
ObjectFit, ParentElement, Render, SharedString, SharedUri, StatefulInteractiveElement, Styled,
|
ObjectFit, ParentElement, Render, SharedString, SharedUri, StatefulInteractiveElement, Styled,
|
||||||
StyledImage, Subscription, SystemNotification, SystemNotificationAction, Task, WeakEntity,
|
StyledImage, Subscription, SystemNotification, SystemNotificationAction, Task, WeakEntity,
|
||||||
Window, div, img, list, px, relative, retain_all, svg,
|
Window, div, img, list, px, relative, rems, retain_all, svg,
|
||||||
};
|
};
|
||||||
use gpui_kit::assets::IconName;
|
use gpui_kit::assets::IconName;
|
||||||
use gpui_kit::base::StyledExt as _;
|
use gpui_kit::base::StyledExt as _;
|
||||||
@@ -1077,7 +1077,7 @@ impl ChatPanel {
|
|||||||
window.open_dialog(cx, move |this, _window, cx| {
|
window.open_dialog(cx, move |this, _window, cx| {
|
||||||
let relays = profile.messaging_relays();
|
let relays = profile.messaging_relays();
|
||||||
|
|
||||||
this.title("Messaging Relays")
|
this.title("Messaging relays")
|
||||||
.close_button(true)
|
.close_button(true)
|
||||||
.child(v_flex().gap_1().children({
|
.child(v_flex().gap_1().children({
|
||||||
let mut items = vec![];
|
let mut items = vec![];
|
||||||
@@ -1134,7 +1134,7 @@ impl ChatPanel {
|
|||||||
svg()
|
svg()
|
||||||
.path("brand/coop.svg")
|
.path("brand/coop.svg")
|
||||||
.size_12()
|
.size_12()
|
||||||
.text_color(cx.theme().list_active),
|
.text_color(cx.theme().accent),
|
||||||
)
|
)
|
||||||
.child(PRIVATE_NOTICE)
|
.child(PRIVATE_NOTICE)
|
||||||
.into_any_element()
|
.into_any_element()
|
||||||
@@ -1228,7 +1228,11 @@ impl ChatPanel {
|
|||||||
cx,
|
cx,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.element(ix.into(), window, cx);
|
.element(
|
||||||
|
SharedString::from(format!("text-{}", message.id.to_hex())).into(),
|
||||||
|
window,
|
||||||
|
cx,
|
||||||
|
);
|
||||||
|
|
||||||
self.render_text_message(ix, message, text, show_author, cx)
|
self.render_text_message(ix, message, text, show_author, cx)
|
||||||
} else {
|
} else {
|
||||||
@@ -1238,7 +1242,7 @@ impl ChatPanel {
|
|||||||
|
|
||||||
fn render_text_message(
|
fn render_text_message(
|
||||||
&self,
|
&self,
|
||||||
ix: usize,
|
_ix: usize,
|
||||||
message: &Message,
|
message: &Message,
|
||||||
rendered_text: AnyElement,
|
rendered_text: AnyElement,
|
||||||
show_author: bool,
|
show_author: bool,
|
||||||
@@ -1270,7 +1274,7 @@ impl ChatPanel {
|
|||||||
None => rendered_text,
|
None => rendered_text,
|
||||||
};
|
};
|
||||||
|
|
||||||
let row = MessageRow::new(ix)
|
let row = MessageRow::new(SharedString::from(format!("message-{}", id.to_hex())))
|
||||||
.show_author(show_author)
|
.show_author(show_author)
|
||||||
.hide_avatar(hide_avatar)
|
.hide_avatar(hide_avatar)
|
||||||
.avatar(
|
.avatar(
|
||||||
@@ -1300,16 +1304,6 @@ impl ChatPanel {
|
|||||||
this.child(self.render_message_file(&id, file, cx))
|
this.child(self.render_message_file(&id, file, cx))
|
||||||
})
|
})
|
||||||
.when(has_reactions, |this| this.child(reactions))
|
.when(has_reactions, |this| this.child(reactions))
|
||||||
.overlay(
|
|
||||||
div()
|
|
||||||
.group_hover("", |this| this.bg(cx.theme().list_active))
|
|
||||||
.absolute()
|
|
||||||
.left_0()
|
|
||||||
.top_0()
|
|
||||||
.w(px(2.))
|
|
||||||
.h_full()
|
|
||||||
.bg(gpui::transparent_black()),
|
|
||||||
)
|
|
||||||
.overlay(self.render_actions(&id, &pk, cx))
|
.overlay(self.render_actions(&id, &pk, cx))
|
||||||
.on_mouse_down(
|
.on_mouse_down(
|
||||||
MouseButton::Middle,
|
MouseButton::Middle,
|
||||||
@@ -1399,14 +1393,19 @@ impl ChatPanel {
|
|||||||
) -> impl IntoIterator<Item = impl IntoElement> {
|
) -> impl IntoIterator<Item = impl IntoElement> {
|
||||||
let mut items = Vec::with_capacity(replies.len());
|
let mut items = Vec::with_capacity(replies.len());
|
||||||
|
|
||||||
for (ix, id) in replies.iter().enumerate() {
|
for id in replies.iter() {
|
||||||
let Some(message) = self.message(id) else {
|
let Some(message) = self.message(id) else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
let author = self.profile(&message.author, cx);
|
let author = self.profile(&message.author, cx);
|
||||||
|
|
||||||
items.push(
|
items.push(
|
||||||
ReplyPreview::new(ix, author.name(), message.preview()).on_click({
|
ReplyPreview::new(
|
||||||
|
SharedString::from(format!("reply-{}", id.to_hex())),
|
||||||
|
author.name(),
|
||||||
|
message.preview(),
|
||||||
|
)
|
||||||
|
.on_click({
|
||||||
let id = *id;
|
let id = *id;
|
||||||
cx.listener(move |this, _event, _window, _cx| {
|
cx.listener(move |this, _event, _window, _cx| {
|
||||||
this.scroll_to(&id);
|
this.scroll_to(&id);
|
||||||
@@ -1437,7 +1436,7 @@ impl ChatPanel {
|
|||||||
} else if failed {
|
} else if failed {
|
||||||
SharedString::from("• Error")
|
SharedString::from("• Error")
|
||||||
} else if pending {
|
} else if pending {
|
||||||
SharedString::from("• Sending...")
|
SharedString::from("• Sending")
|
||||||
} else {
|
} else {
|
||||||
SharedString::from("• Unknown")
|
SharedString::from("• Unknown")
|
||||||
};
|
};
|
||||||
@@ -1462,7 +1461,7 @@ impl ChatPanel {
|
|||||||
})
|
})
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
this.title(SharedString::from("Sent Reports"))
|
this.title(SharedString::from("Sent reports"))
|
||||||
.close_button(true)
|
.close_button(true)
|
||||||
.child(v_flex().gap_4().children(items))
|
.child(v_flex().gap_4().children(items))
|
||||||
});
|
});
|
||||||
@@ -1699,7 +1698,7 @@ impl ChatPanel {
|
|||||||
img(local.image_source())
|
img(local.image_source())
|
||||||
.border_1()
|
.border_1()
|
||||||
.border_color(cx.theme().border)
|
.border_color(cx.theme().border)
|
||||||
.h(px(250.))
|
.h(rems(16.))
|
||||||
.object_fit(ObjectFit::Cover)
|
.object_fit(ObjectFit::Cover)
|
||||||
.rounded(cx.theme().radius_lg),
|
.rounded(cx.theme().radius_lg),
|
||||||
)
|
)
|
||||||
@@ -1734,7 +1733,7 @@ impl ChatPanel {
|
|||||||
.border_1()
|
.border_1()
|
||||||
.border_color(cx.theme().border)
|
.border_color(cx.theme().border)
|
||||||
.rounded(cx.theme().radius)
|
.rounded(cx.theme().radius)
|
||||||
.child(Icon::new(IconName::Lock).text_color(cx.theme().primary))
|
.child(Icon::new(IconName::Lock).text_color(cx.theme().accent))
|
||||||
.child(
|
.child(
|
||||||
v_flex()
|
v_flex()
|
||||||
.min_w_0()
|
.min_w_0()
|
||||||
@@ -1835,11 +1834,15 @@ impl ChatPanel {
|
|||||||
items
|
items
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_reply(&self, ix: usize, id: &EventId, cx: &Context<Self>) -> impl IntoElement {
|
fn render_reply(&self, id: &EventId, cx: &Context<Self>) -> impl IntoElement {
|
||||||
if let Some(text) = self.message(id) {
|
if let Some(text) = self.message(id) {
|
||||||
let profile = self.directory.read(cx).person(&text.author, cx);
|
let profile = self.directory.read(cx).person(&text.author, cx);
|
||||||
|
|
||||||
ReplyPreview::new(ix, profile.name(), text.preview())
|
ReplyPreview::new(
|
||||||
|
SharedString::from(format!("reply-{}", id.to_hex())),
|
||||||
|
profile.name(),
|
||||||
|
text.preview(),
|
||||||
|
)
|
||||||
.on_remove({
|
.on_remove({
|
||||||
let id = text.id;
|
let id = text.id;
|
||||||
cx.listener(move |this, _, _, cx| {
|
cx.listener(move |this, _, _, cx| {
|
||||||
@@ -1859,8 +1862,8 @@ impl ChatPanel {
|
|||||||
) -> impl IntoIterator<Item = impl IntoElement> {
|
) -> impl IntoIterator<Item = impl IntoElement> {
|
||||||
let mut items = vec![];
|
let mut items = vec![];
|
||||||
|
|
||||||
for (ix, id) in self.replies_to.read(cx).iter().enumerate() {
|
for id in self.replies_to.read(cx).iter() {
|
||||||
items.push(self.render_reply(ix, id, cx));
|
items.push(self.render_reply(id, cx));
|
||||||
}
|
}
|
||||||
|
|
||||||
items
|
items
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
use gpui::{
|
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::base::StyledExt as _;
|
||||||
use gpui_kit::component::description_list::{DescriptionItem, DescriptionList};
|
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) {
|
pub(crate) fn open(group: WeakEntity<Group>, window: &mut Window, cx: &mut App) {
|
||||||
window.open_dialog(cx, move |this, _window, cx| {
|
window.open_dialog(cx, move |this, _window, cx| {
|
||||||
this.max_h(px(600.))
|
this.max_h(rems(37.5))
|
||||||
.close_button(true)
|
.close_button(true)
|
||||||
.title("About Group")
|
.title("About group")
|
||||||
.child(body(&group, cx))
|
.child(body(&group, cx))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use common::TimestampExt;
|
|||||||
use gpui::prelude::FluentBuilder;
|
use gpui::prelude::FluentBuilder;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
App, AppContext, ClipboardItem, Entity, IntoElement, ParentElement, SharedString, Styled,
|
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::button::{Button, ButtonVariant, ButtonVariants};
|
||||||
use gpui_kit::component::dialog::DialogButtonProps;
|
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| {
|
window.open_dialog(cx, move |this, _window, cx| {
|
||||||
this.max_h(px(600.))
|
this.max_h(rems(37.5))
|
||||||
.close_button(true)
|
.close_button(true)
|
||||||
.title("Invites")
|
.title("Invites")
|
||||||
.child(body(group.clone(), input.clone(), cx))
|
.child(body(group.clone(), input.clone(), cx))
|
||||||
|
|||||||
+18
-20
@@ -8,7 +8,7 @@ use gpui::{
|
|||||||
Action, Anchor, AnyElement, App, AppContext, ClipboardItem, Context, Entity, EventEmitter,
|
Action, Anchor, AnyElement, App, AppContext, ClipboardItem, Context, Entity, EventEmitter,
|
||||||
FocusHandle, Focusable, FollowMode, InteractiveElement, IntoElement, ListAlignment,
|
FocusHandle, Focusable, FollowMode, InteractiveElement, IntoElement, ListAlignment,
|
||||||
ListScrollEvent, ListState, ParentElement, Render, SharedString, Styled, Subscription, Task,
|
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::assets::IconName;
|
||||||
use gpui_kit::base::StyledExt as _;
|
use gpui_kit::base::StyledExt as _;
|
||||||
@@ -167,7 +167,7 @@ pub fn actions(group: WeakEntity<Group>, cx: &App) -> AnyElement {
|
|||||||
)
|
)
|
||||||
.child(
|
.child(
|
||||||
Button::new("group-delete")
|
Button::new("group-delete")
|
||||||
.icon(IconName::CircleX)
|
.icon(IconName::Trash)
|
||||||
.tooltip("Delete group")
|
.tooltip("Delete group")
|
||||||
.ghost()
|
.ghost()
|
||||||
.small()
|
.small()
|
||||||
@@ -965,16 +965,11 @@ impl GroupPanel {
|
|||||||
.py_1p5()
|
.py_1p5()
|
||||||
.border_b_1()
|
.border_b_1()
|
||||||
.border_color(cx.theme().border)
|
.border_color(cx.theme().border)
|
||||||
.children(pins.iter().map(|pin| {
|
.children(
|
||||||
div()
|
pins.iter().map(|pin| {
|
||||||
.px_1p5()
|
gpui_kit::component::tag::Tag::secondary().child(pin_label(group, pin))
|
||||||
.py_0p5()
|
}),
|
||||||
.rounded(cx.theme().radius)
|
)
|
||||||
.bg(cx.theme().primary)
|
|
||||||
.text_xs()
|
|
||||||
.text_color(cx.theme().muted_foreground)
|
|
||||||
.child(pin_label(group, pin))
|
|
||||||
}))
|
|
||||||
.into_any_element()
|
.into_any_element()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1025,7 +1020,7 @@ impl GroupPanel {
|
|||||||
.child(
|
.child(
|
||||||
Button::new("load-older")
|
Button::new("load-older")
|
||||||
.label(if loading {
|
.label(if loading {
|
||||||
"Loading earlier messages…"
|
"Loading earlier messages"
|
||||||
} else {
|
} else {
|
||||||
"Load earlier messages"
|
"Load earlier messages"
|
||||||
})
|
})
|
||||||
@@ -1083,7 +1078,7 @@ impl GroupPanel {
|
|||||||
row.child("You're in preview mode. Join this group to talk.")
|
row.child("You're in preview mode. Join this group to talk.")
|
||||||
.child(
|
.child(
|
||||||
Button::new("join")
|
Button::new("join")
|
||||||
.label("Request to Join")
|
.label("Request to join")
|
||||||
.small()
|
.small()
|
||||||
.ghost()
|
.ghost()
|
||||||
.on_click(cx.listener(move |this, _event, _window, cx| {
|
.on_click(cx.listener(move |this, _event, _window, cx| {
|
||||||
@@ -1152,7 +1147,11 @@ impl GroupPanel {
|
|||||||
cx,
|
cx,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.element(ix.into(), window, cx),
|
.element(
|
||||||
|
SharedString::from(format!("text-{}", message.id.to_hex())).into(),
|
||||||
|
window,
|
||||||
|
cx,
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
let admin = nostr
|
let admin = nostr
|
||||||
@@ -1378,7 +1377,7 @@ impl GroupPanel {
|
|||||||
.child(
|
.child(
|
||||||
div()
|
div()
|
||||||
.flex_shrink_0()
|
.flex_shrink_0()
|
||||||
.max_w(px(140.))
|
.max_w(rems(8.75))
|
||||||
.truncate()
|
.truncate()
|
||||||
.font_semibold()
|
.font_semibold()
|
||||||
.text_color(cx.theme().foreground)
|
.text_color(cx.theme().foreground)
|
||||||
@@ -1408,8 +1407,7 @@ impl GroupPanel {
|
|||||||
fn render_attachments(&self, cx: &mut Context<Self>) -> Vec<AnyElement> {
|
fn render_attachments(&self, cx: &mut Context<Self>) -> Vec<AnyElement> {
|
||||||
self.attachments
|
self.attachments
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.map(|url| {
|
||||||
.map(|(ix, url)| {
|
|
||||||
let url = url.clone();
|
let url = url.clone();
|
||||||
|
|
||||||
h_flex()
|
h_flex()
|
||||||
@@ -1425,12 +1423,12 @@ impl GroupPanel {
|
|||||||
.child(Icon::new(IconName::Link).xsmall())
|
.child(Icon::new(IconName::Link).xsmall())
|
||||||
.child(
|
.child(
|
||||||
div()
|
div()
|
||||||
.max_w(px(200.))
|
.max_w(rems(12.5))
|
||||||
.truncate()
|
.truncate()
|
||||||
.child(attachment_name(&url)),
|
.child(attachment_name(&url)),
|
||||||
)
|
)
|
||||||
.child(
|
.child(
|
||||||
Button::new(SharedString::from(format!("remove-attachment-{ix}")))
|
Button::new(SharedString::from(format!("remove-attachment-{}", url)))
|
||||||
.icon(IconName::Close)
|
.icon(IconName::Close)
|
||||||
.tooltip("Remove")
|
.tooltip("Remove")
|
||||||
.ghost()
|
.ghost()
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ pub(crate) struct Actions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn render(
|
pub(crate) fn render(
|
||||||
ix: usize,
|
_ix: usize,
|
||||||
message: &Message,
|
message: &Message,
|
||||||
content: AnyElement,
|
content: AnyElement,
|
||||||
show_author: bool,
|
show_author: bool,
|
||||||
@@ -58,7 +58,10 @@ pub(crate) fn render(
|
|||||||
nostr.read(cx).current_user(),
|
nostr.read(cx).current_user(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let row = MessageRow::new(ix)
|
let row = MessageRow::new(SharedString::from(format!(
|
||||||
|
"message-{}",
|
||||||
|
message.id.to_hex()
|
||||||
|
)))
|
||||||
.show_author(show_author)
|
.show_author(show_author)
|
||||||
.hide_avatar(hide_avatar)
|
.hide_avatar(hide_avatar)
|
||||||
.avatar(
|
.avatar(
|
||||||
@@ -249,7 +252,7 @@ pub(crate) fn render(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn render_activity(
|
pub(crate) fn render_activity(
|
||||||
ix: usize,
|
_ix: usize,
|
||||||
activity: &Activity,
|
activity: &Activity,
|
||||||
persons: &Entity<Directory>,
|
persons: &Entity<Directory>,
|
||||||
cx: &App,
|
cx: &App,
|
||||||
@@ -258,12 +261,14 @@ pub(crate) fn render_activity(
|
|||||||
let hide_avatar = AppSettings::get_hide_avatar(cx);
|
let hide_avatar = AppSettings::get_hide_avatar(cx);
|
||||||
|
|
||||||
h_flex()
|
h_flex()
|
||||||
.id(ix)
|
.id(SharedString::from(format!(
|
||||||
|
"activity-{}",
|
||||||
|
activity.id.to_hex()
|
||||||
|
)))
|
||||||
.w_full()
|
.w_full()
|
||||||
.gap_2()
|
.gap_2()
|
||||||
.py_1()
|
.py_1()
|
||||||
.px_3()
|
.px_3()
|
||||||
.hover(|this| this.bg(cx.theme().list_hover))
|
|
||||||
.child(badge(activity, cx))
|
.child(badge(activity, cx))
|
||||||
.when(!hide_avatar, |this| {
|
.when(!hide_avatar, |this| {
|
||||||
this.child(
|
this.child(
|
||||||
@@ -340,7 +345,7 @@ fn replies(
|
|||||||
|
|
||||||
let mut items = Vec::with_capacity(targets.len());
|
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 context = entity.read_with(cx, |group, cx| {
|
||||||
let message = group.message(*id)?;
|
let message = group.message(*id)?;
|
||||||
let author = persons.read(cx).person(&message.author, cx);
|
let author = persons.read(cx).person(&message.author, cx);
|
||||||
@@ -359,7 +364,11 @@ fn replies(
|
|||||||
let panel = panel.clone();
|
let panel = panel.clone();
|
||||||
|
|
||||||
items.push(
|
items.push(
|
||||||
ReplyPreview::new(ix, author, preview)
|
ReplyPreview::new(
|
||||||
|
SharedString::from(format!("reply-{}", id.to_hex())),
|
||||||
|
author,
|
||||||
|
preview,
|
||||||
|
)
|
||||||
.on_click(move |_event, _window, cx| {
|
.on_click(move |_event, _window, cx| {
|
||||||
if let Err(error) = panel.update(cx, |panel, cx| {
|
if let Err(error) = panel.update(cx, |panel, cx| {
|
||||||
panel.scroll_to(&id, cx);
|
panel.scroll_to(&id, cx);
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ use gpui_kit::component::dialog::DialogButtonProps;
|
|||||||
use gpui_kit::component::input::InputState;
|
use gpui_kit::component::input::InputState;
|
||||||
use gpui_kit::component::notification::Notification;
|
use gpui_kit::component::notification::Notification;
|
||||||
use gpui_kit::component::switch::Switch;
|
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 nip29::{Group, GroupId, GroupMetadata};
|
||||||
use nostr_sdk::prelude::RelayUrl;
|
use nostr_sdk::prelude::RelayUrl;
|
||||||
use ui::settings_row;
|
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);
|
let supported = *livekit.read(cx) != Some(false);
|
||||||
|
|
||||||
this.close_button(true)
|
this.close_button(true)
|
||||||
.title("Edit Group")
|
.title("Edit group")
|
||||||
.button_props(
|
.button_props(
|
||||||
DialogButtonProps::default()
|
DialogButtonProps::default()
|
||||||
.cancel_text("Cancel")
|
.cancel_text("Cancel")
|
||||||
@@ -161,11 +161,14 @@ pub(crate) fn open(group: WeakEntity<Group>, window: &mut Window, cx: &mut App)
|
|||||||
.child(settings_row(
|
.child(settings_row(
|
||||||
"LiveKit",
|
"LiveKit",
|
||||||
if supported {
|
if supported {
|
||||||
"Announce audio and video support."
|
"Announce audio and video support"
|
||||||
} else {
|
} else {
|
||||||
"The relay doesn't announce LiveKit support."
|
"The relay doesn't announce LiveKit support."
|
||||||
},
|
},
|
||||||
Switch::new("livekit").checked(current.livekit).on_click({
|
Switch::new("livekit")
|
||||||
|
.checked(current.livekit)
|
||||||
|
.disabled(!supported)
|
||||||
|
.on_click({
|
||||||
let flags = flags.clone();
|
let flags = flags.clone();
|
||||||
let livekit = livekit.clone();
|
let livekit = livekit.clone();
|
||||||
|
|
||||||
@@ -293,10 +296,10 @@ fn children_section(children: &Entity<Vec<GroupId>>, cx: &App) -> AnyElement {
|
|||||||
.flex_shrink_0()
|
.flex_shrink_0()
|
||||||
.gap_1()
|
.gap_1()
|
||||||
.when(ix > 0, |this| {
|
.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| {
|
.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(
|
section = section.child(
|
||||||
@@ -319,11 +322,12 @@ fn children_section(children: &Entity<Vec<GroupId>>, cx: &App) -> AnyElement {
|
|||||||
|
|
||||||
fn move_button(
|
fn move_button(
|
||||||
children: Entity<Vec<GroupId>>,
|
children: Entity<Vec<GroupId>>,
|
||||||
|
child: &GroupId,
|
||||||
ix: usize,
|
ix: usize,
|
||||||
target: usize,
|
target: usize,
|
||||||
direction: &'static str,
|
direction: &'static str,
|
||||||
) -> Button {
|
) -> Button {
|
||||||
Button::new(SharedString::from(format!("child-{direction}-{ix}")))
|
Button::new(SharedString::from(format!("child-{direction}-{child}")))
|
||||||
.label(if direction == "up" { "Up" } else { "Down" })
|
.label(if direction == "up" { "Up" } else { "Down" })
|
||||||
.ghost()
|
.ghost()
|
||||||
.small()
|
.small()
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ pub fn open_nutzap(
|
|||||||
|
|
||||||
window.open_dialog(cx, move |this, _window, _cx| {
|
window.open_dialog(cx, move |this, _window, _cx| {
|
||||||
this.width(px(380.))
|
this.width(px(380.))
|
||||||
.title("Send Nutzap")
|
.title("Send eCash")
|
||||||
.on_ok({
|
.on_ok({
|
||||||
let send = send.clone();
|
let send = send.clone();
|
||||||
move |event, window, cx| send(event, window, cx)
|
move |event, window, cx| send(event, window, cx)
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ impl WalletPanel {
|
|||||||
.border_dashed()
|
.border_dashed()
|
||||||
.border_color(cx.theme().border)
|
.border_color(cx.theme().border)
|
||||||
.rounded(cx.theme().radius_lg)
|
.rounded(cx.theme().radius_lg)
|
||||||
.child("No transactions yet.")
|
.child("No transactions yet")
|
||||||
.into_any_element();
|
.into_any_element();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -646,7 +646,7 @@ fn open_receive_dialog(window: &mut Window, cx: &mut App) {
|
|||||||
.step(1.)
|
.step(1.)
|
||||||
.min(1.)
|
.min(1.)
|
||||||
});
|
});
|
||||||
let token_input = cx.new(|cx| InputState::new(window, cx).placeholder("cashu…"));
|
let token_input = cx.new(|cx| InputState::new(window, cx).placeholder("cashu"));
|
||||||
|
|
||||||
let create_invoice: SubmitFn = {
|
let create_invoice: SubmitFn = {
|
||||||
let wallet = WalletRegistry::global(cx);
|
let wallet = WalletRegistry::global(cx);
|
||||||
|
|||||||
+10
-9
@@ -1,6 +1,6 @@
|
|||||||
use gpui::{
|
use gpui::{
|
||||||
App, Div, Hsla, InteractiveElement, IntoElement, ParentElement, Pixels, RenderOnce,
|
App, Div, Hsla, InteractiveElement, IntoElement, ParentElement, Rems, RenderOnce, SharedString,
|
||||||
SharedString, StyleRefinement, Styled, Window, div, px,
|
StyleRefinement, Styled, Window, div, rems,
|
||||||
};
|
};
|
||||||
use gpui_base::AvatarImage;
|
use gpui_base::AvatarImage;
|
||||||
use gpui_kit::base::StyledExt as _;
|
use gpui_kit::base::StyledExt as _;
|
||||||
@@ -115,7 +115,7 @@ impl RenderOnce for Avatar {
|
|||||||
#[derive(IntoElement)]
|
#[derive(IntoElement)]
|
||||||
struct PixelAvatar {
|
struct PixelAvatar {
|
||||||
seed: u64,
|
seed: u64,
|
||||||
side: Pixels,
|
side: Rems,
|
||||||
style: StyleRefinement,
|
style: StyleRefinement,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,13 +187,14 @@ impl RenderOnce for PixelAvatar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The rendered side length of an avatar at `size`.
|
/// The rendered side length of an avatar at `size`.
|
||||||
fn side_length(size: Size) -> Pixels {
|
fn side_length(size: Size) -> Rems {
|
||||||
match size {
|
match size {
|
||||||
Size::XSmall => px(16.),
|
Size::XSmall => rems(1.),
|
||||||
Size::Small => px(24.),
|
Size::Small => rems(1.5),
|
||||||
Size::Medium => px(48.),
|
Size::Medium => rems(3.),
|
||||||
Size::Large => px(80.),
|
Size::Large => rems(5.),
|
||||||
Size::Size(size) => size,
|
// Custom sizes arrive in px; assume the 16px default rem.
|
||||||
|
Size::Size(size) => rems(size.as_f32() / 16.),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use gpui::{
|
|||||||
Animation, AnimationExt as _, AnyElement, App, ClickEvent, Context, ElementId,
|
Animation, AnimationExt as _, AnyElement, App, ClickEvent, Context, ElementId,
|
||||||
InteractiveElement as _, IntoElement, MouseButton, MouseDownEvent, ObjectFit,
|
InteractiveElement as _, IntoElement, MouseButton, MouseDownEvent, ObjectFit,
|
||||||
ParentElement as _, RenderOnce, SharedString, SharedUri, StatefulInteractiveElement as _,
|
ParentElement as _, RenderOnce, SharedString, SharedUri, StatefulInteractiveElement as _,
|
||||||
StyleRefinement, Styled, StyledImage, Window, div, img, px,
|
StyleRefinement, Styled, StyledImage, Window, div, img, rems,
|
||||||
};
|
};
|
||||||
use gpui_kit::assets::IconName;
|
use gpui_kit::assets::IconName;
|
||||||
use gpui_kit::component::button::{Button, ButtonVariants as _};
|
use gpui_kit::component::button::{Button, ButtonVariants as _};
|
||||||
@@ -199,10 +199,10 @@ impl RenderOnce for MessageRow {
|
|||||||
if show_author {
|
if show_author {
|
||||||
match avatar {
|
match avatar {
|
||||||
Some(avatar) => this.child(avatar),
|
Some(avatar) => this.child(avatar),
|
||||||
None => this.child(div().flex_shrink_0().w(px(24.))),
|
None => this.child(div().flex_shrink_0().w_6()),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.child(div().flex_shrink_0().w(px(24.)))
|
this.child(div().flex_shrink_0().w_6())
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.child(
|
.child(
|
||||||
@@ -212,7 +212,7 @@ impl RenderOnce for MessageRow {
|
|||||||
.min_w_0()
|
.min_w_0()
|
||||||
.flex_initial()
|
.flex_initial()
|
||||||
.overflow_hidden()
|
.overflow_hidden()
|
||||||
.text_size(px(15.))
|
.text_base()
|
||||||
.when(show_author, |this| {
|
.when(show_author, |this| {
|
||||||
this.child(
|
this.child(
|
||||||
h_flex()
|
h_flex()
|
||||||
@@ -383,7 +383,7 @@ impl RenderOnce for MessageMedia {
|
|||||||
img(only.clone())
|
img(only.clone())
|
||||||
.border_1()
|
.border_1()
|
||||||
.border_color(cx.theme().border)
|
.border_color(cx.theme().border)
|
||||||
.h(px(250.))
|
.h(rems(16.))
|
||||||
.object_fit(ObjectFit::Cover)
|
.object_fit(ObjectFit::Cover)
|
||||||
.rounded(cx.theme().radius_lg),
|
.rounded(cx.theme().radius_lg),
|
||||||
)
|
)
|
||||||
@@ -398,8 +398,11 @@ impl RenderOnce for MessageMedia {
|
|||||||
.flex_wrap()
|
.flex_wrap()
|
||||||
.gap_2()
|
.gap_2()
|
||||||
.refine_style(&style)
|
.refine_style(&style)
|
||||||
.children(media.into_iter().enumerate().map(|(ix, item)| {
|
.children(media.into_iter().map(|item| {
|
||||||
div().id(format!("media-{ix}")).flex_shrink_0().child(
|
div()
|
||||||
|
.id(SharedString::from(format!("media-{}", item)))
|
||||||
|
.flex_shrink_0()
|
||||||
|
.child(
|
||||||
img(item)
|
img(item)
|
||||||
.h_32()
|
.h_32()
|
||||||
.border_1()
|
.border_1()
|
||||||
@@ -494,7 +497,7 @@ impl RenderOnce for ReactionBar {
|
|||||||
.when(!group.mine, |this| this.border_color(cx.theme().border))
|
.when(!group.mine, |this| this.border_color(cx.theme().border))
|
||||||
.when(group.image.is_none(), |this| this.child(group.emoji))
|
.when(group.image.is_none(), |this| this.child(group.emoji))
|
||||||
.when_some(group.image, |this, image| {
|
.when_some(group.image, |this, image| {
|
||||||
this.child(img(image).size(px(16.)).flex_shrink_0())
|
this.child(img(image).size_4().flex_shrink_0())
|
||||||
})
|
})
|
||||||
.child(SharedString::from(group.count.to_string()))
|
.child(SharedString::from(group.count.to_string()))
|
||||||
}))
|
}))
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ use nip29::{GroupReference, GroupsRegistry};
|
|||||||
type SubmitFn = Rc<dyn Fn(&ClickEvent, &mut Window, &mut App) -> bool>;
|
type SubmitFn = Rc<dyn Fn(&ClickEvent, &mut Window, &mut App) -> bool>;
|
||||||
|
|
||||||
pub fn open(window: &mut Window, cx: &mut App) {
|
pub fn open(window: &mut Window, cx: &mut App) {
|
||||||
let input = cx.new(|cx| InputState::new(window, cx).placeholder("naddr1…"));
|
let input = cx.new(|cx| InputState::new(window, cx).placeholder("naddr1"));
|
||||||
|
|
||||||
let join: SubmitFn = {
|
let join: SubmitFn = {
|
||||||
let input = input.clone();
|
let input = input.clone();
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use gpui::prelude::FluentBuilder;
|
|||||||
use gpui::{
|
use gpui::{
|
||||||
AnyElement, App, AppContext, Context, Div, Entity, InteractiveElement as _, IntoElement,
|
AnyElement, App, AppContext, Context, Div, Entity, InteractiveElement as _, IntoElement,
|
||||||
ParentElement, Render, SharedString, StatefulInteractiveElement as _, StyleRefinement, Styled,
|
ParentElement, Render, SharedString, StatefulInteractiveElement as _, StyleRefinement, Styled,
|
||||||
Subscription, Task, WeakEntity, Window, div, px,
|
Subscription, Task, WeakEntity, Window, div, px, rems,
|
||||||
};
|
};
|
||||||
use gpui_kit::base::StyledExt as _;
|
use gpui_kit::base::StyledExt as _;
|
||||||
use gpui_kit::component::button::{Button, ButtonVariants};
|
use gpui_kit::component::button::{Button, ButtonVariants};
|
||||||
@@ -491,7 +491,7 @@ impl Render for NewGroup {
|
|||||||
.child(
|
.child(
|
||||||
v_flex()
|
v_flex()
|
||||||
.id("group-dialog-content")
|
.id("group-dialog-content")
|
||||||
.h(px(500.))
|
.h(rems(31.25))
|
||||||
.gap_3()
|
.gap_3()
|
||||||
.when_some(self.error.clone(), |this, error| {
|
.when_some(self.error.clone(), |this, error| {
|
||||||
this.child(self.render_error(&error, web_url.as_deref(), cx))
|
this.child(self.render_error(&error, web_url.as_deref(), cx))
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ impl ProfileDialog {
|
|||||||
let bio_input = cx.new(|cx| {
|
let bio_input = cx.new(|cx| {
|
||||||
TextareaState::new(window, cx)
|
TextareaState::new(window, cx)
|
||||||
.auto_grow(3, 8)
|
.auto_grow(3, 8)
|
||||||
.placeholder("A short introduce about you.")
|
.placeholder("A short introduction about you")
|
||||||
});
|
});
|
||||||
|
|
||||||
let directory = Directory::new(cx);
|
let directory = Directory::new(cx);
|
||||||
@@ -438,7 +438,7 @@ impl Render for ProfileDialog {
|
|||||||
Button::new("update")
|
Button::new("update")
|
||||||
.icon(IconName::SquarePen)
|
.icon(IconName::SquarePen)
|
||||||
.label("Update")
|
.label("Update")
|
||||||
.primary()
|
.outline()
|
||||||
.on_click(cx.listener(move |this, _ev, window, cx| {
|
.on_click(cx.listener(move |this, _ev, window, cx| {
|
||||||
this.toggle_edit(window, cx);
|
this.toggle_edit(window, cx);
|
||||||
})),
|
})),
|
||||||
@@ -449,7 +449,7 @@ impl Render for ProfileDialog {
|
|||||||
Button::new("message")
|
Button::new("message")
|
||||||
.icon(IconName::MessageSquare)
|
.icon(IconName::MessageSquare)
|
||||||
.label("Message")
|
.label("Message")
|
||||||
.primary()
|
.outline()
|
||||||
.on_click(cx.listener(move |this, _ev, window, cx| {
|
.on_click(cx.listener(move |this, _ev, window, cx| {
|
||||||
this.message(window, cx);
|
this.message(window, cx);
|
||||||
})),
|
})),
|
||||||
|
|||||||
@@ -352,7 +352,7 @@ impl GossipRelays {
|
|||||||
let metadata = self.metadata;
|
let metadata = self.metadata;
|
||||||
|
|
||||||
if !value.starts_with("ws") {
|
if !value.starts_with("ws") {
|
||||||
self.set_error("Relay URl is invalid", window, cx);
|
self.set_error("Relay URL is invalid", window, cx);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -364,7 +364,7 @@ impl GossipRelays {
|
|||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.set_error("Relay URl is invalid", window, cx);
|
self.set_error("Relay URL is invalid", window, cx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -496,7 +496,7 @@ impl InboxRelays {
|
|||||||
let value = self.input.read(cx).value().to_string();
|
let value = self.input.read(cx).value().to_string();
|
||||||
|
|
||||||
if !value.starts_with("ws") {
|
if !value.starts_with("ws") {
|
||||||
self.set_error("Relay URl is invalid", window, cx);
|
self.set_error("Relay URL is invalid", window, cx);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -508,7 +508,7 @@ impl InboxRelays {
|
|||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.set_error("Relay URl is invalid", window, cx);
|
self.set_error("Relay URL is invalid", window, cx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -646,7 +646,7 @@ fn relay_row(
|
|||||||
.px_2()
|
.px_2()
|
||||||
.justify_between()
|
.justify_between()
|
||||||
.rounded(cx.theme().radius)
|
.rounded(cx.theme().radius)
|
||||||
.bg(cx.theme().sidebar)
|
.bg(cx.theme().secondary)
|
||||||
.context_menu({
|
.context_menu({
|
||||||
let on_remove = on_remove.clone();
|
let on_remove = on_remove.clone();
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use common::TimestampExt;
|
|||||||
use gpui::prelude::FluentBuilder;
|
use gpui::prelude::FluentBuilder;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
App, AppContext, Context, Div, Entity, IntoElement, ParentElement, Render, SharedString,
|
App, AppContext, Context, Div, Entity, IntoElement, ParentElement, Render, SharedString,
|
||||||
Styled, Subscription, Task, Window, div, px, relative, uniform_list,
|
Styled, Subscription, Task, Window, div, relative, rems, uniform_list,
|
||||||
};
|
};
|
||||||
use gpui_kit::assets::IconName;
|
use gpui_kit::assets::IconName;
|
||||||
use gpui_kit::base::StyledExt as _;
|
use gpui_kit::base::StyledExt as _;
|
||||||
@@ -324,7 +324,7 @@ impl Screening {
|
|||||||
|
|
||||||
items
|
items
|
||||||
})
|
})
|
||||||
.h(px(300.)),
|
.h(rems(18.75)),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
@@ -571,7 +571,7 @@ fn status_badge(status: Option<bool>, cx: &App) -> Div {
|
|||||||
if let Some(status) = status {
|
if let Some(status) = status {
|
||||||
this.child(Icon::new(IconName::CircleCheck).small().text_color({
|
this.child(Icon::new(IconName::CircleCheck).small().text_color({
|
||||||
if status {
|
if status {
|
||||||
cx.theme().primary
|
cx.theme().success
|
||||||
} else {
|
} else {
|
||||||
cx.theme().muted_foreground
|
cx.theme().muted_foreground
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ impl Preferences {
|
|||||||
});
|
});
|
||||||
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
let mint_input = cx.new(|cx| InputState::new(window, cx).placeholder("https://mint…"));
|
let mint_input = cx.new(|cx| InputState::new(window, cx).placeholder("https://mint"));
|
||||||
|
|
||||||
let subscriptions = vec![
|
let subscriptions = vec![
|
||||||
Self::wire_number_input(&font_size_input, FONT_SIZE_RANGE, cx, |value, cx| {
|
Self::wire_number_input(&font_size_input, FONT_SIZE_RANGE, cx, |value, cx| {
|
||||||
@@ -446,7 +446,7 @@ impl Preferences {
|
|||||||
|
|
||||||
impl Render for Preferences {
|
impl Render for Preferences {
|
||||||
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||||
const SCREENING: &str = "Show an screening dialog to verify the unknown sender.";
|
const SCREENING: &str = "Show a screening dialog to verify the unknown sender.";
|
||||||
const WOT: &str = "Treat people followed by your contacts as known senders.";
|
const WOT: &str = "Treat people followed by your contacts as known senders.";
|
||||||
const AVATAR: &str = "Hide all avatar pictures to improve performance.";
|
const AVATAR: &str = "Hide all avatar pictures to improve performance.";
|
||||||
const APPEARANCE: &str =
|
const APPEARANCE: &str =
|
||||||
@@ -475,7 +475,7 @@ impl Render for Preferences {
|
|||||||
|
|
||||||
let background_label = match &panel_background_path {
|
let background_label = match &panel_background_path {
|
||||||
Some(path) => path.display().to_string(),
|
Some(path) => path.display().to_string(),
|
||||||
None => String::from("Default Background"),
|
None => String::from("Default background"),
|
||||||
};
|
};
|
||||||
|
|
||||||
v_flex()
|
v_flex()
|
||||||
@@ -497,7 +497,7 @@ impl Render for Preferences {
|
|||||||
cx,
|
cx,
|
||||||
))
|
))
|
||||||
.child(settings_row(
|
.child(settings_row(
|
||||||
"Web of Trust",
|
"Web of trust",
|
||||||
WOT,
|
WOT,
|
||||||
Switch::new("wot-auto-trust")
|
Switch::new("wot-auto-trust")
|
||||||
.checked(wot_auto_trust)
|
.checked(wot_auto_trust)
|
||||||
@@ -536,33 +536,33 @@ impl Render for Preferences {
|
|||||||
}),
|
}),
|
||||||
cx,
|
cx,
|
||||||
))
|
))
|
||||||
.child(self.render_theme_choice("theme-light", "Light Theme", LIGHT_THEME, false, cx))
|
.child(self.render_theme_choice("theme-light", "Light theme", LIGHT_THEME, false, cx))
|
||||||
.child(self.render_theme_choice("theme-dark", "Dark Theme", DARK_THEME, true, cx))
|
.child(self.render_theme_choice("theme-dark", "Dark theme", DARK_THEME, true, cx))
|
||||||
.child(Separator::horizontal())
|
.child(Separator::horizontal())
|
||||||
.child(
|
.child(
|
||||||
v_flex()
|
v_flex()
|
||||||
.w_full()
|
.w_full()
|
||||||
.gap_3()
|
.gap_3()
|
||||||
.child(settings_row(
|
.child(settings_row(
|
||||||
"Font Size",
|
"Font size",
|
||||||
FONT_SIZE,
|
FONT_SIZE,
|
||||||
NumberInput::new(&self.font_size_input).w_24(),
|
NumberInput::new(&self.font_size_input).w_24(),
|
||||||
cx,
|
cx,
|
||||||
))
|
))
|
||||||
.child(settings_row(
|
.child(settings_row(
|
||||||
"Corner Radius",
|
"Corner radius",
|
||||||
RADIUS,
|
RADIUS,
|
||||||
NumberInput::new(&self.radius_input).w_24(),
|
NumberInput::new(&self.radius_input).w_24(),
|
||||||
cx,
|
cx,
|
||||||
))
|
))
|
||||||
.child(settings_row(
|
.child(settings_row(
|
||||||
"Large Corner Radius",
|
"Large corner radius",
|
||||||
RADIUS_LG,
|
RADIUS_LG,
|
||||||
NumberInput::new(&self.radius_lg_input).w_24(),
|
NumberInput::new(&self.radius_lg_input).w_24(),
|
||||||
cx,
|
cx,
|
||||||
))
|
))
|
||||||
.child(settings_row(
|
.child(settings_row(
|
||||||
"Focus Ring",
|
"Focus ring",
|
||||||
FOCUS_RING,
|
FOCUS_RING,
|
||||||
Switch::new("focus-ring")
|
Switch::new("focus-ring")
|
||||||
.checked(theme.focus_ring)
|
.checked(theme.focus_ring)
|
||||||
@@ -624,7 +624,7 @@ impl Render for Preferences {
|
|||||||
)
|
)
|
||||||
.child(Separator::horizontal())
|
.child(Separator::horizontal())
|
||||||
.child(settings_row(
|
.child(settings_row(
|
||||||
"Decoupling Encryption Key",
|
"Decoupling encryption key",
|
||||||
NIP4E,
|
NIP4E,
|
||||||
Switch::new("nip4e")
|
Switch::new("nip4e")
|
||||||
.checked(nip4e)
|
.checked(nip4e)
|
||||||
@@ -634,7 +634,7 @@ impl Render for Preferences {
|
|||||||
cx,
|
cx,
|
||||||
))
|
))
|
||||||
.child(settings_row(
|
.child(settings_row(
|
||||||
"Rotate Encryption Key",
|
"Rotate encryption key",
|
||||||
NIP4E_ROTATION,
|
NIP4E_ROTATION,
|
||||||
Switch::new("nip4e_rotation")
|
Switch::new("nip4e_rotation")
|
||||||
.checked(nip4e_rotation_days.is_some())
|
.checked(nip4e_rotation_days.is_some())
|
||||||
@@ -654,7 +654,7 @@ impl Render for Preferences {
|
|||||||
.child(self.render_dictation_shortcut(window, cx))
|
.child(self.render_dictation_shortcut(window, cx))
|
||||||
.child(Separator::horizontal())
|
.child(Separator::horizontal())
|
||||||
.child(settings_block(
|
.child(settings_block(
|
||||||
"Media Upload Service",
|
"Media upload service",
|
||||||
MEDIA,
|
MEDIA,
|
||||||
h_flex()
|
h_flex()
|
||||||
.gap_1()
|
.gap_1()
|
||||||
|
|||||||
@@ -678,7 +678,7 @@ impl TabGroupRenderer for CoopTabGroupSkin {
|
|||||||
h_flex()
|
h_flex()
|
||||||
.id("tabs-inner")
|
.id("tabs-inner")
|
||||||
.relative()
|
.relative()
|
||||||
.gap(px(4.))
|
.gap_1()
|
||||||
.overflow_x_scroll()
|
.overflow_x_scroll()
|
||||||
.lock_scroll_axis()
|
.lock_scroll_axis()
|
||||||
.track_scroll(&self.scroll_handle)
|
.track_scroll(&self.scroll_handle)
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ use chat::{ChatEvent, ChatRegistry};
|
|||||||
use common::download_dir;
|
use common::download_dir;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
Action, App, AppContext, Context, Entity, Focusable, InteractiveElement, IntoElement,
|
Action, App, AppContext, Context, Entity, Focusable, InteractiveElement, IntoElement,
|
||||||
ParentElement, Pixels, Render, SharedString, Styled, Subscription, Task, Window, div, px,
|
ParentElement, Pixels, Render, SharedString, Styled, Subscription, Task, Window, div, px, rems,
|
||||||
};
|
};
|
||||||
use gpui_kit::component::button::{Button, ButtonVariant};
|
use gpui_kit::component::button::{Button, ButtonVariant};
|
||||||
use gpui_kit::component::command::{
|
use gpui_kit::component::command::{
|
||||||
@@ -480,7 +480,7 @@ impl Workspace {
|
|||||||
.bordered(false)
|
.bordered(false)
|
||||||
.rounded(cx.theme().radius_lg)
|
.rounded(cx.theme().radius_lg)
|
||||||
.placeholder("Search themes...")
|
.placeholder("Search themes...")
|
||||||
.max_h(px(420.))
|
.max_h(rems(26.25))
|
||||||
.on_confirm(move |index, _, cx| {
|
.on_confirm(move |index, _, cx| {
|
||||||
if let Some(name) = Self::theme_name_at(index, cx) {
|
if let Some(name) = Self::theme_name_at(index, cx) {
|
||||||
AppSettings::select_theme(&name, cx);
|
AppSettings::select_theme(&name, cx);
|
||||||
|
|||||||
@@ -296,7 +296,7 @@ impl BrowsePanel {
|
|||||||
.max_w_64()
|
.max_w_64()
|
||||||
.px_1()
|
.px_1()
|
||||||
.rounded(cx.theme().radius)
|
.rounded(cx.theme().radius)
|
||||||
.bg(cx.theme().sidebar)
|
.bg(cx.theme().secondary)
|
||||||
.child(Input::new(&self.input).appearance(false).flex_1())
|
.child(Input::new(&self.input).appearance(false).flex_1())
|
||||||
.child(
|
.child(
|
||||||
Button::new("relay-browse")
|
Button::new("relay-browse")
|
||||||
@@ -376,7 +376,7 @@ impl BrowsePanel {
|
|||||||
.cursor_pointer()
|
.cursor_pointer()
|
||||||
.border_1()
|
.border_1()
|
||||||
.border_color(transparent_black())
|
.border_color(transparent_black())
|
||||||
.bg(cx.theme().sidebar)
|
.bg(cx.theme().group_box)
|
||||||
.hover(|this| {
|
.hover(|this| {
|
||||||
this.bg(cx.theme().secondary)
|
this.bg(cx.theme().secondary)
|
||||||
.border_color(cx.theme().border)
|
.border_color(cx.theme().border)
|
||||||
@@ -510,12 +510,12 @@ impl Render for BrowsePanel {
|
|||||||
} else {
|
} else {
|
||||||
let text = if discover {
|
let text = if discover {
|
||||||
if self.discovering {
|
if self.discovering {
|
||||||
"Discovering groups…"
|
"Discovering groups"
|
||||||
} else {
|
} else {
|
||||||
"No groups found."
|
"No groups found."
|
||||||
}
|
}
|
||||||
} else if self.loading {
|
} else if self.loading {
|
||||||
"Loading groups…"
|
"Loading groups"
|
||||||
} else {
|
} else {
|
||||||
"No groups found."
|
"No groups found."
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -307,7 +307,7 @@ impl ContactListPanel {
|
|||||||
.rounded(cx.theme().radius_lg)
|
.rounded(cx.theme().radius_lg)
|
||||||
.text_xs()
|
.text_xs()
|
||||||
.text_align(TextAlign::Center)
|
.text_align(TextAlign::Center)
|
||||||
.child(SharedString::from("Please add some relays."))
|
.child(SharedString::from("No contacts yet"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -213,17 +213,17 @@ impl GreeterPanel {
|
|||||||
} else {
|
} else {
|
||||||
requests
|
requests
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.map(|(room, preview)| {
|
||||||
.map(|(index, (room, preview))| {
|
|
||||||
let room = room.clone();
|
let room = room.clone();
|
||||||
let dock = dock.clone();
|
let dock = dock.clone();
|
||||||
let name = room.read(cx).display_name(cx);
|
let name = room.read(cx).display_name(cx);
|
||||||
let seed = room.read(cx).display_image_seed(cx);
|
let seed = room.read(cx).display_image_seed(cx);
|
||||||
let created_at = room.read(cx).created_at.to_ago();
|
let created_at = room.read(cx).created_at.to_ago();
|
||||||
|
let id = room.read(cx).id;
|
||||||
let preview = preview.clone();
|
let preview = preview.clone();
|
||||||
|
|
||||||
h_flex()
|
h_flex()
|
||||||
.id(format!("request-{index}"))
|
.id(format!("request-{id}"))
|
||||||
.group("")
|
.group("")
|
||||||
.w_full()
|
.w_full()
|
||||||
.h_9()
|
.h_9()
|
||||||
@@ -280,8 +280,8 @@ impl GreeterPanel {
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
.child(
|
.child(
|
||||||
Button::new(format!("response-{index}"))
|
Button::new(format!("response-{id}"))
|
||||||
.label("Response")
|
.label("Respond")
|
||||||
.xsmall()
|
.xsmall()
|
||||||
.ghost()
|
.ghost()
|
||||||
.invisible()
|
.invisible()
|
||||||
@@ -332,17 +332,17 @@ impl GreeterPanel {
|
|||||||
let rows: Vec<AnyElement> = self
|
let rows: Vec<AnyElement> = self
|
||||||
.follow_ups
|
.follow_ups
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.map(|(room, preview)| {
|
||||||
.map(|(index, (room, preview))| {
|
|
||||||
let room = room.clone();
|
let room = room.clone();
|
||||||
let dock = dock.clone();
|
let dock = dock.clone();
|
||||||
let name = room.read(cx).display_name(cx);
|
let name = room.read(cx).display_name(cx);
|
||||||
let seed = room.read(cx).display_image_seed(cx);
|
let seed = room.read(cx).display_image_seed(cx);
|
||||||
let created_at = room.read(cx).created_at.to_ago();
|
let created_at = room.read(cx).created_at.to_ago();
|
||||||
|
let id = room.read(cx).id;
|
||||||
let preview = preview.clone();
|
let preview = preview.clone();
|
||||||
|
|
||||||
h_flex()
|
h_flex()
|
||||||
.id(format!("follow-up-{index}"))
|
.id(format!("follow-up-{id}"))
|
||||||
.group("")
|
.group("")
|
||||||
.w_full()
|
.w_full()
|
||||||
.h_9()
|
.h_9()
|
||||||
@@ -399,7 +399,7 @@ impl GreeterPanel {
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
.child(
|
.child(
|
||||||
Button::new(format!("reply-{index}"))
|
Button::new(format!("reply-{id}"))
|
||||||
.label("Reply")
|
.label("Reply")
|
||||||
.xsmall()
|
.xsmall()
|
||||||
.ghost()
|
.ghost()
|
||||||
|
|||||||
@@ -284,7 +284,7 @@ fn open_logout_dialog(window: &mut Window, cx: &mut App) {
|
|||||||
|
|
||||||
window.open_alert_dialog(cx, |alert, _, _| {
|
window.open_alert_dialog(cx, |alert, _, _| {
|
||||||
alert
|
alert
|
||||||
.title("Log Out?")
|
.title("Log out")
|
||||||
.description(DESCRIPTION)
|
.description(DESCRIPTION)
|
||||||
.button_props(
|
.button_props(
|
||||||
DialogButtonProps::default()
|
DialogButtonProps::default()
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ pub(crate) fn open_room(
|
|||||||
.button_props(
|
.button_props(
|
||||||
DialogButtonProps::default()
|
DialogButtonProps::default()
|
||||||
.cancel_text("Ignore")
|
.cancel_text("Ignore")
|
||||||
.ok_text("Response"),
|
.ok_text("Respond"),
|
||||||
)
|
)
|
||||||
.on_cancel(move |_event, window, cx| {
|
.on_cancel(move |_event, window, cx| {
|
||||||
window.dispatch_action(Box::new(ClosePanel), cx);
|
window.dispatch_action(Box::new(ClosePanel), cx);
|
||||||
@@ -200,7 +200,7 @@ impl Sidebar {
|
|||||||
h_flex()
|
h_flex()
|
||||||
.gap_1()
|
.gap_1()
|
||||||
.when(spam, |this| {
|
.when(spam, |this| {
|
||||||
this.child(Tag::danger().xsmall().child("SPAM"))
|
this.child(Tag::danger().xsmall().child("Spam"))
|
||||||
})
|
})
|
||||||
.when(!spam, |this| {
|
.when(!spam, |this| {
|
||||||
this.child(
|
this.child(
|
||||||
|
|||||||
@@ -309,7 +309,7 @@ impl Sidebar {
|
|||||||
public_key: *public_key,
|
public_key: *public_key,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
None => rows.push(SidebarRow::Empty("Searching...")),
|
None => rows.push(SidebarRow::Empty("Searching")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user