Migre le projet vers Blazor WebAssembly en .NET 10

This commit is contained in:
2026-04-13 21:29:12 +02:00
parent b11056097d
commit 90f17c9c89
26 changed files with 4314 additions and 94 deletions

View File

@@ -0,0 +1,200 @@
(() => {
const assetTokenStorageKey = "chesscubing-arena-asset-token";
let viewportStarted = false;
let audioContext = null;
function syncViewportHeight() {
const visibleHeight = window.visualViewport?.height ?? window.innerHeight;
const viewportTopOffset = window.visualViewport?.offsetTop ?? 0;
const viewportHeight = Math.max(
visibleHeight + viewportTopOffset,
window.innerHeight,
document.documentElement.clientHeight,
);
document.documentElement.style.setProperty("--app-visible-height", `${Math.round(visibleHeight)}px`);
document.documentElement.style.setProperty("--app-viewport-top", `${Math.round(viewportTopOffset)}px`);
document.documentElement.style.setProperty("--app-viewport-height", `${Math.round(viewportHeight)}px`);
}
function startViewport() {
if (viewportStarted) {
return;
}
viewportStarted = true;
syncViewportHeight();
window.addEventListener("load", syncViewportHeight);
window.addEventListener("resize", syncViewportHeight);
window.addEventListener("scroll", syncViewportHeight, { passive: true });
window.addEventListener("pageshow", syncViewportHeight);
window.addEventListener("orientationchange", syncViewportHeight);
window.visualViewport?.addEventListener("resize", syncViewportHeight);
window.visualViewport?.addEventListener("scroll", syncViewportHeight);
window.setTimeout(syncViewportHeight, 0);
window.setTimeout(syncViewportHeight, 150);
window.setTimeout(syncViewportHeight, 400);
window.requestAnimationFrame(() => window.requestAnimationFrame(syncViewportHeight));
}
function getAudioContext() {
const AudioContextClass = window.AudioContext || window.webkitAudioContext;
if (!AudioContextClass) {
return null;
}
if (!audioContext) {
try {
audioContext = new AudioContextClass();
} catch {
return null;
}
}
return audioContext;
}
function primeAudio() {
const context = getAudioContext();
if (!context || context.state === "running") {
return;
}
context.resume().catch(() => undefined);
}
function playCubePhaseAlert() {
primeAudio();
const context = getAudioContext();
if (!context || context.state !== "running") {
return false;
}
const pattern = [
{ frequency: 740, offset: 0, duration: 0.12, gain: 0.035 },
{ frequency: 988, offset: 0.18, duration: 0.12, gain: 0.04 },
{ frequency: 1318, offset: 0.36, duration: 0.2, gain: 0.05 },
];
const startAt = context.currentTime + 0.02;
pattern.forEach(({ frequency, offset, duration, gain }) => {
const oscillator = context.createOscillator();
const envelope = context.createGain();
const toneStartAt = startAt + offset;
oscillator.type = "triangle";
oscillator.frequency.setValueAtTime(frequency, toneStartAt);
envelope.gain.setValueAtTime(0.0001, toneStartAt);
envelope.gain.exponentialRampToValueAtTime(gain, toneStartAt + 0.02);
envelope.gain.exponentialRampToValueAtTime(0.0001, toneStartAt + duration);
oscillator.connect(envelope);
envelope.connect(context.destination);
oscillator.start(toneStartAt);
oscillator.stop(toneStartAt + duration + 0.03);
});
return true;
}
window.chesscubingPage = {
setBodyState(page, bodyClass) {
if (page) {
document.body.dataset.page = page;
} else {
delete document.body.dataset.page;
}
document.body.className = bodyClass || "";
},
};
window.chesscubingViewport = {
start: startViewport,
};
window.chesscubingStorage = {
getMatchState(storageKey, windowNameKey) {
try {
const raw = window.localStorage.getItem(storageKey);
if (raw) {
return raw;
}
} catch {
}
try {
if (!window.name || !window.name.startsWith(windowNameKey)) {
return null;
}
return window.name.slice(windowNameKey.length);
} catch {
return null;
}
},
setMatchState(storageKey, windowNameKey, value) {
try {
window.name = `${windowNameKey}${value}`;
} catch {
}
try {
window.localStorage.setItem(storageKey, value);
} catch {
}
},
clearMatchState(storageKey) {
try {
window.localStorage.removeItem(storageKey);
} catch {
}
try {
window.name = "";
} catch {
}
},
};
window.chesscubingAudio = {
prime: primeAudio,
playCubePhaseAlert,
};
window.chesscubingBrowser = {
async forceRefresh(path) {
const refreshToken = `${Date.now()}`;
try {
window.sessionStorage.setItem(assetTokenStorageKey, refreshToken);
} catch {
}
if ("caches" in window) {
try {
const cacheKeys = await window.caches.keys();
await Promise.all(cacheKeys.map((cacheKey) => window.caches.delete(cacheKey)));
} catch {
}
}
if ("serviceWorker" in navigator) {
try {
const registrations = await navigator.serviceWorker.getRegistrations();
await Promise.all(registrations.map((registration) => registration.update().catch(() => undefined)));
await Promise.all(registrations.map((registration) => registration.unregister().catch(() => undefined)));
} catch {
}
}
const targetUrl = new URL(path, window.location.href);
targetUrl.searchParams.set("refresh", refreshToken);
window.location.replace(targetUrl.toString());
},
};
startViewport();
})();