Redesign for the v1 stable release #3
2
crates/coop/src/dialogs/mod.rs
Normal file
2
crates/coop/src/dialogs/mod.rs
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
pub mod compose;
|
||||||
|
pub mod screening;
|
||||||
@@ -12,10 +12,10 @@ use ui::Root;
|
|||||||
use crate::actions::Quit;
|
use crate::actions::Quit;
|
||||||
|
|
||||||
mod actions;
|
mod actions;
|
||||||
|
mod dialogs;
|
||||||
mod panels;
|
mod panels;
|
||||||
mod sidebar;
|
mod sidebar;
|
||||||
mod user;
|
mod user;
|
||||||
mod views;
|
|
||||||
mod workspace;
|
mod workspace;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use theme::ActiveTheme;
|
|||||||
use ui::button::{Button, ButtonVariants};
|
use ui::button::{Button, ButtonVariants};
|
||||||
use ui::{h_flex, v_flex, Icon, IconName, Sizable, StyledExt};
|
use ui::{h_flex, v_flex, Icon, IconName, Sizable, StyledExt};
|
||||||
|
|
||||||
use crate::panels::{connect, import, profile, relay_list};
|
use crate::panels::{connect, import, messaging_relays, profile, relay_list};
|
||||||
use crate::workspace::Workspace;
|
use crate::workspace::Workspace;
|
||||||
|
|
||||||
pub fn init(window: &mut Window, cx: &mut App) -> Entity<GreeterPanel> {
|
pub fn init(window: &mut Window, cx: &mut App) -> Entity<GreeterPanel> {
|
||||||
@@ -166,7 +166,7 @@ impl Render for GreeterPanel {
|
|||||||
.small()
|
.small()
|
||||||
.on_click(move |_ev, window, cx| {
|
.on_click(move |_ev, window, cx| {
|
||||||
Workspace::add_panel(
|
Workspace::add_panel(
|
||||||
import::init(window, cx),
|
messaging_relays::init(window, cx),
|
||||||
DockPlacement::Center,
|
DockPlacement::Center,
|
||||||
window,
|
window,
|
||||||
cx,
|
cx,
|
||||||
|
|||||||
@@ -2,11 +2,12 @@ use std::collections::HashSet;
|
|||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use anyhow::{anyhow, Error};
|
use anyhow::{anyhow, Error};
|
||||||
|
use dock::panel::{Panel, PanelEvent};
|
||||||
use gpui::prelude::FluentBuilder;
|
use gpui::prelude::FluentBuilder;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
div, px, uniform_list, App, AppContext, Context, Entity, InteractiveElement, IntoElement,
|
div, relative, uniform_list, AnyElement, App, AppContext, Context, Entity, EventEmitter,
|
||||||
ParentElement, Render, SharedString, Styled, Subscription, Task, TextAlign, UniformList,
|
FocusHandle, Focusable, InteractiveElement, IntoElement, ParentElement, Render, SharedString,
|
||||||
Window,
|
Styled, Subscription, Task, TextAlign, UniformList, Window,
|
||||||
};
|
};
|
||||||
use nostr_sdk::prelude::*;
|
use nostr_sdk::prelude::*;
|
||||||
use smallvec::{smallvec, SmallVec};
|
use smallvec::{smallvec, SmallVec};
|
||||||
@@ -14,15 +15,21 @@ use state::NostrRegistry;
|
|||||||
use theme::ActiveTheme;
|
use theme::ActiveTheme;
|
||||||
use ui::button::{Button, ButtonVariants};
|
use ui::button::{Button, ButtonVariants};
|
||||||
use ui::input::{InputEvent, InputState, TextInput};
|
use ui::input::{InputEvent, InputState, TextInput};
|
||||||
use ui::{h_flex, v_flex, IconName, Sizable, WindowExtension};
|
use ui::{divider, h_flex, v_flex, IconName, Sizable, StyledExt};
|
||||||
|
|
||||||
pub fn init(window: &mut Window, cx: &mut App) -> Entity<SetupRelay> {
|
pub fn init(window: &mut Window, cx: &mut App) -> Entity<MessagingRelayPanel> {
|
||||||
cx.new(|cx| SetupRelay::new(window, cx))
|
cx.new(|cx| MessagingRelayPanel::new(window, cx))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct SetupRelay {
|
pub struct MessagingRelayPanel {
|
||||||
|
name: SharedString,
|
||||||
|
focus_handle: FocusHandle,
|
||||||
|
|
||||||
|
/// Relay URL input
|
||||||
input: Entity<InputState>,
|
input: Entity<InputState>,
|
||||||
|
|
||||||
|
/// Error message
|
||||||
error: Option<SharedString>,
|
error: Option<SharedString>,
|
||||||
|
|
||||||
// All relays
|
// All relays
|
||||||
@@ -35,13 +42,12 @@ pub struct SetupRelay {
|
|||||||
_tasks: SmallVec<[Task<()>; 1]>,
|
_tasks: SmallVec<[Task<()>; 1]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SetupRelay {
|
impl MessagingRelayPanel {
|
||||||
pub fn new(window: &mut Window, cx: &mut Context<Self>) -> Self {
|
pub fn new(window: &mut Window, cx: &mut Context<Self>) -> Self {
|
||||||
|
let input = cx.new(|cx| InputState::new(window, cx).placeholder("wss://example.com"));
|
||||||
let nostr = NostrRegistry::global(cx);
|
let nostr = NostrRegistry::global(cx);
|
||||||
let client = nostr.read(cx).client();
|
let client = nostr.read(cx).client();
|
||||||
|
|
||||||
let input = cx.new(|cx| InputState::new(window, cx).placeholder("wss://example.com"));
|
|
||||||
|
|
||||||
let mut subscriptions = smallvec![];
|
let mut subscriptions = smallvec![];
|
||||||
let mut tasks = smallvec![];
|
let mut tasks = smallvec![];
|
||||||
|
|
||||||
@@ -64,18 +70,16 @@ impl SetupRelay {
|
|||||||
|
|
||||||
subscriptions.push(
|
subscriptions.push(
|
||||||
// Subscribe to user's input events
|
// Subscribe to user's input events
|
||||||
cx.subscribe_in(
|
cx.subscribe_in(&input, window, move |this, _input, event, window, cx| {
|
||||||
&input,
|
|
||||||
window,
|
|
||||||
move |this: &mut Self, _, event, window, cx| {
|
|
||||||
if let InputEvent::PressEnter { .. } = event {
|
if let InputEvent::PressEnter { .. } = event {
|
||||||
this.add(window, cx);
|
this.add(window, cx);
|
||||||
}
|
}
|
||||||
},
|
}),
|
||||||
),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
|
name: "Update Messaging Relays".into(),
|
||||||
|
focus_handle: cx.focus_handle(),
|
||||||
input,
|
input,
|
||||||
relays: HashSet::new(),
|
relays: HashSet::new(),
|
||||||
error: None,
|
error: None,
|
||||||
@@ -94,8 +98,7 @@ impl SetupRelay {
|
|||||||
.limit(1);
|
.limit(1);
|
||||||
|
|
||||||
if let Some(event) = client.database().query(filter).await?.first_owned() {
|
if let Some(event) = client.database().query(filter).await?.first_owned() {
|
||||||
let urls = nip17::extract_owned_relay_list(event).collect();
|
Ok(nip17::extract_owned_relay_list(event).collect())
|
||||||
Ok(urls)
|
|
||||||
} else {
|
} else {
|
||||||
Err(anyhow!("Not found."))
|
Err(anyhow!("Not found."))
|
||||||
}
|
}
|
||||||
@@ -133,10 +136,9 @@ impl SetupRelay {
|
|||||||
self.error = Some(error.into());
|
self.error = Some(error.into());
|
||||||
cx.notify();
|
cx.notify();
|
||||||
|
|
||||||
// Clear the error message after a delay
|
|
||||||
cx.spawn_in(window, async move |this, cx| {
|
cx.spawn_in(window, async move |this, cx| {
|
||||||
cx.background_executor().timer(Duration::from_secs(2)).await;
|
cx.background_executor().timer(Duration::from_secs(2)).await;
|
||||||
|
// Clear the error message after a delay
|
||||||
this.update(cx, |this, cx| {
|
this.update(cx, |this, cx| {
|
||||||
this.error = None;
|
this.error = None;
|
||||||
cx.notify();
|
cx.notify();
|
||||||
@@ -148,11 +150,7 @@ impl SetupRelay {
|
|||||||
|
|
||||||
pub fn set_relays(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
pub fn set_relays(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||||
if self.relays.is_empty() {
|
if self.relays.is_empty() {
|
||||||
self.set_error(
|
self.set_error("You need to add at least 1 relay", window, cx);
|
||||||
"You need to add at least 1 relay to receive messages from others.",
|
|
||||||
window,
|
|
||||||
cx,
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -160,7 +158,6 @@ impl SetupRelay {
|
|||||||
let client = nostr.read(cx).client();
|
let client = nostr.read(cx).client();
|
||||||
let public_key = nostr.read(cx).identity().read(cx).public_key();
|
let public_key = nostr.read(cx).identity().read(cx).public_key();
|
||||||
let write_relays = nostr.read(cx).write_relays(&public_key, cx);
|
let write_relays = nostr.read(cx).write_relays(&public_key, cx);
|
||||||
|
|
||||||
let relays = self.relays.clone();
|
let relays = self.relays.clone();
|
||||||
|
|
||||||
let task: Task<Result<(), Error>> = cx.background_spawn(async move {
|
let task: Task<Result<(), Error>> = cx.background_spawn(async move {
|
||||||
@@ -192,10 +189,7 @@ impl SetupRelay {
|
|||||||
cx.spawn_in(window, async move |this, cx| {
|
cx.spawn_in(window, async move |this, cx| {
|
||||||
match task.await {
|
match task.await {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
cx.update(|window, cx| {
|
// TODO
|
||||||
window.close_modal(cx);
|
|
||||||
})
|
|
||||||
.ok();
|
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
this.update_in(cx, |this, window, cx| {
|
this.update_in(cx, |this, window, cx| {
|
||||||
@@ -219,7 +213,10 @@ impl SetupRelay {
|
|||||||
let mut items = Vec::new();
|
let mut items = Vec::new();
|
||||||
|
|
||||||
for ix in range {
|
for ix in range {
|
||||||
if let Some(url) = relays.iter().nth(ix) {
|
let Some(url) = relays.iter().nth(ix) else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
items.push(
|
items.push(
|
||||||
div()
|
div()
|
||||||
.id(SharedString::from(url.to_string()))
|
.id(SharedString::from(url.to_string()))
|
||||||
@@ -228,17 +225,15 @@ impl SetupRelay {
|
|||||||
.h_9()
|
.h_9()
|
||||||
.py_0p5()
|
.py_0p5()
|
||||||
.child(
|
.child(
|
||||||
div()
|
h_flex()
|
||||||
.px_2()
|
.px_2()
|
||||||
.h_full()
|
|
||||||
.w_full()
|
|
||||||
.flex()
|
.flex()
|
||||||
.items_center()
|
|
||||||
.justify_between()
|
.justify_between()
|
||||||
.rounded(cx.theme().radius)
|
.rounded(cx.theme().radius)
|
||||||
.bg(cx.theme().elevated_surface_background)
|
.bg(cx.theme().elevated_surface_background)
|
||||||
.text_xs()
|
.child(
|
||||||
.child(SharedString::from(url.to_string()))
|
div().text_sm().child(SharedString::from(url.to_string())),
|
||||||
|
)
|
||||||
.child(
|
.child(
|
||||||
Button::new("remove_{ix}")
|
Button::new("remove_{ix}")
|
||||||
.icon(IconName::Close)
|
.icon(IconName::Close)
|
||||||
@@ -256,39 +251,69 @@ impl SetupRelay {
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
items
|
items
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.w_full()
|
.h_full()
|
||||||
.min_h(px(200.))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_empty(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
|
fn render_empty(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||||
h_flex()
|
h_flex()
|
||||||
|
.mt_2()
|
||||||
.h_20()
|
.h_20()
|
||||||
.mb_2()
|
|
||||||
.justify_center()
|
.justify_center()
|
||||||
|
.border_2()
|
||||||
|
.border_dashed()
|
||||||
|
.border_color(cx.theme().border)
|
||||||
|
.rounded(cx.theme().radius_lg)
|
||||||
.text_sm()
|
.text_sm()
|
||||||
.text_align(TextAlign::Center)
|
.text_align(TextAlign::Center)
|
||||||
.child(SharedString::from("Please add some relays."))
|
.child(SharedString::from("Please add some relays."))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Render for SetupRelay {
|
impl Panel for MessagingRelayPanel {
|
||||||
|
fn panel_id(&self) -> SharedString {
|
||||||
|
self.name.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn title(&self, _cx: &App) -> AnyElement {
|
||||||
|
self.name.clone().into_any_element()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EventEmitter<PanelEvent> for MessagingRelayPanel {}
|
||||||
|
|
||||||
|
impl Focusable for MessagingRelayPanel {
|
||||||
|
fn focus_handle(&self, _: &App) -> gpui::FocusHandle {
|
||||||
|
self.focus_handle.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Render for MessagingRelayPanel {
|
||||||
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 {
|
||||||
v_flex()
|
v_flex()
|
||||||
.gap_3()
|
.size_full()
|
||||||
.text_sm()
|
.items_center()
|
||||||
|
.justify_center()
|
||||||
|
.p_2()
|
||||||
|
.gap_10()
|
||||||
.child(
|
.child(
|
||||||
div()
|
div()
|
||||||
.text_color(cx.theme().text_muted)
|
.text_center()
|
||||||
.child(SharedString::from("In order to receive messages from others, you need to set up at least one Messaging Relay.")),
|
.font_semibold()
|
||||||
|
.line_height(relative(1.25))
|
||||||
|
.child(SharedString::from("Update Messaging Relays")),
|
||||||
)
|
)
|
||||||
.child(
|
.child(
|
||||||
v_flex()
|
v_flex()
|
||||||
|
.w_112()
|
||||||
.gap_2()
|
.gap_2()
|
||||||
|
.text_sm()
|
||||||
|
.child(
|
||||||
|
v_flex()
|
||||||
|
.gap_1p5()
|
||||||
.child(
|
.child(
|
||||||
h_flex()
|
h_flex()
|
||||||
.gap_1()
|
.gap_1()
|
||||||
@@ -321,5 +346,15 @@ impl Render for SetupRelay {
|
|||||||
this.child(self.render_empty(window, cx))
|
this.child(self.render_empty(window, cx))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
.child(divider(cx))
|
||||||
|
.child(
|
||||||
|
Button::new("submit")
|
||||||
|
.label("Update")
|
||||||
|
.primary()
|
||||||
|
.on_click(cx.listener(move |this, _ev, window, cx| {
|
||||||
|
this.set_relays(window, cx);
|
||||||
|
})),
|
||||||
|
),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
pub mod connect;
|
pub mod connect;
|
||||||
pub mod greeter;
|
pub mod greeter;
|
||||||
pub mod import;
|
pub mod import;
|
||||||
|
pub mod messaging_relays;
|
||||||
pub mod profile;
|
pub mod profile;
|
||||||
pub mod relay_list;
|
pub mod relay_list;
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ impl RelayListPanel {
|
|||||||
let public_key = signer.get_public_key().await?;
|
let public_key = signer.get_public_key().await?;
|
||||||
|
|
||||||
let filter = Filter::new()
|
let filter = Filter::new()
|
||||||
.kind(Kind::InboxRelays)
|
.kind(Kind::RelayList)
|
||||||
.author(public_key)
|
.author(public_key)
|
||||||
.limit(1);
|
.limit(1);
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ use ui::context_menu::ContextMenuExt;
|
|||||||
use ui::modal::ModalButtonProps;
|
use ui::modal::ModalButtonProps;
|
||||||
use ui::{h_flex, StyledExt, WindowExtension};
|
use ui::{h_flex, StyledExt, WindowExtension};
|
||||||
|
|
||||||
use crate::views::screening;
|
use crate::dialogs::screening;
|
||||||
|
|
||||||
#[derive(IntoElement)]
|
#[derive(IntoElement)]
|
||||||
pub struct RoomListItem {
|
pub struct RoomListItem {
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ use ui::input::{InputEvent, InputState, TextInput};
|
|||||||
use ui::{h_flex, v_flex, Icon, IconName, Sizable, StyledExt, WindowExtension};
|
use ui::{h_flex, v_flex, Icon, IconName, Sizable, StyledExt, WindowExtension};
|
||||||
|
|
||||||
use crate::actions::{RelayStatus, Reload};
|
use crate::actions::{RelayStatus, Reload};
|
||||||
use crate::views::compose::compose_button;
|
use crate::dialogs::compose::compose_button;
|
||||||
|
|
||||||
mod list_item;
|
mod list_item;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
pub mod compose;
|
|
||||||
pub mod preferences;
|
|
||||||
pub mod screening;
|
|
||||||
pub mod setup_relay;
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
use gpui::{div, App, AppContext, Context, Entity, IntoElement, Render, Window};
|
|
||||||
|
|
||||||
pub fn init(window: &mut Window, cx: &mut App) -> Entity<Preferences> {
|
|
||||||
cx.new(|cx| Preferences::new(window, cx))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Preferences {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Preferences {
|
|
||||||
pub fn new(_window: &mut Window, _cx: &mut App) -> Self {
|
|
||||||
Self {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Render for Preferences {
|
|
||||||
fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
|
|
||||||
div()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -13,17 +13,14 @@ use gpui::{
|
|||||||
use nostr_connect::prelude::*;
|
use nostr_connect::prelude::*;
|
||||||
use person::PersonRegistry;
|
use person::PersonRegistry;
|
||||||
use smallvec::{smallvec, SmallVec};
|
use smallvec::{smallvec, SmallVec};
|
||||||
use theme::{ActiveTheme, Theme, ThemeMode, ThemeRegistry};
|
use theme::{ActiveTheme, Theme, ThemeRegistry};
|
||||||
use ui::button::{Button, ButtonVariants};
|
use ui::button::{Button, ButtonVariants};
|
||||||
use ui::modal::ModalButtonProps;
|
use ui::modal::ModalButtonProps;
|
||||||
use ui::{h_flex, v_flex, Root, Sizable, WindowExtension};
|
use ui::{h_flex, v_flex, Root, Sizable, WindowExtension};
|
||||||
|
|
||||||
use crate::actions::{
|
use crate::actions::{reset, KeyringPopup, Logout, Themes, ViewProfile};
|
||||||
reset, DarkMode, KeyringPopup, Logout, Settings, Themes, ViewProfile, ViewRelays,
|
|
||||||
};
|
|
||||||
use crate::panels::greeter;
|
use crate::panels::greeter;
|
||||||
use crate::user::viewer;
|
use crate::user::viewer;
|
||||||
use crate::views::{preferences, setup_relay};
|
|
||||||
use crate::{sidebar, user};
|
use crate::{sidebar, user};
|
||||||
|
|
||||||
pub fn init(window: &mut Window, cx: &mut App) -> Entity<Workspace> {
|
pub fn init(window: &mut Window, cx: &mut App) -> Entity<Workspace> {
|
||||||
@@ -153,17 +150,6 @@ impl Workspace {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_settings(&mut self, _ev: &Settings, window: &mut Window, cx: &mut Context<Self>) {
|
|
||||||
let view = preferences::init(window, cx);
|
|
||||||
|
|
||||||
window.open_modal(cx, move |modal, _window, _cx| {
|
|
||||||
modal
|
|
||||||
.title(SharedString::from("Preferences"))
|
|
||||||
.width(px(520.))
|
|
||||||
.child(view.clone())
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_profile(&mut self, _ev: &ViewProfile, window: &mut Window, cx: &mut Context<Self>) {
|
fn on_profile(&mut self, _ev: &ViewProfile, window: &mut Window, cx: &mut Context<Self>) {
|
||||||
let view = user::init(window, cx);
|
let view = user::init(window, cx);
|
||||||
let entity = view.downgrade();
|
let entity = view.downgrade();
|
||||||
@@ -211,38 +197,6 @@ impl Workspace {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_relays(&mut self, _ev: &ViewRelays, window: &mut Window, cx: &mut Context<Self>) {
|
|
||||||
let view = setup_relay::init(window, cx);
|
|
||||||
let entity = view.downgrade();
|
|
||||||
|
|
||||||
window.open_modal(cx, move |this, _window, _cx| {
|
|
||||||
let entity = entity.clone();
|
|
||||||
|
|
||||||
this.confirm()
|
|
||||||
.title(SharedString::from("Set Up Messaging Relays"))
|
|
||||||
.child(view.clone())
|
|
||||||
.button_props(ModalButtonProps::default().ok_text("Update"))
|
|
||||||
.on_ok(move |_, window, cx| {
|
|
||||||
entity
|
|
||||||
.update(cx, |this, cx| {
|
|
||||||
this.set_relays(window, cx);
|
|
||||||
})
|
|
||||||
.ok();
|
|
||||||
|
|
||||||
// false to keep the modal open
|
|
||||||
false
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_dark_mode(&mut self, _ev: &DarkMode, window: &mut Window, cx: &mut Context<Self>) {
|
|
||||||
if cx.theme().mode.is_dark() {
|
|
||||||
Theme::change(ThemeMode::Light, Some(window), cx);
|
|
||||||
} else {
|
|
||||||
Theme::change(ThemeMode::Dark, Some(window), cx);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_themes(&mut self, _ev: &Themes, window: &mut Window, cx: &mut Context<Self>) {
|
fn on_themes(&mut self, _ev: &Themes, window: &mut Window, cx: &mut Context<Self>) {
|
||||||
window.open_modal(cx, move |this, _window, cx| {
|
window.open_modal(cx, move |this, _window, cx| {
|
||||||
let registry = ThemeRegistry::global(cx);
|
let registry = ThemeRegistry::global(cx);
|
||||||
@@ -365,10 +319,7 @@ impl Render for Workspace {
|
|||||||
|
|
||||||
div()
|
div()
|
||||||
.id(SharedString::from("workspace"))
|
.id(SharedString::from("workspace"))
|
||||||
.on_action(cx.listener(Self::on_settings))
|
|
||||||
.on_action(cx.listener(Self::on_profile))
|
.on_action(cx.listener(Self::on_profile))
|
||||||
.on_action(cx.listener(Self::on_relays))
|
|
||||||
.on_action(cx.listener(Self::on_dark_mode))
|
|
||||||
.on_action(cx.listener(Self::on_themes))
|
.on_action(cx.listener(Self::on_themes))
|
||||||
.on_action(cx.listener(Self::on_sign_out))
|
.on_action(cx.listener(Self::on_sign_out))
|
||||||
.on_action(cx.listener(Self::on_open_pubkey))
|
.on_action(cx.listener(Self::on_open_pubkey))
|
||||||
|
|||||||
@@ -488,6 +488,18 @@ impl NostrRegistry {
|
|||||||
match res {
|
match res {
|
||||||
Ok(event) => {
|
Ok(event) => {
|
||||||
log::info!("Received relay list event: {event:?}");
|
log::info!("Received relay list event: {event:?}");
|
||||||
|
|
||||||
|
// Construct a filter to continuously receive relay list events
|
||||||
|
let filter = Filter::new()
|
||||||
|
.kind(Kind::RelayList)
|
||||||
|
.author(public_key)
|
||||||
|
.since(Timestamp::now());
|
||||||
|
|
||||||
|
// Subscribe to the relay list events
|
||||||
|
client
|
||||||
|
.subscribe_to(BOOTSTRAP_RELAYS, vec![filter], None)
|
||||||
|
.await?;
|
||||||
|
|
||||||
return Ok(RelayState::Set);
|
return Ok(RelayState::Set);
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
@@ -578,13 +590,23 @@ impl NostrRegistry {
|
|||||||
|
|
||||||
// Stream events from the write relays
|
// Stream events from the write relays
|
||||||
let mut stream = client
|
let mut stream = client
|
||||||
.stream_events_from(urls, vec![filter], Duration::from_secs(TIMEOUT))
|
.stream_events_from(&urls, vec![filter], Duration::from_secs(TIMEOUT))
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
while let Some((_url, res)) = stream.next().await {
|
while let Some((_url, res)) = stream.next().await {
|
||||||
match res {
|
match res {
|
||||||
Ok(event) => {
|
Ok(event) => {
|
||||||
log::info!("Received messaging relays event: {event:?}");
|
log::info!("Received messaging relays event: {event:?}");
|
||||||
|
|
||||||
|
// Construct a filter to continuously receive relay list events
|
||||||
|
let filter = Filter::new()
|
||||||
|
.kind(Kind::InboxRelays)
|
||||||
|
.author(public_key)
|
||||||
|
.since(Timestamp::now());
|
||||||
|
|
||||||
|
// Subscribe to the relay list events
|
||||||
|
client.subscribe_to(&urls, vec![filter], None).await?;
|
||||||
|
|
||||||
return Ok(RelayState::Set);
|
return Ok(RelayState::Set);
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user