v0.2.6-pre.014

This commit is contained in:
2026-08-22 00:21:14 +02:00
parent c07db925b1
commit 6907e4bbb8
39 changed files with 1544 additions and 370 deletions

View File

@@ -1,4 +1,6 @@
<!doctype html>
<!-- file: crates/ksp-app-wallet-desk/frontend/main.html -->
<!-- version: 1 -->
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
@@ -6,20 +8,22 @@
<title>Wallet Desk — Dashboard</title>
</head>
<body>
<header class="app-header bg-dark text-white shadow-sm">
<div class="container-fluid h-100 d-flex align-items-center gap-3 px-4">
<img class="app-logo" src="./imgs/logo.png" alt="KSP">
<div class="d-flex flex-column me-auto">
<span class="fw-semibold">Wallet Desk — <span id="headerViewTitle">Dashboard</span></span>
<small id="shellStatus" class="text-white-50 app-shell-status">Initialisation du shell…</small>
<header class="app-header shadow-sm">
<nav class="navbar h-100 py-0 bg-light text-dark">
<div class="container-fluid h-100 d-flex align-items-center gap-3 px-4 flex-nowrap">
<img class="app-logo" src="./imgs/logo.png" alt="KSP">
<div class="d-flex flex-column me-auto">
<span class="fw-semibold text-primary">Wallet Desk — <span id="headerViewTitle" class="text-body">Dashboard</span></span>
<small id="shellStatus" class="text-body-secondary app-shell-status">Initialisation du shell…</small>
</div>
<button class="btn btn-outline-secondary btn-sm" type="button" data-shell-action="deselect" disabled>
<i class="fa-solid fa-xmark me-2" aria-hidden="true"></i>Deselect
</button>
<button class="btn btn-outline-primary btn-sm" type="button" data-shell-action="lock" disabled>
<i class="fa-solid fa-lock me-2" aria-hidden="true"></i>Lock
</button>
</div>
<button class="btn btn-outline-light btn-sm" type="button" data-shell-action="deselect" disabled>
<i class="fa-solid fa-xmark me-2" aria-hidden="true"></i>Deselect
</button>
<button class="btn btn-outline-light btn-sm" type="button" data-shell-action="lock" disabled>
<i class="fa-solid fa-lock me-2" aria-hidden="true"></i>Lock
</button>
</div>
</nav>
</header>
<main class="app-main container-fluid p-0">
<div class="row g-0 h-100">
@@ -42,7 +46,7 @@
<h1 id="viewTitle" class="h3 mb-1">Dashboard</h1>
<p class="text-body-secondary mb-0">Identité autorisée et balance SOL via le Transport HTTP composite sont actives.</p>
</div>
<span class="badge text-bg-secondary">0.2.6-pre.013</span>
<span class="badge text-bg-secondary">0.2.6-pre.014</span>
</div>
<section data-view-panel="dashboard">
<div class="row g-3">

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-app-wallet-desk/frontend/sass/splash.scss
// version: 1
// version: 2
@font-face {
font-family: "Dos Amazigh";
@@ -9,13 +9,23 @@
font-display: swap;
}
*,
*::before,
*::after {
box-sizing: border-box;
}
html,
body {
display: flex;
width: 100vw;
height: 100vh;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
body {
display: flex;
align-items: center;
justify-content: center;
background: transparent;
@@ -25,8 +35,12 @@ body {
#splash-container {
position: relative;
width: 960px;
max-width: 100%;
height: 637px;
max-height: 100%;
overflow: hidden;
opacity: 0;
will-change: opacity;
}
#splash-image {
@@ -35,6 +49,11 @@ body {
width: 100%;
height: 100%;
z-index: 1;
object-fit: contain;
user-select: none;
-webkit-user-select: none;
-webkit-user-drag: none;
pointer-events: none;
}
#app-name {
@@ -49,17 +68,70 @@ body {
font-weight: bold;
text-align: center;
text-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
white-space: nowrap;
user-select: none;
-webkit-user-select: none;
-webkit-user-drag: none;
pointer-events: none;
}
#splash-status {
#debug-info {
position: absolute;
right: 1rem;
bottom: 1rem;
left: 1rem;
top: 0;
left: 0;
z-index: 3;
padding: 0.55rem 0.75rem;
width: 55%;
max-height: 30%;
overflow-y: auto;
padding: 8px;
color: #fff;
background: rgba(0, 0, 0, 0.35);
background: rgba(0, 0, 0, 0.18);
font-family: monospace;
font-size: 0.82rem;
font-size: 12px;
scrollbar-width: none;
}
#messages-container {
position: absolute;
right: 0;
bottom: 0;
left: 0;
z-index: 3;
max-height: 30%;
overflow-y: auto;
padding: 10px 10px 36px;
background: rgba(0, 0, 0, 0.18);
font-family: Arial, sans-serif;
font-size: 14px;
scrollbar-width: none;
}
#debug-info::-webkit-scrollbar,
#messages-container::-webkit-scrollbar {
display: none;
}
.splash-message {
margin-bottom: 8px;
padding: 6px 10px;
border-radius: 4px;
color: #fff;
font-weight: bold;
animation: splashMessageFadeIn 0.3s ease-in-out;
}
.splash-message.info { background: rgba(33, 150, 243, 0.22); }
.splash-message.warning { background: rgba(255, 152, 0, 0.22); }
.splash-message.error { background: rgba(244, 67, 54, 0.22); }
.splash-message.success { background: rgba(76, 175, 80, 0.22); }
@keyframes splashMessageFadeIn {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}

View File

@@ -1,16 +1,23 @@
<!doctype html>
<!-- file: crates/ksp-app-wallet-desk/frontend/splash.html -->
<!-- version: 1 -->
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Chargement — KSP Wallet Desk</title>
</head>
<body>
<div id="splash-container">
<img id="splash-image" src="./imgs/splash.png" alt="">
<div id="app-name">Wallet Desk</div>
<div id="splash-status">Initialisation…</div>
</div>
<script type="module" src="./ts/splash.ts"></script>
</body>
<head>
<meta charset="utf-8">
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<link rel="stylesheet" href="sass/splash.scss">
<title>KSP Wallet Desk — Chargement</title>
</head>
<body>
<div id="splash-container" style="opacity: 0;">
<img id="splash-image" src="imgs/splash.png" alt="Chargement de KSP Wallet Desk">
<div id="app-name">Wallet Desk</div>
<div id="debug-info" aria-live="off" hidden></div>
<div id="messages-container" aria-live="polite"></div>
</div>
<script type="module" src="ts/splash.ts" defer></script>
</body>
</html>

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-app-wallet-desk/frontend/ts/main.ts
// version: 14
// version: 15
import { Modal } from "bootstrap";
import DataTable from "datatables.net-bs5";
@@ -190,7 +190,7 @@ function initializeWalletTable(): void {
zeroRecords: "Aucun wallet correspondant.",
},
});
frontendDebug("main", "Wallet inventory DataTable initialized", { phase: "pre.013-integration-compliance" });
frontendDebug("main", "Wallet inventory DataTable initialized", { phase: "pre.014-desktop-polish" });
}
function renderWalletInventory(entries: WalletInventoryEntryDto[]): void {

View File

@@ -1,12 +1,11 @@
// file: crates/ksp-app-wallet-desk/frontend/ts/splash.ts
// version: 1
// version: 2
import { listen } from "@tauri-apps/api/event";
import { getCurrentWindow } from "@tauri-apps/api/window";
import type { SplashOrderDto } from "./bindings/ksp_app_wallet_desk/splash/SplashOrderDto.ts";
import { frontendDebug, frontendError, frontendInfo, frontendTrace, installFrontendConsoleBridge } from "./frontend_log";
import { invokeKsp } from "./invoke";
import "../sass/splash.scss";
installFrontendConsoleBridge("splash");
@@ -50,21 +49,46 @@ async function animateOpacity(element: HTMLElement, fromOpacity: number, toOpaci
frontendTrace("splash", "Splash opacity animation completed", { toOpacity, durationMs });
}
function replaceStatus(message: string | null): void {
if (!message) {
function scrollToLatest(element: HTMLElement): void {
element.scrollTop = element.scrollHeight;
}
function addMessage(message: string, status: string | null): void {
const container = document.querySelector<HTMLElement>("#messages-container");
if (!container) {
return;
}
const status = document.querySelector<HTMLElement>("#splash-status");
if (status) {
status.textContent = message;
frontendTrace("splash", "Splash status replaced", { message });
const line = document.createElement("div");
const safeStatus = status === "warning" || status === "error" || status === "success" ? status : "info";
line.className = `splash-message ${safeStatus}`;
line.textContent = message;
container.appendChild(line);
scrollToLatest(container);
}
function addDebugMessage(message: string): void {
const container = document.querySelector<HTMLElement>("#debug-info");
if (!container) {
return;
}
container.hidden = false;
const line = document.createElement("div");
line.textContent = `${new Date().toLocaleTimeString()}: ${message}`;
container.appendChild(line);
scrollToLatest(container);
}
async function handleSplashOrder(order: SplashOrderDto): Promise<void> {
frontendTrace("splash", "Splash order received", { action: order.action });
const container = document.querySelector<HTMLElement>("#splash-container");
replaceStatus(order.message);
if (order.action === "add_message" && order.message) {
addMessage(order.message, order.status);
return;
}
if (order.action === "add_debug" && order.message) {
addDebugMessage(order.message);
return;
}
if (!container) {
return;
}
@@ -93,7 +117,7 @@ async function initializeSplash(): Promise<void> {
try {
await invokeKsp<void>("splash", "splash_frontend_ready");
} catch {
replaceStatus("Le lifecycle du splash n'a pas pu démarrer.");
addMessage("Le lifecycle du splash n'a pas pu démarrer.", "error");
if (container) {
container.style.opacity = "1";
container.style.willChange = "auto";