Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0b97248fb8 | ||
|
|
f54f448ecb | ||
|
|
bd1f2b899d | ||
|
|
efd3c83193 | ||
|
|
85fa1e2359 | ||
|
|
cd6ba5884f | ||
|
|
bfed56ba13 | ||
|
|
d1018ba8d1 | ||
|
|
a42542c16e | ||
|
|
26a6ec954c |
+1
-4
@@ -4,10 +4,7 @@
|
|||||||
"enabled": true
|
"enabled": true
|
||||||
},
|
},
|
||||||
"files": {
|
"files": {
|
||||||
"ignore": [
|
"ignore": ["./src/routes.gen.ts", "./src/commands.gen.ts"]
|
||||||
"./src/routes.gen.ts",
|
|
||||||
"./src/commands.gen.ts"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"linter": {
|
"linter": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
|
|||||||
Generated
+10
-11
@@ -2987,8 +2987,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "keyring-search"
|
name = "keyring-search"
|
||||||
version = "1.2.1"
|
version = "1.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/reyamir/keyring-search#59d54e6a28229f09f87b9b043690ee8a1d63221e"
|
||||||
checksum = "8fba83ff0a0efb658afeaaa6de89c7abd3ccd34333f5a36d5dae417334fcd488"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
@@ -3481,7 +3480,7 @@ checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "nostr"
|
name = "nostr"
|
||||||
version = "0.35.0"
|
version = "0.35.0"
|
||||||
source = "git+https://github.com/rust-nostr/nostr#7587fba8ee72041689aa46c1436ecfa73d75d381"
|
source = "git+https://github.com/rust-nostr/nostr#4da48df74e494f8705e4887ce31a63adeba7b47b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aes",
|
"aes",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
@@ -3512,7 +3511,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "nostr-connect"
|
name = "nostr-connect"
|
||||||
version = "0.35.0"
|
version = "0.35.0"
|
||||||
source = "git+https://github.com/rust-nostr/nostr#7587fba8ee72041689aa46c1436ecfa73d75d381"
|
source = "git+https://github.com/rust-nostr/nostr#4da48df74e494f8705e4887ce31a63adeba7b47b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"async-utility",
|
"async-utility",
|
||||||
@@ -3526,7 +3525,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "nostr-database"
|
name = "nostr-database"
|
||||||
version = "0.35.0"
|
version = "0.35.0"
|
||||||
source = "git+https://github.com/rust-nostr/nostr#7587fba8ee72041689aa46c1436ecfa73d75d381"
|
source = "git+https://github.com/rust-nostr/nostr#4da48df74e494f8705e4887ce31a63adeba7b47b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"flatbuffers",
|
"flatbuffers",
|
||||||
@@ -3540,7 +3539,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "nostr-lmdb"
|
name = "nostr-lmdb"
|
||||||
version = "0.35.0"
|
version = "0.35.0"
|
||||||
source = "git+https://github.com/rust-nostr/nostr#7587fba8ee72041689aa46c1436ecfa73d75d381"
|
source = "git+https://github.com/rust-nostr/nostr#4da48df74e494f8705e4887ce31a63adeba7b47b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"heed",
|
"heed",
|
||||||
"nostr",
|
"nostr",
|
||||||
@@ -3553,7 +3552,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "nostr-relay-pool"
|
name = "nostr-relay-pool"
|
||||||
version = "0.35.0"
|
version = "0.35.0"
|
||||||
source = "git+https://github.com/rust-nostr/nostr#7587fba8ee72041689aa46c1436ecfa73d75d381"
|
source = "git+https://github.com/rust-nostr/nostr#4da48df74e494f8705e4887ce31a63adeba7b47b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-utility",
|
"async-utility",
|
||||||
"async-wsocket",
|
"async-wsocket",
|
||||||
@@ -3571,7 +3570,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "nostr-sdk"
|
name = "nostr-sdk"
|
||||||
version = "0.35.0"
|
version = "0.35.0"
|
||||||
source = "git+https://github.com/rust-nostr/nostr#7587fba8ee72041689aa46c1436ecfa73d75d381"
|
source = "git+https://github.com/rust-nostr/nostr#4da48df74e494f8705e4887ce31a63adeba7b47b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-utility",
|
"async-utility",
|
||||||
"atomic-destructor",
|
"atomic-destructor",
|
||||||
@@ -3590,7 +3589,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "nostr-zapper"
|
name = "nostr-zapper"
|
||||||
version = "0.35.0"
|
version = "0.35.0"
|
||||||
source = "git+https://github.com/rust-nostr/nostr#7587fba8ee72041689aa46c1436ecfa73d75d381"
|
source = "git+https://github.com/rust-nostr/nostr#4da48df74e494f8705e4887ce31a63adeba7b47b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"nostr",
|
"nostr",
|
||||||
@@ -3725,7 +3724,7 @@ version = "0.7.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56"
|
checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro-crate 3.2.0",
|
"proc-macro-crate 1.3.1",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.79",
|
"syn 2.0.79",
|
||||||
@@ -3734,7 +3733,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "nwc"
|
name = "nwc"
|
||||||
version = "0.35.0"
|
version = "0.35.0"
|
||||||
source = "git+https://github.com/rust-nostr/nostr#7587fba8ee72041689aa46c1436ecfa73d75d381"
|
source = "git+https://github.com/rust-nostr/nostr#4da48df74e494f8705e4887ce31a63adeba7b47b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"async-utility",
|
"async-utility",
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ futures = "0.3.30"
|
|||||||
linkify = "0.10.0"
|
linkify = "0.10.0"
|
||||||
regex = "1.10.4"
|
regex = "1.10.4"
|
||||||
keyring = { version = "3", features = ["apple-native", "windows-native"] }
|
keyring = { version = "3", features = ["apple-native", "windows-native"] }
|
||||||
keyring-search = "1.2.0"
|
keyring-search = { git = "https://github.com/reyamir/keyring-search" }
|
||||||
tracing-subscriber = { version = "0.3.18", features = ["fmt"] }
|
tracing-subscriber = { version = "0.3.18", features = ["fmt"] }
|
||||||
|
|
||||||
[target.'cfg(target_os = "macos")'.dependencies]
|
[target.'cfg(target_os = "macos")'.dependencies]
|
||||||
|
|||||||
@@ -46,9 +46,7 @@
|
|||||||
"decorum:allow-show-snap-overlay",
|
"decorum:allow-show-snap-overlay",
|
||||||
"clipboard-manager:allow-write-text",
|
"clipboard-manager:allow-write-text",
|
||||||
"clipboard-manager:allow-read-text",
|
"clipboard-manager:allow-read-text",
|
||||||
"dialog:allow-open",
|
"dialog:default",
|
||||||
"dialog:allow-ask",
|
|
||||||
"dialog:allow-message",
|
|
||||||
"process:allow-restart",
|
"process:allow-restart",
|
||||||
"process:allow-exit",
|
"process:allow-exit",
|
||||||
"fs:allow-read-file",
|
"fs:allow-read-file",
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
{"window":{"identifier":"window","description":"Capability for the desktop","local":true,"windows":["*"],"permissions":["core:path:default","core:event:default","core:window:default","core:app:default","core:resources:default","core:menu:default","core:tray:default","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","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","core:menu:allow-new","core:menu:allow-popup","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","decorum:allow-show-snap-overlay","clipboard-manager:allow-write-text","clipboard-manager:allow-read-text","dialog:allow-open","dialog:allow-ask","dialog:allow-message","process:allow-restart","process:allow-exit","fs:allow-read-file","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"]}}
|
{"window":{"identifier":"window","description":"Capability for the desktop","local":true,"windows":["*"],"permissions":["core:path:default","core:event:default","core:window:default","core:app:default","core:resources:default","core:menu:default","core:tray:default","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","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","core:menu:allow-new","core:menu:allow-popup","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","decorum:allow-show-snap-overlay","clipboard-manager:allow-write-text","clipboard-manager:allow-read-text","dialog:default","process:allow-restart","process:allow-exit","fs:allow-read-file","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"]}}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 620 B |
@@ -228,12 +228,6 @@ pub fn open_window(window: NewWindow, app_handle: tauri::AppHandle) -> Result<St
|
|||||||
.transparent(true)
|
.transparent(true)
|
||||||
.decorations(false)
|
.decorations(false)
|
||||||
.closable(window.closable)
|
.closable(window.closable)
|
||||||
.effects(WindowEffectsConfig {
|
|
||||||
state: None,
|
|
||||||
effects: vec![Effect::Mica],
|
|
||||||
radius: None,
|
|
||||||
color: None,
|
|
||||||
})
|
|
||||||
.build()
|
.build()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
|||||||
+155
-107
@@ -18,7 +18,11 @@ use std::{
|
|||||||
str::FromStr,
|
str::FromStr,
|
||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
use tauri::{path::BaseDirectory, Emitter, EventTarget, Listener, Manager};
|
use tauri::{
|
||||||
|
menu::{Menu, MenuItem},
|
||||||
|
path::BaseDirectory,
|
||||||
|
Emitter, EventTarget, Listener, Manager, WebviewWindowBuilder,
|
||||||
|
};
|
||||||
use tauri_plugin_decorum::WebviewWindowExt;
|
use tauri_plugin_decorum::WebviewWindowExt;
|
||||||
use tauri_plugin_notification::{NotificationExt, PermissionState};
|
use tauri_plugin_notification::{NotificationExt, PermissionState};
|
||||||
use tauri_specta::{collect_commands, Builder};
|
use tauri_specta::{collect_commands, Builder};
|
||||||
@@ -30,7 +34,6 @@ pub mod common;
|
|||||||
pub struct Nostr {
|
pub struct Nostr {
|
||||||
client: Client,
|
client: Client,
|
||||||
queue: RwLock<HashSet<PublicKey>>,
|
queue: RwLock<HashSet<PublicKey>>,
|
||||||
is_syncing: RwLock<bool>,
|
|
||||||
settings: RwLock<Settings>,
|
settings: RwLock<Settings>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,7 +71,7 @@ pub const QUEUE_DELAY: u64 = 300;
|
|||||||
pub const NOTIFICATION_SUB_ID: &str = "lume_notification";
|
pub const NOTIFICATION_SUB_ID: &str = "lume_notification";
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
tracing_subscriber::fmt::init();
|
// tracing_subscriber::fmt::init();
|
||||||
|
|
||||||
let builder = Builder::<tauri::Wry>::new().commands(collect_commands![
|
let builder = Builder::<tauri::Wry>::new().commands(collect_commands![
|
||||||
get_relays,
|
get_relays,
|
||||||
@@ -173,6 +176,53 @@ fn main() {
|
|||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
main_window.set_traffic_lights_inset(7.0, 10.0).unwrap();
|
main_window.set_traffic_lights_inset(7.0, 10.0).unwrap();
|
||||||
|
|
||||||
|
// Setup tray menu item
|
||||||
|
let open_i = MenuItem::with_id(app, "open", "Open Lume", true, None::<&str>)?;
|
||||||
|
let quit_i = MenuItem::with_id(app, "quit", "Quit", true, None::<&str>)?;
|
||||||
|
// Create tray menu
|
||||||
|
let menu = Menu::with_items(app, &[&open_i, &quit_i])?;
|
||||||
|
// Get main tray
|
||||||
|
let tray = app.tray_by_id("main").unwrap();
|
||||||
|
// Set menu
|
||||||
|
tray.set_menu(Some(menu)).unwrap();
|
||||||
|
// Listen to tray events
|
||||||
|
tray.on_menu_event(|handle, event| match event.id().as_ref() {
|
||||||
|
"open" => {
|
||||||
|
if let Some(window) = handle.get_window("main") {
|
||||||
|
if window.is_visible().unwrap_or_default() {
|
||||||
|
let _ = window.set_focus();
|
||||||
|
} else {
|
||||||
|
let _ = window.show();
|
||||||
|
let _ = window.set_focus();
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
let window = WebviewWindowBuilder::from_config(
|
||||||
|
handle,
|
||||||
|
handle.config().app.windows.first().unwrap(),
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
.build()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
// Set decoration
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
window.create_overlay_titlebar().unwrap();
|
||||||
|
|
||||||
|
// Restore native border
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
window.add_border(None);
|
||||||
|
|
||||||
|
// Set a custom inset to the traffic lights
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
window.set_traffic_lights_inset(7.0, 10.0).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"quit" => {
|
||||||
|
std::process::exit(0);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
});
|
||||||
|
|
||||||
let client = tauri::async_runtime::block_on(async move {
|
let client = tauri::async_runtime::block_on(async move {
|
||||||
// Setup database
|
// Setup database
|
||||||
let database = NostrLMDB::open(config_dir.join("nostr"))
|
let database = NostrLMDB::open(config_dir.join("nostr"))
|
||||||
@@ -231,110 +281,9 @@ fn main() {
|
|||||||
app.manage(Nostr {
|
app.manage(Nostr {
|
||||||
client,
|
client,
|
||||||
queue: RwLock::new(HashSet::new()),
|
queue: RwLock::new(HashSet::new()),
|
||||||
is_syncing: RwLock::new(false),
|
|
||||||
settings: RwLock::new(Settings::default()),
|
settings: RwLock::new(Settings::default()),
|
||||||
});
|
});
|
||||||
|
|
||||||
// Trigger some actions for window events
|
|
||||||
main_window.on_window_event(move |event| match event {
|
|
||||||
tauri::WindowEvent::Focused(focused) => {
|
|
||||||
if !focused {
|
|
||||||
let handle = handle_clone_event.clone();
|
|
||||||
|
|
||||||
tauri::async_runtime::spawn(async move {
|
|
||||||
let state = handle.state::<Nostr>();
|
|
||||||
let client = &state.client;
|
|
||||||
|
|
||||||
if *state.is_syncing.read().await {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut is_syncing = state.is_syncing.write().await;
|
|
||||||
|
|
||||||
// Mark sync in progress
|
|
||||||
*is_syncing = true;
|
|
||||||
|
|
||||||
let opts = SyncOptions::default();
|
|
||||||
let accounts = get_all_accounts();
|
|
||||||
|
|
||||||
if !accounts.is_empty() {
|
|
||||||
let public_keys: Vec<PublicKey> = accounts
|
|
||||||
.iter()
|
|
||||||
.filter_map(|acc| PublicKey::from_str(acc).ok())
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let filter = Filter::new().pubkeys(public_keys).kinds(vec![
|
|
||||||
Kind::TextNote,
|
|
||||||
Kind::Repost,
|
|
||||||
Kind::Reaction,
|
|
||||||
Kind::ZapReceipt,
|
|
||||||
]);
|
|
||||||
|
|
||||||
if let Ok(output) = client.sync(filter, &opts).await {
|
|
||||||
println!("Received: {}", output.received.len())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let filter = Filter::new().kinds(vec![
|
|
||||||
Kind::TextNote,
|
|
||||||
Kind::Repost,
|
|
||||||
Kind::ContactList,
|
|
||||||
Kind::FollowSet,
|
|
||||||
]);
|
|
||||||
|
|
||||||
// Get all public keys in database
|
|
||||||
if let Ok(events) = client.database().query(vec![filter]).await {
|
|
||||||
let public_keys: HashSet<PublicKey> = events
|
|
||||||
.iter()
|
|
||||||
.flat_map(|ev| ev.tags.public_keys().copied())
|
|
||||||
.collect();
|
|
||||||
let pk_vec: Vec<PublicKey> = public_keys.into_iter().collect();
|
|
||||||
|
|
||||||
for chunk in pk_vec.chunks(500) {
|
|
||||||
if chunk.is_empty() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let authors = chunk.to_owned();
|
|
||||||
|
|
||||||
let filter = Filter::new()
|
|
||||||
.authors(authors.clone())
|
|
||||||
.kinds(vec![
|
|
||||||
Kind::Metadata,
|
|
||||||
Kind::FollowSet,
|
|
||||||
Kind::Interests,
|
|
||||||
Kind::InterestSet,
|
|
||||||
])
|
|
||||||
.limit(1000);
|
|
||||||
|
|
||||||
if let Ok(output) = client.sync(filter, &opts).await {
|
|
||||||
println!("Received: {}", output.received.len())
|
|
||||||
}
|
|
||||||
|
|
||||||
let filter = Filter::new()
|
|
||||||
.authors(authors)
|
|
||||||
.kinds(vec![
|
|
||||||
Kind::TextNote,
|
|
||||||
Kind::Repost,
|
|
||||||
Kind::EventDeletion,
|
|
||||||
])
|
|
||||||
.limit(500);
|
|
||||||
|
|
||||||
if let Ok(output) = client.sync(filter, &opts).await {
|
|
||||||
println!("Received: {}", output.received.len())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mark sync is done
|
|
||||||
*is_syncing = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tauri::WindowEvent::Moved(_size) => {}
|
|
||||||
_ => {}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Listen for request metadata
|
// Listen for request metadata
|
||||||
app.listen_any("request_metadata", move |event| {
|
app.listen_any("request_metadata", move |event| {
|
||||||
let payload = event.payload();
|
let payload = event.payload();
|
||||||
@@ -379,7 +328,101 @@ fn main() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Run notification thread
|
// Run a thread for negentropy
|
||||||
|
tauri::async_runtime::spawn(async move {
|
||||||
|
let state = handle_clone_event.state::<Nostr>();
|
||||||
|
let client = &state.client;
|
||||||
|
|
||||||
|
// Use default sync options
|
||||||
|
let opts = SyncOptions::default();
|
||||||
|
|
||||||
|
// Set interval
|
||||||
|
let mut interval = tokio::time::interval(tokio::time::Duration::from_secs(600));
|
||||||
|
|
||||||
|
loop {
|
||||||
|
interval.tick().await;
|
||||||
|
|
||||||
|
let accounts = get_all_accounts();
|
||||||
|
let public_keys: Vec<PublicKey> = accounts
|
||||||
|
.iter()
|
||||||
|
.filter_map(|acc| PublicKey::from_str(acc).ok())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
if !public_keys.is_empty() {
|
||||||
|
// Create filter for notification
|
||||||
|
//
|
||||||
|
let filter = Filter::new().pubkeys(public_keys.clone()).kinds(vec![
|
||||||
|
Kind::TextNote,
|
||||||
|
Kind::Repost,
|
||||||
|
Kind::Reaction,
|
||||||
|
Kind::ZapReceipt,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Sync notification
|
||||||
|
//
|
||||||
|
if let Ok(output) = client.sync(filter, &opts).await {
|
||||||
|
println!("Received: {}", output.received.len())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create filter for contact list
|
||||||
|
//
|
||||||
|
let filter = Filter::new()
|
||||||
|
.authors(public_keys)
|
||||||
|
.kinds(vec![Kind::ContactList, Kind::FollowSet]);
|
||||||
|
|
||||||
|
// Sync events for contact list
|
||||||
|
//
|
||||||
|
if let Ok(events) = client.database().query(vec![filter]).await {
|
||||||
|
// Get unique public keys
|
||||||
|
let public_keys: HashSet<PublicKey> = events
|
||||||
|
.iter()
|
||||||
|
.flat_map(|ev| ev.tags.public_keys().copied())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
// Convert to vector
|
||||||
|
let public_keys: Vec<PublicKey> = public_keys.into_iter().collect();
|
||||||
|
|
||||||
|
for chunk in public_keys.chunks(1000) {
|
||||||
|
if chunk.is_empty() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let authors = chunk.to_owned();
|
||||||
|
|
||||||
|
// Create filter for metadata
|
||||||
|
//
|
||||||
|
let filter = Filter::new().authors(authors.clone()).kinds(vec![
|
||||||
|
Kind::Metadata,
|
||||||
|
Kind::FollowSet,
|
||||||
|
Kind::Interests,
|
||||||
|
Kind::InterestSet,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Sync metadata
|
||||||
|
//
|
||||||
|
if let Ok(output) = client.sync(filter, &opts).await {
|
||||||
|
println!("Received: {}", output.received.len())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create filter for text note
|
||||||
|
//
|
||||||
|
let filter = Filter::new()
|
||||||
|
.authors(authors)
|
||||||
|
.kinds(vec![Kind::TextNote, Kind::Repost, Kind::EventDeletion])
|
||||||
|
.limit(100);
|
||||||
|
|
||||||
|
// Sync text note
|
||||||
|
//
|
||||||
|
if let Ok(output) = client.sync(filter, &opts).await {
|
||||||
|
println!("Received: {}", output.received.len())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Run a thread for handle notification
|
||||||
tauri::async_runtime::spawn(async move {
|
tauri::async_runtime::spawn(async move {
|
||||||
let state = handle_clone.state::<Nostr>();
|
let state = handle_clone.state::<Nostr>();
|
||||||
let client = &state.client;
|
let client = &state.client;
|
||||||
@@ -499,8 +542,13 @@ fn main() {
|
|||||||
.plugin(tauri_plugin_upload::init())
|
.plugin(tauri_plugin_upload::init())
|
||||||
.plugin(tauri_plugin_updater::Builder::new().build())
|
.plugin(tauri_plugin_updater::Builder::new().build())
|
||||||
.plugin(tauri_plugin_window_state::Builder::default().build())
|
.plugin(tauri_plugin_window_state::Builder::default().build())
|
||||||
.run(ctx)
|
.build(ctx)
|
||||||
.expect("error while running tauri application");
|
.expect("error while running tauri application")
|
||||||
|
.run(|_app_handle, event| {
|
||||||
|
if let tauri::RunEvent::ExitRequested { api, .. } = event {
|
||||||
|
api.prevent_exit();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"$schema": "../node_modules/@tauri-apps/cli/config.schema.json",
|
"$schema": "../node_modules/@tauri-apps/cli/config.schema.json",
|
||||||
"productName": "Lume",
|
"productName": "Lume",
|
||||||
"version": "24.11.0",
|
"version": "24.11.3",
|
||||||
"identifier": "nu.lume.Lume",
|
"identifier": "nu.lume.Lume",
|
||||||
"build": {
|
"build": {
|
||||||
"beforeDevCommand": "pnpm dev",
|
"beforeDevCommand": "pnpm dev",
|
||||||
@@ -30,6 +30,13 @@
|
|||||||
"$RESOURCE/*"
|
"$RESOURCE/*"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"trayIcon": {
|
||||||
|
"id": "main",
|
||||||
|
"iconAsTemplate": true,
|
||||||
|
"menuOnLeftClick": true,
|
||||||
|
"tooltip": "Lume",
|
||||||
|
"iconPath": "./icons/tray.png"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"bundle": {
|
"bundle": {
|
||||||
|
|||||||
@@ -13,9 +13,7 @@
|
|||||||
"hiddenTitle": true,
|
"hiddenTitle": true,
|
||||||
"transparent": true,
|
"transparent": true,
|
||||||
"windowEffects": {
|
"windowEffects": {
|
||||||
"effects": [
|
"effects": ["underWindowBackground"]
|
||||||
"underWindowBackground"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -10,12 +10,7 @@
|
|||||||
"minWidth": 480,
|
"minWidth": 480,
|
||||||
"minHeight": 700,
|
"minHeight": 700,
|
||||||
"transparent": true,
|
"transparent": true,
|
||||||
"decorations": false,
|
"decorations": false
|
||||||
"windowEffects": {
|
|
||||||
"effects": [
|
|
||||||
"mica"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-38
@@ -3,11 +3,9 @@ import type {
|
|||||||
MaybePromise,
|
MaybePromise,
|
||||||
PersistedQuery,
|
PersistedQuery,
|
||||||
} from "@tanstack/query-persist-client-core";
|
} from "@tanstack/query-persist-client-core";
|
||||||
import { ask, message, open } from "@tauri-apps/plugin-dialog";
|
import { open } from "@tauri-apps/plugin-dialog";
|
||||||
import { readFile } from "@tauri-apps/plugin-fs";
|
import { readFile } from "@tauri-apps/plugin-fs";
|
||||||
import { relaunch } from "@tauri-apps/plugin-process";
|
|
||||||
import type { Store as TauriStore } from "@tauri-apps/plugin-store";
|
import type { Store as TauriStore } from "@tauri-apps/plugin-store";
|
||||||
import { check } from "@tauri-apps/plugin-updater";
|
|
||||||
import { BitcoinUnit } from "bitcoin-units";
|
import { BitcoinUnit } from "bitcoin-units";
|
||||||
import { type ClassValue, clsx } from "clsx";
|
import { type ClassValue, clsx } from "clsx";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
@@ -170,41 +168,6 @@ export function decodeZapInvoice(tags: string[][]) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function checkForAppUpdates(silent: boolean) {
|
|
||||||
const update = await check();
|
|
||||||
|
|
||||||
if (!update) {
|
|
||||||
if (silent) return;
|
|
||||||
|
|
||||||
await message("You are on the latest version. Stay awesome!", {
|
|
||||||
title: "No Update Available",
|
|
||||||
kind: "info",
|
|
||||||
okLabel: "OK",
|
|
||||||
});
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (update?.available) {
|
|
||||||
const yes = await ask(
|
|
||||||
`Update to ${update.version} is available!\n\nRelease notes: ${update.body}`,
|
|
||||||
{
|
|
||||||
title: "Update Available",
|
|
||||||
kind: "info",
|
|
||||||
okLabel: "Update",
|
|
||||||
cancelLabel: "Cancel",
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
if (yes) {
|
|
||||||
await update.downloadAndInstall();
|
|
||||||
await relaunch();
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function upload(filePath?: string) {
|
export async function upload(filePath?: string) {
|
||||||
const allowExts = [
|
const allowExts = [
|
||||||
"png",
|
"png",
|
||||||
|
|||||||
@@ -160,7 +160,7 @@ function Header({
|
|||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={(e) => showContextMenu(e)}
|
onClick={(e) => showContextMenu(e)}
|
||||||
className="hidden shrink-0 group-hover:inline-flex items-center justify-center size-6 border-[.5px] border-neutral-200 dark:border-neutral-800 shadow shadow-neutral-200/50 dark:shadow-none rounded-full bg-white dark:bg-black"
|
className="hidden shrink-0 group-hover:inline-flex items-center justify-center size-6 bg-white dark:bg-neutral-800 border-[.5px] border-neutral-200 dark:border-neutral-800 shadow shadow-neutral-200/50 dark:shadow-none rounded-full"
|
||||||
>
|
>
|
||||||
<CaretDown className="size-3" weight="bold" />
|
<CaretDown className="size-3" weight="bold" />
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
+29
-31
@@ -31,6 +31,7 @@ import { Route as ColumnsLayoutStoriesIdImport } from './routes/columns/_layout/
|
|||||||
import { Route as ColumnsLayoutNewsfeedIdImport } from './routes/columns/_layout/newsfeed.$id'
|
import { Route as ColumnsLayoutNewsfeedIdImport } from './routes/columns/_layout/newsfeed.$id'
|
||||||
import { Route as ColumnsLayoutInterestsIdImport } from './routes/columns/_layout/interests.$id'
|
import { Route as ColumnsLayoutInterestsIdImport } from './routes/columns/_layout/interests.$id'
|
||||||
import { Route as ColumnsLayoutGroupsIdImport } from './routes/columns/_layout/groups.$id'
|
import { Route as ColumnsLayoutGroupsIdImport } from './routes/columns/_layout/groups.$id'
|
||||||
|
import { Route as ColumnsLayoutEventsIdImport } from './routes/columns/_layout/events.$id'
|
||||||
import { Route as ColumnsLayoutCreateNewsfeedUsersImport } from './routes/columns/_layout/create-newsfeed.users'
|
import { Route as ColumnsLayoutCreateNewsfeedUsersImport } from './routes/columns/_layout/create-newsfeed.users'
|
||||||
import { Route as ColumnsLayoutCreateNewsfeedF2fImport } from './routes/columns/_layout/create-newsfeed.f2f'
|
import { Route as ColumnsLayoutCreateNewsfeedF2fImport } from './routes/columns/_layout/create-newsfeed.f2f'
|
||||||
|
|
||||||
@@ -75,9 +76,6 @@ const ColumnsLayoutNotificationIdLazyImport = createFileRoute(
|
|||||||
const ColumnsLayoutLaunchpadIdLazyImport = createFileRoute(
|
const ColumnsLayoutLaunchpadIdLazyImport = createFileRoute(
|
||||||
'/columns/_layout/launchpad/$id',
|
'/columns/_layout/launchpad/$id',
|
||||||
)()
|
)()
|
||||||
const ColumnsLayoutEventsIdLazyImport = createFileRoute(
|
|
||||||
'/columns/_layout/events/$id',
|
|
||||||
)()
|
|
||||||
|
|
||||||
// Create/Update Routes
|
// Create/Update Routes
|
||||||
|
|
||||||
@@ -326,14 +324,6 @@ const ColumnsLayoutLaunchpadIdLazyRoute =
|
|||||||
import('./routes/columns/_layout/launchpad.$id.lazy').then((d) => d.Route),
|
import('./routes/columns/_layout/launchpad.$id.lazy').then((d) => d.Route),
|
||||||
)
|
)
|
||||||
|
|
||||||
const ColumnsLayoutEventsIdLazyRoute = ColumnsLayoutEventsIdLazyImport.update({
|
|
||||||
id: '/events/$id',
|
|
||||||
path: '/events/$id',
|
|
||||||
getParentRoute: () => ColumnsLayoutRoute,
|
|
||||||
} as any).lazy(() =>
|
|
||||||
import('./routes/columns/_layout/events.$id.lazy').then((d) => d.Route),
|
|
||||||
)
|
|
||||||
|
|
||||||
const ColumnsLayoutStoriesIdRoute = ColumnsLayoutStoriesIdImport.update({
|
const ColumnsLayoutStoriesIdRoute = ColumnsLayoutStoriesIdImport.update({
|
||||||
id: '/stories/$id',
|
id: '/stories/$id',
|
||||||
path: '/stories/$id',
|
path: '/stories/$id',
|
||||||
@@ -366,6 +356,14 @@ const ColumnsLayoutGroupsIdRoute = ColumnsLayoutGroupsIdImport.update({
|
|||||||
import('./routes/columns/_layout/groups.$id.lazy').then((d) => d.Route),
|
import('./routes/columns/_layout/groups.$id.lazy').then((d) => d.Route),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const ColumnsLayoutEventsIdRoute = ColumnsLayoutEventsIdImport.update({
|
||||||
|
id: '/events/$id',
|
||||||
|
path: '/events/$id',
|
||||||
|
getParentRoute: () => ColumnsLayoutRoute,
|
||||||
|
} as any).lazy(() =>
|
||||||
|
import('./routes/columns/_layout/events.$id.lazy').then((d) => d.Route),
|
||||||
|
)
|
||||||
|
|
||||||
const ColumnsLayoutCreateNewsfeedUsersRoute =
|
const ColumnsLayoutCreateNewsfeedUsersRoute =
|
||||||
ColumnsLayoutCreateNewsfeedUsersImport.update({
|
ColumnsLayoutCreateNewsfeedUsersImport.update({
|
||||||
id: '/users',
|
id: '/users',
|
||||||
@@ -580,6 +578,13 @@ declare module '@tanstack/react-router' {
|
|||||||
preLoaderRoute: typeof ColumnsLayoutCreateNewsfeedUsersImport
|
preLoaderRoute: typeof ColumnsLayoutCreateNewsfeedUsersImport
|
||||||
parentRoute: typeof ColumnsLayoutCreateNewsfeedImport
|
parentRoute: typeof ColumnsLayoutCreateNewsfeedImport
|
||||||
}
|
}
|
||||||
|
'/columns/_layout/events/$id': {
|
||||||
|
id: '/columns/_layout/events/$id'
|
||||||
|
path: '/events/$id'
|
||||||
|
fullPath: '/columns/events/$id'
|
||||||
|
preLoaderRoute: typeof ColumnsLayoutEventsIdImport
|
||||||
|
parentRoute: typeof ColumnsLayoutImport
|
||||||
|
}
|
||||||
'/columns/_layout/groups/$id': {
|
'/columns/_layout/groups/$id': {
|
||||||
id: '/columns/_layout/groups/$id'
|
id: '/columns/_layout/groups/$id'
|
||||||
path: '/groups/$id'
|
path: '/groups/$id'
|
||||||
@@ -608,13 +613,6 @@ declare module '@tanstack/react-router' {
|
|||||||
preLoaderRoute: typeof ColumnsLayoutStoriesIdImport
|
preLoaderRoute: typeof ColumnsLayoutStoriesIdImport
|
||||||
parentRoute: typeof ColumnsLayoutImport
|
parentRoute: typeof ColumnsLayoutImport
|
||||||
}
|
}
|
||||||
'/columns/_layout/events/$id': {
|
|
||||||
id: '/columns/_layout/events/$id'
|
|
||||||
path: '/events/$id'
|
|
||||||
fullPath: '/columns/events/$id'
|
|
||||||
preLoaderRoute: typeof ColumnsLayoutEventsIdLazyImport
|
|
||||||
parentRoute: typeof ColumnsLayoutImport
|
|
||||||
}
|
|
||||||
'/columns/_layout/launchpad/$id': {
|
'/columns/_layout/launchpad/$id': {
|
||||||
id: '/columns/_layout/launchpad/$id'
|
id: '/columns/_layout/launchpad/$id'
|
||||||
path: '/launchpad/$id'
|
path: '/launchpad/$id'
|
||||||
@@ -691,11 +689,11 @@ interface ColumnsLayoutRouteChildren {
|
|||||||
ColumnsLayoutOnboardingLazyRoute: typeof ColumnsLayoutOnboardingLazyRoute
|
ColumnsLayoutOnboardingLazyRoute: typeof ColumnsLayoutOnboardingLazyRoute
|
||||||
ColumnsLayoutSearchLazyRoute: typeof ColumnsLayoutSearchLazyRoute
|
ColumnsLayoutSearchLazyRoute: typeof ColumnsLayoutSearchLazyRoute
|
||||||
ColumnsLayoutTrendingLazyRoute: typeof ColumnsLayoutTrendingLazyRoute
|
ColumnsLayoutTrendingLazyRoute: typeof ColumnsLayoutTrendingLazyRoute
|
||||||
|
ColumnsLayoutEventsIdRoute: typeof ColumnsLayoutEventsIdRoute
|
||||||
ColumnsLayoutGroupsIdRoute: typeof ColumnsLayoutGroupsIdRoute
|
ColumnsLayoutGroupsIdRoute: typeof ColumnsLayoutGroupsIdRoute
|
||||||
ColumnsLayoutInterestsIdRoute: typeof ColumnsLayoutInterestsIdRoute
|
ColumnsLayoutInterestsIdRoute: typeof ColumnsLayoutInterestsIdRoute
|
||||||
ColumnsLayoutNewsfeedIdRoute: typeof ColumnsLayoutNewsfeedIdRoute
|
ColumnsLayoutNewsfeedIdRoute: typeof ColumnsLayoutNewsfeedIdRoute
|
||||||
ColumnsLayoutStoriesIdRoute: typeof ColumnsLayoutStoriesIdRoute
|
ColumnsLayoutStoriesIdRoute: typeof ColumnsLayoutStoriesIdRoute
|
||||||
ColumnsLayoutEventsIdLazyRoute: typeof ColumnsLayoutEventsIdLazyRoute
|
|
||||||
ColumnsLayoutLaunchpadIdLazyRoute: typeof ColumnsLayoutLaunchpadIdLazyRoute
|
ColumnsLayoutLaunchpadIdLazyRoute: typeof ColumnsLayoutLaunchpadIdLazyRoute
|
||||||
ColumnsLayoutNotificationIdLazyRoute: typeof ColumnsLayoutNotificationIdLazyRoute
|
ColumnsLayoutNotificationIdLazyRoute: typeof ColumnsLayoutNotificationIdLazyRoute
|
||||||
ColumnsLayoutRelaysUrlLazyRoute: typeof ColumnsLayoutRelaysUrlLazyRoute
|
ColumnsLayoutRelaysUrlLazyRoute: typeof ColumnsLayoutRelaysUrlLazyRoute
|
||||||
@@ -715,11 +713,11 @@ const ColumnsLayoutRouteChildren: ColumnsLayoutRouteChildren = {
|
|||||||
ColumnsLayoutOnboardingLazyRoute: ColumnsLayoutOnboardingLazyRoute,
|
ColumnsLayoutOnboardingLazyRoute: ColumnsLayoutOnboardingLazyRoute,
|
||||||
ColumnsLayoutSearchLazyRoute: ColumnsLayoutSearchLazyRoute,
|
ColumnsLayoutSearchLazyRoute: ColumnsLayoutSearchLazyRoute,
|
||||||
ColumnsLayoutTrendingLazyRoute: ColumnsLayoutTrendingLazyRoute,
|
ColumnsLayoutTrendingLazyRoute: ColumnsLayoutTrendingLazyRoute,
|
||||||
|
ColumnsLayoutEventsIdRoute: ColumnsLayoutEventsIdRoute,
|
||||||
ColumnsLayoutGroupsIdRoute: ColumnsLayoutGroupsIdRoute,
|
ColumnsLayoutGroupsIdRoute: ColumnsLayoutGroupsIdRoute,
|
||||||
ColumnsLayoutInterestsIdRoute: ColumnsLayoutInterestsIdRoute,
|
ColumnsLayoutInterestsIdRoute: ColumnsLayoutInterestsIdRoute,
|
||||||
ColumnsLayoutNewsfeedIdRoute: ColumnsLayoutNewsfeedIdRoute,
|
ColumnsLayoutNewsfeedIdRoute: ColumnsLayoutNewsfeedIdRoute,
|
||||||
ColumnsLayoutStoriesIdRoute: ColumnsLayoutStoriesIdRoute,
|
ColumnsLayoutStoriesIdRoute: ColumnsLayoutStoriesIdRoute,
|
||||||
ColumnsLayoutEventsIdLazyRoute: ColumnsLayoutEventsIdLazyRoute,
|
|
||||||
ColumnsLayoutLaunchpadIdLazyRoute: ColumnsLayoutLaunchpadIdLazyRoute,
|
ColumnsLayoutLaunchpadIdLazyRoute: ColumnsLayoutLaunchpadIdLazyRoute,
|
||||||
ColumnsLayoutNotificationIdLazyRoute: ColumnsLayoutNotificationIdLazyRoute,
|
ColumnsLayoutNotificationIdLazyRoute: ColumnsLayoutNotificationIdLazyRoute,
|
||||||
ColumnsLayoutRelaysUrlLazyRoute: ColumnsLayoutRelaysUrlLazyRoute,
|
ColumnsLayoutRelaysUrlLazyRoute: ColumnsLayoutRelaysUrlLazyRoute,
|
||||||
@@ -786,11 +784,11 @@ export interface FileRoutesByFullPath {
|
|||||||
'/columns/trending': typeof ColumnsLayoutTrendingLazyRoute
|
'/columns/trending': typeof ColumnsLayoutTrendingLazyRoute
|
||||||
'/columns/create-newsfeed/f2f': typeof ColumnsLayoutCreateNewsfeedF2fRoute
|
'/columns/create-newsfeed/f2f': typeof ColumnsLayoutCreateNewsfeedF2fRoute
|
||||||
'/columns/create-newsfeed/users': typeof ColumnsLayoutCreateNewsfeedUsersRoute
|
'/columns/create-newsfeed/users': typeof ColumnsLayoutCreateNewsfeedUsersRoute
|
||||||
|
'/columns/events/$id': typeof ColumnsLayoutEventsIdRoute
|
||||||
'/columns/groups/$id': typeof ColumnsLayoutGroupsIdRoute
|
'/columns/groups/$id': typeof ColumnsLayoutGroupsIdRoute
|
||||||
'/columns/interests/$id': typeof ColumnsLayoutInterestsIdRoute
|
'/columns/interests/$id': typeof ColumnsLayoutInterestsIdRoute
|
||||||
'/columns/newsfeed/$id': typeof ColumnsLayoutNewsfeedIdRoute
|
'/columns/newsfeed/$id': typeof ColumnsLayoutNewsfeedIdRoute
|
||||||
'/columns/stories/$id': typeof ColumnsLayoutStoriesIdRoute
|
'/columns/stories/$id': typeof ColumnsLayoutStoriesIdRoute
|
||||||
'/columns/events/$id': typeof ColumnsLayoutEventsIdLazyRoute
|
|
||||||
'/columns/launchpad/$id': typeof ColumnsLayoutLaunchpadIdLazyRoute
|
'/columns/launchpad/$id': typeof ColumnsLayoutLaunchpadIdLazyRoute
|
||||||
'/columns/notification/$id': typeof ColumnsLayoutNotificationIdLazyRoute
|
'/columns/notification/$id': typeof ColumnsLayoutNotificationIdLazyRoute
|
||||||
'/columns/relays/$url': typeof ColumnsLayoutRelaysUrlLazyRoute
|
'/columns/relays/$url': typeof ColumnsLayoutRelaysUrlLazyRoute
|
||||||
@@ -825,11 +823,11 @@ export interface FileRoutesByTo {
|
|||||||
'/columns/trending': typeof ColumnsLayoutTrendingLazyRoute
|
'/columns/trending': typeof ColumnsLayoutTrendingLazyRoute
|
||||||
'/columns/create-newsfeed/f2f': typeof ColumnsLayoutCreateNewsfeedF2fRoute
|
'/columns/create-newsfeed/f2f': typeof ColumnsLayoutCreateNewsfeedF2fRoute
|
||||||
'/columns/create-newsfeed/users': typeof ColumnsLayoutCreateNewsfeedUsersRoute
|
'/columns/create-newsfeed/users': typeof ColumnsLayoutCreateNewsfeedUsersRoute
|
||||||
|
'/columns/events/$id': typeof ColumnsLayoutEventsIdRoute
|
||||||
'/columns/groups/$id': typeof ColumnsLayoutGroupsIdRoute
|
'/columns/groups/$id': typeof ColumnsLayoutGroupsIdRoute
|
||||||
'/columns/interests/$id': typeof ColumnsLayoutInterestsIdRoute
|
'/columns/interests/$id': typeof ColumnsLayoutInterestsIdRoute
|
||||||
'/columns/newsfeed/$id': typeof ColumnsLayoutNewsfeedIdRoute
|
'/columns/newsfeed/$id': typeof ColumnsLayoutNewsfeedIdRoute
|
||||||
'/columns/stories/$id': typeof ColumnsLayoutStoriesIdRoute
|
'/columns/stories/$id': typeof ColumnsLayoutStoriesIdRoute
|
||||||
'/columns/events/$id': typeof ColumnsLayoutEventsIdLazyRoute
|
|
||||||
'/columns/launchpad/$id': typeof ColumnsLayoutLaunchpadIdLazyRoute
|
'/columns/launchpad/$id': typeof ColumnsLayoutLaunchpadIdLazyRoute
|
||||||
'/columns/notification/$id': typeof ColumnsLayoutNotificationIdLazyRoute
|
'/columns/notification/$id': typeof ColumnsLayoutNotificationIdLazyRoute
|
||||||
'/columns/relays/$url': typeof ColumnsLayoutRelaysUrlLazyRoute
|
'/columns/relays/$url': typeof ColumnsLayoutRelaysUrlLazyRoute
|
||||||
@@ -867,11 +865,11 @@ export interface FileRoutesById {
|
|||||||
'/columns/_layout/trending': typeof ColumnsLayoutTrendingLazyRoute
|
'/columns/_layout/trending': typeof ColumnsLayoutTrendingLazyRoute
|
||||||
'/columns/_layout/create-newsfeed/f2f': typeof ColumnsLayoutCreateNewsfeedF2fRoute
|
'/columns/_layout/create-newsfeed/f2f': typeof ColumnsLayoutCreateNewsfeedF2fRoute
|
||||||
'/columns/_layout/create-newsfeed/users': typeof ColumnsLayoutCreateNewsfeedUsersRoute
|
'/columns/_layout/create-newsfeed/users': typeof ColumnsLayoutCreateNewsfeedUsersRoute
|
||||||
|
'/columns/_layout/events/$id': typeof ColumnsLayoutEventsIdRoute
|
||||||
'/columns/_layout/groups/$id': typeof ColumnsLayoutGroupsIdRoute
|
'/columns/_layout/groups/$id': typeof ColumnsLayoutGroupsIdRoute
|
||||||
'/columns/_layout/interests/$id': typeof ColumnsLayoutInterestsIdRoute
|
'/columns/_layout/interests/$id': typeof ColumnsLayoutInterestsIdRoute
|
||||||
'/columns/_layout/newsfeed/$id': typeof ColumnsLayoutNewsfeedIdRoute
|
'/columns/_layout/newsfeed/$id': typeof ColumnsLayoutNewsfeedIdRoute
|
||||||
'/columns/_layout/stories/$id': typeof ColumnsLayoutStoriesIdRoute
|
'/columns/_layout/stories/$id': typeof ColumnsLayoutStoriesIdRoute
|
||||||
'/columns/_layout/events/$id': typeof ColumnsLayoutEventsIdLazyRoute
|
|
||||||
'/columns/_layout/launchpad/$id': typeof ColumnsLayoutLaunchpadIdLazyRoute
|
'/columns/_layout/launchpad/$id': typeof ColumnsLayoutLaunchpadIdLazyRoute
|
||||||
'/columns/_layout/notification/$id': typeof ColumnsLayoutNotificationIdLazyRoute
|
'/columns/_layout/notification/$id': typeof ColumnsLayoutNotificationIdLazyRoute
|
||||||
'/columns/_layout/relays/$url': typeof ColumnsLayoutRelaysUrlLazyRoute
|
'/columns/_layout/relays/$url': typeof ColumnsLayoutRelaysUrlLazyRoute
|
||||||
@@ -909,11 +907,11 @@ export interface FileRouteTypes {
|
|||||||
| '/columns/trending'
|
| '/columns/trending'
|
||||||
| '/columns/create-newsfeed/f2f'
|
| '/columns/create-newsfeed/f2f'
|
||||||
| '/columns/create-newsfeed/users'
|
| '/columns/create-newsfeed/users'
|
||||||
|
| '/columns/events/$id'
|
||||||
| '/columns/groups/$id'
|
| '/columns/groups/$id'
|
||||||
| '/columns/interests/$id'
|
| '/columns/interests/$id'
|
||||||
| '/columns/newsfeed/$id'
|
| '/columns/newsfeed/$id'
|
||||||
| '/columns/stories/$id'
|
| '/columns/stories/$id'
|
||||||
| '/columns/events/$id'
|
|
||||||
| '/columns/launchpad/$id'
|
| '/columns/launchpad/$id'
|
||||||
| '/columns/notification/$id'
|
| '/columns/notification/$id'
|
||||||
| '/columns/relays/$url'
|
| '/columns/relays/$url'
|
||||||
@@ -947,11 +945,11 @@ export interface FileRouteTypes {
|
|||||||
| '/columns/trending'
|
| '/columns/trending'
|
||||||
| '/columns/create-newsfeed/f2f'
|
| '/columns/create-newsfeed/f2f'
|
||||||
| '/columns/create-newsfeed/users'
|
| '/columns/create-newsfeed/users'
|
||||||
|
| '/columns/events/$id'
|
||||||
| '/columns/groups/$id'
|
| '/columns/groups/$id'
|
||||||
| '/columns/interests/$id'
|
| '/columns/interests/$id'
|
||||||
| '/columns/newsfeed/$id'
|
| '/columns/newsfeed/$id'
|
||||||
| '/columns/stories/$id'
|
| '/columns/stories/$id'
|
||||||
| '/columns/events/$id'
|
|
||||||
| '/columns/launchpad/$id'
|
| '/columns/launchpad/$id'
|
||||||
| '/columns/notification/$id'
|
| '/columns/notification/$id'
|
||||||
| '/columns/relays/$url'
|
| '/columns/relays/$url'
|
||||||
@@ -987,11 +985,11 @@ export interface FileRouteTypes {
|
|||||||
| '/columns/_layout/trending'
|
| '/columns/_layout/trending'
|
||||||
| '/columns/_layout/create-newsfeed/f2f'
|
| '/columns/_layout/create-newsfeed/f2f'
|
||||||
| '/columns/_layout/create-newsfeed/users'
|
| '/columns/_layout/create-newsfeed/users'
|
||||||
|
| '/columns/_layout/events/$id'
|
||||||
| '/columns/_layout/groups/$id'
|
| '/columns/_layout/groups/$id'
|
||||||
| '/columns/_layout/interests/$id'
|
| '/columns/_layout/interests/$id'
|
||||||
| '/columns/_layout/newsfeed/$id'
|
| '/columns/_layout/newsfeed/$id'
|
||||||
| '/columns/_layout/stories/$id'
|
| '/columns/_layout/stories/$id'
|
||||||
| '/columns/_layout/events/$id'
|
|
||||||
| '/columns/_layout/launchpad/$id'
|
| '/columns/_layout/launchpad/$id'
|
||||||
| '/columns/_layout/notification/$id'
|
| '/columns/_layout/notification/$id'
|
||||||
| '/columns/_layout/relays/$url'
|
| '/columns/_layout/relays/$url'
|
||||||
@@ -1098,11 +1096,11 @@ export const routeTree = rootRoute
|
|||||||
"/columns/_layout/onboarding",
|
"/columns/_layout/onboarding",
|
||||||
"/columns/_layout/search",
|
"/columns/_layout/search",
|
||||||
"/columns/_layout/trending",
|
"/columns/_layout/trending",
|
||||||
|
"/columns/_layout/events/$id",
|
||||||
"/columns/_layout/groups/$id",
|
"/columns/_layout/groups/$id",
|
||||||
"/columns/_layout/interests/$id",
|
"/columns/_layout/interests/$id",
|
||||||
"/columns/_layout/newsfeed/$id",
|
"/columns/_layout/newsfeed/$id",
|
||||||
"/columns/_layout/stories/$id",
|
"/columns/_layout/stories/$id",
|
||||||
"/columns/_layout/events/$id",
|
|
||||||
"/columns/_layout/launchpad/$id",
|
"/columns/_layout/launchpad/$id",
|
||||||
"/columns/_layout/notification/$id",
|
"/columns/_layout/notification/$id",
|
||||||
"/columns/_layout/relays/$url",
|
"/columns/_layout/relays/$url",
|
||||||
@@ -1193,6 +1191,10 @@ export const routeTree = rootRoute
|
|||||||
"filePath": "columns/_layout/create-newsfeed.users.tsx",
|
"filePath": "columns/_layout/create-newsfeed.users.tsx",
|
||||||
"parent": "/columns/_layout/create-newsfeed"
|
"parent": "/columns/_layout/create-newsfeed"
|
||||||
},
|
},
|
||||||
|
"/columns/_layout/events/$id": {
|
||||||
|
"filePath": "columns/_layout/events.$id.tsx",
|
||||||
|
"parent": "/columns/_layout"
|
||||||
|
},
|
||||||
"/columns/_layout/groups/$id": {
|
"/columns/_layout/groups/$id": {
|
||||||
"filePath": "columns/_layout/groups.$id.tsx",
|
"filePath": "columns/_layout/groups.$id.tsx",
|
||||||
"parent": "/columns/_layout"
|
"parent": "/columns/_layout"
|
||||||
@@ -1209,10 +1211,6 @@ export const routeTree = rootRoute
|
|||||||
"filePath": "columns/_layout/stories.$id.tsx",
|
"filePath": "columns/_layout/stories.$id.tsx",
|
||||||
"parent": "/columns/_layout"
|
"parent": "/columns/_layout"
|
||||||
},
|
},
|
||||||
"/columns/_layout/events/$id": {
|
|
||||||
"filePath": "columns/_layout/events.$id.lazy.tsx",
|
|
||||||
"parent": "/columns/_layout"
|
|
||||||
},
|
|
||||||
"/columns/_layout/launchpad/$id": {
|
"/columns/_layout/launchpad/$id": {
|
||||||
"filePath": "columns/_layout/launchpad.$id.lazy.tsx",
|
"filePath": "columns/_layout/launchpad.$id.lazy.tsx",
|
||||||
"parent": "/columns/_layout"
|
"parent": "/columns/_layout"
|
||||||
|
|||||||
+12
-2
@@ -1,4 +1,5 @@
|
|||||||
import { commands } from "@/commands.gen";
|
import { commands } from "@/commands.gen";
|
||||||
|
import { cn } from "@/commons";
|
||||||
import { Spinner } from "@/components";
|
import { Spinner } from "@/components";
|
||||||
import type { Metadata, NostrEvent } from "@/types";
|
import type { Metadata, NostrEvent } from "@/types";
|
||||||
import { type QueryClient, queryOptions } from "@tanstack/react-query";
|
import { type QueryClient, queryOptions } from "@tanstack/react-query";
|
||||||
@@ -36,7 +37,7 @@ export const Route = createRootRouteWithContext<RouterContext>()({
|
|||||||
});
|
});
|
||||||
|
|
||||||
function Screen() {
|
function Screen() {
|
||||||
const { queryClient } = Route.useRouteContext();
|
const { queryClient, platform } = Route.useRouteContext();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const unlisten = getCurrentWindow().listen<string>(
|
const unlisten = getCurrentWindow().listen<string>(
|
||||||
@@ -60,7 +61,16 @@ function Screen() {
|
|||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return <Outlet />;
|
return (
|
||||||
|
<div
|
||||||
|
className={cn(
|
||||||
|
"size-full",
|
||||||
|
platform === "windows" ? "bg-neutral-100 dark:bg-neutral-900" : "",
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<Outlet />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function Pending() {
|
function Pending() {
|
||||||
|
|||||||
@@ -22,10 +22,19 @@ export const Route = createLazyFileRoute("/_app")({
|
|||||||
});
|
});
|
||||||
|
|
||||||
function Layout() {
|
function Layout() {
|
||||||
|
const { platform } = Route.useRouteContext();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col w-screen h-screen">
|
<div className="flex flex-col w-screen h-screen">
|
||||||
<Topbar />
|
<Topbar />
|
||||||
<div className="flex-1 bg-neutral-100 dark:bg-neutral-900 border-t-[.5px] border-black/20 dark:border-white/30">
|
<div
|
||||||
|
className={cn(
|
||||||
|
"flex-1 bg-neutral-100 dark:bg-neutral-900 border-t-[.5px]",
|
||||||
|
platform === "windows"
|
||||||
|
? "border-black/10 dark:border-white/10"
|
||||||
|
: "border-black/20 dark:border-white/30",
|
||||||
|
)}
|
||||||
|
>
|
||||||
<Outlet />
|
<Outlet />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+36
-9
@@ -1,14 +1,41 @@
|
|||||||
import { commands } from '@/commands.gen'
|
import { commands } from "@/commands.gen";
|
||||||
import { createFileRoute, redirect } from '@tanstack/react-router'
|
import { createFileRoute, redirect } from "@tanstack/react-router";
|
||||||
|
import { ask } from "@tauri-apps/plugin-dialog";
|
||||||
|
import { relaunch } from "@tauri-apps/plugin-process";
|
||||||
|
import { check } from "@tauri-apps/plugin-updater";
|
||||||
|
|
||||||
export const Route = createFileRoute('/_app')({
|
async function checkForAppUpdates() {
|
||||||
beforeLoad: async () => {
|
const update = await check();
|
||||||
const accounts = await commands.getAccounts()
|
|
||||||
|
|
||||||
if (!accounts.length) {
|
if (update?.available) {
|
||||||
throw redirect({ to: '/new', replace: true })
|
const yes = await ask(
|
||||||
|
`Update to ${update.version} is available!\n\nRelease notes: ${update.body}`,
|
||||||
|
{
|
||||||
|
title: "Update Available",
|
||||||
|
kind: "info",
|
||||||
|
okLabel: "Update",
|
||||||
|
cancelLabel: "Cancel",
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
if (yes) {
|
||||||
|
await update.downloadAndInstall();
|
||||||
|
await relaunch();
|
||||||
}
|
}
|
||||||
|
|
||||||
return { accounts }
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Route = createFileRoute("/_app")({
|
||||||
|
beforeLoad: async () => {
|
||||||
|
await checkForAppUpdates();
|
||||||
|
const accounts = await commands.getAccounts();
|
||||||
|
|
||||||
|
if (!accounts.length) {
|
||||||
|
throw redirect({ to: "/new", replace: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
return { accounts };
|
||||||
},
|
},
|
||||||
})
|
});
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ function Screen() {
|
|||||||
data?.map((item) => (
|
data?.map((item) => (
|
||||||
<div
|
<div
|
||||||
key={item}
|
key={item}
|
||||||
className="w-full p-2 mb-2 overflow-hidden bg-white rounded-lg h-max dark:bg-black/20shadow-primary dark:ring-1 ring-neutral-800/50"
|
className="w-full p-2 mb-2 overflow-hidden bg-white rounded-lg h-max dark:bg-black/20 shadow-primary dark:ring-1 ring-neutral-800/50"
|
||||||
>
|
>
|
||||||
<User.Provider pubkey={item}>
|
<User.Provider pubkey={item}>
|
||||||
<User.Root>
|
<User.Root>
|
||||||
|
|||||||
@@ -60,9 +60,9 @@ function Screen() {
|
|||||||
|
|
||||||
const renderItem = useCallback(
|
const renderItem = useCallback(
|
||||||
(item: NostrEvent) => {
|
(item: NostrEvent) => {
|
||||||
|
const users = item.tags.filter((tag) => tag[0] === "p");
|
||||||
const name =
|
const name =
|
||||||
item.tags.find((tag) => tag[0] === "title")?.[1] || "Unnamed";
|
item.tags.find((tag) => tag[0] === "title")?.[1] || "Unnamed";
|
||||||
|
|
||||||
const label = item.tags.find((tag) => tag[0] === "d")?.[1] || nanoid();
|
const label = item.tags.find((tag) => tag[0] === "d")?.[1] || nanoid();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -71,32 +71,24 @@ function Screen() {
|
|||||||
className="mb-3 group flex flex-col rounded-xl overflow-hidden bg-white dark:bg-neutral-800/50 shadow-lg shadow-primary dark:ring-1 dark:ring-neutral-800"
|
className="mb-3 group flex flex-col rounded-xl overflow-hidden bg-white dark:bg-neutral-800/50 shadow-lg shadow-primary dark:ring-1 dark:ring-neutral-800"
|
||||||
>
|
>
|
||||||
<div className="px-2 pt-2">
|
<div className="px-2 pt-2">
|
||||||
<ScrollArea.Root
|
<div className="p-3 h-16 bg-neutral-100 dark:bg-neutral-800 rounded-lg">
|
||||||
type={"scroll"}
|
|
||||||
scrollHideDelay={300}
|
|
||||||
className="overflow-hidden size-full"
|
|
||||||
>
|
|
||||||
<ScrollArea.Viewport className="p-3 h-16 bg-neutral-100 dark:bg-neutral-800 rounded-lg">
|
|
||||||
<div className="flex flex-wrap items-center justify-center gap-2">
|
<div className="flex flex-wrap items-center justify-center gap-2">
|
||||||
{item.tags
|
{users.slice(0, 5).map((tag) => (
|
||||||
.filter((tag) => tag[0] === "p")
|
|
||||||
.map((tag) => (
|
|
||||||
<User.Provider key={tag[1]} pubkey={tag[1]}>
|
<User.Provider key={tag[1]} pubkey={tag[1]}>
|
||||||
<User.Root>
|
<User.Root>
|
||||||
<User.Avatar className="size-8 rounded-full" />
|
<User.Avatar className="size-8 rounded-full" />
|
||||||
</User.Root>
|
</User.Root>
|
||||||
</User.Provider>
|
</User.Provider>
|
||||||
))}
|
))}
|
||||||
|
{users.length > 5 ? (
|
||||||
|
<div className="size-8 rounded-full inline-flex items-center justify-center bg-neutral-300 dark:bg-neutral-700">
|
||||||
|
<p className="truncate leading-tight text-[8px] font-medium">
|
||||||
|
+{users.length - 5}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</ScrollArea.Viewport>
|
|
||||||
<ScrollArea.Scrollbar
|
|
||||||
className="flex select-none touch-none p-0.5 duration-[160ms] ease-out data-[orientation=vertical]:w-2"
|
|
||||||
orientation="vertical"
|
|
||||||
>
|
|
||||||
<ScrollArea.Thumb className="flex-1 bg-black/10 dark:bg-white/10 rounded-full relative before:content-[''] before:absolute before:top-1/2 before:left-1/2 before:-translate-x-1/2 before:-translate-y-1/2 before:w-full before:h-full before:min-w-[44px] before:min-h-[44px]" />
|
|
||||||
</ScrollArea.Scrollbar>
|
|
||||||
<ScrollArea.Corner className="bg-transparent" />
|
|
||||||
</ScrollArea.Root>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="p-2 flex items-center justify-between">
|
<div className="p-2 flex items-center justify-between">
|
||||||
<div className="inline-flex items-center gap-2">
|
<div className="inline-flex items-center gap-2">
|
||||||
|
|||||||
@@ -183,7 +183,6 @@ function ReplyList() {
|
|||||||
"event",
|
"event",
|
||||||
async (data) => {
|
async (data) => {
|
||||||
const event = LumeEvent.from(data.payload.raw, data.payload.parsed);
|
const event = LumeEvent.from(data.payload.raw, data.payload.parsed);
|
||||||
console.log(event);
|
|
||||||
|
|
||||||
await queryClient.setQueryData(
|
await queryClient.setQueryData(
|
||||||
["replies", id],
|
["replies", id],
|
||||||
@@ -200,6 +199,16 @@ function ReplyList() {
|
|||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const unlisten = getCurrentWindow().listen(id, async () => {
|
||||||
|
await queryClient.invalidateQueries({ queryKey: ["replies", id] });
|
||||||
|
});
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
unlisten.then((f) => f());
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="px-3">
|
<div className="px-3">
|
||||||
<div className="flex items-center text-sm font-semibold h-14 text-neutral-600 dark:text-white/30">
|
<div className="flex items-center text-sm font-semibold h-14 text-neutral-600 dark:text-white/30">
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
import { commands } from "@/commands.gen";
|
||||||
|
import { createFileRoute } from "@tanstack/react-router";
|
||||||
|
|
||||||
|
export const Route = createFileRoute("/columns/_layout/events/$id")({
|
||||||
|
beforeLoad: async () => {
|
||||||
|
const accounts = await commands.getAccounts();
|
||||||
|
return { accounts };
|
||||||
|
},
|
||||||
|
});
|
||||||
@@ -88,7 +88,7 @@ export function Screen() {
|
|||||||
>
|
>
|
||||||
<ScrollArea.Viewport
|
<ScrollArea.Viewport
|
||||||
ref={ref}
|
ref={ref}
|
||||||
className="relative h-full bg-white dark:bg-black rounded-t-xl shadow shadow-neutral-300/50 dark:shadow-none border-[.5px] border-neutral-300 dark:border-neutral-700"
|
className="relative h-full bg-white dark:bg-neutral-800 rounded-t-xl shadow shadow-neutral-300/50 dark:shadow-none border-[.5px] border-neutral-300 dark:border-neutral-700"
|
||||||
>
|
>
|
||||||
<Virtualizer scrollRef={ref as unknown as RefObject<HTMLElement>}>
|
<Virtualizer scrollRef={ref as unknown as RefObject<HTMLElement>}>
|
||||||
{isFetching && !isLoading && !isFetchingNextPage ? (
|
{isFetching && !isLoading && !isFetchingNextPage ? (
|
||||||
|
|||||||
@@ -62,11 +62,11 @@ function Newsfeeds() {
|
|||||||
|
|
||||||
const renderItem = useCallback(
|
const renderItem = useCallback(
|
||||||
(item: NostrEvent) => {
|
(item: NostrEvent) => {
|
||||||
|
const users = item.tags.filter((tag) => tag[0] === "p");
|
||||||
const name =
|
const name =
|
||||||
item.kind === 3
|
item.kind === 3
|
||||||
? "Contacts"
|
? "Contacts"
|
||||||
: item.tags.find((tag) => tag[0] === "title")?.[1] || "Unnamed";
|
: item.tags.find((tag) => tag[0] === "title")?.[1] || "Unnamed";
|
||||||
|
|
||||||
const label =
|
const label =
|
||||||
item.kind === 3
|
item.kind === 3
|
||||||
? `newsfeed-${id.slice(0, 5)}`
|
? `newsfeed-${id.slice(0, 5)}`
|
||||||
@@ -78,32 +78,24 @@ function Newsfeeds() {
|
|||||||
className="group flex flex-col rounded-xl overflow-hidden bg-white dark:bg-neutral-800/50 shadow-lg shadow-primary dark:ring-1 dark:ring-neutral-800"
|
className="group flex flex-col rounded-xl overflow-hidden bg-white dark:bg-neutral-800/50 shadow-lg shadow-primary dark:ring-1 dark:ring-neutral-800"
|
||||||
>
|
>
|
||||||
<div className="px-2 pt-2">
|
<div className="px-2 pt-2">
|
||||||
<ScrollArea.Root
|
<div className="p-3 h-16 bg-neutral-100 dark:bg-neutral-800 rounded-lg">
|
||||||
type={"scroll"}
|
|
||||||
scrollHideDelay={300}
|
|
||||||
className="overflow-hidden size-full"
|
|
||||||
>
|
|
||||||
<ScrollArea.Viewport className="p-3 h-16 bg-neutral-100 dark:bg-neutral-800 rounded-lg">
|
|
||||||
<div className="flex flex-wrap items-center justify-center gap-2">
|
<div className="flex flex-wrap items-center justify-center gap-2">
|
||||||
{item.tags
|
{users.slice(0, 5).map((tag) => (
|
||||||
.filter((tag) => tag[0] === "p")
|
|
||||||
.map((tag) => (
|
|
||||||
<User.Provider key={tag[1]} pubkey={tag[1]}>
|
<User.Provider key={tag[1]} pubkey={tag[1]}>
|
||||||
<User.Root>
|
<User.Root>
|
||||||
<User.Avatar className="size-8 rounded-full" />
|
<User.Avatar className="size-8 rounded-full" />
|
||||||
</User.Root>
|
</User.Root>
|
||||||
</User.Provider>
|
</User.Provider>
|
||||||
))}
|
))}
|
||||||
|
{users.length > 5 ? (
|
||||||
|
<div className="size-8 rounded-full inline-flex items-center justify-center bg-neutral-300 dark:bg-neutral-700">
|
||||||
|
<p className="truncate leading-tight text-[8px] font-medium">
|
||||||
|
+{users.length - 5}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</ScrollArea.Viewport>
|
|
||||||
<ScrollArea.Scrollbar
|
|
||||||
className="flex select-none touch-none p-0.5 duration-[160ms] ease-out data-[orientation=vertical]:w-2"
|
|
||||||
orientation="vertical"
|
|
||||||
>
|
|
||||||
<ScrollArea.Thumb className="flex-1 bg-black/10 dark:bg-white/10 rounded-full relative before:content-[''] before:absolute before:top-1/2 before:left-1/2 before:-translate-x-1/2 before:-translate-y-1/2 before:w-full before:h-full before:min-w-[44px] before:min-h-[44px]" />
|
|
||||||
</ScrollArea.Scrollbar>
|
|
||||||
<ScrollArea.Corner className="bg-transparent" />
|
|
||||||
</ScrollArea.Root>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="p-2 flex items-center justify-between">
|
<div className="p-2 flex items-center justify-between">
|
||||||
<div className="inline-flex items-center gap-2">
|
<div className="inline-flex items-center gap-2">
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import type { Metadata } from "@/types";
|
|||||||
import { CaretDown } from "@phosphor-icons/react";
|
import { CaretDown } from "@phosphor-icons/react";
|
||||||
import { createLazyFileRoute, useAwaited } from "@tanstack/react-router";
|
import { createLazyFileRoute, useAwaited } from "@tanstack/react-router";
|
||||||
import { Menu, MenuItem } from "@tauri-apps/api/menu";
|
import { Menu, MenuItem } from "@tauri-apps/api/menu";
|
||||||
|
import { getCurrentWindow } from "@tauri-apps/api/window";
|
||||||
import { message } from "@tauri-apps/plugin-dialog";
|
import { message } from "@tauri-apps/plugin-dialog";
|
||||||
import {
|
import {
|
||||||
useCallback,
|
useCallback,
|
||||||
@@ -170,9 +171,7 @@ function Screen() {
|
|||||||
setText("");
|
setText("");
|
||||||
setIsPublish(true);
|
setIsPublish(true);
|
||||||
|
|
||||||
await queryClient.invalidateQueries({
|
await getCurrentWindow().emit(reply_to, {});
|
||||||
queryKey: ["replies", reply_to],
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
setError(res.error);
|
setError(res.error);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { cn } from "@/commons";
|
||||||
import { createLazyFileRoute } from "@tanstack/react-router";
|
import { createLazyFileRoute } from "@tanstack/react-router";
|
||||||
|
|
||||||
export const Route = createLazyFileRoute("/new")({
|
export const Route = createLazyFileRoute("/new")({
|
||||||
@@ -5,10 +6,17 @@ export const Route = createLazyFileRoute("/new")({
|
|||||||
});
|
});
|
||||||
|
|
||||||
function Screen() {
|
function Screen() {
|
||||||
|
const { platform } = Route.useRouteContext();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
data-tauri-drag-region
|
data-tauri-drag-region
|
||||||
className="bg-white/50 dark:bg-black/50 relative size-full flex items-center justify-center"
|
className={cn(
|
||||||
|
"relative size-full flex items-center justify-center",
|
||||||
|
platform === "windows"
|
||||||
|
? "bg-neutral-200 dark:bg-neutral-900"
|
||||||
|
: "bg-white/20 dark:bg-black/20",
|
||||||
|
)}
|
||||||
>
|
>
|
||||||
<div className="w-[350px] flex flex-col gap-8">
|
<div className="w-[350px] flex flex-col gap-8">
|
||||||
<div className="flex flex-col gap-1 text-center">
|
<div className="flex flex-col gap-1 text-center">
|
||||||
|
|||||||
+1
-4
@@ -1,10 +1,7 @@
|
|||||||
/** @type {import('tailwindcss').Config} */
|
/** @type {import('tailwindcss').Config} */
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
content: [
|
content: ["./src/**/*.{js,ts,jsx,tsx}", "index.html"],
|
||||||
"./src/**/*.{js,ts,jsx,tsx}",
|
|
||||||
"index.html",
|
|
||||||
],
|
|
||||||
theme: {
|
theme: {
|
||||||
extend: {
|
extend: {
|
||||||
keyframes: {
|
keyframes: {
|
||||||
|
|||||||
+4
-13
@@ -2,19 +2,12 @@
|
|||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "ESNext",
|
"target": "ESNext",
|
||||||
"useDefineForClassFields": true,
|
"useDefineForClassFields": true,
|
||||||
"lib": [
|
"lib": ["ESNext", "ES2020", "DOM", "DOM.Iterable"],
|
||||||
"ESNext",
|
|
||||||
"ES2020",
|
|
||||||
"DOM",
|
|
||||||
"DOM.Iterable"
|
|
||||||
],
|
|
||||||
"module": "ESNext",
|
"module": "ESNext",
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"baseUrl": "./",
|
"baseUrl": "./",
|
||||||
"paths": {
|
"paths": {
|
||||||
"@/*": [
|
"@/*": ["./src/*"]
|
||||||
"./src/*"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"moduleResolution": "bundler",
|
"moduleResolution": "bundler",
|
||||||
"allowImportingTsExtensions": true,
|
"allowImportingTsExtensions": true,
|
||||||
@@ -26,11 +19,9 @@
|
|||||||
"noUnusedLocals": true,
|
"noUnusedLocals": true,
|
||||||
"noImplicitAny": false,
|
"noImplicitAny": false,
|
||||||
"noUnusedParameters": true,
|
"noUnusedParameters": true,
|
||||||
"noFallthroughCasesInSwitch": true,
|
"noFallthroughCasesInSwitch": true
|
||||||
},
|
},
|
||||||
"include": [
|
"include": ["src"],
|
||||||
"src"
|
|
||||||
],
|
|
||||||
"references": [
|
"references": [
|
||||||
{
|
{
|
||||||
"path": "./tsconfig.node.json"
|
"path": "./tsconfig.node.json"
|
||||||
|
|||||||
+1
-3
@@ -6,7 +6,5 @@
|
|||||||
"moduleResolution": "bundler",
|
"moduleResolution": "bundler",
|
||||||
"allowSyntheticDefaultImports": true
|
"allowSyntheticDefaultImports": true
|
||||||
},
|
},
|
||||||
"include": [
|
"include": ["vite.config.ts"]
|
||||||
"vite.config.ts"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user