narrarium-astro-reader 0.1.32 → 0.1.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/layouts/BaseLayout.astro +11 -0
- package/src/styles/global.css +28 -0
package/package.json
CHANGED
|
@@ -173,6 +173,8 @@ const isChapterPage = Number.isFinite(currentChapterNumber);
|
|
|
173
173
|
try { storedKeyB64 = localStorage.getItem("narrarium-reader-aes-key"); } catch (_) {}
|
|
174
174
|
|
|
175
175
|
if (storedKeyB64) {
|
|
176
|
+
// Show loading overlay while we verify and decrypt with the stored key.
|
|
177
|
+
document.body.classList.add("reader-decrypting");
|
|
176
178
|
crypto.subtle.importKey(
|
|
177
179
|
"raw", b64ToBytes(storedKeyB64),
|
|
178
180
|
{ name: "AES-GCM", length: 256 },
|
|
@@ -186,8 +188,12 @@ const isChapterPage = Number.isFinite(currentChapterNumber);
|
|
|
186
188
|
return window._narrariumDecryptPage(key, true);
|
|
187
189
|
});
|
|
188
190
|
})
|
|
191
|
+
.then(function () {
|
|
192
|
+
document.body.classList.remove("reader-decrypting");
|
|
193
|
+
})
|
|
189
194
|
.catch(function () {
|
|
190
195
|
// Stored key is stale or corrupt — clear it and show lock screen.
|
|
196
|
+
document.body.classList.remove("reader-decrypting");
|
|
191
197
|
try { localStorage.removeItem("narrarium-reader-aes-key"); } catch (_) {}
|
|
192
198
|
document.body.classList.add("reader-auth-locked");
|
|
193
199
|
_resolveReady("locked");
|
|
@@ -198,6 +204,11 @@ const isChapterPage = Number.isFinite(currentChapterNumber);
|
|
|
198
204
|
}
|
|
199
205
|
})();
|
|
200
206
|
</script>
|
|
207
|
+
{canary && (
|
|
208
|
+
<div id="reader-loading" aria-hidden="true">
|
|
209
|
+
<div class="reader-loading__spinner"></div>
|
|
210
|
+
</div>
|
|
211
|
+
)}
|
|
201
212
|
{canary && (
|
|
202
213
|
<div id="reader-password-gate" role="dialog" aria-modal="true" aria-label="Access required">
|
|
203
214
|
<div class="reader-password-gate__inner">
|
package/src/styles/global.css
CHANGED
|
@@ -1466,6 +1466,34 @@ mark {
|
|
|
1466
1466
|
}
|
|
1467
1467
|
}
|
|
1468
1468
|
|
|
1469
|
+
/* ─── Auto-decrypt loading overlay ──────────────────────────── */
|
|
1470
|
+
#reader-loading {
|
|
1471
|
+
display: none;
|
|
1472
|
+
position: fixed;
|
|
1473
|
+
inset: 0;
|
|
1474
|
+
z-index: 199;
|
|
1475
|
+
background: var(--app-bg);
|
|
1476
|
+
align-items: center;
|
|
1477
|
+
justify-content: center;
|
|
1478
|
+
}
|
|
1479
|
+
|
|
1480
|
+
body.reader-decrypting #reader-loading {
|
|
1481
|
+
display: flex;
|
|
1482
|
+
}
|
|
1483
|
+
|
|
1484
|
+
.reader-loading__spinner {
|
|
1485
|
+
width: 32px;
|
|
1486
|
+
height: 32px;
|
|
1487
|
+
border: 3px solid var(--line);
|
|
1488
|
+
border-top-color: var(--accent);
|
|
1489
|
+
border-radius: 50%;
|
|
1490
|
+
animation: reader-spin 0.7s linear infinite;
|
|
1491
|
+
}
|
|
1492
|
+
|
|
1493
|
+
@keyframes reader-spin {
|
|
1494
|
+
to { transform: rotate(360deg); }
|
|
1495
|
+
}
|
|
1496
|
+
|
|
1469
1497
|
/* ─── Password gate ──────────────────────────────────────────── */
|
|
1470
1498
|
#reader-password-gate {
|
|
1471
1499
|
display: none;
|