4 <meta charset=
"utf-8" />
8 font-family: system-ui;
19 flex-direction: column;
26 flex-direction: column;
42 -webkit-app-region: no-drag;
46 border-radius:
0.5rem;
47 border: solid thin #ccc;
48 background: transparent;
57 #button:hover:active {
68 <div id=
"wrapper" aria-hidden=
"true" aria-live=
"assertive" aria-atomic=
"true">
69 <img id=
"spinner" src=
"./error-network.svg" />
72 <p id=
"description"></p>
74 <button id=
"button" style=
"display: none" type=
"button"></button>
77 <script type=
"module">
78 const titleElement = document.getElementById(
"title");
79 const descriptionElement = document.getElementById(
"description");
80 const buttonElement = document.getElementById(
"button");
81 const wrapperElement = document.getElementById(
"wrapper");
82 const locationSearchParams = new URLSearchParams(location.search);
84 const title = locationSearchParams.get(
"title") ||
"";
85 const description = locationSearchParams.get(
"description") ||
"";
86 const buttonText = locationSearchParams.get(
"button") ||
"";
87 const buttonTarget = locationSearchParams.get(
"buttonTarget") ||
"";
88 const theme = locationSearchParams.get(
"theme") ||
"light";
89 const draggable = locationSearchParams.has(
"draggable");
92 document.body.style.setProperty(
"-webkit-app-region-",
"drag");
95 document.documentElement.style.background = theme ===
"dark" ?
"#666" :
"#fff";
96 document.documentElement.style.color = theme ===
"dark" ?
"#e1e1e1" :
"#222";
98 titleElement.textContent = title;
99 descriptionElement.textContent = description;
100 buttonElement.textContent = buttonText;
102 buttonElement.addEventListener(
"click", () =
> {
103 window.location.href = buttonTarget;
106 const maxCooldown =
300;
107 const cooldownDuration =
1000 *
60 *
60 *
2; //
2 hours
108 const retryCooldownList = [
1,
2,
5,
10,
30,
60,
180, maxCooldown];
110 buttonElement.style.display =
"block";
111 wrapperElement.removeAttribute(
"aria-hidden");
114 const firstCheckDatetime = Date.now();
117 if (Date.now() - firstCheckDatetime
> cooldownDuration) {
121 await new Promise((resolve) =
> {
122 const cooldown = retryCooldownList.length ? retryCooldownList.shift() : maxCooldown;
123 setTimeout(resolve, cooldown *
1000);
127 const response = await fetch(buttonTarget);
128 if (response.ok) buttonElement.click();