chore: refactor account and fixes
This commit is contained in:
@@ -31,6 +31,7 @@ impl Account {
|
||||
cx.set_global(GlobalAccount(account));
|
||||
}
|
||||
|
||||
/// Login to the account using the given signer.
|
||||
pub fn login<S>(&mut self, signer: S, window: &mut Window, cx: &mut Context<Self>)
|
||||
where
|
||||
S: NostrSigner + 'static,
|
||||
@@ -56,12 +57,15 @@ impl Account {
|
||||
|
||||
cx.spawn_in(window, async move |this, cx| match task.await {
|
||||
Ok(profile) => {
|
||||
cx.update(|_, cx| {
|
||||
cx.update(|window, cx| {
|
||||
this.update(cx, |this, cx| {
|
||||
this.profile = Some(profile);
|
||||
this.subscribe(cx);
|
||||
cx.notify();
|
||||
this.profile(profile, cx);
|
||||
|
||||
cx.defer_in(window, |this, _, cx| {
|
||||
this.subscribe(cx);
|
||||
});
|
||||
})
|
||||
.ok();
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
@@ -75,28 +79,80 @@ impl Account {
|
||||
.detach();
|
||||
}
|
||||
|
||||
/// Create a new account with the given metadata.
|
||||
pub fn new_account(&mut self, metadata: Metadata, window: &mut Window, cx: &mut Context<Self>) {
|
||||
let client = get_client();
|
||||
const DEFAULT_NIP_65_RELAYS: [&str; 4] = [
|
||||
"wss://relay.damus.io",
|
||||
"wss://relay.primal.net",
|
||||
"wss://relay.nostr.net",
|
||||
"wss://nos.lol",
|
||||
];
|
||||
|
||||
const DEFAULT_MESSAGING_RELAYS: [&str; 2] =
|
||||
["wss://auth.nostr1.com", "wss://relay.0xchat.com"];
|
||||
|
||||
let keys = Keys::generate();
|
||||
let public_key = keys.public_key();
|
||||
|
||||
let task: Task<Result<Profile, Error>> = cx.background_spawn(async move {
|
||||
let public_key = keys.public_key();
|
||||
let client = get_client();
|
||||
|
||||
// Update signer
|
||||
client.set_signer(keys).await;
|
||||
|
||||
// Set metadata
|
||||
client.set_metadata(&metadata).await?;
|
||||
|
||||
// Create relay list
|
||||
let tags: Vec<Tag> = DEFAULT_NIP_65_RELAYS
|
||||
.into_iter()
|
||||
.filter_map(|url| {
|
||||
if let Ok(url) = RelayUrl::parse(url) {
|
||||
Some(Tag::relay_metadata(url, None))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
let builder = EventBuilder::new(Kind::RelayList, "").tags(tags);
|
||||
|
||||
if let Err(e) = client.send_event_builder(builder).await {
|
||||
log::error!("Failed to send relay list event: {}", e);
|
||||
};
|
||||
|
||||
// Create messaging relay list
|
||||
let tags: Vec<Tag> = DEFAULT_MESSAGING_RELAYS
|
||||
.into_iter()
|
||||
.filter_map(|url| {
|
||||
if let Ok(url) = RelayUrl::parse(url) {
|
||||
Some(Tag::relay(url))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
let builder = EventBuilder::new(Kind::InboxRelays, "").tags(tags);
|
||||
|
||||
if let Err(e) = client.send_event_builder(builder).await {
|
||||
log::error!("Failed to send messaging relay list event: {}", e);
|
||||
};
|
||||
|
||||
Ok(Profile::new(public_key, metadata))
|
||||
});
|
||||
|
||||
cx.spawn_in(window, async move |this, cx| {
|
||||
if let Ok(profile) = task.await {
|
||||
cx.update(|_, cx| {
|
||||
cx.update(|window, cx| {
|
||||
this.update(cx, |this, cx| {
|
||||
this.profile = Some(profile);
|
||||
this.subscribe(cx);
|
||||
cx.notify();
|
||||
this.profile(profile, cx);
|
||||
|
||||
cx.defer_in(window, |this, _, cx| {
|
||||
this.subscribe(cx);
|
||||
});
|
||||
})
|
||||
.ok();
|
||||
})
|
||||
.ok();
|
||||
} else {
|
||||
@@ -109,12 +165,18 @@ impl Account {
|
||||
.detach();
|
||||
}
|
||||
|
||||
pub fn subscribe(&self, cx: &Context<Self>) {
|
||||
/// Sets the profile for the account.
|
||||
pub fn profile(&mut self, profile: Profile, cx: &mut Context<Self>) {
|
||||
self.profile = Some(profile);
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
/// Subscribes to the current account's metadata.
|
||||
pub fn subscribe(&self, cx: &mut Context<Self>) {
|
||||
let Some(profile) = self.profile.as_ref() else {
|
||||
return;
|
||||
};
|
||||
|
||||
let client = get_client();
|
||||
let user = profile.public_key();
|
||||
let opts = SubscribeAutoCloseOptions::default().exit_policy(ReqExitPolicy::ExitOnEOSE);
|
||||
|
||||
@@ -145,6 +207,7 @@ impl Account {
|
||||
let new_msg = Filter::new().kind(Kind::GiftWrap).pubkey(user).limit(0);
|
||||
|
||||
let task: Task<Result<(), Error>> = cx.background_spawn(async move {
|
||||
let client = get_client();
|
||||
client.subscribe(metadata, Some(opts)).await?;
|
||||
client.subscribe(data, None).await?;
|
||||
|
||||
|
||||
@@ -337,13 +337,7 @@ impl Room {
|
||||
.author(*pubkey)
|
||||
.limit(1);
|
||||
|
||||
let is_ready = client
|
||||
.database()
|
||||
.query(filter)
|
||||
.await
|
||||
.ok()
|
||||
.and_then(|events| events.first_owned())
|
||||
.is_some();
|
||||
let is_ready = client.database().query(filter).await?.first().is_some();
|
||||
|
||||
result.push((*pubkey, is_ready));
|
||||
}
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
use account::Account;
|
||||
use anyhow::Error;
|
||||
use global::get_client;
|
||||
use gpui::{
|
||||
div, impl_internal_actions, prelude::FluentBuilder, px, App, AppContext, Axis, Context, Entity,
|
||||
InteractiveElement, IntoElement, ParentElement, Render, Styled, Subscription, Window,
|
||||
InteractiveElement, IntoElement, ParentElement, Render, Styled, Subscription, Task, Window,
|
||||
};
|
||||
use nostr_sdk::prelude::*;
|
||||
use serde::Deserialize;
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
use std::sync::Arc;
|
||||
@@ -13,7 +16,7 @@ use ui::{
|
||||
ContextModal, IconName, Root, Sizable, TitleBar,
|
||||
};
|
||||
|
||||
use crate::views::{chat, compose, contacts, profile, relays, welcome};
|
||||
use crate::views::{chat, compose, contacts, login, new_account, profile, relays, welcome};
|
||||
use crate::views::{onboarding, sidebar};
|
||||
|
||||
const MODAL_WIDTH: f32 = 420.;
|
||||
@@ -25,6 +28,16 @@ pub fn init(window: &mut Window, cx: &mut App) -> Entity<ChatSpace> {
|
||||
ChatSpace::new(window, cx)
|
||||
}
|
||||
|
||||
pub fn login(window: &mut Window, cx: &mut App) {
|
||||
let panel = login::init(window, cx);
|
||||
ChatSpace::set_center_panel(panel, window, cx);
|
||||
}
|
||||
|
||||
pub fn new_account(window: &mut Window, cx: &mut App) {
|
||||
let panel = new_account::init(window, cx);
|
||||
ChatSpace::set_center_panel(panel, window, cx);
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Deserialize)]
|
||||
pub enum PanelKind {
|
||||
Room(u64),
|
||||
@@ -37,6 +50,7 @@ pub enum ModalKind {
|
||||
Compose,
|
||||
Contact,
|
||||
Relay,
|
||||
SetupRelay,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Deserialize)]
|
||||
@@ -65,10 +79,17 @@ pub struct ChatSpace {
|
||||
|
||||
impl ChatSpace {
|
||||
pub fn new(window: &mut Window, cx: &mut App) -> Entity<Self> {
|
||||
let account = Account::global(cx);
|
||||
let dock = cx.new(|cx| DockArea::new(window, cx));
|
||||
let dock = cx.new(|cx| {
|
||||
let panel = Arc::new(onboarding::init(window, cx));
|
||||
let center = DockItem::panel(panel);
|
||||
let mut dock = DockArea::new(window, cx);
|
||||
// Initialize the dock area with the center panel
|
||||
dock.set_center(center, window, cx);
|
||||
dock
|
||||
});
|
||||
|
||||
cx.new(|cx| {
|
||||
let account = Account::global(cx);
|
||||
let mut subscriptions = smallvec![];
|
||||
|
||||
subscriptions.push(cx.observe_in(
|
||||
@@ -83,35 +104,17 @@ impl ChatSpace {
|
||||
},
|
||||
));
|
||||
|
||||
let mut this = Self {
|
||||
Self {
|
||||
dock,
|
||||
subscriptions,
|
||||
titlebar: false,
|
||||
};
|
||||
|
||||
if Account::global(cx).read(cx).profile.is_some() {
|
||||
this.open_chats(window, cx);
|
||||
} else {
|
||||
this.open_onboarding(window, cx);
|
||||
}
|
||||
|
||||
this
|
||||
})
|
||||
}
|
||||
|
||||
pub fn set_center_panel<P: PanelView>(panel: P, window: &mut Window, cx: &mut App) {
|
||||
if let Some(Some(root)) = window.root::<Root>() {
|
||||
if let Ok(chatspace) = root.read(cx).view().clone().downcast::<ChatSpace>() {
|
||||
let panel = Arc::new(panel);
|
||||
let center = DockItem::panel(panel);
|
||||
|
||||
chatspace.update(cx, |this, cx| {
|
||||
this.dock.update(cx, |this, cx| {
|
||||
this.set_center(center, window, cx);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
fn show_titlebar(&mut self, cx: &mut Context<Self>) {
|
||||
self.titlebar = true;
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
fn open_onboarding(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||
@@ -147,31 +150,44 @@ impl ChatSpace {
|
||||
this.set_left_dock(left, Some(px(SIDEBAR_WIDTH)), true, window, cx);
|
||||
this.set_center(center, window, cx);
|
||||
});
|
||||
}
|
||||
|
||||
fn show_titlebar(&mut self, cx: &mut Context<Self>) {
|
||||
self.titlebar = true;
|
||||
cx.notify();
|
||||
}
|
||||
cx.defer_in(window, |this, window, cx| {
|
||||
let verify_messaging_relays = this.verify_messaging_relays(cx);
|
||||
|
||||
fn render_appearance_btn(&self, 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)
|
||||
cx.spawn_in(window, async move |_, cx| {
|
||||
if let Ok(status) = verify_messaging_relays.await {
|
||||
if !status {
|
||||
cx.update(|window, cx| {
|
||||
window.dispatch_action(
|
||||
Box::new(ToggleModal {
|
||||
modal: ModalKind::SetupRelay,
|
||||
}),
|
||||
cx,
|
||||
);
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
})
|
||||
.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);
|
||||
}
|
||||
}))
|
||||
.detach();
|
||||
});
|
||||
}
|
||||
|
||||
fn verify_messaging_relays(&self, cx: &App) -> Task<Result<bool, Error>> {
|
||||
cx.background_spawn(async move {
|
||||
let client = get_client();
|
||||
let signer = client.signer().await?;
|
||||
let public_key = signer.get_public_key().await?;
|
||||
|
||||
let filter = Filter::new()
|
||||
.kind(Kind::InboxRelays)
|
||||
.author(public_key)
|
||||
.limit(1);
|
||||
|
||||
let exist = client.database().query(filter).await?.first().is_some();
|
||||
|
||||
Ok(exist)
|
||||
})
|
||||
}
|
||||
|
||||
fn on_panel_action(&mut self, action: &AddPanel, window: &mut Window, cx: &mut Context<Self>) {
|
||||
@@ -235,8 +251,32 @@ impl ChatSpace {
|
||||
.child(relays.clone())
|
||||
});
|
||||
}
|
||||
ModalKind::SetupRelay => {
|
||||
let relays = relays::init(window, cx);
|
||||
|
||||
window.open_modal(cx, move |this, _, _| {
|
||||
this.width(px(MODAL_WIDTH))
|
||||
.title("Your Messaging Relays are not configured")
|
||||
.child(relays.clone())
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
fn set_center_panel<P: PanelView>(panel: P, window: &mut Window, cx: &mut App) {
|
||||
if let Some(Some(root)) = window.root::<Root>() {
|
||||
if let Ok(chatspace) = root.read(cx).view().clone().downcast::<ChatSpace>() {
|
||||
let panel = Arc::new(panel);
|
||||
let center = DockItem::panel(panel);
|
||||
|
||||
chatspace.update(cx, |this, cx| {
|
||||
this.dock.update(cx, |this, cx| {
|
||||
this.set_center(center, window, cx);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for ChatSpace {
|
||||
@@ -266,7 +306,33 @@ impl Render for ChatSpace {
|
||||
.justify_end()
|
||||
.gap_2()
|
||||
.px_2()
|
||||
.child(self.render_appearance_btn(cx)),
|
||||
.child(
|
||||
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,
|
||||
);
|
||||
}
|
||||
})),
|
||||
),
|
||||
),
|
||||
)
|
||||
})
|
||||
@@ -27,7 +27,7 @@ use std::{collections::HashSet, mem, sync::Arc, time::Duration};
|
||||
use ui::{theme::Theme, Root};
|
||||
|
||||
pub(crate) mod asset;
|
||||
pub(crate) mod chat_space;
|
||||
pub(crate) mod chatspace;
|
||||
pub(crate) mod views;
|
||||
|
||||
actions!(coop, [Quit]);
|
||||
@@ -84,7 +84,7 @@ fn main() {
|
||||
};
|
||||
|
||||
let filter = Filter::new()
|
||||
.kind(Kind::ArticlesCurationSet)
|
||||
.kind(Kind::ReleaseArtifactSet)
|
||||
.coordinate(&coordinate)
|
||||
.limit(1);
|
||||
|
||||
@@ -334,7 +334,7 @@ fn main() {
|
||||
})
|
||||
.detach();
|
||||
|
||||
Root::new(chat_space::init(window, cx).into(), window, cx)
|
||||
Root::new(chatspace::init(window, cx).into(), window, cx)
|
||||
})
|
||||
})
|
||||
.expect("Failed to open window. Please restart the application.");
|
||||
|
||||
@@ -178,6 +178,7 @@ impl Login {
|
||||
}
|
||||
} else if content.starts_with("bunker://") {
|
||||
let keys = get_client_keys().to_owned();
|
||||
|
||||
let Ok(uri) = NostrConnectURI::parse(content.as_ref()) else {
|
||||
self.set_error_message("Bunker URL is not valid".to_owned(), cx);
|
||||
self.set_logging_in(false, cx);
|
||||
@@ -196,8 +197,8 @@ impl Login {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
self.set_logging_in(false, cx);
|
||||
window.push_notification(Notification::error(INPUT_INVALID), cx);
|
||||
self.set_logging_in(false, cx);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ use async_utility::task::spawn;
|
||||
use common::nip96_upload;
|
||||
use global::{constants::IMAGE_SERVICE, get_client};
|
||||
use gpui::{
|
||||
div, img, prelude::FluentBuilder, px, relative, AnyElement, App, AppContext, Context, Entity,
|
||||
div, img, prelude::FluentBuilder, relative, AnyElement, App, AppContext, Context, Entity,
|
||||
EventEmitter, Flatten, FocusHandle, Focusable, IntoElement, ParentElement, PathPromptOptions,
|
||||
Render, SharedString, Styled, Window,
|
||||
};
|
||||
@@ -19,9 +19,6 @@ use ui::{
|
||||
Disableable, Icon, IconName, Sizable, Size, StyledExt,
|
||||
};
|
||||
|
||||
const STEAM_ID_DESCRIPTION: &str =
|
||||
"Steam ID is used to get your currently playing game and update your status.";
|
||||
|
||||
pub fn init(window: &mut Window, cx: &mut App) -> Entity<NewAccount> {
|
||||
NewAccount::new(window, cx)
|
||||
}
|
||||
@@ -30,7 +27,6 @@ pub struct NewAccount {
|
||||
name_input: Entity<TextInput>,
|
||||
avatar_input: Entity<TextInput>,
|
||||
bio_input: Entity<TextInput>,
|
||||
steam_input: Entity<TextInput>,
|
||||
is_uploading: bool,
|
||||
is_submitting: bool,
|
||||
// Panel
|
||||
@@ -59,12 +55,6 @@ impl NewAccount {
|
||||
.placeholder("https://example.com/avatar.jpg")
|
||||
});
|
||||
|
||||
let steam_input = cx.new(|cx| {
|
||||
TextInput::new(window, cx)
|
||||
.text_size(Size::Small)
|
||||
.placeholder("76561199810385277")
|
||||
});
|
||||
|
||||
let bio_input = cx.new(|cx| {
|
||||
TextInput::new(window, cx)
|
||||
.text_size(Size::Small)
|
||||
@@ -75,7 +65,6 @@ impl NewAccount {
|
||||
Self {
|
||||
name_input,
|
||||
avatar_input,
|
||||
steam_input,
|
||||
bio_input,
|
||||
is_uploading: false,
|
||||
is_submitting: false,
|
||||
@@ -92,12 +81,8 @@ impl NewAccount {
|
||||
let avatar = self.avatar_input.read(cx).text().to_string();
|
||||
let name = self.name_input.read(cx).text().to_string();
|
||||
let bio = self.bio_input.read(cx).text().to_string();
|
||||
let steam = self.steam_input.read(cx).text().to_string();
|
||||
|
||||
let mut metadata = Metadata::new()
|
||||
.display_name(name)
|
||||
.about(bio)
|
||||
.custom_field("steam", steam);
|
||||
let mut metadata = Metadata::new().display_name(name).about(bio);
|
||||
|
||||
if let Ok(url) = Url::from_str(&avatar) {
|
||||
metadata = metadata.picture(url);
|
||||
@@ -126,6 +111,7 @@ impl NewAccount {
|
||||
this.update(cx, |this, cx| {
|
||||
this.set_uploading(false, cx);
|
||||
})
|
||||
.ok();
|
||||
})
|
||||
.ok();
|
||||
|
||||
@@ -299,21 +285,6 @@ impl Render for NewAccount {
|
||||
.child("Bio:")
|
||||
.child(self.bio_input.clone()),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.flex()
|
||||
.flex_col()
|
||||
.gap_1()
|
||||
.text_sm()
|
||||
.child("Steam ID:")
|
||||
.child(self.steam_input.clone())
|
||||
.child(
|
||||
div()
|
||||
.text_size(px(10.))
|
||||
.text_color(cx.theme().base.step(cx, ColorScaleStep::ELEVEN))
|
||||
.child(STEAM_ID_DESCRIPTION),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.my_2()
|
||||
|
||||
@@ -10,13 +10,7 @@ use ui::{
|
||||
Icon, IconName, StyledExt,
|
||||
};
|
||||
|
||||
use crate::chat_space::ChatSpace;
|
||||
|
||||
use super::{login, new_account};
|
||||
|
||||
const LOGO_URL: &str = "brand/coop.svg";
|
||||
const TITLE: &str = "Welcome to Coop!";
|
||||
const SUBTITLE: &str = "Secure Communication on Nostr.";
|
||||
use crate::chatspace;
|
||||
|
||||
pub fn init(window: &mut Window, cx: &mut App) -> Entity<Onboarding> {
|
||||
Onboarding::new(window, cx)
|
||||
@@ -42,16 +36,6 @@ impl Onboarding {
|
||||
focus_handle: cx.focus_handle(),
|
||||
}
|
||||
}
|
||||
|
||||
fn open_new_account(&self, window: &mut Window, cx: &mut Context<Self>) {
|
||||
let new_account = new_account::init(window, cx);
|
||||
ChatSpace::set_center_panel(new_account, window, cx);
|
||||
}
|
||||
|
||||
fn open_login(&self, window: &mut Window, cx: &mut Context<Self>) {
|
||||
let login = login::init(window, cx);
|
||||
ChatSpace::set_center_panel(login, window, cx);
|
||||
}
|
||||
}
|
||||
|
||||
impl Panel for Onboarding {
|
||||
@@ -74,10 +58,6 @@ impl Panel for Onboarding {
|
||||
fn popup_menu(&self, menu: PopupMenu, _cx: &App) -> PopupMenu {
|
||||
menu.track_focus(&self.focus_handle)
|
||||
}
|
||||
|
||||
fn toolbar_buttons(&self, _window: &Window, _cx: &App) -> Vec<Button> {
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
|
||||
impl EventEmitter<PanelEvent> for Onboarding {}
|
||||
@@ -90,6 +70,9 @@ impl Focusable for Onboarding {
|
||||
|
||||
impl Render for Onboarding {
|
||||
fn render(&mut self, _window: &mut gpui::Window, cx: &mut Context<Self>) -> impl IntoElement {
|
||||
const TITLE: &str = "Welcome to Coop!";
|
||||
const SUBTITLE: &str = "Secure Communication on Nostr.";
|
||||
|
||||
div()
|
||||
.py_4()
|
||||
.size_full()
|
||||
@@ -106,7 +89,7 @@ impl Render for Onboarding {
|
||||
.gap_4()
|
||||
.child(
|
||||
svg()
|
||||
.path(LOGO_URL)
|
||||
.path("brand/coop.svg")
|
||||
.size_16()
|
||||
.text_color(cx.theme().base.step(cx, ColorScaleStep::THREE)),
|
||||
)
|
||||
@@ -139,8 +122,8 @@ impl Render for Onboarding {
|
||||
.label("Start Messaging")
|
||||
.primary()
|
||||
.reverse()
|
||||
.on_click(cx.listener(move |this, _, window, cx| {
|
||||
this.open_new_account(window, cx);
|
||||
.on_click(cx.listener(move |_, _, window, cx| {
|
||||
chatspace::new_account(window, cx);
|
||||
})),
|
||||
)
|
||||
.child(
|
||||
@@ -148,8 +131,8 @@ impl Render for Onboarding {
|
||||
.label("Already have an account? Log in.")
|
||||
.ghost()
|
||||
.underline()
|
||||
.on_click(cx.listener(move |this, _, window, cx| {
|
||||
this.open_login(window, cx);
|
||||
.on_click(cx.listener(move |_, _, window, cx| {
|
||||
chatspace::login(window, cx);
|
||||
})),
|
||||
),
|
||||
)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use anyhow::{anyhow, Error};
|
||||
use anyhow::Error;
|
||||
use global::{constants::NEW_MESSAGE_SUB_ID, get_client};
|
||||
use gpui::{
|
||||
div, prelude::FluentBuilder, px, uniform_list, App, AppContext, Context, Entity, FocusHandle,
|
||||
@@ -41,11 +41,6 @@ impl Relays {
|
||||
});
|
||||
|
||||
let relays = cx.new(|cx| {
|
||||
let relays = vec![
|
||||
RelayUrl::parse("wss://auth.nostr1.com").unwrap(),
|
||||
RelayUrl::parse("wss://relay.0xchat.com").unwrap(),
|
||||
];
|
||||
|
||||
let task: Task<Result<Vec<RelayUrl>, Error>> = cx.background_spawn(async move {
|
||||
let client = get_client();
|
||||
let signer = client.signer().await?;
|
||||
@@ -59,16 +54,18 @@ impl Relays {
|
||||
if let Some(event) = client.database().query(filter).await?.first_owned() {
|
||||
let relays = event
|
||||
.tags
|
||||
.filter_standardized(TagKind::Relay)
|
||||
.filter_map(|t| match t {
|
||||
TagStandard::Relay(url) => Some(url.to_owned()),
|
||||
_ => None,
|
||||
})
|
||||
.filter(TagKind::Relay)
|
||||
.filter_map(|tag| RelayUrl::parse(tag.content()?).ok())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
Ok(relays)
|
||||
} else {
|
||||
Err(anyhow!("Messaging Relays not found."))
|
||||
let relays = vec![
|
||||
RelayUrl::parse("wss://auth.nostr1.com")?,
|
||||
RelayUrl::parse("wss://relay.0xchat.com")?,
|
||||
];
|
||||
|
||||
Ok(relays)
|
||||
}
|
||||
});
|
||||
|
||||
@@ -86,7 +83,7 @@ impl Relays {
|
||||
})
|
||||
.detach();
|
||||
|
||||
relays
|
||||
vec![]
|
||||
});
|
||||
|
||||
cx.new(|cx| {
|
||||
|
||||
@@ -25,7 +25,7 @@ use ui::{
|
||||
IconName, Sizable, StyledExt,
|
||||
};
|
||||
|
||||
use crate::chat_space::{AddPanel, ModalKind, PanelKind, ToggleModal};
|
||||
use crate::chatspace::{AddPanel, ModalKind, PanelKind, ToggleModal};
|
||||
|
||||
mod button;
|
||||
mod folder;
|
||||
|
||||
Reference in New Issue
Block a user