build fix

This commit is contained in:
2026-01-13 13:18:46 +01:00
parent a69b4c0bcb
commit bbb767cd20
4 changed files with 61 additions and 31 deletions

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{ {
"name": "radio-tauri", "name": "radio-tauri",
"version": "0.1.0", "version": "0.1.1",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "radio-tauri", "name": "radio-tauri",
"version": "0.1.0", "version": "0.1.1",
"devDependencies": { "devDependencies": {
"@tauri-apps/cli": "^2", "@tauri-apps/cli": "^2",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",

View File

@@ -4,6 +4,7 @@ version = "0.1.1"
description = "A Tauri App" description = "A Tauri App"
authors = ["you"] authors = ["you"]
edition = "2021" edition = "2021"
default-run = "radio-tauri"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

View File

@@ -3,7 +3,6 @@ use std::io::{BufRead, BufReader};
use std::net::{IpAddr, SocketAddr, TcpListener, TcpStream, UdpSocket}; use std::net::{IpAddr, SocketAddr, TcpListener, TcpStream, UdpSocket};
use std::process::{Child, Command, Stdio}; use std::process::{Child, Command, Stdio};
use std::sync::Mutex; use std::sync::Mutex;
use std::thread;
use std::time::Duration; use std::time::Duration;
#[cfg(windows)] #[cfg(windows)]
@@ -14,7 +13,7 @@ const CREATE_NO_WINDOW: u32 = 0x08000000;
use mdns_sd::{ServiceDaemon, ServiceEvent}; use mdns_sd::{ServiceDaemon, ServiceEvent};
use serde_json::json; use serde_json::json;
use tauri::{AppHandle, Manager, State}; use tauri::{AppHandle, Manager, State, Emitter};
use tauri_plugin_shell::process::{CommandChild, CommandEvent}; use tauri_plugin_shell::process::{CommandChild, CommandEvent};
use tauri_plugin_shell::ShellExt; use tauri_plugin_shell::ShellExt;
use reqwest; use reqwest;
@@ -560,40 +559,55 @@ pub fn run() {
let controller = player::spawn_player_thread(shared); let controller = player::spawn_player_thread(shared);
app.manage(PlayerRuntime { shared, controller }); app.manage(PlayerRuntime { shared, controller });
// Start mDNS discovery in background without blocking setup.
// This allows the main window to show immediately.
let handle = app.handle().clone(); let handle = app.handle().clone();
thread::spawn(move || { tauri::async_runtime::spawn(async move {
let mdns = ServiceDaemon::new().expect("Failed to create daemon"); // Small delay to ensure window is fully initialized first.
let receiver = mdns tokio::time::sleep(Duration::from_millis(100)).await;
.browse("_googlecast._tcp.local.")
.expect("Failed to browse"); std::thread::spawn(move || {
while let Ok(event) = receiver.recv() { let mdns = ServiceDaemon::new().expect("Failed to create daemon");
match event { let receiver = mdns
ServiceEvent::ServiceResolved(info) => { .browse("_googlecast._tcp.local.")
let name = info .expect("Failed to browse");
.get_property_val_str("fn")
.or_else(|| Some(info.get_fullname())) while let Ok(event) = receiver.recv() {
.unwrap() match event {
.to_string(); ServiceEvent::ServiceResolved(info) => {
let addresses = info.get_addresses(); let name = info
let ip = addresses .get_property_val_str("fn")
.iter() .or_else(|| Some(info.get_fullname()))
.find(|ip| ip.is_ipv4()) .unwrap()
.or_else(|| addresses.iter().next()); .to_string();
let addresses = info.get_addresses();
let ip = addresses
.iter()
.find(|ip| ip.is_ipv4())
.or_else(|| addresses.iter().next());
if let Some(ip) = ip { if let Some(ip) = ip {
let state = handle.state::<AppState>(); let state = handle.state::<AppState>();
let mut devices = state.known_devices.lock().unwrap(); let mut devices = state.known_devices.lock().unwrap();
let ip_str = ip.to_string(); let ip_str = ip.to_string();
if !devices.contains_key(&name) { if !devices.contains_key(&name) {
println!("Discovered Cast Device: {} at {}", name, ip_str); println!("Discovered Cast Device: {} at {}", name, ip_str);
devices.insert(name, ip_str); devices.insert(name.clone(), ip_str.clone());
// Emit event to frontend when new device is discovered.
let _ = handle.emit("cast-device-discovered", json!({
"name": name,
"ip": ip_str
}));
}
} }
} }
_ => {}
} }
_ => {}
} }
} });
}); });
Ok(()) Ok(())
}) })
.invoke_handler(tauri::generate_handler![ .invoke_handler(tauri::generate_handler![

View File

@@ -1050,6 +1050,17 @@ function setupEventListeners() {
await appWindow.close(); await appWindow.close();
}); });
// Listen for cast device discovery events from backend
if (runningInTauri && window.__TAURI__ && window.__TAURI__.event) {
window.__TAURI__.event.listen('cast-device-discovered', (event) => {
console.log('Cast device discovered:', event.payload);
// If cast overlay is currently open, refresh the device list
if (!castOverlay.classList.contains('hidden')) {
refreshCastDeviceList();
}
});
}
// Menu button - explicit functionality or placeholder? // Menu button - explicit functionality or placeholder?
// Menu removed — header click opens stations via artwork placeholder // Menu removed — header click opens stations via artwork placeholder
@@ -1353,6 +1364,10 @@ async function openCastOverlay() {
castOverlay.setAttribute('aria-hidden', 'false'); castOverlay.setAttribute('aria-hidden', 'false');
// ensure cast overlay shows linear list style // ensure cast overlay shows linear list style
deviceListEl.classList.remove('stations-grid'); deviceListEl.classList.remove('stations-grid');
await refreshCastDeviceList();
}
async function refreshCastDeviceList() {
deviceListEl.innerHTML = '<li class="device"><div class="device-main">Scanning...</div><div class="device-sub">Searching for speakers</div></li>'; deviceListEl.innerHTML = '<li class="device"><div class="device-main">Scanning...</div><div class="device-sub">Searching for speakers</div></li>';
try { try {