import browser from "webextension-polyfill"; import stringToHTML from "@/seqta/utils/stringToHTML"; import { settingsState } from "@/seqta/utils/listeners/SettingsState"; import loadingSpinner from "./loading-spinner.html?raw"; import loadingOverlay from "./loading-overlay.html?raw"; import { startLoadingCanvas } from "./loadingCanvas"; import { pickLoadingVariant, resolveLoadingTheme, type LoadingVariant, } from "./loadingVariants"; let stopCanvas: (() => void) | null = null; let unbindThemeGuard: (() => void) | null = null; let activeLoading: { host: HTMLElement; shadow: ShadowRoot; variant: LoadingVariant; } | null = null; const THEME_GUARD_KEYS = [ "selectedTheme", "selectedColor", "DarkMode", "adaptiveThemeColour", "selectedFont", ] as const; const LOADING_PALETTE_DARK = { line: "rgba(255, 255, 255, 0.08)", lineAccent: "rgba(255, 255, 255, 0.15)", lineBlue: "rgba(96, 165, 250, 0.42)", grid: "rgba(255, 255, 255, 0.028)", text: "#f4f4f5", version: "rgba(255, 255, 255, 0.35)", } as const; const LOADING_PALETTE_LIGHT = { line: "rgba(24, 24, 27, 0.1)", lineAccent: "rgba(24, 24, 27, 0.18)", lineBlue: "rgba(37, 99, 235, 0.5)", grid: "rgba(24, 24, 27, 0.055)", text: "#18181b", version: "rgba(24, 24, 27, 0.42)", } as const; function loadingPalette(darkMode: boolean) { return darkMode ? LOADING_PALETTE_DARK : LOADING_PALETTE_LIGHT; } const loadingStyles = /* css */ ` :host { --bk-line-color: ${LOADING_PALETTE_DARK.line}; --bk-line-accent: ${LOADING_PALETTE_DARK.lineAccent}; --bk-line-blue: ${LOADING_PALETTE_DARK.lineBlue}; --bk-grid-color: ${LOADING_PALETTE_DARK.grid}; --bk-spin-outer: 1s; --bk-spin-inner: 3s; --bk-spin-small: 3s; --bk-stage-name: bkloading-stage-in; --bk-stage-duration: 0.85s; --bk-vignette-fill: radial-gradient(ellipse at center, transparent 32%, rgba(0, 0, 0, 0.75) 100%); --bk-version-color: ${LOADING_PALETTE_DARK.version}; color: ${LOADING_PALETTE_DARK.text}; opacity: 1; transition: opacity 0.85s cubic-bezier(0.4, 0, 0.2, 1); } :host(.closeLoading) { opacity: 0; pointer-events: none; } .bkloading__canvas { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; } .bkloading__vignette { position: absolute; inset: 0; pointer-events: none; background: var(--bk-vignette-fill); opacity: 0.88; } .bkloading__content { position: absolute; inset: 0; display: grid; place-items: center; pointer-events: none; } .bkloading__logo-stage, .bkloading-inline { position: relative; } .bkloading__logo-stage { width: 220px; height: 220px; animation-name: var(--bk-stage-name); animation-duration: var(--bk-stage-duration); animation-timing-function: cubic-bezier(0.22, 1, 0.36, 1); animation-fill-mode: both; } .bkloading-inline { width: 120px; height: 120px; margin: 0 auto; } .bkloading__logo-stage .svg, .bkloading-inline .svg { transform-origin: center center; position: absolute; top: 50%; left: 50%; backface-visibility: hidden; will-change: transform; } .bkloading__logo-stage .logo, .bkloading-inline .logo { transform: translate3d(-50%, -50%, 0); } .bkloading__logo-stage .logo { z-index: 2; } .bkloading__logo-stage .big-circle { margin: -90px; animation: bkloading-spin var(--bk-spin-inner) linear infinite; } .bkloading__logo-stage .small-circle { margin: -67px; animation: bkloading-spin var(--bk-spin-small) linear infinite; } .bkloading__logo-stage .outer-circle { margin: -110px; animation: bkloading-spin-reverse var(--bk-spin-outer) linear infinite; } .bkloading-inline .big-circle { margin: -88px; animation: bkloading-spin 3s linear infinite; } .bkloading-inline .small-circle { margin: -66px; animation: bkloading-spin-reverse 3s linear infinite; } .bkloading-inline .outer-circle { margin: -108px; animation: bkloading-spin 4.5s linear infinite; } .bkloading__version { position: absolute; right: 12px; bottom: 10px; font-size: 0.95rem; letter-spacing: 0.02em; color: var(--bk-version-color); pointer-events: none; } @keyframes bkloading-stage-in { from { opacity: 0; transform: translate3d(0, 12px, 0) scale(0.94); } to { opacity: 1; transform: translate3d(0, 0, 0) scale(1); } } @keyframes bkloading-spin { to { transform: rotate(360deg); } } @keyframes bkloading-spin-reverse { to { transform: rotate(-360deg); } } @media (prefers-reduced-motion: reduce) { .bkloading__logo-stage .big-circle, .bkloading__logo-stage .small-circle, .bkloading__logo-stage .outer-circle, .bkloading-inline .big-circle, .bkloading-inline .small-circle, .bkloading-inline .outer-circle { animation: none !important; } } `; function overlayWithSpinner(): string { return loadingOverlay.replace( "
", `