feat: add edit messages relay button

This commit is contained in:
2025-02-13 07:54:38 +07:00
parent d63b6f1047
commit 2aa2196565
7 changed files with 405 additions and 55 deletions

View File

@@ -48,6 +48,7 @@ fn main() {
_ = client.add_relay("wss://relay.primal.net/").await;
_ = client.add_relay("wss://user.kindpag.es/").await;
_ = client.add_relay("wss://directory.yabu.me/").await;
_ = client.add_discovery_relay("wss://relaydiscovery.com").await;
// Connect to all relays
_ = client.connect().await

View File

@@ -4,8 +4,9 @@ use common::{
profile::NostrProfile,
};
use gpui::{
actions, div, img, impl_internal_actions, px, App, AppContext, Axis, Context, Entity,
InteractiveElement, IntoElement, ObjectFit, ParentElement, Render, Styled, StyledImage, Window,
actions, div, img, impl_internal_actions, prelude::FluentBuilder, px, App, AppContext, Axis,
Context, Entity, InteractiveElement, IntoElement, ObjectFit, ParentElement, Render, Styled,
StyledImage, Window,
};
use log::info;
use nostr_sdk::prelude::*;
@@ -17,7 +18,7 @@ use ui::{
button::{Button, ButtonRounded, ButtonVariants},
dock_area::{dock::DockPlacement, DockArea, DockItem},
popup_menu::PopupMenuExt,
theme::{scale::ColorScaleStep, ActiveTheme},
theme::{scale::ColorScaleStep, ActiveTheme, Appearance, Theme},
ContextModal, Icon, IconName, Root, Sizable, TitleBar,
};
@@ -52,6 +53,7 @@ pub fn init(account: NostrProfile, window: &mut Window, cx: &mut App) -> Entity<
pub struct AppView {
account: NostrProfile,
relays: Entity<Option<Vec<String>>>,
dock: Entity<DockArea>,
}
@@ -107,14 +109,21 @@ impl AppView {
.detach();
cx.new(|cx| {
let public_key = account.public_key();
let relays = cx.new(|_| None);
let async_relays = relays.downgrade();
// Check user's messaging relays and determine user is ready for NIP17 or not.
// If not, show the setup modal and instruct user setup inbox relays
let client = get_client();
let public_key = account.public_key();
let window_handle = window.window_handle();
let (tx, rx) = oneshot::channel::<bool>();
let (tx, rx) = oneshot::channel::<Option<Vec<String>>>();
let this = Self { account, dock };
let this = Self {
account,
relays,
dock,
};
cx.background_spawn(async move {
let filter = Filter::new()
@@ -122,22 +131,43 @@ impl AppView {
.author(public_key)
.limit(1);
let is_ready = if let Ok(events) = client.database().query(filter).await {
events.first_owned().is_some()
let relays = if let Ok(events) = client.database().query(filter).await {
if let Some(event) = events.first_owned() {
Some(
event
.tags
.filter_standardized(TagKind::Relay)
.filter_map(|t| match t {
TagStandard::Relay(url) => Some(url.to_string()),
_ => None,
})
.collect::<Vec<_>>(),
)
} else {
None
}
} else {
false
None
};
_ = tx.send(is_ready);
_ = tx.send(relays);
})
.detach();
cx.spawn(|this, mut cx| async move {
if let Ok(is_ready) = rx.await {
if !is_ready {
if let Ok(result) = rx.await {
if let Some(relays) = result {
_ = cx.update(|cx| {
_ = async_relays.update(cx, |this, cx| {
*this = Some(relays);
cx.notify();
});
});
} else {
_ = cx.update_window(window_handle, |_, window, cx| {
this.update(cx, |this: &mut Self, cx| {
this.render_relays_setup(window, cx)
this.render_setup_relays(window, cx)
})
});
}
@@ -149,8 +179,8 @@ impl AppView {
})
}
fn render_relays_setup(&self, window: &mut Window, cx: &mut Context<Self>) {
let relays = cx.new(|cx| Relays::new(window, cx));
fn render_setup_relays(&self, window: &mut Window, cx: &mut Context<Self>) {
let relays = cx.new(|cx| Relays::new(None, window, cx));
window.open_modal(cx, move |this, window, cx| {
let is_loading = relays.read(cx).loading();
@@ -181,6 +211,75 @@ impl AppView {
});
}
fn render_edit_relay(&self, window: &mut Window, cx: &mut Context<Self>) {
let relays = self.relays.read(cx).clone();
let view = cx.new(|cx| Relays::new(relays, window, cx));
window.open_modal(cx, move |this, window, cx| {
let is_loading = view.read(cx).loading();
this.width(px(420.))
.title("Edit your Messaging Relays")
.child(view.clone())
.footer(
div()
.p_2()
.border_t_1()
.border_color(cx.theme().base.step(cx, ColorScaleStep::FIVE))
.child(
Button::new("update_inbox_relays_btn")
.label("Update")
.primary()
.bold()
.rounded(ButtonRounded::Large)
.w_full()
.loading(is_loading)
.on_click(window.listener_for(&view, |this, _, window, cx| {
this.update(window, cx);
})),
),
)
});
}
fn render_appearance_button(
&self,
_window: &mut Window,
cx: &mut Context<Self>,
) -> impl IntoElement {
Button::new("appearance")
.xsmall()
.ghost()
.map(|this| {
if cx.theme().appearance.is_dark() {
this.icon(IconName::Sun)
} else {
this.icon(IconName::Moon)
}
})
.on_click(cx.listener(|_, _, window, cx| {
if cx.theme().appearance.is_dark() {
Theme::change(Appearance::Light, Some(window), cx);
} else {
Theme::change(Appearance::Dark, Some(window), cx);
}
}))
}
fn render_relays_button(
&self,
_window: &mut Window,
cx: &mut Context<Self>,
) -> impl IntoElement {
Button::new("relays")
.xsmall()
.ghost()
.icon(IconName::Relays)
.on_click(cx.listener(|this, _, window, cx| {
this.render_edit_relay(window, cx);
}))
}
fn render_account(&self) -> impl IntoElement {
Button::new("account")
.ghost()
@@ -276,8 +375,10 @@ impl Render for AppView {
.flex()
.items_center()
.justify_end()
.gap_1()
.gap_2()
.px_2()
.child(self.render_appearance_button(window, cx))
.child(self.render_relays_button(window, cx))
.child(self.render_account()),
),
)

View File

@@ -12,6 +12,8 @@ use ui::{
ContextModal, IconName, Sizable,
};
const MESSAGE: &str = "In order to receive messages from others, you need to setup Messaging Relays. You can use the recommend relays or add more.";
pub struct Relays {
relays: Entity<Vec<Url>>,
input: Entity<TextInput>,
@@ -20,12 +22,20 @@ pub struct Relays {
}
impl Relays {
pub fn new(window: &mut Window, cx: &mut Context<'_, Self>) -> Self {
pub fn new(
relays: Option<Vec<String>>,
window: &mut Window,
cx: &mut Context<'_, Self>,
) -> Self {
let relays = cx.new(|_| {
vec![
Url::parse("wss://auth.nostr1.com").unwrap(),
Url::parse("wss://relay.0xchat.com").unwrap(),
]
if let Some(value) = relays {
value.into_iter().map(|v| Url::parse(&v).unwrap()).collect()
} else {
vec![
Url::parse("wss://auth.nostr1.com").unwrap(),
Url::parse("wss://relay.0xchat.com").unwrap(),
]
}
});
let input = cx.new(|cx| {
@@ -136,8 +146,6 @@ impl Relays {
impl Render for Relays {
fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
let msg = "In order to receive messages from others, you need to setup Messaging Relays. You can use the recommend relays or add more.";
div()
.track_focus(&self.focus_handle)
.flex()
@@ -148,7 +156,7 @@ impl Render for Relays {
.px_2()
.text_xs()
.text_color(cx.theme().base.step(cx, ColorScaleStep::ELEVEN))
.child(msg),
.child(MESSAGE),
)
.child(
div()

View File

@@ -500,7 +500,7 @@ impl ButtonVariant {
_ => cx.theme().accent.step(cx, ColorScaleStep::ONE),
},
ButtonVariant::Link => cx.theme().accent.step(cx, ColorScaleStep::NINE),
ButtonVariant::Ghost => cx.theme().base.step(cx, ColorScaleStep::ELEVEN),
ButtonVariant::Ghost => cx.theme().base.step(cx, ColorScaleStep::TWELVE),
ButtonVariant::Custom(colors) => colors.foreground,
_ => cx.theme().base.step(cx, ColorScaleStep::TWELVE),
}

View File

@@ -60,6 +60,7 @@ pub enum IconName {
Minimize,
Minus,
Moon,
Relays,
Palette,
PanelBottom,
PanelBottomOpen,
@@ -143,6 +144,7 @@ impl IconName {
Self::Minimize => "icons/minimize.svg",
Self::Minus => "icons/minus.svg",
Self::Moon => "icons/moon.svg",
Self::Relays => "icons/relays.svg",
Self::Palette => "icons/palette.svg",
Self::PanelBottom => "icons/panel-bottom.svg",
Self::PanelBottomOpen => "icons/panel-bottom-open.svg",