fix(opds): more robust parsing for authors in metadata, closes #3120 (#3134)

This commit is contained in:
Huang Xin
2026-02-01 22:57:10 +08:00
committed by GitHub
parent c848a319ff
commit 8a468a6d1f
3 changed files with 33 additions and 11 deletions
@@ -134,11 +134,25 @@ async function handleRequest(request: NextRequest, method: 'GET' | 'HEAD') {
const buf = await response.arrayBuffer();
const length = buf.byteLength;
console.log(`[OPDS Proxy] Success: ${url} (${length} bytes)`);
const excludedHeaders = new Set([
'content-encoding',
'content-length',
'transfer-encoding',
'connection',
'keep-alive',
]);
const proxyHeaders: Record<string, string> = {};
for (const [key, value] of response.headers.entries()) {
if (!excludedHeaders.has(key.toLowerCase())) {
proxyHeaders[key] = value;
}
}
return new NextResponse(buf, {
status: 200,
headers: {
...Object.fromEntries(response.headers.entries()),
...proxyHeaders,
'Content-Type': contentType,
'Content-Length': length.toString(),
'Cache-Control': 'public, max-age=300',
@@ -45,9 +45,12 @@ export function PublicationCard({
const imageUrl = imageLink ? resolveURL(imageLink.href, baseURL) : null;
const authors = useMemo(() => {
return publication.metadata?.author
?.map((author) => (typeof author === 'string' ? author : author.name))
.join(', ');
const author = publication.metadata?.author;
if (!author) return undefined;
const authorList = Array.isArray(author) ? author : [author];
return authorList.map((a) => (typeof a === 'string' ? a : a?.name)).filter(Boolean);
}, [publication.metadata?.author]);
const price = useMemo(() => {
@@ -83,7 +86,9 @@ export function PublicationCard({
<h3 className='card-title line-clamp-1 text-sm'>
{publication.metadata?.title || 'Untitled'}
</h3>
{authors && <p className='text-base-content/70 line-clamp-1 text-xs'>{authors}</p>}
{authors && authors.length > 0 && (
<p className='text-base-content/70 line-clamp-1 text-xs'>{authors.join(', ')}</p>
)}
{price && (
<div className='card-actions mt-2 justify-end'>
<div className='badge badge-outline badge-sm'>{price}</div>
@@ -56,9 +56,12 @@ export function PublicationView({
const imageUrl = coverImage ? resolveURL(coverImage.href, baseURL) : null;
const authors = useMemo(() => {
return publication.metadata?.author?.map((author) =>
typeof author === 'string' ? author : author.name,
);
const author = publication.metadata?.author;
if (!author) return undefined;
const authorList = Array.isArray(author) ? author : [author];
return authorList.map((a) => (typeof a === 'string' ? a : a?.name)).filter(Boolean);
}, [publication.metadata?.author]);
const acquisitionLinks = useMemo(() => {
@@ -162,9 +165,9 @@ export function PublicationView({
) : (
<Dropdown
label={_('Download')}
className='dropdown-bottom flex justify-center'
className='dropdown-bottom dropdown-center flex justify-center'
buttonClassName={clsx(
'btn btn-ghost btn-primary min-w-20 rounded-3xl p-0 hover:bg-transparent',
'btn btn-primary min-w-20 rounded-3xl p-0 bg-primary hover:bg-primary',
downloadedBook && 'btn-success',
)}
disabled={downloading}
@@ -174,7 +177,7 @@ export function PublicationView({
>
<div
className={clsx(
'delete-menu dropdown-content dropdown-center no-triangle',
'delete-menu dropdown-content no-triangle !relative',
'border-base-300 !bg-base-200 z-20 mt-2 max-w-[80vw] shadow-2xl',
)}
>