wip: refactor

This commit is contained in:
2025-01-24 13:30:07 +07:00
parent 272259cd16
commit 3b6541b900
15 changed files with 99 additions and 93 deletions

14
Cargo.lock generated
View File

@@ -1032,6 +1032,18 @@ version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
[[package]]
name = "common"
version = "0.1.0"
dependencies = [
"anyhow",
"chrono",
"gpui",
"itertools 0.13.0",
"nostr-sdk",
"random_name_generator",
]
[[package]]
name = "concurrent-queue"
version = "2.5.0"
@@ -1073,11 +1085,11 @@ version = "0.1.0"
dependencies = [
"anyhow",
"chrono",
"common",
"dirs 5.0.1",
"gpui",
"itertools 0.13.0",
"nostr-sdk",
"random_name_generator",
"reqwest_client",
"rust-embed",
"serde",

View File

@@ -10,6 +10,7 @@ path = "src/main.rs"
[dependencies]
ui = { path = "../ui" }
common = { path = "../common" }
gpui.workspace = true
reqwest_client.workspace = true
@@ -26,4 +27,3 @@ rust-embed.workspace = true
smol.workspace = true
tracing-subscriber = { version = "0.3.18", features = ["fmt"] }
random_name_generator = "0.3.6"

View File

@@ -1,12 +1,15 @@
use asset::Assets;
use constants::{
ALL_MESSAGES_SUB_ID, APP_NAME, FAKE_SIG, KEYRING_SERVICE, METADATA_DELAY, NEW_MESSAGE_SUB_ID,
use common::constants::{
ALL_MESSAGES_SUB_ID, APP_ID, APP_NAME, FAKE_SIG, KEYRING_SERVICE, METADATA_DELAY,
NEW_MESSAGE_SUB_ID,
};
use dirs::config_dir;
use gpui::{
actions, point, px, size, App, AppContext, Bounds, SharedString, TitlebarOptions,
VisualContext, WindowBounds, WindowDecorations, WindowKind, WindowOptions,
VisualContext, WindowBounds, WindowKind, WindowOptions,
};
#[cfg(target_os = "linux")]
use gpui::{WindowBackgroundAppearance, WindowDecorations};
use nostr_sdk::prelude::*;
use states::{app::AppRegistry, chat::ChatRegistry};
use std::{
@@ -24,9 +27,7 @@ use ui::Root;
use views::app::AppView;
mod asset;
mod constants;
mod states;
mod utils;
mod views;
actions!(main_menu, [Quit]);
@@ -38,8 +39,6 @@ static CLIENT: OnceLock<Client> = OnceLock::new();
pub enum Signal {
/// Receive event
Event(Event),
/// Receive metadata
Metadata(PublicKey),
/// Receive EOSE
Eose,
}
@@ -157,11 +156,6 @@ async fn main() {
};
}
}
Kind::Metadata => {
if let Err(e) = signal_tx.send(Signal::Metadata(event.pubkey)).await {
println!("Send error: {}", e)
}
}
_ => {}
}
} else if let RelayMessage::EndOfStoredEvents(subscription_id) = message {
@@ -226,40 +220,6 @@ async fn main() {
// Set quit action
cx.on_action(quit);
cx.spawn(|async_cx| {
let task = cx.read_credentials(KEYRING_SERVICE);
async move {
if let Ok(res) = task.await {
if let Some((npub, secret)) = res {
let public_key = PublicKey::from_bech32(&npub).unwrap();
let hex = String::from_utf8(secret).unwrap();
let keys = Keys::parse(&hex).unwrap();
// Update signer
async_cx
.background_executor()
.spawn(async move { client.set_signer(keys).await })
.detach();
// Update global state
_ = async_cx.update_global::<AppRegistry, _>(|state, cx| {
state.set_user(public_key, cx);
});
} else {
_ = async_cx.update_global::<AppRegistry, _>(|state, _| {
state.set_loading();
});
}
} else {
_ = async_cx.update_global::<AppRegistry, _>(|state, _| {
state.set_loading();
});
}
}
})
.detach();
cx.spawn(|async_cx| async move {
let (tx, rx) = smol::channel::unbounded::<Signal>();
@@ -281,11 +241,6 @@ async fn main() {
chat.init(cx);
});
}
Signal::Metadata(public_key) => {
_ = async_cx.update_global::<AppRegistry, _>(|state, cx| {
state.set_refresh(public_key, cx);
});
}
Signal::Event(event) => {
_ = async_cx.update_global::<ChatRegistry, _>(|state, cx| {
state.receive(event, cx)
@@ -296,8 +251,33 @@ async fn main() {
})
.detach();
// Set window size
let bounds = Bounds::centered(None, size(px(900.0), px(680.0)), cx);
cx.spawn(|async_cx| {
let task = cx.read_credentials(KEYRING_SERVICE);
async move {
if let Ok(Some((npub, secret))) = task.await {
let public_key = PublicKey::from_bech32(&npub).expect("Something wrong.");
let hex = String::from_utf8(secret).expect("Something wrong.");
let keys = Keys::parse(&hex).expect("Something wrong.");
// Update signer
async_cx
.background_executor()
.spawn(async move { client.set_signer(keys).await })
.detach();
// Update global state
_ = async_cx.update_global::<AppRegistry, _>(|state, cx| {
state.set_user(public_key, cx);
});
} else {
_ = async_cx.update_global::<AppRegistry, _>(|state, _| {
state.is_loading = false;
});
}
}
})
.detach();
let opts = WindowOptions {
#[cfg(not(target_os = "linux"))]
@@ -306,8 +286,11 @@ async fn main() {
traffic_light_position: Some(point(px(9.0), px(9.0))),
appears_transparent: true,
}),
window_bounds: Some(WindowBounds::Windowed(bounds)),
window_decorations: Some(WindowDecorations::Client),
window_bounds: Some(WindowBounds::Windowed(Bounds::centered(
None,
size(px(900.0), px(680.0)),
cx,
))),
#[cfg(target_os = "linux")]
window_background: WindowBackgroundAppearance::Transparent,
#[cfg(target_os = "linux")]
@@ -317,11 +300,11 @@ async fn main() {
};
cx.open_window(opts, |cx| {
let app_view = cx.new_view(AppView::new);
cx.set_window_title("Coop");
cx.set_window_title(APP_NAME);
cx.set_app_id(APP_ID);
cx.activate(true);
cx.new_view(|cx| Root::new(app_view.into(), cx))
cx.new_view(|cx| Root::new(cx.new_view(AppView::new).into(), cx))
})
.expect("System error");
});

View File

@@ -1,7 +1,5 @@
use crate::{
constants::{ALL_MESSAGES_SUB_ID, NEW_MESSAGE_SUB_ID},
get_client,
};
use crate::get_client;
use common::constants::{ALL_MESSAGES_SUB_ID, NEW_MESSAGE_SUB_ID};
use gpui::*;
use nostr_sdk::prelude::*;
use std::time::Duration;
@@ -81,10 +79,6 @@ impl AppRegistry {
.detach();
}
pub fn set_loading(&mut self) {
self.is_loading = false
}
pub fn set_user(&mut self, public_key: PublicKey, cx: &mut AppContext) {
self.user.update(cx, |model, cx| {
*model = Some(public_key);
@@ -94,13 +88,6 @@ impl AppRegistry {
self.is_loading = false;
}
pub fn set_refresh(&mut self, public_key: PublicKey, cx: &mut AppContext) {
self.refreshs.update(cx, |this, cx| {
this.push(public_key);
cx.notify();
})
}
pub fn current_user(&self) -> WeakModel<Option<PublicKey>> {
self.user.downgrade()
}

View File

@@ -1,13 +1,12 @@
use crate::{
get_client,
utils::{compare, room_hash},
};
use common::utils::{compare, room_hash};
use gpui::{AppContext, Context, Global, Model, WeakModel};
use itertools::Itertools;
use nostr_sdk::prelude::*;
use room::Room;
use std::cmp::Reverse;
use crate::get_client;
pub mod room;
pub struct Inbox {

View File

@@ -1,4 +1,4 @@
use crate::{
use common::{
constants::IMAGE_SERVICE,
utils::{compare, random_name, room_hash, shorted_public_key},
};

View File

@@ -1,4 +1,5 @@
use crate::{constants::IMAGE_SERVICE, get_client, states::app::AppRegistry};
use crate::{get_client, states::app::AppRegistry};
use common::constants::IMAGE_SERVICE;
use gpui::prelude::FluentBuilder;
use gpui::{
actions, img, Context, IntoElement, Model, ObjectFit, ParentElement, Render, Styled,

View File

@@ -1,10 +1,8 @@
use crate::{
use async_utility::task::spawn;
use common::{
constants::IMAGE_SERVICE,
get_client,
states::chat::room::Room,
utils::{compare, message_time, nip96_upload},
};
use async_utility::task::spawn;
use gpui::{
div, img, list, px, white, AnyElement, AppContext, Context, EventEmitter, Flatten, FocusHandle,
FocusableView, InteractiveElement, IntoElement, ListAlignment, ListState, Model, ObjectFit,
@@ -29,6 +27,8 @@ use ui::{
v_flex, ContextModal, Icon, IconName, Sizable,
};
use crate::{get_client, states::chat::room::Room};
mod message;
#[derive(Clone)]
@@ -363,7 +363,9 @@ impl ChatPanel {
let (tx, rx) = oneshot::channel::<Url>();
spawn(async move {
if let Ok(url) = nip96_upload(file_data).await {
let client = get_client();
if let Ok(url) = nip96_upload(client, file_data).await {
_ = tx.send(url);
}
});

View File

@@ -1,8 +1,10 @@
use crate::{constants::KEYRING_SERVICE, get_client, states::app::AppRegistry};
use common::constants::KEYRING_SERVICE;
use gpui::{div, IntoElement, ParentElement, Render, Styled, View, ViewContext, VisualContext};
use nostr_sdk::prelude::*;
use ui::input::{InputEvent, TextInput};
use crate::{get_client, states::app::AppRegistry};
pub struct Onboarding {
input: View<TextInput>,
}

View File

@@ -4,8 +4,8 @@ use crate::{
app::AppRegistry,
chat::room::{Member, Room},
},
utils::{random_name, room_hash},
};
use common::utils::{random_name, room_hash};
use gpui::{
div, img, impl_internal_actions, px, uniform_list, Context, FocusHandle, InteractiveElement,
IntoElement, Model, ParentElement, Render, SharedString, StatefulInteractiveElement, Styled,

View File

@@ -1,8 +1,8 @@
use crate::{
states::chat::ChatRegistry,
utils::message_ago,
views::app::{AddPanel, PanelKind},
};
use common::utils::message_ago;
use gpui::{
div, img, percentage, prelude::FluentBuilder, px, InteractiveElement, IntoElement,
ParentElement, Render, SharedString, StatefulInteractiveElement, Styled, ViewContext,

14
crates/common/Cargo.toml Normal file
View File

@@ -0,0 +1,14 @@
[package]
name = "common"
version = "0.1.0"
edition = "2021"
publish = false
[dependencies]
gpui.workspace = true
nostr-sdk.workspace = true
anyhow.workspace = true
itertools.workspace = true
chrono.workspace = true
random_name_generator = "0.3.6"

View File

@@ -1,8 +1,13 @@
pub const KEYRING_SERVICE: &str = "Coop Safe Storage";
pub const APP_NAME: &str = "Coop";
pub const APP_ID: &str = "su.reya.coop";
pub const FAKE_SIG: &str = "f9e79d141c004977192d05a86f81ec7c585179c371f7350a5412d33575a2a356433f58e405c2296ed273e2fe0aafa25b641e39cc4e1f3f261ebf55bce0cbac83";
pub const NEW_MESSAGE_SUB_ID: &str = "listen_new_giftwrap";
pub const ALL_MESSAGES_SUB_ID: &str = "listen_all_giftwraps";
pub const METADATA_DELAY: u64 = 200;
/// Image Resizer Service
pub const IMAGE_SERVICE: &str = "https://wsrv.nl";
/// NIP96 Media Server
pub const NIP96_SERVER: &str = "https://nostrcheck.me";

2
crates/common/src/lib.rs Normal file
View File

@@ -0,0 +1,2 @@
pub mod constants;
pub mod utils;

View File

@@ -1,4 +1,4 @@
use crate::{constants::NIP96_SERVER, get_client};
use crate::constants::NIP96_SERVER;
use chrono::{Datelike, Local, TimeZone};
use nostr_sdk::prelude::*;
use rnglib::{Language, RNG};
@@ -7,8 +7,7 @@ use std::{
hash::{DefaultHasher, Hash, Hasher},
};
pub async fn nip96_upload(file: Vec<u8>) -> anyhow::Result<Url, anyhow::Error> {
let client = get_client();
pub async fn nip96_upload(client: &Client, file: Vec<u8>) -> anyhow::Result<Url, anyhow::Error> {
let signer = client.signer().await?;
let server_url = Url::parse(NIP96_SERVER)?;