feat(nostr): integrate nostr
This commit is contained in:
parent
893c2d9ea7
commit
eb0d678521
35
src/app.rs
35
src/app.rs
|
@ -4,23 +4,48 @@ use leptos::*;
|
||||||
use leptos_meta::*;
|
use leptos_meta::*;
|
||||||
use crate::components::{item_form::ItemForm, items_list::ItemsList};
|
use crate::components::{item_form::ItemForm, items_list::ItemsList};
|
||||||
use crate::models::item::Item;
|
use crate::models::item::Item;
|
||||||
|
use crate::nostr::NostrClient;
|
||||||
|
use tokio::sync::mpsc;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
use serde_json;
|
||||||
|
use leptos::spawn_local;
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn App() -> impl IntoView {
|
pub fn App() -> impl IntoView {
|
||||||
provide_meta_context();
|
provide_meta_context();
|
||||||
// Signal to store and update the list of items.
|
// Signal to store and update the list of items.
|
||||||
let (items_signal, set_items) = create_signal(Vec::<Item>::new());
|
let (items_signal, set_items) = create_signal(Vec::<Item>::new());
|
||||||
|
let (tx, mut rx) = mpsc::channel::<String>(100);
|
||||||
|
|
||||||
|
|
||||||
|
spawn_local(async move {
|
||||||
|
//initialize nostr client
|
||||||
|
let nostr_client = NostrClient::new("wss://relay.example.com").await.unwrap();
|
||||||
|
nostr_client.subscribe_to_items(tx.clone()).await.unwrap();
|
||||||
|
|
||||||
|
// Handle incoming events
|
||||||
|
while let Some(content) = rx.recv().await {
|
||||||
|
if let Ok(item) = serde_json::from_str::<Item>(&content) {
|
||||||
|
set_items.update(|items| items.push(item));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Function to handle adding a new item to the list.
|
// Function to handle adding a new item to the list.
|
||||||
let add_item = move |name: String, description: String, tags: Vec<(String, String)>| {
|
let add_item = move |name: String, description: String, tags: Vec<(String, String)>| {
|
||||||
set_items.update(|items| {
|
set_items.update(|items| {
|
||||||
items.push(Item {
|
let item = Item {
|
||||||
id: Uuid::new_v4().to_string(),
|
id: Uuid::new_v4().to_string(),
|
||||||
name,
|
name: name.clone(),
|
||||||
description,
|
description: description.clone(),
|
||||||
tags,
|
tags: tags.clone(),
|
||||||
});
|
};
|
||||||
|
items.push(item);
|
||||||
|
});
|
||||||
|
|
||||||
|
spawn_local(async move {
|
||||||
|
let nostr_client = NostrClient::new("wss://relay.example.com").await.unwrap();
|
||||||
|
nostr_client.publish_item(name, description, tags).await.unwrap();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
pub mod app;
|
pub mod app;
|
||||||
pub mod components;
|
pub mod components;
|
||||||
pub mod models;
|
pub mod models;
|
||||||
|
pub mod nostr;
|
||||||
|
|
||||||
|
|
||||||
#[cfg(feature = "hydrate")]
|
#[cfg(feature = "hydrate")]
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
use nostr_sdk::client::Error;
|
||||||
|
use nostr_sdk::prelude::*;
|
||||||
|
use tokio::sync::mpsc;
|
||||||
|
use nostr_sdk::RelayPoolNotification;
|
||||||
|
|
||||||
|
pub struct NostrClient {
|
||||||
|
client: Client,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NostrClient {
|
||||||
|
pub async fn new(relay_url: &str) -> Result<Self, Error> {
|
||||||
|
let keys = Keys::generate_from_os_random();
|
||||||
|
let client = Client::new(&keys);
|
||||||
|
client.add_relay(relay_url, None).await?;
|
||||||
|
client.connect().await;
|
||||||
|
|
||||||
|
Ok(Self { client })
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn publish_item(
|
||||||
|
&self,
|
||||||
|
name: String,
|
||||||
|
description: String,
|
||||||
|
tags: Vec<(String, String)>
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
let content = serde_json::json!({
|
||||||
|
"name": name,
|
||||||
|
"description": description,
|
||||||
|
"tags": tags
|
||||||
|
});
|
||||||
|
self.client.publish_text_note(content.to_string(), &[]).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn subscribe_to_items(
|
||||||
|
&self,
|
||||||
|
tx: mpsc::Sender<String>
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
let mut notifications = self.client.notifications();
|
||||||
|
tokio::spawn(async move {
|
||||||
|
while let Ok(notification) = notifications.recv().await {
|
||||||
|
if let RelayPoolNotification::Event(_url, event) = notification {
|
||||||
|
let content = event.content.clone();
|
||||||
|
tx.send(content).await.unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue