дзеркало
https://github.com/l0ng-ai/openidea.git
синхронізовано 2026-11-08 19:02:17 +02:00
fix(app): Give the Settings window a plain loader and make the splash bar progress
The Settings window loads the same page as project windows, so it showed the launch splash with the logo. It now shows only the bar, after 400 ms. The bar's sliding animation was switched off under reduced motion, leaving a static 40% fill. It is now a fake progress that eases towards ~90% and fills to 100% before the splash fades out. Claude-Session: https://claude.ai/code/session_01B65qLEKnkeYTGdbwhLpjCu
Цей коміт міститься в:
1 джерело
b1bb4a69cd
коміт
29e89f2525
4 files changed
+36
-10
No files matched your search
+1
-1
@@ -16,7 +16,7 @@
|
||||
<rect x="43" y="18" width="8" height="28" rx="1.5" fill="#FF4F1A" />
|
||||
</svg>
|
||||
<span>OpenIDEA</span>
|
||||
<div class="splash-bar" role="progressbar" aria-label="Loading"></div>
|
||||
<div class="splash-bar" role="progressbar" aria-label="Loading"><i></i></div>
|
||||
</div>
|
||||
<script type="module" src="/src/main.tsx"></script>
|
||||
</body>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* global document, localStorage */
|
||||
/* global document, localStorage, window */
|
||||
// Runs before the app's CSS loads: restores the last theme (theme.ts stores it)
|
||||
// so a new window starts in it instead of flashing the light default.
|
||||
// An external file because the CSP forbids inline scripts.
|
||||
@@ -9,3 +9,7 @@ try {
|
||||
} catch {
|
||||
/* storage unavailable */
|
||||
}
|
||||
// Settings windows (`settings-<parent>`) load this page too: splash.css drops the logo for them.
|
||||
if (window.__TAURI_INTERNALS__?.metadata?.currentWindow?.label?.startsWith("settings-")) {
|
||||
document.documentElement.dataset.window = "settings";
|
||||
}
|
||||
@@ -29,16 +29,20 @@ body, .splash { background: #e9eaee; }
|
||||
:root[data-theme^="dark"] .splash { color: #8c8f95; }
|
||||
.splash svg { width: 56px; height: 56px; }
|
||||
.splash-bar { width: 120px; height: 2px; border-radius: 1px; overflow: hidden; background: rgb(127 127 127 / 0.18); }
|
||||
.splash-bar::after {
|
||||
content: "";
|
||||
/* Fake progress: eases towards ~90% over the 4 s cap; hideSplash() fills it before fading out. */
|
||||
.splash-bar > i {
|
||||
display: block;
|
||||
width: 40%;
|
||||
height: 100%;
|
||||
background: #3871e1;
|
||||
animation: splash-bar 1.1s ease-in-out infinite;
|
||||
transform-origin: left;
|
||||
animation: splash-fill 4s cubic-bezier(0.1, 0.7, 0.3, 1) both;
|
||||
}
|
||||
/* Settings window: a dialog, not a launch. Only the bar, and only if loading takes a while. */
|
||||
:root[data-window="settings"] .splash { animation-delay: 400ms; }
|
||||
:root[data-window="settings"] .splash > :not(.splash-bar) { display: none; }
|
||||
@keyframes splash-in { from { opacity: 0; } }
|
||||
@keyframes splash-bar { from { transform: translateX(-100%); } to { transform: translateX(250%); } }
|
||||
@keyframes splash-fill { from { transform: scaleX(0.04); } to { transform: scaleX(0.92); } }
|
||||
/* The fill stays: it grows in place, which reduced motion allows. */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.splash, .splash-bar::after { animation: none; }
|
||||
.splash { animation: none; }
|
||||
}
|
||||
@@ -6,6 +6,19 @@
|
||||
const holds: Promise<unknown>[] = [];
|
||||
/** Never keep the splash longer than this; a slow open shows its own progress. */
|
||||
const MAX_WAIT_MS = 4000;
|
||||
const FILL_MS = 120;
|
||||
|
||||
/** Runs the fake progress bar to 100% from wherever its animation has got to; false if nothing shows yet. */
|
||||
function completeBar(el: HTMLElement): boolean {
|
||||
const fill = el.querySelector<HTMLElement>(".splash-bar > i");
|
||||
if (!fill || getComputedStyle(el).opacity === "0") return false;
|
||||
fill.style.transform = getComputedStyle(fill).transform;
|
||||
fill.style.animation = "none";
|
||||
void fill.offsetWidth;
|
||||
fill.style.transition = `transform ${FILL_MS}ms ease-out`;
|
||||
fill.style.transform = "scaleX(1)";
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Keeps the splash up until `work` settles. Call before `hideSplash()`. */
|
||||
export function holdSplash(work: Promise<unknown>): void {
|
||||
@@ -21,8 +34,13 @@ export function hideSplash(): void {
|
||||
// Two frames: let React commit the state the holds produced before uncovering it.
|
||||
requestAnimationFrame(() =>
|
||||
requestAnimationFrame(() => {
|
||||
el.classList.add("splash-out");
|
||||
setTimeout(() => el.remove(), 200);
|
||||
setTimeout(
|
||||
() => {
|
||||
el.classList.add("splash-out");
|
||||
setTimeout(() => el.remove(), 200);
|
||||
},
|
||||
completeBar(el) ? FILL_MS : 0,
|
||||
);
|
||||
}),
|
||||
),
|
||||
);
|
||||
|
||||
Reference in new issue
Заблокувати користувача