Compare commits

...

10 Commits

9 changed files with 256 additions and 212 deletions

View File

@@ -396,6 +396,12 @@ async function start() {
res.set('Cache-Control', 'no-store, no-cache, must-revalidate, private'); res.set('Cache-Control', 'no-store, no-cache, must-revalidate, private');
} }
})); }));
expressApp.use(express.static(path.join(frontendDir, 'src'), {
etag: false,
setHeaders: (res) => {
res.set('Cache-Control', 'no-store, no-cache, must-revalidate, private');
}
}));
expressApp.get('*', (req, res) => { expressApp.get('*', (req, res) => {
res.set('Cache-Control', 'no-store, no-cache, must-revalidate, private'); res.set('Cache-Control', 'no-store, no-cache, must-revalidate, private');
res.sendFile(path.join(frontendDir, 'index.html')); res.sendFile(path.join(frontendDir, 'index.html'));
@@ -407,7 +413,7 @@ async function start() {
playerExpressApp.use('/build', express.static(path.join(__dirname, 'build'))); playerExpressApp.use('/build', express.static(path.join(__dirname, 'build')));
} }
expressServer = expressApp.listen(FRONTEND_PORT, '127.0.0.1', () => { expressServer = expressApp.listen(FRONTEND_PORT, () => {
sendToTauri('status', { message: 'All backend services running and healthy.' }); sendToTauri('status', { message: 'All backend services running and healthy.' });
debugLog("Frontend Express running on 4890. Sending READY to Tauri."); debugLog("Frontend Express running on 4890. Sending READY to Tauri.");
sendToTauri('ready', { url: `http://localhost:${FRONTEND_PORT}` }); sendToTauri('ready', { url: `http://localhost:${FRONTEND_PORT}` });

View File

@@ -1,6 +1,6 @@
{ {
"name": "vyla-home", "name": "vyla-home",
"version": "1.1.25", "version": "1.1.31",
"description": "Vyla Home Desktop App Launcher", "description": "Vyla Home Desktop App Launcher",
"main": "main.js", "main": "main.js",
"scripts": { "scripts": {

69
src-tauri/Cargo.lock generated
View File

@@ -270,7 +270,7 @@ version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5" checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5"
dependencies = [ dependencies = [
"objc2", "objc2 0.6.4",
] ]
[[package]] [[package]]
@@ -762,7 +762,7 @@ dependencies = [
"bitflags 2.13.1", "bitflags 2.13.1",
"block2", "block2",
"libc", "libc",
"objc2", "objc2 0.6.4",
] ]
[[package]] [[package]]
@@ -2079,7 +2079,7 @@ dependencies = [
"dpi", "dpi",
"gtk", "gtk",
"keyboard-types", "keyboard-types",
"objc2", "objc2 0.6.4",
"objc2-app-kit", "objc2-app-kit",
"objc2-core-foundation", "objc2-core-foundation",
"objc2-foundation", "objc2-foundation",
@@ -2157,6 +2157,22 @@ dependencies = [
"syn 2.0.119", "syn 2.0.119",
] ]
[[package]]
name = "objc-sys"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310"
[[package]]
name = "objc2"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804"
dependencies = [
"objc-sys",
"objc2-encode",
]
[[package]] [[package]]
name = "objc2" name = "objc2"
version = "0.6.4" version = "0.6.4"
@@ -2175,7 +2191,7 @@ checksum = "d49e936b501e5c5bf01fda3a9452ff86dc3ea98ad5f283e1455153142d97518c"
dependencies = [ dependencies = [
"bitflags 2.13.1", "bitflags 2.13.1",
"block2", "block2",
"objc2", "objc2 0.6.4",
"objc2-core-foundation", "objc2-core-foundation",
"objc2-foundation", "objc2-foundation",
] ]
@@ -2187,7 +2203,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73ad74d880bb43877038da939b7427bba67e9dd42004a18b809ba7d87cee241c" checksum = "73ad74d880bb43877038da939b7427bba67e9dd42004a18b809ba7d87cee241c"
dependencies = [ dependencies = [
"bitflags 2.13.1", "bitflags 2.13.1",
"objc2", "objc2 0.6.4",
"objc2-foundation", "objc2-foundation",
] ]
@@ -2197,7 +2213,7 @@ version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b402a653efbb5e82ce4df10683b6b28027616a2715e90009947d50b8dd298fa" checksum = "0b402a653efbb5e82ce4df10683b6b28027616a2715e90009947d50b8dd298fa"
dependencies = [ dependencies = [
"objc2", "objc2 0.6.4",
"objc2-foundation", "objc2-foundation",
] ]
@@ -2209,7 +2225,7 @@ checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536"
dependencies = [ dependencies = [
"bitflags 2.13.1", "bitflags 2.13.1",
"dispatch2", "dispatch2",
"objc2", "objc2 0.6.4",
] ]
[[package]] [[package]]
@@ -2220,7 +2236,7 @@ checksum = "e022c9d066895efa1345f8e33e584b9f958da2fd4cd116792e15e07e4720a807"
dependencies = [ dependencies = [
"bitflags 2.13.1", "bitflags 2.13.1",
"dispatch2", "dispatch2",
"objc2", "objc2 0.6.4",
"objc2-core-foundation", "objc2-core-foundation",
"objc2-io-surface", "objc2-io-surface",
] ]
@@ -2231,7 +2247,7 @@ version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5d563b38d2b97209f8e861173de434bd0214cf020e3423a52624cd1d989f006" checksum = "e5d563b38d2b97209f8e861173de434bd0214cf020e3423a52624cd1d989f006"
dependencies = [ dependencies = [
"objc2", "objc2 0.6.4",
"objc2-foundation", "objc2-foundation",
] ]
@@ -2241,7 +2257,7 @@ version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca347214e24bc973fc025fd0d36ebb179ff30536ed1f80252706db19ee452009" checksum = "ca347214e24bc973fc025fd0d36ebb179ff30536ed1f80252706db19ee452009"
dependencies = [ dependencies = [
"objc2", "objc2 0.6.4",
"objc2-foundation", "objc2-foundation",
] ]
@@ -2252,7 +2268,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0cde0dfb48d25d2b4862161a4d5fcc0e3c24367869ad306b0c9ec0073bfed92d" checksum = "0cde0dfb48d25d2b4862161a4d5fcc0e3c24367869ad306b0c9ec0073bfed92d"
dependencies = [ dependencies = [
"bitflags 2.13.1", "bitflags 2.13.1",
"objc2", "objc2 0.6.4",
"objc2-core-foundation", "objc2-core-foundation",
"objc2-core-graphics", "objc2-core-graphics",
] ]
@@ -2280,7 +2296,7 @@ checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272"
dependencies = [ dependencies = [
"bitflags 2.13.1", "bitflags 2.13.1",
"block2", "block2",
"objc2", "objc2 0.6.4",
"objc2-core-foundation", "objc2-core-foundation",
] ]
@@ -2291,7 +2307,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "180788110936d59bab6bd83b6060ffdfffb3b922ba1396b312ae795e1de9d81d" checksum = "180788110936d59bab6bd83b6060ffdfffb3b922ba1396b312ae795e1de9d81d"
dependencies = [ dependencies = [
"bitflags 2.13.1", "bitflags 2.13.1",
"objc2", "objc2 0.6.4",
"objc2-core-foundation", "objc2-core-foundation",
] ]
@@ -2302,7 +2318,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96c1358452b371bf9f104e21ec536d37a650eb10f7ee379fff67d2e08d537f1f" checksum = "96c1358452b371bf9f104e21ec536d37a650eb10f7ee379fff67d2e08d537f1f"
dependencies = [ dependencies = [
"bitflags 2.13.1", "bitflags 2.13.1",
"objc2", "objc2 0.6.4",
"objc2-core-foundation", "objc2-core-foundation",
"objc2-foundation", "objc2-foundation",
] ]
@@ -2315,7 +2331,7 @@ checksum = "d87d638e33c06f577498cbcc50491496a3ed4246998a7fbba7ccb98b1e7eab22"
dependencies = [ dependencies = [
"bitflags 2.13.1", "bitflags 2.13.1",
"block2", "block2",
"objc2", "objc2 0.6.4",
"objc2-cloud-kit", "objc2-cloud-kit",
"objc2-core-data", "objc2-core-data",
"objc2-core-foundation", "objc2-core-foundation",
@@ -2334,7 +2350,7 @@ version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9df9128cbbfef73cda168416ccf7f837b62737d748333bfe9ab71c245d76613e" checksum = "9df9128cbbfef73cda168416ccf7f837b62737d748333bfe9ab71c245d76613e"
dependencies = [ dependencies = [
"objc2", "objc2 0.6.4",
"objc2-foundation", "objc2-foundation",
] ]
@@ -2346,7 +2362,7 @@ checksum = "b2e5aaab980c433cf470df9d7af96a7b46a9d892d521a2cbbb2f8a4c16751e7f"
dependencies = [ dependencies = [
"bitflags 2.13.1", "bitflags 2.13.1",
"block2", "block2",
"objc2", "objc2 0.6.4",
"objc2-app-kit", "objc2-app-kit",
"objc2-core-foundation", "objc2-core-foundation",
"objc2-foundation", "objc2-foundation",
@@ -3211,7 +3227,7 @@ dependencies = [
"bytemuck", "bytemuck",
"js-sys", "js-sys",
"ndk", "ndk",
"objc2", "objc2 0.6.4",
"objc2-core-foundation", "objc2-core-foundation",
"objc2-core-graphics", "objc2-core-graphics",
"objc2-foundation", "objc2-foundation",
@@ -3385,7 +3401,7 @@ dependencies = [
"log", "log",
"ndk", "ndk",
"ndk-sys", "ndk-sys",
"objc2", "objc2 0.6.4",
"objc2-app-kit", "objc2-app-kit",
"objc2-foundation", "objc2-foundation",
"objc2-ui-kit", "objc2-ui-kit",
@@ -3441,7 +3457,7 @@ dependencies = [
"log", "log",
"mime", "mime",
"muda", "muda",
"objc2", "objc2 0.6.4",
"objc2-app-kit", "objc2-app-kit",
"objc2-foundation", "objc2-foundation",
"objc2-ui-kit", "objc2-ui-kit",
@@ -3612,7 +3628,7 @@ dependencies = [
"gtk", "gtk",
"http", "http",
"jni", "jni",
"objc2", "objc2 0.6.4",
"objc2-ui-kit", "objc2-ui-kit",
"objc2-web-kit", "objc2-web-kit",
"raw-window-handle", "raw-window-handle",
@@ -3636,7 +3652,7 @@ dependencies = [
"http", "http",
"jni", "jni",
"log", "log",
"objc2", "objc2 0.6.4",
"objc2-app-kit", "objc2-app-kit",
"once_cell", "once_cell",
"percent-encoding", "percent-encoding",
@@ -4051,7 +4067,7 @@ dependencies = [
"dirs", "dirs",
"libappindicator", "libappindicator",
"muda", "muda",
"objc2", "objc2 0.6.4",
"objc2-app-kit", "objc2-app-kit",
"objc2-core-foundation", "objc2-core-foundation",
"objc2-core-graphics", "objc2-core-graphics",
@@ -4222,9 +4238,10 @@ dependencies = [
[[package]] [[package]]
name = "vyla-home" name = "vyla-home"
version = "1.1.25" version = "1.1.31"
dependencies = [ dependencies = [
"base64 0.22.1", "base64 0.22.1",
"objc2 0.5.2",
"serde", "serde",
"serde_json", "serde_json",
"tauri", "tauri",
@@ -4475,7 +4492,7 @@ version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9bec5a31f3f9362f2258fd0e9c9dd61a9ca432e7306cc78c444258f0dce9a9c" checksum = "d9bec5a31f3f9362f2258fd0e9c9dd61a9ca432e7306cc78c444258f0dce9a9c"
dependencies = [ dependencies = [
"objc2", "objc2 0.6.4",
"objc2-app-kit", "objc2-app-kit",
"objc2-core-foundation", "objc2-core-foundation",
"objc2-foundation", "objc2-foundation",
@@ -4930,7 +4947,7 @@ dependencies = [
"jni", "jni",
"libc", "libc",
"ndk", "ndk",
"objc2", "objc2 0.6.4",
"objc2-app-kit", "objc2-app-kit",
"objc2-core-foundation", "objc2-core-foundation",
"objc2-foundation", "objc2-foundation",

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "vyla-home" name = "vyla-home"
version = "1.1.25" version = "1.1.31"
description = "Vyla Home Desktop App Launcher" description = "Vyla Home Desktop App Launcher"
edition = "2021" edition = "2021"
@@ -16,6 +16,9 @@ serde = { version = "1", features = ["derive"] }
serde_json = "1" serde_json = "1"
base64 = "0.22" base64 = "0.22"
[target.'cfg(target_os = "macos")'.dependencies]
objc2 = "0.5"
[profile.release] [profile.release]
opt-level = 3 opt-level = 3
lto = true lto = true

View File

@@ -6,16 +6,8 @@
<dict> <dict>
<key>NSAllowsLocalNetworking</key> <key>NSAllowsLocalNetworking</key>
<true/> <true/>
<key>NSExceptionDomains</key> <key>NSAllowsArbitraryLoads</key>
<dict> <true/>
<key>localhost</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSIncludesSubdomains</key>
<false/>
</dict>
</dict>
</dict> </dict>
</dict> </dict>
</plist> </plist>

View File

@@ -16,5 +16,17 @@ fn main() {
} }
} }
#[cfg(unix)]
{
use std::os::unix::fs::PermissionsExt;
let node_path = std::path::Path::new("../bin/node");
if node_path.exists() {
let _ = std::fs::set_permissions(
node_path,
std::fs::Permissions::from_mode(0o755),
);
}
}
tauri_build::build(); tauri_build::build();
} }

View File

@@ -7,11 +7,19 @@ use tauri::{Emitter, Manager, State, WebviewUrl, WebviewWindowBuilder};
fn debug_log(msg: &str) { fn debug_log(msg: &str) {
let log_dir = if let Ok(app_data) = std::env::var("APPDATA") { let log_dir = if let Ok(app_data) = std::env::var("APPDATA") {
std::path::PathBuf::from(app_data).join("vyla-home").join("vyla-home-files").join("logs") std::path::PathBuf::from(app_data)
.join("vyla-home")
.join("vyla-home-files")
.join("logs")
} else if let Ok(home) = std::env::var("HOME") { } else if let Ok(home) = std::env::var("HOME") {
std::path::PathBuf::from(home).join("Library").join("Logs").join("VylaHome") std::path::PathBuf::from(home)
.join("Library")
.join("Logs")
.join("VylaHome")
} else if let Ok(user_profile) = std::env::var("USERPROFILE") { } else if let Ok(user_profile) = std::env::var("USERPROFILE") {
std::path::PathBuf::from(user_profile).join(".vyla-home").join("logs") std::path::PathBuf::from(user_profile)
.join(".vyla-home")
.join("logs")
} else { } else {
std::env::temp_dir().join("vyla-home-logs") std::env::temp_dir().join("vyla-home-logs")
}; };
@@ -19,7 +27,11 @@ fn debug_log(msg: &str) {
let _ = std::fs::create_dir_all(&log_dir); let _ = std::fs::create_dir_all(&log_dir);
let log_path = log_dir.join("rust-debug.log"); let log_path = log_dir.join("rust-debug.log");
if let Ok(mut file) = std::fs::OpenOptions::new().create(true).append(true).open(&log_path) { if let Ok(mut file) = std::fs::OpenOptions::new()
.create(true)
.append(true)
.open(&log_path)
{
use std::io::Write; use std::io::Write;
let _ = writeln!(file, "[RUST] {}", msg); let _ = writeln!(file, "[RUST] {}", msg);
} }
@@ -109,6 +121,7 @@ fn find_node_binary(app: &tauri::App) -> Option<String> {
if node_exe.exists() { if node_exe.exists() {
return Some(clean_path(&node_exe)); return Some(clean_path(&node_exe));
} }
let node = p.join("node"); let node = p.join("node");
if node.exists() { if node.exists() {
return Some(clean_path(&node)); return Some(clean_path(&node));
@@ -166,7 +179,6 @@ fn resolve_script_and_root(app: &tauri::App) -> (String, String) {
resource_dir.join("_up_").join("main.js"), resource_dir.join("_up_").join("main.js"),
resource_dir.join("up").join("main.js"), resource_dir.join("up").join("main.js"),
]; ];
for candidate in candidates { for candidate in candidates {
if candidate.exists() { if candidate.exists() {
let root_dir = candidate.parent().unwrap(); let root_dir = candidate.parent().unwrap();
@@ -325,10 +337,7 @@ const LINK_HANDLER_SCRIPT: &str = r##"
padding: 0 !important; padding: 0 !important;
} }
.vyla-nav-btn:hover { .vyla-nav-btn:hover { opacity: 1 !important; }
opacity: 1 !important;
}
.vyla-nav-btn svg { .vyla-nav-btn svg {
width: 20px !important; width: 20px !important;
height: 20px !important; height: 20px !important;
@@ -455,11 +464,12 @@ const LINK_HANDLER_SCRIPT: &str = r##"
} }
} }
if (document.readyState === 'loading') { if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', injectLiquidNavBar); document.addEventListener('DOMContentLoaded', injectLiquidNavBar);
} else { } else {
injectLiquidNavBar(); injectLiquidNavBar();
} }
const navObserver = new MutationObserver(() => { const navObserver = new MutationObserver(() => {
if (!document.getElementById('vyla-floating-nav')) { if (!document.getElementById('vyla-floating-nav')) {
injectLiquidNavBar(); injectLiquidNavBar();
@@ -503,9 +513,9 @@ fn open_new_window(app: tauri::AppHandle, url: String) -> Result<(), String> {
let final_url = if url.starts_with("http") || url.starts_with("tauri://") { let final_url = if url.starts_with("http") || url.starts_with("tauri://") {
url.clone() url.clone()
} else if url.starts_with('/') { } else if url.starts_with('/') {
format!("http://localhost:4890{}", url) format!("http://127.0.0.1:4890{}", url)
} else { } else {
format!("http://localhost:4890/{}", url) format!("http://127.0.0.1:4890/{}", url)
}; };
if let Some(window) = app.get_webview_window("main") { if let Some(window) = app.get_webview_window("main") {
@@ -578,6 +588,123 @@ fn get_logo_base64(app: tauri::AppHandle) -> Result<String, String> {
Err("icon_white.png not found".to_string()) Err("icon_white.png not found".to_string())
} }
fn handle_tauri_cmd(w: &tauri::WebviewWindow, msg: &BackendMessage) {
let window_label = msg
.data
.get("window")
.and_then(|v| v.as_str())
.unwrap_or("main");
debug_log(&format!("[MAIN-DEBUG] Finding window by label: {}", window_label));
let cmd_window = match w.app_handle().get_webview_window(window_label) {
Some(win) => win,
None => {
debug_log(&format!("[TAURI-CMD] Window '{}' NOT FOUND!", window_label));
return;
}
};
let cmd = match msg.data.get("cmd").and_then(|c| c.as_str()) {
Some(c) => c,
None => return,
};
debug_log(&format!("[TAURI-CMD] Executing action: {}", cmd));
match cmd {
"win_minimize" => {
let res = cmd_window.minimize();
debug_log(&format!("[TAURI-CMD] Minimize result: {:?}", res));
}
"win_maximize" => {
let is_max = cmd_window.is_maximized().unwrap_or(false);
debug_log(&format!("[TAURI-CMD] Currently maximized: {}", is_max));
let res = if is_max {
cmd_window.unmaximize()
} else {
cmd_window.maximize()
};
debug_log(&format!("[TAURI-CMD] Maximize/Unmaximize result: {:?}", res));
}
"win_close" => {
let res = cmd_window.close();
debug_log(&format!("[TAURI-CMD] Close result: {:?}", res));
}
"win_drag" => {
let res = cmd_window.start_dragging();
debug_log(&format!("[TAURI-CMD] Drag result: {:?}", res));
}
"open_new_window" => {
debug_log("[TAURI-CMD-DEBUG] open_new_window command received");
debug_log(&format!(
"[TAURI-CMD-DEBUG] Full message data: {}",
serde_json::to_string(&msg.data).unwrap_or_default()
));
let url = match msg.data.get("url").and_then(|u| u.as_str()) {
Some(u) => u.to_string(),
None => {
debug_log("[TAURI-CMD-DEBUG] ERROR: No URL found in message data");
debug_log(&format!(
"[TAURI-CMD-DEBUG] Available keys: {:?}",
msg.data.as_object().map(|o| o.keys().collect::<Vec<_>>())
));
return;
}
};
debug_log(&format!("[TAURI-CMD-DEBUG] URL extracted: {}", url));
debug_log(&format!("[TAURI-CMD-DEBUG] URL length: {}", url.len()));
debug_log("[TAURI-CMD-DEBUG] Attempting to dispatch to main thread");
let app_handle = w.app_handle().clone();
let closure_handle = app_handle.clone();
match app_handle.run_on_main_thread(move || {
debug_log("[TAURI-CMD-DEBUG] Now on main thread, calling open_new_window");
match open_new_window(closure_handle, url) {
Ok(_) => debug_log("[TAURI-CMD-DEBUG] open_new_window succeeded"),
Err(e) => debug_log(&format!("[TAURI-CMD-DEBUG] open_new_window error: {}", e)),
}
}) {
Ok(_) => debug_log("[TAURI-CMD-DEBUG] Main thread dispatch succeeded"),
Err(e) => debug_log(&format!("[TAURI-CMD-DEBUG] Main thread dispatch failed: {}", e)),
}
}
_ => {}
}
}
fn handle_ready(w: &tauri::WebviewWindow, msg: &BackendMessage) {
let url_str = match msg.data.get("url").and_then(|u| u.as_str()) {
Some(u) => u,
None => return,
};
let url_parsed = match url_str.parse::<tauri::Url>() {
Ok(u) => u,
Err(_) => return,
};
#[cfg(target_os = "macos")]
{
use objc2::msg_send;
use objc2::runtime::AnyObject;
debug_log("Attempting with_webview on ready event");
let result = w.with_webview(|webview| unsafe {
debug_log("Inside with_webview closure");
let wk_webview = webview.inner() as *mut AnyObject;
let config: *mut AnyObject = msg_send![wk_webview, configuration];
let _: () = msg_send![config, setUpgradeKnownHostsToHTTPS: false];
debug_log("setUpgradeKnownHostsToHTTPS set to false");
});
debug_log(&format!("with_webview result: {:?}", result));
}
let _ = w.navigate(url_parsed);
}
fn main() { fn main() {
debug_log("=== Vyla Home Executable Started ==="); debug_log("=== Vyla Home Executable Started ===");
@@ -603,7 +730,7 @@ fn main() {
std::path::PathBuf::from(appdata_env) std::path::PathBuf::from(appdata_env)
.join("vyla-home") .join("vyla-home")
.join("vyla-home-files") .join("vyla-home-files")
} else if let Ok(home) = std::env::var("HOME") { } else if let Ok(home) = std::env::var("HOME") {
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
let base = std::path::PathBuf::from(&home) let base = std::path::PathBuf::from(&home)
.join("Library") .join("Library")
@@ -640,7 +767,10 @@ fn main() {
} }
if version_mismatch { if version_mismatch {
debug_log(&format!("App version updated to {}. Cleaning old files.", current_app_version)); debug_log(&format!(
"App version updated to {}. Cleaning old files.",
current_app_version
));
let dirs_to_remove = ["frontend", "player", "stream-api", "auth-proxy", "config"]; let dirs_to_remove = ["frontend", "player", "stream-api", "auth-proxy", "config"];
for d in dirs_to_remove { for d in dirs_to_remove {
let _ = std::fs::remove_dir_all(vyla_files.join(d)); let _ = std::fs::remove_dir_all(vyla_files.join(d));
@@ -660,6 +790,7 @@ fn main() {
let (main_js, root_dir) = resolve_script_and_root(app); let (main_js, root_dir) = resolve_script_and_root(app);
debug_log("Searching for node binary..."); debug_log("Searching for node binary...");
let node_bin = match find_node_binary(app) { let node_bin = match find_node_binary(app) {
Some(bin) => { Some(bin) => {
debug_log(&format!("Found node binary: {}", bin)); debug_log(&format!("Found node binary: {}", bin));
@@ -675,7 +806,6 @@ fn main() {
}; };
let vyla_files_str = clean_path(&vyla_files); let vyla_files_str = clean_path(&vyla_files);
std::thread::sleep(std::time::Duration::from_millis(400)); std::thread::sleep(std::time::Duration::from_millis(400));
let mut cmd = Command::new(&node_bin); let mut cmd = Command::new(&node_bin);
@@ -700,6 +830,7 @@ fn main() {
"Node child process spawned successfully, PID: {}", "Node child process spawned successfully, PID: {}",
child.id() child.id()
)); ));
if let Some(stderr) = child.stderr.take() { if let Some(stderr) = child.stderr.take() {
let w = window.clone(); let w = window.clone();
std::thread::spawn(move || { std::thread::spawn(move || {
@@ -707,8 +838,14 @@ fn main() {
let reader = BufReader::new(stderr); let reader = BufReader::new(stderr);
for line in reader.lines().flatten() { for line in reader.lines().flatten() {
debug_log(&format!("[NODE STDERR] {}", line)); debug_log(&format!("[NODE STDERR] {}", line));
if line.contains("Error") || line.contains("Exception") || line.contains("MODULE_NOT_FOUND") { if line.contains("Error")
let _ = w.emit("error", serde_json::json!({ "message": format!("Backend failed: {}", line) })); || line.contains("Exception")
|| line.contains("MODULE_NOT_FOUND")
{
let _ = w.emit(
"error",
serde_json::json!({ "message": format!("Backend failed: {}", line) }),
);
} }
} }
}); });
@@ -721,144 +858,22 @@ fn main() {
let reader = BufReader::new(stdout); let reader = BufReader::new(stdout);
for line in reader.lines().flatten() { for line in reader.lines().flatten() {
debug_log(&format!("[NODE STDOUT] {}", line)); debug_log(&format!("[NODE STDOUT] {}", line));
if let Ok(msg) = serde_json::from_str::<BackendMessage>(&line) {
debug_log(&format!("[MAIN-DEBUG] Received event: {}", msg.event));
debug_log(&format!(
"[MAIN-DEBUG] Event data: {}",
serde_json::to_string(&msg.data).unwrap_or_default()
));
if msg.event == "tauri-cmd" {
let window_label = msg
.data
.get("window")
.and_then(|val| val.as_str())
.unwrap_or("main");
debug_log(&format!(
"[MAIN-DEBUG] Finding window by label: {}",
window_label
));
if let Some(cmd_window) = let msg = match serde_json::from_str::<BackendMessage>(&line) {
w.app_handle().get_webview_window(window_label) Ok(m) => m,
{ Err(_) => continue,
if let Some(cmd) = };
msg.data.get("cmd").and_then(|c| c.as_str())
{ debug_log(&format!("[MAIN-DEBUG] Received event: {}", msg.event));
debug_log(&format!( debug_log(&format!(
"[TAURI-CMD] Executing action: {}", "[MAIN-DEBUG] Event data: {}",
cmd serde_json::to_string(&msg.data).unwrap_or_default()
)); ));
match cmd {
"win_minimize" => { match msg.event.as_str() {
let res = cmd_window.minimize(); "tauri-cmd" => handle_tauri_cmd(&w, &msg),
debug_log(&format!( "ready" => handle_ready(&w, &msg),
"[TAURI-CMD] Minimize result: {:?}", _ => {
res
));
}
"win_maximize" => {
let is_max = cmd_window
.is_maximized()
.unwrap_or(false);
debug_log(&format!(
"[TAURI-CMD] Currently maximized: {}",
is_max
));
let res = if is_max {
cmd_window.unmaximize()
} else {
cmd_window.maximize()
};
debug_log(&format!(
"[TAURI-CMD] Maximize/Unmaximize result: {:?}",
res
));
}
"win_close" => {
let res = cmd_window.close();
debug_log(&format!(
"[TAURI-CMD] Close result: {:?}",
res
));
}
"win_drag" => {
let res = cmd_window.start_dragging();
debug_log(&format!(
"[TAURI-CMD] Drag result: {:?}",
res
));
}
"open_new_window" => {
debug_log("[TAURI-CMD-DEBUG] open_new_window command received");
debug_log(&format!(
"[TAURI-CMD-DEBUG] Full message data: {}",
serde_json::to_string(&msg.data)
.unwrap_or_default()
));
if let Some(url) = msg
.data
.get("url")
.and_then(|u| u.as_str())
{
debug_log(&format!(
"[TAURI-CMD-DEBUG] URL extracted: {}",
url
));
debug_log(&format!(
"[TAURI-CMD-DEBUG] URL length: {}",
url.len()
));
debug_log("[TAURI-CMD-DEBUG] Attempting to dispatch to main thread");
let app_handle = w.app_handle().clone();
let closure_handle = app_handle.clone();
let url_owned = url.to_string();
let dispatch_result = app_handle
.run_on_main_thread(move || {
debug_log("[TAURI-CMD-DEBUG] Now on main thread, calling open_new_window");
match open_new_window(
closure_handle,
url_owned,
) {
Ok(_) => {
debug_log("[TAURI-CMD-DEBUG] open_new_window succeeded");
}
Err(e) => {
debug_log(&format!(
"[TAURI-CMD-DEBUG] open_new_window error: {}",
e
));
}
}
});
match dispatch_result {
Ok(_) => debug_log(
"[TAURI-CMD-DEBUG] Main thread dispatch succeeded",
),
Err(e) => debug_log(&format!(
"[TAURI-CMD-DEBUG] Main thread dispatch failed: {}",
e
)),
}
} else {
debug_log("[TAURI-CMD-DEBUG] ERROR: No URL found in message data");
debug_log(&format!(
"[TAURI-CMD-DEBUG] Available keys: {:?}",
msg.data
.as_object()
.map(|o| o.keys().collect::<Vec<_>>())
));
}
}
_ => {}
}
}
} else {
debug_log(&format!(
"[TAURI-CMD] Window '{}' NOT FOUND!",
window_label
));
}
} else {
let _ = w.emit(&msg.event, msg.data.clone()); let _ = w.emit(&msg.event, msg.data.clone());
} }
} }
@@ -884,7 +899,7 @@ fn main() {
Ok(()) Ok(())
}) })
.on_window_event(|window, event| { .on_window_event(|window, event| {
if let tauri::WindowEvent::Destroyed = event { if let tauri::WindowEvent::Destroyed = event {
if window.label() == "main" { if window.label() == "main" {
let state: State<NodeServices> = window.state(); let state: State<NodeServices> = window.state();

View File

@@ -1,7 +1,7 @@
{ {
"$schema": "https://schema.tauri.app/config/2", "$schema": "https://schema.tauri.app/config/2",
"productName": "Vyla Home", "productName": "Vyla Home",
"version": "1.1.25", "version": "1.1.31",
"identifier": "com.vyla.home", "identifier": "com.vyla.home",
"build": { "build": {
"frontendDist": "../ui" "frontendDist": "../ui"
@@ -24,7 +24,7 @@
], ],
"macOS": { "macOS": {
"exceptionDomain": "localhost", "exceptionDomain": "localhost",
"infoPlist": "../Info.plist" "infoPlist": "Info.plist"
}, },
"windows": { "windows": {
"webviewInstallMode": { "webviewInstallMode": {

View File

@@ -587,7 +587,6 @@ void main() {
const data = e.payload || e; const data = e.payload || e;
if (data && data.url) { if (data && data.url) {
setStatus("Launching..."); setStatus("Launching...");
window.location.replace(data.url);
} }
}); });