// Learn more about Tauri commands at https://tauri.app/develop/calling-rust/ use std::env; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Mutex; use tauri::{Emitter, Manager, Runtime, WebviewUrl, WebviewWindow, WebviewWindowBuilder}; #[cfg(not(feature = "e2e"))] use tauri_plugin_deep_link::DeepLinkExt; use tauri_plugin_log::{Target, TargetKind}; // Store pending URLs that need to be handled when the window is ready static PENDING_URLS: Mutex> = Mutex::new(Vec::new()); // Set to true once the user has confirmed they want to quit, so the close // interceptor lets the next CloseRequested through instead of looping back // to the confirmation dialog. static QUIT_CONFIRMED: AtomicBool = AtomicBool::new(false); pub(crate) fn backend_error(code: &str) -> String { serde_json::json!({ "code": code }).to_string() } pub(crate) fn backend_error_with_detail(code: &str, detail: impl std::fmt::Display) -> String { serde_json::json!({ "code": code, "params": { "detail": detail.to_string() } }).to_string() } /// A share link Donut cannot use, carrying which part is unsupported so the UI /// can say so instead of implying a typo. The code keeps its VLESS name because /// REST clients already match on it. pub(crate) fn vless_config_error(error: &crate::xray::XrayError) -> String { serde_json::json!({ "code": "VLESS_CONFIG_INVALID", "params": { "reason": error.reason_code(), "detail": error.to_string() } }) .to_string() } /// `donutbrowser_lib::sync::scheduler` -> `sync::scheduler`, `lib.rs` itself /// -> `app`, and `webview::