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:
parent
e7f58bb7ad
commit
29a99d0713
4 changed files with 25 additions and 18 deletions
File diff suppressed because one or more lines are too long
|
|
@ -4,7 +4,7 @@
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<title>Archivr</title>
|
<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">
|
<link rel="stylesheet" crossorigin href="/assets/index-CLkuyO9A.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,16 @@ export async function fetchEntryDetail(archiveId, entryUid) {
|
||||||
return getJson(`/api/archives/${archiveId}/entries/${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) {
|
export async function updateEntryTitle(archiveId, entryUid, title) {
|
||||||
const res = await fetch(`/api/archives/${archiveId}/entries/${entryUid}`, {
|
const res = await fetch(`/api/archives/${archiveId}/entries/${entryUid}`, {
|
||||||
method: 'PATCH',
|
method: 'PATCH',
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import { useState, useEffect } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
|
import { fetchEntryArtifacts } from '../api';
|
||||||
|
|
||||||
// ── Date helper ────────────────────────────────────────────────────────────────
|
// ── Date helper ────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
|
@ -911,6 +912,10 @@ function MediaLightbox({ items, startIndex, onClose }) {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const h = e => {
|
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 === 'Escape') onClose();
|
||||||
if (e.key === 'ArrowRight') setIdx(i => Math.min(i + 1, items.length - 1));
|
if (e.key === 'ArrowRight') setIdx(i => Math.min(i + 1, items.length - 1));
|
||||||
if (e.key === 'ArrowLeft') setIdx(i => Math.max(i - 1, 0));
|
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;
|
let cancelled = false;
|
||||||
|
|
||||||
Promise.all(
|
fetchEntryArtifacts(archiveId, entryUid, tweetArtifacts.map(a => a.index))
|
||||||
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();
|
|
||||||
})
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.then(data => { if (!cancelled) setTweets(data); })
|
.then(data => { if (!cancelled) setTweets(data); })
|
||||||
.catch(e => { if (!cancelled) setError(e.message || 'Failed to load tweet.'); })
|
.catch(e => { if (!cancelled) setError(e.message || 'Failed to load tweet.'); })
|
||||||
.finally(() => { if (!cancelled) setLoading(false); });
|
.finally(() => { if (!cancelled) setLoading(false); });
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue