feat(qbz-slint): splash screen during session restore
Adds a splash screen (logo, wordmark, spinner) shown while the app boots and restores a saved session. The login form no longer flashes for returning users — the app starts on `splash` and resolves to `shell` (restored) or `login` (no saved session), matching the current QBZ app behavior. cc
This commit is contained in:
3 files changed
+87
-7
No files matched your search
@@ -115,8 +115,14 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
log::info!("[qbz-slint] session restored for user {user_id}");
|
||||
enter_shell(runtime, weak, image_cache).await;
|
||||
}
|
||||
Ok(None) => log::info!("[qbz-slint] no saved session — showing login"),
|
||||
Err(e) => log::error!("[qbz-slint] session restore failed: {e}"),
|
||||
Ok(None) => {
|
||||
log::info!("[qbz-slint] no saved session — showing login");
|
||||
let _ = weak.upgrade_in_event_loop(|w| w.set_screen(AppScreen::Login));
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("[qbz-slint] session restore failed: {e}");
|
||||
let _ = weak.upgrade_in_event_loop(|w| w.set_screen(AppScreen::Login));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -5,16 +5,16 @@
|
||||
// (POC ADR, sections 13 and 21).
|
||||
|
||||
import { Theme } from "foundation/semantic-colors.slint";
|
||||
import { SplashScreen } from "splash/SplashScreen.slint";
|
||||
import { LoginScreen } from "login/LoginScreen.slint";
|
||||
import { AppShell } from "shell/AppShell.slint";
|
||||
|
||||
// Re-export the HomeState global so the Rust layer can populate it.
|
||||
export { HomeState } from "state.slint";
|
||||
|
||||
// Which top-level screen is shown. During M1 the screen switches on a
|
||||
// login-button click without real authentication; M2 ties the switch
|
||||
// to a real session.
|
||||
export enum AppScreen { login, shell }
|
||||
// Which top-level screen is shown. The app starts on `splash` while it
|
||||
// restores a saved session, then resolves to `shell` or `login`.
|
||||
export enum AppScreen { splash, login, shell }
|
||||
|
||||
export component AppWindow inherits Window {
|
||||
title: "QBZ";
|
||||
@@ -24,7 +24,7 @@ export component AppWindow inherits Window {
|
||||
min-height: 600px;
|
||||
background: Theme.surface-main;
|
||||
|
||||
in-out property <AppScreen> screen: AppScreen.login;
|
||||
in-out property <AppScreen> screen: AppScreen.splash;
|
||||
|
||||
// Forwarded to the Rust layer, which maps them to typed AppCommands.
|
||||
callback sign-in-via-browser();
|
||||
@@ -32,6 +32,8 @@ export component AppWindow inherits Window {
|
||||
callback start-offline();
|
||||
callback open-tos();
|
||||
|
||||
if root.screen == AppScreen.splash: SplashScreen { }
|
||||
|
||||
if root.screen == AppScreen.login: LoginScreen {
|
||||
sign-in-via-browser => {
|
||||
root.sign-in-via-browser();
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
// Splash screen — shown while the app boots and tries to restore a
|
||||
// saved session, so the login form never flashes for returning users.
|
||||
|
||||
import { Theme } from "../foundation/semantic-colors.slint";
|
||||
import { Typography } from "../foundation/typography.slint";
|
||||
import { Radius } from "../foundation/radius.slint";
|
||||
import { Spacing } from "../foundation/spacing.slint";
|
||||
import { Spinner } from "std-widgets.slint";
|
||||
|
||||
export component SplashScreen inherits Rectangle {
|
||||
background: Theme.surface-main;
|
||||
|
||||
VerticalLayout {
|
||||
alignment: center;
|
||||
|
||||
HorizontalLayout {
|
||||
alignment: center;
|
||||
|
||||
Rectangle {
|
||||
width: 720px;
|
||||
background: Theme.surface-card;
|
||||
border-radius: Radius.lg;
|
||||
drop-shadow-blur: 32px;
|
||||
drop-shadow-color: Theme.card-shadow;
|
||||
drop-shadow-offset-y: 8px;
|
||||
|
||||
VerticalLayout {
|
||||
padding: Spacing.card-padding;
|
||||
spacing: 0px;
|
||||
|
||||
HorizontalLayout {
|
||||
alignment: center;
|
||||
Image {
|
||||
source: @image-url("../assets/qbz-logo.png");
|
||||
width: 140px;
|
||||
height: 140px;
|
||||
image-fit: contain;
|
||||
}
|
||||
}
|
||||
Rectangle { height: Spacing.sm; }
|
||||
Text {
|
||||
text: @tr("QBZ");
|
||||
color: Theme.text-primary;
|
||||
font-size: Typography.wordmark;
|
||||
font-weight: Typography.semibold;
|
||||
letter-spacing: 8px;
|
||||
horizontal-alignment: center;
|
||||
}
|
||||
Rectangle { height: 2px; }
|
||||
Text {
|
||||
text: @tr("QOBUZ™ PLAYER");
|
||||
color: Theme.text-muted;
|
||||
font-size: Typography.subtitle;
|
||||
letter-spacing: 4px;
|
||||
horizontal-alignment: center;
|
||||
}
|
||||
|
||||
Rectangle { height: Spacing.xl; }
|
||||
|
||||
HorizontalLayout {
|
||||
alignment: center;
|
||||
Spinner {
|
||||
indeterminate: true;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user