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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "narrarium-astro-reader",
3
- "version": "0.1.32",
3
+ "version": "0.1.33",
4
4
  "type": "module",
5
5
  "description": "Astro reader and scaffolding CLI for Narrarium book repositories.",
6
6
  "license": "MIT",
@@ -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">
@@ -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;