From 82ece364b459eccc1555b53b85867bd4de69296c Mon Sep 17 00:00:00 2001 From: Ayaka Neko Date: Fri, 1 Aug 2025 15:44:05 +0800 Subject: [PATCH] fix(stage-tamagotchi): onboarding white screen Close #337 --- .../src-tauri/src/app/commands/mod.rs | 6 +- .../src-tauri/src/app/windows/chat.rs | 15 ++++- .../src-tauri/src/app/windows/onboarding.rs | 13 +++- .../src-tauri/src/app/windows/settings.rs | 13 +++- apps/stage-tamagotchi/src-tauri/src/lib.rs | 14 ++-- .../src/lib.rs | 64 +++++++++++++------ 6 files changed, 85 insertions(+), 40 deletions(-) diff --git a/apps/stage-tamagotchi/src-tauri/src/app/commands/mod.rs b/apps/stage-tamagotchi/src-tauri/src/app/commands/mod.rs index 3a70cc27e..62a7cbf9f 100644 --- a/apps/stage-tamagotchi/src-tauri/src/app/commands/mod.rs +++ b/apps/stage-tamagotchi/src-tauri/src/app/commands/mod.rs @@ -11,7 +11,7 @@ pub async fn open_settings_window(app: tauri::AppHandle) -> Result<(), tauri::Er return Ok(()); } - settings::new_settings_window(&app)?; + settings::new_settings_window(&app, None)?; Ok(()) } @@ -23,7 +23,7 @@ pub async fn open_chat_window(app: tauri::AppHandle) -> Result<(), tauri::Error> return Ok(()); } - chat::new_chat_window(&app)?; + chat::new_chat_window(&app, None)?; Ok(()) } @@ -35,7 +35,7 @@ pub async fn open_onboarding_window(app: tauri::AppHandle) -> Result<(), tauri:: return Ok(()); } - onboarding::new_onboarding_window(&app)?; + onboarding::new_onboarding_window(&app, None)?; Ok(()) } diff --git a/apps/stage-tamagotchi/src-tauri/src/app/windows/chat.rs b/apps/stage-tamagotchi/src-tauri/src/app/windows/chat.rs index 843d160d3..edd107290 100644 --- a/apps/stage-tamagotchi/src-tauri/src/app/windows/chat.rs +++ b/apps/stage-tamagotchi/src-tauri/src/app/windows/chat.rs @@ -1,11 +1,14 @@ -use std::path::Path; +use std::{path::Path, sync::Arc}; use anyhow::{Ok, Result}; #[cfg(target_os = "macos")] use tauri::TitleBarStyle; -use tauri::{Runtime, WebviewUrl, WebviewWindowBuilder}; +use tauri::{Runtime, WebviewUrl, WebviewWindowBuilder, webview::PageLoadPayload}; -pub fn new_chat_window(app: &tauri::AppHandle) -> Result> { +pub fn new_chat_window( + app: &tauri::AppHandle, + page_load_handler: Option, PageLoadPayload) + Send + Sync>>, +) -> Result> { let mut builder = WebviewWindowBuilder::new( app, "chat", @@ -17,6 +20,12 @@ pub fn new_chat_window(app: &tauri::AppHandle) -> Result( - app: &tauri::AppHandle + app: &tauri::AppHandle, + page_load_handler: Option, PageLoadPayload) + Send + Sync>>, ) -> Result> { let mut builder = WebviewWindowBuilder::new( app, @@ -19,6 +20,12 @@ pub fn new_onboarding_window( .transparent(false) .accept_first_mouse(true); + if let Some(handler) = page_load_handler { + builder = builder.on_page_load(move |window, load| { + handler(window, load); + }); + } + #[cfg(target_os = "macos")] { // macOS traffic light (red, yellow, green) position customization diff --git a/apps/stage-tamagotchi/src-tauri/src/app/windows/settings.rs b/apps/stage-tamagotchi/src-tauri/src/app/windows/settings.rs index 5881c7282..724156690 100644 --- a/apps/stage-tamagotchi/src-tauri/src/app/windows/settings.rs +++ b/apps/stage-tamagotchi/src-tauri/src/app/windows/settings.rs @@ -1,12 +1,13 @@ -use std::path::Path; +use std::{path::Path, sync::Arc}; use anyhow::{Ok, Result}; #[cfg(target_os = "macos")] use tauri::TitleBarStyle; -use tauri::{Runtime, WebviewUrl, WebviewWindowBuilder}; +use tauri::{Runtime, WebviewUrl, WebviewWindowBuilder, webview::PageLoadPayload}; pub fn new_settings_window( - app: &tauri::AppHandle + app: &tauri::AppHandle, + page_load_handler: Option, PageLoadPayload) + Send + Sync>>, ) -> Result> { let mut builder = WebviewWindowBuilder::new( app, @@ -19,6 +20,12 @@ pub fn new_settings_window( .transparent(false) .accept_first_mouse(true); + if let Some(handler) = page_load_handler { + builder = builder.on_page_load(move |window, load| { + handler(window, load); + }); + } + #[cfg(target_os = "macos")] { // macOS traffic light (red, yellow, green) position customization diff --git a/apps/stage-tamagotchi/src-tauri/src/lib.rs b/apps/stage-tamagotchi/src-tauri/src/lib.rs index da4af1890..a13d6cfa9 100644 --- a/apps/stage-tamagotchi/src-tauri/src/lib.rs +++ b/apps/stage-tamagotchi/src-tauri/src/lib.rs @@ -35,16 +35,16 @@ pub fn run() { .plugin(tauri_plugin_window_pass_through_on_hover::init()) .plugin(tauri_plugin_window_router_link::init( WindowMatcher::new() - .register("chat", |app| { - chat::new_chat_window(&app) + .register("chat", |app, on_page_load| { + chat::new_chat_window(&app, on_page_load) .map_err(|e| e) }) - .register("settings", |app| { - settings::new_settings_window(&app) + .register("settings", |app, on_page_load| { + settings::new_settings_window(&app, on_page_load) .map_err(|e| e) }) - .register("onboarding", |app| { - onboarding::new_onboarding_window(&app) + .register("onboarding", |app, on_page_load| { + onboarding::new_onboarding_window(&app, on_page_load) .map_err(|e| e) }) )) @@ -137,7 +137,7 @@ pub fn run() { return; } - app::windows::settings::new_settings_window(app).unwrap(); + app::windows::settings::new_settings_window(app, None).unwrap(); } "center" => { let _ = app.get_webview_window("main") diff --git a/crates/tauri-plugin-window-router-link/src/lib.rs b/crates/tauri-plugin-window-router-link/src/lib.rs index 49939358a..5e93287e7 100644 --- a/crates/tauri-plugin-window-router-link/src/lib.rs +++ b/crates/tauri-plugin-window-router-link/src/lib.rs @@ -1,4 +1,4 @@ -use std::collections::HashMap; +use std::{collections::HashMap, sync::Arc}; use anyhow::Result; #[cfg(debug_assertions)] @@ -7,10 +7,15 @@ use tauri::{ Manager, Runtime, plugin::{Builder, TauriPlugin}, + webview::{PageLoadEvent, PageLoadPayload}, }; -pub type WindowCreator = - Box) -> Result> + Send + Sync>; +pub type PageLoadHandler = + Option, PageLoadPayload) + Send + Sync>>; + +pub type WindowCreator = Box< + dyn Fn(tauri::AppHandle, PageLoadHandler) -> Result> + Send + Sync, +>; // Define a matcher struct that holds window creation logic pub struct WindowMatcher { @@ -30,7 +35,10 @@ impl WindowMatcher { creator: F, ) -> Self where - F: Fn(tauri::AppHandle) -> Result> + Send + Sync + 'static, + F: Fn(tauri::AppHandle, PageLoadHandler) -> Result> + + Send + + Sync + + 'static, { self .creators @@ -42,6 +50,7 @@ impl WindowMatcher { &self, app: tauri::AppHandle, label: &str, + custom_page_load_handler: PageLoadHandler, ) -> Result, String> { // First try to get existing window if let Some(window) = app.get_webview_window(label) { @@ -50,9 +59,8 @@ impl WindowMatcher { // If no existing window, try to create one using registered creator match self.creators.get(label) { - Some(creator) => { - creator(app).map_err(|e| format!("Failed to create {} window: {}", label, e)) - }, + Some(creator) => creator(app, custom_page_load_handler) + .map_err(|e| format!("Failed to create {} window: {}", label, e)), None => Err(format!("Unknown window label: {}", label)), } } @@ -69,23 +77,37 @@ async fn go( ) -> std::result::Result<(), String> { let window_label = window_label.ok_or("Missing window label")?; let matcher = app_handle.state::>(); - let target_window = matcher.get_or_create_window(app_handle.clone(), &window_label)?; - let mut current_url = target_window - .url() - .map_err(|e| format!("Failed to get current URL: {}", e))?; - let route: String = "/".to_string() + route.trim_start_matches('/'); - current_url.set_fragment(Some(route.to_string().as_str())); + matcher.get_or_create_window( + app_handle.clone(), + &window_label, + Some(Arc::new( + move |target_window: tauri::WebviewWindow, load| { + match load.event() { + PageLoadEvent::Finished => { + let current_url = target_window + .url() + .map_err(|e| format!("Failed to get current URL: {}", e)); + if let Ok(mut current_url) = current_url { + let route: String = "/".to_string() + route.trim_start_matches('/'); + current_url.set_fragment(Some(route.to_string().as_str())); - let _ = target_window.show(); - if let Ok(url) = target_window.url() { - if url == current_url { - // If the URL is already the same, we don't need to navigate again. - return Ok(()); - } + let _ = target_window.show(); + if let Ok(url) = target_window.url() { + if url == current_url { + // If the URL is already the same, we don't need to navigate again. + return; + } - let _ = target_window.navigate(current_url); - } + let _ = target_window.navigate(current_url); + } + } + }, + _ => {}, + } + }, + )), + )?; Ok(()) }