1
Fork 0
mirror of https://github.com/thegeneralist01/archivr synced 2026-07-22 03:05:32 +02:00

fix: move artifact fetch to api.js; stop Escape propagation from lightbox

- Export fetchEntryArtifacts(archiveId, entryUid, indices) from api.js
  using Promise.all + getJson (follows project convention: all /api calls
  go through api.js, never inline fetch in components)
- TweetPreview: import fetchEntryArtifacts, replace inline Promise.all
- MediaLightbox keydown handler: stopPropagation + preventDefault for
  Escape/ArrowLeft/ArrowRight so the parent PreviewModal window listener
  does not also fire and close the modal behind the lightbox
This commit is contained in:
TheGeneralist 2026-07-12 14:14:31 +02:00
parent e7f58bb7ad
commit 29a99d0713
Signed by: thegeneralist01
SSH key fingerprint: SHA256:pp9qddbCNmVNoSjevdvQvM5z0DHN7LTa8qBMbcMq/R4
4 changed files with 25 additions and 18 deletions

View file

@ -4,7 +4,7 @@
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Archivr</title>
<script type="module" crossorigin src="/assets/index-J6UnJptz.js"></script>
<script type="module" crossorigin src="/assets/index-CH_nemMw.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-CLkuyO9A.css">
</head>
<body>

View file

@ -25,6 +25,16 @@ export async function fetchEntryDetail(archiveId, entryUid) {
return getJson(`/api/archives/${archiveId}/entries/${entryUid}`);
}
// Fetch multiple artifact JSON payloads for an entry in parallel.
// Returns a Promise<Array> preserving index order.
export function fetchEntryArtifacts(archiveId, entryUid, indices) {
return Promise.all(
indices.map(idx =>
getJson(`/api/archives/${archiveId}/entries/${entryUid}/artifacts/${idx}`)
)
);
}
export async function updateEntryTitle(archiveId, entryUid, title) {
const res = await fetch(`/api/archives/${archiveId}/entries/${entryUid}`, {
method: 'PATCH',

View file

@ -1,4 +1,5 @@
import { useState, useEffect } from 'react';
import { fetchEntryArtifacts } from '../api';
// Date helper
@ -911,6 +912,10 @@ function MediaLightbox({ items, startIndex, onClose }) {
useEffect(() => {
const h = e => {
if (e.key === 'Escape' || e.key === 'ArrowLeft' || e.key === 'ArrowRight') {
e.stopPropagation();
e.preventDefault();
}
if (e.key === 'Escape') onClose();
if (e.key === 'ArrowRight') setIdx(i => Math.min(i + 1, items.length - 1));
if (e.key === 'ArrowLeft') setIdx(i => Math.max(i - 1, 0));
@ -1088,15 +1093,7 @@ export default function TweetPreview({ archiveId, entryUid, artifacts, entityKin
let cancelled = false;
Promise.all(
tweetArtifacts.map(a =>
fetch(`/api/archives/${archiveId}/entries/${entryUid}/artifacts/${a.index}`)
.then(r => {
if (!r.ok) throw new Error(`HTTP ${r.status}`);
return r.json();
})
)
)
fetchEntryArtifacts(archiveId, entryUid, tweetArtifacts.map(a => a.index))
.then(data => { if (!cancelled) setTweets(data); })
.catch(e => { if (!cancelled) setError(e.message || 'Failed to load tweet.'); })
.finally(() => { if (!cancelled) setLoading(false); });