feat: use latest nostr sdk
This commit is contained in:
597
src-tauri/Cargo.lock
generated
597
src-tauri/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -29,12 +29,12 @@ tauri-plugin-shell = "2.0.0"
|
||||
tauri-plugin-updater = "2.0.0"
|
||||
tauri-plugin-upload = "2.0.0"
|
||||
tauri-plugin-store = "2.0.0"
|
||||
tauri-plugin-decorum = { git = "https://github.com/clearlysid/tauri-plugin-decorum.git" }
|
||||
tauri-plugin-prevent-default = "0.6"
|
||||
tauri-plugin-theme = "2.1.2"
|
||||
tauri-plugin-decorum = { git = "https://github.com/clearlysid/tauri-plugin-decorum" }
|
||||
tauri-specta = { version = "2.0.0-rc.15", features = ["derive", "typescript"] }
|
||||
|
||||
nostr-sdk = { git = "https://github.com/rust-nostr/nostr", features = ["lmdb"] }
|
||||
nostr-relay-builder = { git = "https://github.com/rust-nostr/nostr" }
|
||||
|
||||
specta = "^2.0.0-rc.20"
|
||||
specta-typescript = "0.0.7"
|
||||
@@ -49,14 +49,11 @@ regex = "1.10.4"
|
||||
keyring = { version = "3", features = ["apple-native", "windows-native"] }
|
||||
keyring-search = "1.2.0"
|
||||
tracing-subscriber = "0.3.18"
|
||||
log = "^0.4"
|
||||
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
cocoa = "0.25.0"
|
||||
objc = "0.2.7"
|
||||
rand = "0.8.5"
|
||||
monitor = { git = "https://github.com/ahkohd/tauri-toolkit", branch = "v2" }
|
||||
tauri-nspanel = { git = "https://github.com/ahkohd/tauri-nspanel", branch = "v2" }
|
||||
border = { git = "https://github.com/ahkohd/tauri-toolkit", branch = "v2" }
|
||||
share-picker = { git = "https://github.com/ahkohd/tauri-toolkit", branch = "v2" }
|
||||
|
||||
[profile.release]
|
||||
codegen-units = 1
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
"store:allow-get",
|
||||
"store:allow-set",
|
||||
"store:allow-delete",
|
||||
"theme:default",
|
||||
{
|
||||
"identifier": "http:default",
|
||||
"allow": [
|
||||
|
||||
@@ -63,6 +63,7 @@
|
||||
"shell:allow-open",
|
||||
"store:default",
|
||||
"prevent-default:default",
|
||||
"theme:default",
|
||||
{
|
||||
"identifier": "http:default",
|
||||
"allow": [
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
{"column":{"identifier":"column","description":"Capability for the column","local":true,"windows":["column-*"],"permissions":["core:resources:default","core:tray:default","os:allow-locale","os:allow-os-type","clipboard-manager:allow-write-text","dialog:allow-open","dialog:allow-ask","dialog:allow-message","fs:allow-read-file","core:menu:default","core:menu:allow-new","core:menu:allow-popup","http:default","shell:allow-open","store:allow-get","store:allow-set","store:allow-delete",{"identifier":"http:default","allow":[{"url":"http://**/"},{"url":"https://**/"}]},{"identifier":"fs:allow-read-text-file","allow":[{"path":"$RESOURCE/locales/*"},{"path":"$RESOURCE/resources/*"}]}],"platforms":["linux","macOS","windows"]},"window":{"identifier":"window","description":"Capability for the desktop","local":true,"windows":["main","panel","settings","search-*","zap-*","event-*","user-*","editor-*","popup-*"],"permissions":["core:path:default","core:event:default","core:window:default","core:app:default","core:resources:default","core:menu:default","core:tray:default","notification:allow-is-permission-granted","notification:allow-request-permission","notification:default","os:allow-locale","os:allow-platform","os:allow-os-type","updater:default","updater:allow-check","updater:allow-download-and-install","core:window:allow-create","core:window:allow-close","core:window:allow-destroy","core:window:allow-set-focus","core:window:allow-center","core:window:allow-minimize","core:window:allow-maximize","core:window:allow-set-size","core:window:allow-start-dragging","core:window:allow-toggle-maximize","decorum:allow-show-snap-overlay","clipboard-manager:allow-write-text","clipboard-manager:allow-read-text","core:webview:allow-create-webview-window","core:webview:allow-create-webview","core:webview:allow-set-webview-size","core:webview:allow-set-webview-position","core:webview:allow-webview-close","dialog:allow-open","dialog:allow-ask","dialog:allow-message","process:allow-restart","process:allow-exit","fs:allow-read-file","core:menu:allow-new","core:menu:allow-popup","shell:allow-open","store:default","prevent-default:default",{"identifier":"http:default","allow":[{"url":"http://**/"},{"url":"https://**/"}]},{"identifier":"fs:allow-read-text-file","allow":[{"path":"$RESOURCE/locales/*"},{"path":"$RESOURCE/resources/*"}]}],"platforms":["macOS","windows"]}}
|
||||
{"column":{"identifier":"column","description":"Capability for the column","local":true,"windows":["column-*"],"permissions":["core:resources:default","core:tray:default","os:allow-locale","os:allow-os-type","clipboard-manager:allow-write-text","dialog:allow-open","dialog:allow-ask","dialog:allow-message","fs:allow-read-file","core:menu:default","core:menu:allow-new","core:menu:allow-popup","http:default","shell:allow-open","store:allow-get","store:allow-set","store:allow-delete","theme:default",{"identifier":"http:default","allow":[{"url":"http://**/"},{"url":"https://**/"}]},{"identifier":"fs:allow-read-text-file","allow":[{"path":"$RESOURCE/locales/*"},{"path":"$RESOURCE/resources/*"}]}],"platforms":["linux","macOS","windows"]},"window":{"identifier":"window","description":"Capability for the desktop","local":true,"windows":["main","panel","settings","search-*","zap-*","event-*","user-*","editor-*","popup-*"],"permissions":["core:path:default","core:event:default","core:window:default","core:app:default","core:resources:default","core:menu:default","core:tray:default","notification:allow-is-permission-granted","notification:allow-request-permission","notification:default","os:allow-locale","os:allow-platform","os:allow-os-type","updater:default","updater:allow-check","updater:allow-download-and-install","core:window:allow-create","core:window:allow-close","core:window:allow-destroy","core:window:allow-set-focus","core:window:allow-center","core:window:allow-minimize","core:window:allow-maximize","core:window:allow-set-size","core:window:allow-start-dragging","core:window:allow-toggle-maximize","decorum:allow-show-snap-overlay","clipboard-manager:allow-write-text","clipboard-manager:allow-read-text","core:webview:allow-create-webview-window","core:webview:allow-create-webview","core:webview:allow-set-webview-size","core:webview:allow-set-webview-position","core:webview:allow-webview-close","dialog:allow-open","dialog:allow-ask","dialog:allow-message","process:allow-restart","process:allow-exit","fs:allow-read-file","core:menu:allow-new","core:menu:allow-popup","shell:allow-open","store:default","prevent-default:default","theme:default",{"identifier":"http:default","allow":[{"url":"http://**/"},{"url":"https://**/"}]},{"identifier":"fs:allow-read-text-file","allow":[{"path":"$RESOURCE/locales/*"},{"path":"$RESOURCE/resources/*"}]}],"platforms":["macOS","windows"]}}
|
||||
@@ -5569,6 +5569,31 @@
|
||||
"type": "string",
|
||||
"const": "store:deny-values"
|
||||
},
|
||||
{
|
||||
"description": "Allow all",
|
||||
"type": "string",
|
||||
"const": "theme:default"
|
||||
},
|
||||
{
|
||||
"description": "Enables the get_theme command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "theme:allow-get-theme"
|
||||
},
|
||||
{
|
||||
"description": "Enables the set_theme command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "theme:allow-set-theme"
|
||||
},
|
||||
{
|
||||
"description": "Denies the get_theme command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "theme:deny-get-theme"
|
||||
},
|
||||
{
|
||||
"description": "Denies the set_theme command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "theme:deny-set-theme"
|
||||
},
|
||||
{
|
||||
"description": "This permission set configures which kind of\nupdater functions are exposed to the frontend.\n\n#### Granted Permissions\n\nThe full workflow from checking for updates to installing them\nis enabled.\n\n",
|
||||
"type": "string",
|
||||
|
||||
@@ -5569,6 +5569,31 @@
|
||||
"type": "string",
|
||||
"const": "store:deny-values"
|
||||
},
|
||||
{
|
||||
"description": "Allow all",
|
||||
"type": "string",
|
||||
"const": "theme:default"
|
||||
},
|
||||
{
|
||||
"description": "Enables the get_theme command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "theme:allow-get-theme"
|
||||
},
|
||||
{
|
||||
"description": "Enables the set_theme command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "theme:allow-set-theme"
|
||||
},
|
||||
{
|
||||
"description": "Denies the get_theme command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "theme:deny-get-theme"
|
||||
},
|
||||
{
|
||||
"description": "Denies the set_theme command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"const": "theme:deny-set-theme"
|
||||
},
|
||||
{
|
||||
"description": "This permission set configures which kind of\nupdater functions are exposed to the frontend.\n\n#### Granted Permissions\n\nThe full workflow from checking for updates to installing them\nis enabled.\n\n",
|
||||
"type": "string",
|
||||
|
||||
@@ -28,6 +28,9 @@ pub async fn watch_account(key: String, state: State<'_, Nostr>) -> Result<Strin
|
||||
|
||||
keyring.set_password("").map_err(|e| e.to_string())?;
|
||||
|
||||
// Run sync for this account
|
||||
// run_sync_for(public_key, app_handle);
|
||||
|
||||
// Update state
|
||||
state.accounts.lock().unwrap().push(bech32.clone());
|
||||
|
||||
@@ -41,27 +44,32 @@ pub async fn import_account(
|
||||
password: String,
|
||||
state: State<'_, Nostr>,
|
||||
) -> Result<String, String> {
|
||||
let (npub, enc_bech32) = match key.starts_with("ncryptsec") {
|
||||
let client = &state.client;
|
||||
|
||||
let (npub, enc_bech32, signer) = match key.starts_with("ncryptsec") {
|
||||
true => {
|
||||
let enc = EncryptedSecretKey::from_bech32(key).map_err(|err| err.to_string())?;
|
||||
let enc_bech32 = enc.to_bech32().map_err(|err| err.to_string())?;
|
||||
let secret_key = enc.to_secret_key(password).map_err(|err| err.to_string())?;
|
||||
let keys = Keys::new(secret_key);
|
||||
let npub = keys.public_key().to_bech32().unwrap();
|
||||
let npub = keys
|
||||
.public_key()
|
||||
.to_bech32()
|
||||
.map_err(|err| err.to_string())?;
|
||||
let signer = NostrSigner::Keys(keys);
|
||||
|
||||
(npub, enc_bech32)
|
||||
(npub, enc_bech32, signer)
|
||||
}
|
||||
false => {
|
||||
let secret_key = SecretKey::from_bech32(key).map_err(|err| err.to_string())?;
|
||||
let keys = Keys::new(secret_key.clone());
|
||||
let npub = keys.public_key().to_bech32().unwrap();
|
||||
|
||||
let signer = NostrSigner::Keys(keys);
|
||||
let enc = EncryptedSecretKey::new(&secret_key, password, 16, KeySecurity::Medium)
|
||||
.map_err(|err| err.to_string())?;
|
||||
|
||||
let enc_bech32 = enc.to_bech32().map_err(|err| err.to_string())?;
|
||||
|
||||
(npub, enc_bech32)
|
||||
(npub, enc_bech32, signer)
|
||||
}
|
||||
};
|
||||
|
||||
@@ -75,6 +83,12 @@ pub async fn import_account(
|
||||
let pwd = serde_json::to_string(&account).map_err(|e| e.to_string())?;
|
||||
keyring.set_password(&pwd).map_err(|e| e.to_string())?;
|
||||
|
||||
// Run sync for this account
|
||||
// run_sync_for(public_key, app_handle);
|
||||
|
||||
// Update signer
|
||||
client.set_signer(Some(signer)).await;
|
||||
|
||||
// Update state
|
||||
state.accounts.lock().unwrap().push(npub.clone());
|
||||
|
||||
@@ -115,6 +129,9 @@ pub async fn connect_account(uri: String, state: State<'_, Nostr>) -> Result<Str
|
||||
let j = serde_json::to_string(&account).map_err(|e| e.to_string())?;
|
||||
let _ = keyring.set_password(&j);
|
||||
|
||||
// Run sync for this account
|
||||
// run_sync_for(public_key, app_handle);
|
||||
|
||||
// Update signer
|
||||
let _ = client.set_signer(Some(signer.into())).await;
|
||||
|
||||
|
||||
@@ -313,8 +313,14 @@ pub async fn publish(
|
||||
let builder =
|
||||
EventBuilder::text_note(content, tags).pow(difficulty.unwrap_or(DEFAULT_DIFFICULTY));
|
||||
|
||||
// Sign event
|
||||
let event = client
|
||||
.sign_event_builder(builder)
|
||||
.await
|
||||
.map_err(|err| err.to_string())?;
|
||||
|
||||
// Publish
|
||||
match client.send_event_builder(builder).await {
|
||||
match client.send_event(event).await {
|
||||
Ok(event_id) => Ok(event_id.to_hex()),
|
||||
Err(err) => Err(err.to_string()),
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ use std::{str::FromStr, time::Duration};
|
||||
use tauri::{Emitter, Manager, State};
|
||||
|
||||
use crate::{
|
||||
common::{get_all_accounts, get_latest_event, get_tags_content, process_event},
|
||||
common::{get_all_accounts, get_latest_event, process_event},
|
||||
Nostr, RichEvent, Settings,
|
||||
};
|
||||
|
||||
@@ -182,10 +182,8 @@ pub async fn is_contact(id: String, state: State<'_, Nostr>) -> Result<bool, Str
|
||||
match client.database().query(vec![filter]).await {
|
||||
Ok(events) => {
|
||||
if let Some(event) = events.into_iter().next() {
|
||||
let hex = public_key.to_hex();
|
||||
let pubkeys = get_tags_content(&event, TagKind::p());
|
||||
|
||||
Ok(pubkeys.iter().any(|i| i == &hex))
|
||||
let pubkeys = event.tags.public_keys().collect::<Vec<_>>();
|
||||
Ok(pubkeys.iter().any(|&i| i == &public_key))
|
||||
} else {
|
||||
Ok(false)
|
||||
}
|
||||
@@ -270,7 +268,7 @@ pub async fn set_group(
|
||||
.authors(public_keys)
|
||||
.limit(500);
|
||||
|
||||
if let Ok(report) = client.reconcile(filter, NegentropyOptions::default()).await {
|
||||
if let Ok(report) = client.sync(filter, NegentropyOptions::default()).await {
|
||||
println!("Received: {}", report.received.len());
|
||||
handle.emit("synchronized", ()).unwrap();
|
||||
};
|
||||
@@ -357,7 +355,7 @@ pub async fn set_interest(
|
||||
.hashtags(hashtags)
|
||||
.limit(500);
|
||||
|
||||
if let Ok(report) = client.reconcile(filter, NegentropyOptions::default()).await {
|
||||
if let Ok(report) = client.sync(filter, NegentropyOptions::default()).await {
|
||||
println!("Received: {}", report.received.len());
|
||||
handle.emit("synchronized", ()).unwrap();
|
||||
};
|
||||
|
||||
@@ -5,7 +5,7 @@ use std::str::FromStr;
|
||||
use tauri::{AppHandle, Manager};
|
||||
use tauri_specta::Event as TauriEvent;
|
||||
|
||||
use crate::{common::get_tags_content, Nostr};
|
||||
use crate::Nostr;
|
||||
|
||||
#[derive(Clone, Serialize, Type, TauriEvent)]
|
||||
pub struct NegentropyEvent {
|
||||
@@ -53,7 +53,7 @@ pub fn run_fast_sync(accounts: Vec<String>, app_handle: AppHandle) {
|
||||
.limit(4);
|
||||
|
||||
if let Ok(report) = client
|
||||
.reconcile_with(&bootstrap_relays, profile, NegentropyOptions::default())
|
||||
.sync_with(&bootstrap_relays, profile, NegentropyOptions::default())
|
||||
.await
|
||||
{
|
||||
NegentropyEvent {
|
||||
@@ -72,7 +72,7 @@ pub fn run_fast_sync(accounts: Vec<String>, app_handle: AppHandle) {
|
||||
.limit(4);
|
||||
|
||||
if let Ok(report) = client
|
||||
.reconcile_with(
|
||||
.sync_with(
|
||||
&bootstrap_relays,
|
||||
contact_list.clone(),
|
||||
NegentropyOptions::default(),
|
||||
@@ -92,16 +92,7 @@ pub fn run_fast_sync(accounts: Vec<String>, app_handle: AppHandle) {
|
||||
if let Ok(events) = client.database().query(vec![contact_list]).await {
|
||||
let pubkeys: Vec<PublicKey> = events
|
||||
.iter()
|
||||
.flat_map(|ev| {
|
||||
let tags = get_tags_content(ev, TagKind::p());
|
||||
tags.into_iter().filter_map(|p| {
|
||||
if let Ok(pk) = PublicKey::from_hex(p) {
|
||||
Some(pk)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
})
|
||||
.flat_map(|ev| ev.tags.public_keys().copied())
|
||||
.collect();
|
||||
|
||||
for chunk in pubkeys.chunks(500) {
|
||||
@@ -119,7 +110,7 @@ pub fn run_fast_sync(accounts: Vec<String>, app_handle: AppHandle) {
|
||||
.limit(1000);
|
||||
|
||||
if let Ok(report) = client
|
||||
.reconcile_with(&bootstrap_relays, events, NegentropyOptions::default())
|
||||
.sync_with(&bootstrap_relays, events, NegentropyOptions::default())
|
||||
.await
|
||||
{
|
||||
NegentropyEvent {
|
||||
@@ -138,7 +129,7 @@ pub fn run_fast_sync(accounts: Vec<String>, app_handle: AppHandle) {
|
||||
.limit(1000);
|
||||
|
||||
if let Ok(report) = client
|
||||
.reconcile_with(&bootstrap_relays, metadata, NegentropyOptions::default())
|
||||
.sync_with(&bootstrap_relays, metadata, NegentropyOptions::default())
|
||||
.await
|
||||
{
|
||||
NegentropyEvent {
|
||||
@@ -162,7 +153,7 @@ pub fn run_fast_sync(accounts: Vec<String>, app_handle: AppHandle) {
|
||||
]);
|
||||
|
||||
if let Ok(report) = client
|
||||
.reconcile_with(&bootstrap_relays, others, NegentropyOptions::default())
|
||||
.sync_with(&bootstrap_relays, others, NegentropyOptions::default())
|
||||
.await
|
||||
{
|
||||
NegentropyEvent {
|
||||
@@ -186,7 +177,7 @@ pub fn run_fast_sync(accounts: Vec<String>, app_handle: AppHandle) {
|
||||
.limit(10000);
|
||||
|
||||
if let Ok(report) = client
|
||||
.reconcile_with(
|
||||
.sync_with(
|
||||
&bootstrap_relays,
|
||||
notification,
|
||||
NegentropyOptions::default(),
|
||||
|
||||
@@ -100,9 +100,12 @@ pub fn update_column(
|
||||
|
||||
#[tauri::command(async)]
|
||||
#[specta::specta]
|
||||
pub fn reload_column(label: String, app_handle: tauri::AppHandle) -> Result<bool, String> {
|
||||
pub fn reload_column(label: String, app_handle: tauri::AppHandle) -> Result<(), String> {
|
||||
match app_handle.get_webview(&label) {
|
||||
Some(webview) => Ok(webview.eval("window.location.reload()").is_ok()),
|
||||
Some(webview) => {
|
||||
webview.eval("location.reload(true)").unwrap();
|
||||
Ok(())
|
||||
}
|
||||
None => Err("Cannot reload, column not found.".into()),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,15 +51,6 @@ pub fn get_latest_event(events: &Events) -> Option<&Event> {
|
||||
events.iter().next()
|
||||
}
|
||||
|
||||
pub fn get_tags_content(event: &Event, kind: TagKind) -> Vec<String> {
|
||||
event
|
||||
.tags
|
||||
.iter()
|
||||
.filter(|t| t.kind() == kind)
|
||||
.filter_map(|t| t.content().map(|content| content.to_string()))
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn create_tags(content: &str) -> Vec<Tag> {
|
||||
let mut tags: Vec<Tag> = vec![];
|
||||
let mut tag_set: HashSet<String> = HashSet::new();
|
||||
|
||||
@@ -13,7 +13,8 @@ use commands::{
|
||||
sync::{run_fast_sync, NegentropyEvent},
|
||||
window::*,
|
||||
};
|
||||
use common::{get_all_accounts, get_tags_content, parse_event};
|
||||
use common::{get_all_accounts, parse_event};
|
||||
use log::info;
|
||||
use nostr_sdk::prelude::{Profile as DatabaseProfile, *};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use specta::Type;
|
||||
@@ -94,9 +95,6 @@ pub const FETCH_LIMIT: usize = 50;
|
||||
pub const NOTIFICATION_SUB_ID: &str = "lume_notification";
|
||||
|
||||
fn main() {
|
||||
#[cfg(debug_assertions)]
|
||||
tracing_subscriber::fmt::init();
|
||||
|
||||
let builder = Builder::<tauri::Wry>::new()
|
||||
// Then register them (separated by a comma)
|
||||
.commands(collect_commands![
|
||||
@@ -171,10 +169,7 @@ fn main() {
|
||||
.export(Typescript::default(), "../src/commands.gen.ts")
|
||||
.expect("Failed to export typescript bindings");
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
let tauri_builder = tauri::Builder::default().plugin(tauri_nspanel::init());
|
||||
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
let mut ctx = tauri::generate_context!();
|
||||
let tauri_builder = tauri::Builder::default();
|
||||
|
||||
tauri_builder
|
||||
@@ -193,13 +188,7 @@ fn main() {
|
||||
.app_config_dir()
|
||||
.expect("Error: app config directory not found.");
|
||||
|
||||
let data_dir = handle
|
||||
.path()
|
||||
.app_data_dir()
|
||||
.expect("Error: app data directory not found.");
|
||||
|
||||
let _ = fs::create_dir_all(&config_dir);
|
||||
let _ = fs::create_dir_all(&data_dir);
|
||||
|
||||
// Set custom decoration for Windows
|
||||
#[cfg(target_os = "windows")]
|
||||
@@ -225,7 +214,7 @@ fn main() {
|
||||
|
||||
let (client, bootstrap_relays) = tauri::async_runtime::block_on(async move {
|
||||
// Setup database
|
||||
let database = NostrLMDB::open(config_dir.join("nostr-lmdb"))
|
||||
let database = NostrLMDB::open(config_dir.join("nostr"))
|
||||
.expect("Error: cannot create database.");
|
||||
|
||||
// Config
|
||||
@@ -234,7 +223,8 @@ fn main() {
|
||||
.max_avg_latency(Duration::from_millis(800))
|
||||
.automatic_authentication(false)
|
||||
.connection_timeout(Some(Duration::from_secs(20)))
|
||||
.send_timeout(Some(Duration::from_secs(20)))
|
||||
.send_timeout(Some(Duration::from_secs(10)))
|
||||
.wait_for_send(false)
|
||||
.timeout(Duration::from_secs(20));
|
||||
|
||||
// Setup nostr client
|
||||
@@ -403,21 +393,6 @@ fn main() {
|
||||
});
|
||||
});
|
||||
|
||||
// Run local relay thread
|
||||
//tauri::async_runtime::spawn(async move {
|
||||
// let database = NostrLMDB::open(data_dir.join("local-relay"))
|
||||
// .expect("Error: cannot create database.");
|
||||
// let builder = RelayBuilder::default().database(database).port(1984);
|
||||
//
|
||||
// if let Ok(relay) = LocalRelay::run(builder).await {
|
||||
// println!("Running local relay: {}", relay.url())
|
||||
// }
|
||||
//
|
||||
// loop {
|
||||
// tokio::time::sleep(Duration::from_secs(60)).await;
|
||||
// }
|
||||
//});
|
||||
|
||||
// Run notification thread
|
||||
tauri::async_runtime::spawn(async move {
|
||||
let state = handle_clone.state::<Nostr>();
|
||||
@@ -465,6 +440,7 @@ fn main() {
|
||||
while let Ok(notification) = notifications.recv().await {
|
||||
match notification {
|
||||
RelayPoolNotification::Message { relay_url, message } => {
|
||||
info!(target: "relay_events", "message: {}", message.as_pretty_json());
|
||||
if let RelayMessage::Auth { challenge } = message {
|
||||
match client.auth(challenge, relay_url.clone()).await {
|
||||
Ok(..) => {
|
||||
@@ -521,7 +497,17 @@ fn main() {
|
||||
event,
|
||||
} = message
|
||||
{
|
||||
let tags = get_tags_content(&event, TagKind::p());
|
||||
let tags: Vec<String> = event
|
||||
.tags
|
||||
.public_keys()
|
||||
.filter_map(|pk| {
|
||||
if let Ok(bech32) = pk.to_bech32() {
|
||||
Some(bech32)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
// Handle events from notification subscription
|
||||
if subscription_id == notification_id
|
||||
@@ -587,6 +573,7 @@ fn main() {
|
||||
Ok(())
|
||||
})
|
||||
.plugin(prevent_default())
|
||||
.plugin(tauri_plugin_theme::init(ctx.config_mut()))
|
||||
.plugin(tauri_plugin_decorum::init())
|
||||
.plugin(tauri_plugin_store::Builder::default().build())
|
||||
.plugin(tauri_plugin_clipboard_manager::init())
|
||||
@@ -600,7 +587,7 @@ fn main() {
|
||||
.plugin(tauri_plugin_upload::init())
|
||||
.plugin(tauri_plugin_updater::Builder::new().build())
|
||||
.plugin(tauri_plugin_window_state::Builder::default().build())
|
||||
.run(tauri::generate_context!())
|
||||
.run(ctx)
|
||||
.expect("error while running tauri application");
|
||||
}
|
||||
|
||||
|
||||
@@ -464,7 +464,7 @@ async updateColumn(label: string, width: number, height: number, x: number, y: n
|
||||
else return { status: "error", error: e as any };
|
||||
}
|
||||
},
|
||||
async reloadColumn(label: string) : Promise<Result<boolean, string>> {
|
||||
async reloadColumn(label: string) : Promise<Result<null, string>> {
|
||||
try {
|
||||
return { status: "ok", data: await TAURI_INVOKE("reload_column", { label }) };
|
||||
} catch (e) {
|
||||
|
||||
@@ -74,6 +74,7 @@ export function Column({ column }: { column: LumeColumn }) {
|
||||
<div className="flex flex-col gap-px size-full">
|
||||
<Header
|
||||
label={column.label}
|
||||
webviewLabel={webviewLabel}
|
||||
name={column.name}
|
||||
account={column.account}
|
||||
/>
|
||||
@@ -85,9 +86,10 @@ export function Column({ column }: { column: LumeColumn }) {
|
||||
|
||||
function Header({
|
||||
label,
|
||||
webviewLabel,
|
||||
name,
|
||||
account,
|
||||
}: { label: string; name: string; account?: string }) {
|
||||
}: { label: string; webviewLabel: string; name: string; account?: string }) {
|
||||
const [title, setTitle] = useState("");
|
||||
const [isChanged, setIsChanged] = useState(false);
|
||||
|
||||
@@ -100,7 +102,7 @@ function Header({
|
||||
MenuItem.new({
|
||||
text: "Reload",
|
||||
action: async () => {
|
||||
await commands.reloadColumn(label);
|
||||
await commands.reloadColumn(webviewLabel);
|
||||
},
|
||||
}),
|
||||
PredefinedMenuItem.new({ item: "Separator" }),
|
||||
|
||||
@@ -137,6 +137,13 @@ function Account({ pubkey }: { pubkey: string }) {
|
||||
e.preventDefault();
|
||||
|
||||
const items = await Promise.all([
|
||||
MenuItem.new({
|
||||
text: "Unlock",
|
||||
enabled: !isActive || true,
|
||||
action: () =>
|
||||
LumeWindow.openPopup(`/set-signer/${pubkey}`, undefined, false),
|
||||
}),
|
||||
PredefinedMenuItem.new({ item: "Separator" }),
|
||||
MenuItem.new({
|
||||
text: "View Profile",
|
||||
action: () => LumeWindow.openProfile(pubkey),
|
||||
|
||||
@@ -26,6 +26,7 @@ export const Route = createLazyFileRoute("/_layout/")({
|
||||
});
|
||||
|
||||
function Screen() {
|
||||
const { accounts } = Route.useRouteContext();
|
||||
const columns = useStore(appColumns, (state) => state);
|
||||
|
||||
const [emblaRef, emblaApi] = useEmblaCarousel({
|
||||
@@ -161,7 +162,10 @@ function Screen() {
|
||||
getSystemColumns();
|
||||
} else {
|
||||
const parsed: LumeColumn[] = JSON.parse(prevColumns);
|
||||
appColumns.setState(() => parsed);
|
||||
const fil = parsed.filter((item) =>
|
||||
item.account ? accounts.includes(item.account) : item,
|
||||
);
|
||||
appColumns.setState(() => fil);
|
||||
}
|
||||
} else {
|
||||
window.localStorage.setItem("columns", JSON.stringify(columns));
|
||||
|
||||
@@ -197,6 +197,10 @@ function Screen() {
|
||||
};
|
||||
|
||||
const submit = async () => {
|
||||
if (!text.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentUser) {
|
||||
const signer = await commands.hasSigner(currentUser);
|
||||
|
||||
|
||||
@@ -174,8 +174,8 @@ export const LumeWindow = {
|
||||
label: `popup-${nanoid()}`,
|
||||
url,
|
||||
title: title ?? "",
|
||||
width: 400,
|
||||
height: 500,
|
||||
width: 360,
|
||||
height: 460,
|
||||
maximizable: false,
|
||||
minimizable: false,
|
||||
hidden_title: !!title,
|
||||
|
||||
Reference in New Issue
Block a user