mirror of
https://github.com/thegeneralist01/archivr
synced 2026-07-22 11:15:41 +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:
parent
e7f58bb7ad
commit
29a99d0713
4 changed files with 25 additions and 18 deletions
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -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); });
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue