@@ -304,20 +304,27 @@ impl BackendState {
304304 . clone ( )
305305 . unwrap_or_else ( || backend_dir. to_path_buf ( ) )
306306 } ) ;
307- let webui_dir = env:: var ( "ASTRBOT_WEBUI_DIR" )
307+ let embedded_webui_dir = env:: var ( "ASTRBOT_WEBUI_DIR" )
308308 . ok ( )
309309 . map ( PathBuf :: from)
310310 . or_else ( || {
311311 resolve_resource_path ( app, "webui/index.html" )
312312 . and_then ( |index_path| index_path. parent ( ) . map ( Path :: to_path_buf) )
313313 } ) ;
314+ let webui_dir = resolve_packaged_webui_dir ( embedded_webui_dir, root_dir. as_deref ( ) ) ?;
315+
316+ let args = vec ! [
317+ launch_script_path. to_string_lossy( ) . to_string( ) ,
318+ "--webui-dir" . to_string( ) ,
319+ webui_dir. to_string_lossy( ) . to_string( ) ,
320+ ] ;
314321
315322 let plan = LaunchPlan {
316323 cmd : python_path. to_string_lossy ( ) . to_string ( ) ,
317- args : vec ! [ launch_script_path . to_string_lossy ( ) . to_string ( ) ] ,
324+ args,
318325 cwd,
319326 root_dir,
320- webui_dir,
327+ webui_dir : Some ( webui_dir ) ,
321328 packaged_mode : true ,
322329 } ;
323330 Ok ( Some ( plan) )
@@ -1176,7 +1183,10 @@ fn main() {
11761183 } )
11771184 . on_page_load ( |webview, payload| match payload. event ( ) {
11781185 PageLoadEvent :: Started => {
1179- append_desktop_log ( & format ! ( "page-load started: {}" , payload. url( ) ) )
1186+ append_desktop_log ( & format ! ( "page-load started: {}" , payload. url( ) ) ) ;
1187+ if should_inject_desktop_bridge ( webview. app_handle ( ) , payload. url ( ) ) {
1188+ inject_desktop_bridge ( webview) ;
1189+ }
11801190 }
11811191 PageLoadEvent :: Finished => {
11821192 append_desktop_log ( & format ! ( "page-load finished: {}" , payload. url( ) ) ) ;
@@ -1622,6 +1632,14 @@ fn update_tray_menu_labels(app_handle: &AppHandle) {
16221632
16231633const DESKTOP_BRIDGE_BOOTSTRAP_SCRIPT : & str = r#"
16241634(() => {
1635+ if (
1636+ window.astrbotDesktop &&
1637+ window.astrbotDesktop.__tauriBridge === true &&
1638+ typeof window.astrbotDesktop.onTrayRestartBackend === 'function'
1639+ ) {
1640+ return;
1641+ }
1642+
16251643 const invoke = window.__TAURI_INTERNALS__?.invoke;
16261644 if (typeof invoke !== 'function') return;
16271645
@@ -1998,7 +2016,7 @@ fn should_inject_desktop_bridge(app_handle: &AppHandle, page_url: &Url) -> bool
19982016 let Ok ( backend_url) = Url :: parse ( & state. backend_url ) else {
19992017 return false ;
20002018 } ;
2001- same_origin ( & backend_url, page_url)
2019+ tray_origin_decision ( & backend_url, page_url) . uses_backend_origin
20022020}
20032021
20042022fn inject_desktop_bridge ( webview : & tauri:: Webview < tauri:: Wry > ) {
@@ -2160,6 +2178,109 @@ fn default_packaged_root_dir() -> Option<PathBuf> {
21602178 dirs:: home_dir ( ) . map ( |home| home. join ( ".astrbot" ) )
21612179}
21622180
2181+ fn packaged_fallback_webui_probe_dir ( root_dir : Option < & Path > ) -> Option < PathBuf > {
2182+ match root_dir {
2183+ Some ( root) => Some ( root. join ( "data" ) . join ( "dist" ) ) ,
2184+ None => default_packaged_root_dir ( ) . map ( |root| root. join ( "data" ) . join ( "dist" ) ) ,
2185+ }
2186+ }
2187+
2188+ fn packaged_fallback_webui_dir ( root_dir : Option < & Path > ) -> Option < PathBuf > {
2189+ let candidate = packaged_fallback_webui_probe_dir ( root_dir) ?;
2190+ if candidate. join ( "index.html" ) . is_file ( ) {
2191+ Some ( candidate)
2192+ } else {
2193+ None
2194+ }
2195+ }
2196+
2197+ fn packaged_fallback_webui_index_display ( root_dir : Option < & Path > ) -> String {
2198+ packaged_fallback_webui_probe_dir ( root_dir)
2199+ . map ( |path| path. join ( "index.html" ) . display ( ) . to_string ( ) )
2200+ . unwrap_or_else ( || "<unresolved>" . to_string ( ) )
2201+ }
2202+
2203+ fn packaged_webui_unavailable_error ( locale : & str , embedded_index : Option < & Path > ) -> String {
2204+ if locale == "en-US" {
2205+ if let Some ( index) = embedded_index {
2206+ return format ! (
2207+ "Packaged WebUI is unavailable. Missing embedded index at {} and fallback data/dist. Please reinstall AstrBot or download the matching dist.zip to data/dist." ,
2208+ index. display( )
2209+ ) ;
2210+ }
2211+ return "Packaged WebUI directory is missing and fallback data/dist is unavailable. Please reinstall AstrBot or download the matching dist.zip to data/dist."
2212+ . to_string ( ) ;
2213+ }
2214+
2215+ if let Some ( index) = embedded_index {
2216+ return format ! (
2217+ "内置 WebUI 不可用。缺少内置入口文件:{},且回退目录 data/dist 也不可用。请重装 AstrBot,或下载匹配版本的 dist.zip 到 data/dist。" ,
2218+ index. display( )
2219+ ) ;
2220+ }
2221+
2222+ "内置 WebUI 目录缺失,且回退目录 data/dist 也不可用。请重装 AstrBot,或下载匹配版本的 dist.zip 到 data/dist。" . to_string ( )
2223+ }
2224+
2225+ fn resolve_packaged_webui_dir (
2226+ embedded_webui_dir : Option < PathBuf > ,
2227+ root_dir : Option < & Path > ,
2228+ ) -> Result < PathBuf , String > {
2229+ let locale = resolve_shell_locale ( ) ;
2230+ let fallback_webui_dir = packaged_fallback_webui_dir ( root_dir) ;
2231+
2232+ match embedded_webui_dir {
2233+ Some ( candidate) => {
2234+ let embedded_index = candidate. join ( "index.html" ) ;
2235+ if embedded_index. is_file ( ) {
2236+ return Ok ( candidate) ;
2237+ }
2238+
2239+ append_desktop_log ( & format ! (
2240+ "packaged webui index is missing at {}, trying fallback data/dist" ,
2241+ embedded_index. display( )
2242+ ) ) ;
2243+
2244+ if let Some ( fallback) = fallback_webui_dir {
2245+ append_desktop_log ( & format ! (
2246+ "using fallback webui directory: {}" ,
2247+ fallback. display( )
2248+ ) ) ;
2249+ return Ok ( fallback) ;
2250+ }
2251+
2252+ let fallback_index = packaged_fallback_webui_index_display ( root_dir) ;
2253+ append_desktop_log ( & format ! (
2254+ "packaged webui resolution failed: embedded index missing at {}, fallback index missing at {}" ,
2255+ embedded_index. display( ) ,
2256+ fallback_index
2257+ ) ) ;
2258+
2259+ Err ( packaged_webui_unavailable_error (
2260+ locale,
2261+ Some ( & embedded_index) ,
2262+ ) )
2263+ }
2264+ None => {
2265+ if let Some ( fallback) = fallback_webui_dir {
2266+ append_desktop_log ( & format ! (
2267+ "embedded webui directory not found, using fallback webui directory: {}" ,
2268+ fallback. display( )
2269+ ) ) ;
2270+ return Ok ( fallback) ;
2271+ }
2272+
2273+ let fallback_index = packaged_fallback_webui_index_display ( root_dir) ;
2274+ append_desktop_log ( & format ! (
2275+ "packaged webui resolution failed: embedded webui directory is missing, fallback index missing at {}" ,
2276+ fallback_index
2277+ ) ) ;
2278+
2279+ Err ( packaged_webui_unavailable_error ( locale, None ) )
2280+ }
2281+ }
2282+ }
2283+
21632284fn resolve_backend_timeout_ms ( packaged_mode : bool ) -> Option < Duration > {
21642285 let default_timeout_ms = if packaged_mode { 0_u64 } else { 20_000_u64 } ;
21652286 let parsed_timeout_ms = env:: var ( "ASTRBOT_BACKEND_TIMEOUT_MS" )
0 commit comments