mirror of
https://gitlab.com/vyla-entertainment/home.git
synced 2026-11-09 19:57:20 -05:00
624 lines
25 KiB
HTML
624 lines
25 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<title>Vyla Home</title>
|
|
<style>
|
|
* {
|
|
box-sizing: border-box;
|
|
margin: 0;
|
|
padding: 0;
|
|
}
|
|
|
|
html,
|
|
body {
|
|
width: 100%;
|
|
height: 100%;
|
|
overflow: hidden;
|
|
background: #050505;
|
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
|
|
color: #fff;
|
|
user-select: none;
|
|
}
|
|
|
|
#side-rays {
|
|
position: absolute;
|
|
inset: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
z-index: 0;
|
|
}
|
|
|
|
#side-rays canvas {
|
|
display: block;
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
|
|
.loader-container {
|
|
position: relative;
|
|
z-index: 10;
|
|
width: 100%;
|
|
height: 100%;
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 24px;
|
|
}
|
|
|
|
.loader-card {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
text-align: center;
|
|
max-width: 480px;
|
|
width: 100%;
|
|
}
|
|
|
|
.status-text {
|
|
font-size: 15px;
|
|
font-weight: 500;
|
|
letter-spacing: 0.2px;
|
|
color: rgba(255, 255, 255, 0.85);
|
|
margin-bottom: 24px;
|
|
min-height: 24px;
|
|
display: inline-flex;
|
|
flex-wrap: wrap;
|
|
justify-content: center;
|
|
align-items: center;
|
|
}
|
|
|
|
.status-char {
|
|
display: inline-block;
|
|
opacity: 0;
|
|
filter: blur(10px);
|
|
transform: translateY(6px);
|
|
animation: charIn 0.35s cubic-bezier(0.16, 1, 0.3, 1) forwards;
|
|
white-space: pre;
|
|
}
|
|
|
|
@keyframes charIn {
|
|
to {
|
|
opacity: 1;
|
|
filter: blur(0px);
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
|
|
.progress-track {
|
|
width: 100%;
|
|
height: 10px;
|
|
background: transparent !important;
|
|
backdrop-filter: blur(16px) !important;
|
|
-webkit-backdrop-filter: blur(16px) !important;
|
|
border-radius: 9999px;
|
|
overflow: hidden;
|
|
position: relative;
|
|
margin-bottom: 28px;
|
|
box-shadow: none !important;
|
|
border: none !important;
|
|
}
|
|
|
|
.progress-fill {
|
|
height: 100%;
|
|
width: 0%;
|
|
background: #ffffff !important;
|
|
border-radius: 9999px;
|
|
transition: width 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
box-shadow: none !important;
|
|
}
|
|
|
|
.button-group {
|
|
display: flex;
|
|
gap: 16px;
|
|
width: 100%;
|
|
justify-content: center;
|
|
}
|
|
|
|
.glass-surface {
|
|
position: relative;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
overflow: hidden;
|
|
border-radius: 9999px;
|
|
outline: none !important;
|
|
border: none !important;
|
|
height: 48px;
|
|
min-width: 140px;
|
|
}
|
|
|
|
.glass-surface__filter {
|
|
width: 100%;
|
|
height: 100%;
|
|
pointer-events: none;
|
|
position: absolute;
|
|
inset: 0;
|
|
opacity: 0;
|
|
z-index: -1;
|
|
}
|
|
|
|
.glass-surface__content {
|
|
width: 100%;
|
|
height: 100%;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
border-radius: inherit;
|
|
position: relative;
|
|
z-index: 1;
|
|
}
|
|
|
|
.glass-surface--svg {
|
|
background: transparent !important;
|
|
backdrop-filter: var(--filter-id, url(#glass-filter)) blur(16px) !important;
|
|
-webkit-backdrop-filter: var(--filter-id, url(#glass-filter)) blur(16px) !important;
|
|
box-shadow: none !important;
|
|
border: none !important;
|
|
outline: none !important;
|
|
}
|
|
|
|
.glass-surface--fallback {
|
|
background: transparent !important;
|
|
backdrop-filter: blur(16px) !important;
|
|
-webkit-backdrop-filter: blur(16px) !important;
|
|
box-shadow: none !important;
|
|
border: none !important;
|
|
outline: none !important;
|
|
}
|
|
|
|
.glass-button {
|
|
width: 100%;
|
|
height: 100%;
|
|
border: 0 !important;
|
|
outline: 0 !important;
|
|
background: transparent;
|
|
color: #fff;
|
|
font-size: 14px;
|
|
font-weight: 600;
|
|
cursor: pointer;
|
|
border-radius: inherit;
|
|
padding: 0 24px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
</style>
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<div id="side-rays"></div>
|
|
|
|
<div class="loader-container">
|
|
<div class="loader-card">
|
|
<div class="status-text" id="status-message">Starting runtime engine...</div>
|
|
<div id="debug-log-box"
|
|
style="display: none; width: 100%; max-height: 180px; overflow-y: auto; background: rgba(255, 50, 50, 0.12); border: 1px solid rgba(255, 100, 100, 0.3); border-radius: 8px; padding: 12px; font-family: monospace; font-size: 12px; color: #fca5a5; text-align: left; white-space: pre-wrap; word-break: break-all; margin-bottom: 20px; user-select: text;">
|
|
</div>
|
|
<div class="progress-track" id="progress-track" style="display: none;">
|
|
<div class="progress-fill" id="progress-fill"></div>
|
|
</div>
|
|
|
|
<div class="button-group" id="update-actions" style="display: none;">
|
|
<div class="glass-surface glass-surface--fallback liquid-glass-btn">
|
|
<svg class="glass-surface__filter" xmlns="http://www.w3.org/2000/svg">
|
|
<defs>
|
|
<filter id="glass-filter-1" color-interpolation-filters="sRGB" x="0%" y="0%" width="100%"
|
|
height="100%">
|
|
<feImage class="fe-image" x="0" y="0" width="100%" height="100%"
|
|
preserveAspectRatio="none" result="map" />
|
|
<feDisplacementMap class="redchannel" in="SourceGraphic" in2="map" result="dispRed" />
|
|
<feColorMatrix in="dispRed" type="matrix"
|
|
values="1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0" result="red" />
|
|
<feDisplacementMap class="greenchannel" in="SourceGraphic" in2="map"
|
|
result="dispGreen" />
|
|
<feColorMatrix in="dispGreen" type="matrix"
|
|
values="0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0" result="green" />
|
|
<feDisplacementMap class="bluechannel" in="SourceGraphic" in2="map" result="dispBlue" />
|
|
<feColorMatrix in="dispBlue" type="matrix"
|
|
values="0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0" result="blue" />
|
|
<feBlend in="red" in2="green" mode="screen" result="rg" />
|
|
<feBlend in="rg" in2="blue" mode="screen" result="output" />
|
|
<feGaussianBlur class="gaussianBlur" in="output" stdDeviation="0" />
|
|
</filter>
|
|
</defs>
|
|
</svg>
|
|
<div class="glass-surface__content">
|
|
<button class="glass-button" id="btn-update-yes">Update Now</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="glass-surface glass-surface--fallback liquid-glass-btn">
|
|
<svg class="glass-surface__filter" xmlns="http://www.w3.org/2000/svg">
|
|
<defs>
|
|
<filter id="glass-filter-2" color-interpolation-filters="sRGB" x="0%" y="0%" width="100%"
|
|
height="100%">
|
|
<feImage class="fe-image" x="0" y="0" width="100%" height="100%"
|
|
preserveAspectRatio="none" result="map" />
|
|
<feDisplacementMap class="redchannel" in="SourceGraphic" in2="map" result="dispRed" />
|
|
<feColorMatrix in="dispRed" type="matrix"
|
|
values="1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0" result="red" />
|
|
<feDisplacementMap class="greenchannel" in="SourceGraphic" in2="map"
|
|
result="dispGreen" />
|
|
<feColorMatrix in="dispGreen" type="matrix"
|
|
values="0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0" result="green" />
|
|
<feDisplacementMap class="bluechannel" in="SourceGraphic" in2="map" result="dispBlue" />
|
|
<feColorMatrix in="dispBlue" type="matrix"
|
|
values="0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0" result="blue" />
|
|
<feBlend in="red" in2="green" mode="screen" result="rg" />
|
|
<feBlend in="rg" in2="blue" mode="screen" result="output" />
|
|
<feGaussianBlur class="gaussianBlur" in="output" stdDeviation="0" />
|
|
</filter>
|
|
</defs>
|
|
</svg>
|
|
<div class="glass-surface__content">
|
|
<button class="glass-button" id="btn-update-no">Skip</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<script type="module">
|
|
try {
|
|
const { Renderer, Program, Triangle, Mesh } = await import("https://esm.sh/ogl@1.0.11");
|
|
window.__OGL_LOADED__ = { Renderer, Program, Triangle, Mesh };
|
|
} catch (err) {
|
|
console.warn("OGL Shader background failed to load (offline):", err);
|
|
}
|
|
|
|
window.dispatchEvent(new Event('ogl-ready'));
|
|
</script>
|
|
|
|
<script>
|
|
window.addEventListener('ogl-ready', () => {
|
|
if (!window.__OGL_LOADED__) {
|
|
document.body.style.background = "radial-gradient(circle at 80% 20%, #1e1b4b 0%, #050505 70%)";
|
|
} else {
|
|
const { Renderer, Program, Triangle, Mesh } = window.__OGL_LOADED__;
|
|
const rayContainer = document.getElementById("side-rays");
|
|
const settings = {
|
|
speed: 2.5,
|
|
rayColor1: "#EAB308",
|
|
rayColor2: "#96c8ff",
|
|
intensity: 2,
|
|
spread: 2,
|
|
origin: "top-right",
|
|
tilt: 0,
|
|
saturation: 1.5,
|
|
blend: 0.75,
|
|
falloff: 1.6,
|
|
opacity: 1
|
|
};
|
|
|
|
function hexToRgb(hex) {
|
|
const match = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
|
if (!match) return [1, 1, 1];
|
|
return [
|
|
parseInt(match[1], 16) / 255,
|
|
parseInt(match[2], 16) / 255,
|
|
parseInt(match[3], 16) / 255
|
|
];
|
|
}
|
|
|
|
function originToFlip(origin) {
|
|
switch (origin) {
|
|
case "top-left": return [1, 0];
|
|
case "bottom-right": return [0, 1];
|
|
case "bottom-left": return [1, 1];
|
|
default: return [0, 0];
|
|
}
|
|
}
|
|
|
|
const renderer = new Renderer({
|
|
dpr: Math.min(window.devicePixelRatio, 2),
|
|
alpha: true
|
|
});
|
|
const gl = renderer.gl;
|
|
gl.canvas.style.width = "100%";
|
|
gl.canvas.style.height = "100%";
|
|
rayContainer.appendChild(gl.canvas);
|
|
|
|
const vertexShader = `
|
|
attribute vec2 position;
|
|
void main() {
|
|
gl_Position = vec4(position, 0.0, 1.0);
|
|
}
|
|
`;
|
|
|
|
const fragmentShader = `
|
|
precision highp float;
|
|
uniform float iTime;
|
|
uniform vec2 iResolution;
|
|
uniform float iSpeed;
|
|
uniform vec3 iRayColor1;
|
|
uniform vec3 iRayColor2;
|
|
uniform float iIntensity;
|
|
uniform float iSpread;
|
|
uniform float iFlipX;
|
|
uniform float iFlipY;
|
|
uniform float iTilt;
|
|
uniform float iSaturation;
|
|
uniform float iBlend;
|
|
uniform float iFalloff;
|
|
uniform float iOpacity;
|
|
|
|
float rayStrength(vec2 raySource, vec2 rayRefDirection, vec2 coord, float seedA, float seedB, float speed) {
|
|
vec2 sourceToCoord = coord - raySource;
|
|
float cosAngle = dot(normalize(sourceToCoord), rayRefDirection);
|
|
return clamp(
|
|
(0.45 + 0.15 * sin(cosAngle * seedA + iTime * speed)) +
|
|
(0.3 + 0.2 * cos(-cosAngle * seedB + iTime * speed)),
|
|
0.0, 1.0
|
|
) * clamp((iResolution.x - length(sourceToCoord)) / iResolution.x, 0.5, 1.0);
|
|
}
|
|
|
|
void main() {
|
|
vec2 fragCoord = gl_FragCoord.xy;
|
|
if (iFlipX > 0.5) fragCoord.x = iResolution.x - fragCoord.x;
|
|
if (iFlipY > 0.5) fragCoord.y = iResolution.y - fragCoord.y;
|
|
|
|
vec2 coord = vec2(fragCoord.x, iResolution.y - fragCoord.y);
|
|
vec2 rayPos = vec2(iResolution.x * 1.1, -0.5 * iResolution.y);
|
|
|
|
float tiltRad = iTilt * 3.14159265 / 180.0;
|
|
float cs = cos(tiltRad);
|
|
float sn = sin(tiltRad);
|
|
vec2 rel = coord - rayPos;
|
|
vec2 tiltedCoord = vec2(rel.x * cs - rel.y * sn, rel.x * sn + rel.y * cs) + rayPos;
|
|
|
|
float halfSpread = iSpread * 0.275;
|
|
vec2 rayRefDir1 = normalize(vec2(cos(0.785398 + halfSpread), sin(0.785398 + halfSpread)));
|
|
vec2 rayRefDir2 = normalize(vec2(cos(0.785398 - halfSpread), sin(0.785398 - halfSpread)));
|
|
|
|
vec4 rays1 = vec4(iRayColor1, 1.0) * rayStrength(rayPos, rayRefDir1, tiltedCoord, 36.2214, 21.11349, iSpeed);
|
|
vec4 rays2 = vec4(iRayColor2, 1.0) * rayStrength(rayPos, rayRefDir2, tiltedCoord, 22.3991, 18.0234, iSpeed * 0.2);
|
|
|
|
vec4 color = rays1 * (1.0 - iBlend) * 0.9 + rays2 * iBlend * 0.9;
|
|
float distanceToLight = length(fragCoord.xy - vec2(rayPos.x, iResolution.y - rayPos.y)) / iResolution.y;
|
|
float brightness = iIntensity * 0.4 / pow(max(distanceToLight, 0.001), iFalloff);
|
|
|
|
color.rgb *= brightness;
|
|
float gray = dot(color.rgb, vec3(0.299, 0.587, 0.114));
|
|
color.rgb = mix(vec3(gray), color.rgb, iSaturation);
|
|
color.a = max(color.r, max(color.g, color.b)) * iOpacity;
|
|
|
|
gl_FragColor = color;
|
|
}
|
|
`;
|
|
|
|
const [flipX, flipY] = originToFlip(settings.origin);
|
|
const uniforms = {
|
|
iTime: { value: 0 },
|
|
iResolution: { value: [1, 1] },
|
|
iSpeed: { value: settings.speed },
|
|
iRayColor1: { value: hexToRgb(settings.rayColor1) },
|
|
iRayColor2: { value: hexToRgb(settings.rayColor2) },
|
|
iIntensity: { value: settings.intensity },
|
|
iSpread: { value: settings.spread },
|
|
iFlipX: { value: flipX },
|
|
iFlipY: { value: flipY },
|
|
iTilt: { value: settings.tilt },
|
|
iSaturation: { value: settings.saturation },
|
|
iBlend: { value: settings.blend },
|
|
iFalloff: { value: settings.falloff },
|
|
iOpacity: { value: settings.opacity }
|
|
};
|
|
|
|
const geometry = new Triangle(gl);
|
|
const program = new Program(gl, { vertex: vertexShader, fragment: fragmentShader, uniforms });
|
|
const mesh = new Mesh(gl, { geometry, program });
|
|
|
|
function resize() {
|
|
const width = rayContainer.clientWidth;
|
|
const height = rayContainer.clientHeight;
|
|
renderer.dpr = Math.min(window.devicePixelRatio, 2);
|
|
renderer.setSize(width, height);
|
|
uniforms.iResolution.value = [width * renderer.dpr, height * renderer.dpr];
|
|
}
|
|
|
|
window.addEventListener("resize", resize);
|
|
resize();
|
|
|
|
function animate(time) {
|
|
uniforms.iTime.value = time * 0.001;
|
|
renderer.render({ scene: mesh });
|
|
requestAnimationFrame(animate);
|
|
}
|
|
requestAnimationFrame(animate);
|
|
|
|
function initLiquidButtons() {
|
|
const borderWidth = 0.16;
|
|
const brightness = 35;
|
|
const opacity = 0.55;
|
|
const blur = 4;
|
|
const displace = 1.2;
|
|
const borderRadius = 9999;
|
|
const distortionScale = -380;
|
|
const redOffset = -25;
|
|
const greenOffset = 0;
|
|
const blueOffset = 25;
|
|
const xChannel = "R";
|
|
const yChannel = "G";
|
|
const mixBlendMode = "screen";
|
|
|
|
document.querySelectorAll(".liquid-glass-btn").forEach((btn, index) => {
|
|
const filterId = `glass-filter-${index + 1}`;
|
|
btn.style.setProperty("--filter-id", `url(#${filterId})`);
|
|
|
|
const feImage = btn.querySelector(".fe-image");
|
|
const redChannel = btn.querySelector(".redchannel");
|
|
const greenChannel = btn.querySelector(".greenchannel");
|
|
const blueChannel = btn.querySelector(".bluechannel");
|
|
const gaussianBlur = btn.querySelector(".gaussianBlur");
|
|
|
|
function generateDisplacementMap() {
|
|
const rect = btn.getBoundingClientRect();
|
|
const actualWidth = rect.width || 140;
|
|
const actualHeight = rect.height || 48;
|
|
|
|
const svgContent = `
|
|
<svg viewBox="0 0 ${actualWidth} ${actualHeight}" xmlns="http://www.w3.org/2000/svg">
|
|
<defs>
|
|
<linearGradient id="red-grad-${index}" x1="100%" y1="0%" x2="0%" y2="0%">
|
|
<stop offset="0%" stop-color="#0000"/>
|
|
<stop offset="100%" stop-color="red"/>
|
|
</linearGradient>
|
|
<linearGradient id="blue-grad-${index}" x1="0%" y1="0%" x2="0%" y2="100%">
|
|
<stop offset="0%" stop-color="#0000"/>
|
|
<stop offset="100%" stop-color="blue"/>
|
|
</linearGradient>
|
|
</defs>
|
|
<rect width="${actualWidth}" height="${actualHeight}" fill="black"/>
|
|
<rect width="${actualWidth}" height="${actualHeight}" rx="${borderRadius}" fill="url(#red-grad-${index})"/>
|
|
<rect width="${actualWidth}" height="${actualHeight}" rx="${borderRadius}" fill="url(#blue-grad-${index})" style="mix-blend-mode:${mixBlendMode}"/>
|
|
</svg>
|
|
`;
|
|
return "data:image/svg+xml," + encodeURIComponent(svgContent);
|
|
}
|
|
|
|
function update() {
|
|
feImage.setAttribute("href", generateDisplacementMap());
|
|
redChannel.setAttribute("scale", distortionScale + redOffset);
|
|
greenChannel.setAttribute("scale", distortionScale + greenOffset);
|
|
blueChannel.setAttribute("scale", distortionScale + blueOffset);
|
|
[redChannel, greenChannel, blueChannel].forEach((ch) => {
|
|
ch.setAttribute("xChannelSelector", xChannel);
|
|
ch.setAttribute("yChannelSelector", yChannel);
|
|
});
|
|
gaussianBlur.setAttribute("stdDeviation", displace);
|
|
}
|
|
|
|
update();
|
|
btn.classList.remove("glass-surface--fallback");
|
|
btn.classList.add("glass-surface--svg");
|
|
|
|
const observer = new ResizeObserver(() => setTimeout(update, 0));
|
|
observer.observe(btn);
|
|
});
|
|
}
|
|
|
|
initLiquidButtons();
|
|
}
|
|
});
|
|
</script>
|
|
|
|
<script>
|
|
const statusEl = document.getElementById("status-message");
|
|
const debugBox = document.getElementById("debug-log-box");
|
|
const progressTrack = document.getElementById("progress-track");
|
|
const progressFill = document.getElementById("progress-fill");
|
|
const actionsEl = document.getElementById("update-actions");
|
|
const btnYes = document.getElementById("btn-update-yes");
|
|
const btnNo = document.getElementById("btn-update-no");
|
|
|
|
if (actionsEl) actionsEl.style.display = "none";
|
|
if (progressTrack) progressTrack.style.display = "none";
|
|
|
|
let currentStatusText = "";
|
|
|
|
function setStatus(text, color = "rgba(255, 255, 255, 0.85)") {
|
|
if (!statusEl || text === currentStatusText) return;
|
|
currentStatusText = text;
|
|
statusEl.innerHTML = "";
|
|
statusEl.style.color = color;
|
|
|
|
const chars = Array.from(text);
|
|
chars.forEach((char, index) => {
|
|
const span = document.createElement("span");
|
|
span.className = "status-char";
|
|
span.textContent = char;
|
|
span.style.animationDelay = `${index * 16}ms`;
|
|
statusEl.appendChild(span);
|
|
});
|
|
}
|
|
|
|
function showDebug(msg) {
|
|
if (!debugBox) return;
|
|
debugBox.style.display = "block";
|
|
debugBox.textContent = msg;
|
|
}
|
|
|
|
async function initTauriEvents() {
|
|
let eventApi = null;
|
|
|
|
if (window.__TAURI__?.event && typeof window.__TAURI__.event.listen === 'function') {
|
|
eventApi = window.__TAURI__.event;
|
|
} else if (window.__TAURI_INTERNALS__ && typeof window.__TAURI_INTERNALS__.listen === 'function') {
|
|
eventApi = window.__TAURI_INTERNALS__;
|
|
} else if (window.__TAURI__ && typeof window.__TAURI__.listen === 'function') {
|
|
eventApi = window.__TAURI__;
|
|
}
|
|
|
|
if (!eventApi) {
|
|
setTimeout(initTauriEvents, 50);
|
|
return;
|
|
}
|
|
|
|
eventApi.listen("status", (e) => {
|
|
const data = e.payload || e;
|
|
if (data && data.message) {
|
|
setStatus(data.message);
|
|
}
|
|
});
|
|
|
|
eventApi.listen("download-progress", (e) => {
|
|
const data = e.payload || e;
|
|
if (data) {
|
|
if (progressTrack) progressTrack.style.display = "block";
|
|
if (progressFill) progressFill.style.width = "100%";
|
|
if (actionsEl) actionsEl.style.display = "none";
|
|
setStatus("Downloading update...");
|
|
}
|
|
});
|
|
|
|
eventApi.listen("update-available", (e) => {
|
|
const data = e.payload || e;
|
|
if (data && data.latest) {
|
|
if (progressTrack) progressTrack.style.display = "none";
|
|
setStatus(`Update Available: ${data.latest} (Current: ${data.current})`);
|
|
if (actionsEl) actionsEl.style.display = "flex";
|
|
}
|
|
});
|
|
|
|
eventApi.listen("ready", (e) => {
|
|
const data = e.payload || e;
|
|
if (data && data.url) {
|
|
if (progressTrack) progressTrack.style.display = "none";
|
|
if (actionsEl) actionsEl.style.display = "none";
|
|
setStatus("Launching...");
|
|
}
|
|
});
|
|
|
|
eventApi.listen("error", (e) => {
|
|
const data = e.payload || e;
|
|
const msg = data && data.message ? data.message : JSON.stringify(data);
|
|
setStatus("Runtime Error", "#fca5a5");
|
|
showDebug(msg);
|
|
});
|
|
}
|
|
|
|
btnYes.addEventListener("click", () => {
|
|
if (actionsEl) actionsEl.style.display = "none";
|
|
setStatus("Starting update installation...");
|
|
fetch("http://127.0.0.1:4891/update/yes", { method: "POST" }).catch((err) => {
|
|
setStatus("Failed to reach update service. Retrying...", "#fca5a5");
|
|
showDebug(err.message);
|
|
});
|
|
});
|
|
|
|
btnNo.addEventListener("click", () => {
|
|
if (actionsEl) actionsEl.style.display = "none";
|
|
setStatus("Skipping update. Starting services...");
|
|
fetch("http://127.0.0.1:4891/update/no", { method: "POST" }).catch(() => { });
|
|
});
|
|
|
|
initTauriEvents();
|
|
</script>
|
|
</body>
|
|
|
|
</html> |