fix(uploads): serve private previews through API and show batch cover status
ci / mobile / mobile (Metro-бандл Android) (push) Successful in 1m30s
ci / ts / ts (packages + web) (push) Canceled after 4m13s
ci / module boundaries / boundaries (push) Successful in 8s
ci / api / api (push) Successful in 56s
ci / contract / contract (сгенерированный код совпадает с openapi.yaml) (push) Successful in 1m1s
ci / db / db (push) Successful in 1m7s

This commit is contained in:
mrleo1nid committed 2026-10-29 11:34:55 +03:00
1 parent 37e33c656b
commit 7d62531c02
15 files changed
+533 -410

No files matched your search

+8 -1
View File
@@ -2,6 +2,7 @@ import { formatBytes, formatDateTime, formatDuration } from '../../shared/lib/fo
import { chevronRightIcon, editIcon, refreshIcon } from '../../shared/ui/icons';
import { useId, useState } from 'react';
import { needsFormatAttention } from './files';
import { AudioPreview } from './AudioPreview';
import { UploadStatusBadge, useReasonText, type UploadFile } from './common';
import { useTranslation } from 'react-i18next';
import { Button, cx, Icon } from '../../shared/ui/ui';
@@ -43,6 +44,9 @@ export function BatchCard({
<b>{first.author.username}</b>
<span>{formatDateTime(first.created_at, i18n.language)}</span>
<span>{t('uploads.batch_size', { count: files.length, size: formatBytes(size, i18n.language) })}</span>
<span className={cx(s.badge, first.batch_has_cover ? u.tone_info : u.tone_muted)}>
{t(first.batch_has_cover ? 'uploads.batch_cover_present' : 'uploads.batch_cover_absent')}
</span>
<span style={{ flex: 1 }} />
{selectable && (
<Button variant="ghost" onClick={() => onEditBatch(first.batch_id)}>
@@ -56,6 +60,7 @@ export function BatchCard({
<QueueRow
key={f.id}
file={f}
active={!collapsed}
selectable={selectable}
checked={selected.has(f.id)}
onCheck={(on) => onToggle([f.id], on)}
@@ -70,6 +75,7 @@ export function BatchCard({
function QueueRow({
file: f,
active,
selectable,
checked,
onCheck,
@@ -77,6 +83,7 @@ function QueueRow({
onRetry,
}: {
file: UploadFile;
active: boolean;
selectable: boolean;
checked: boolean;
onCheck: (on: boolean) => void;
@@ -142,7 +149,7 @@ function QueueRow({
</div>
<div className={u.rowActions}>
{f.stream_url && (
<audio controls preload="metadata" src={f.stream_url} aria-label={t('uploads.listen', { name: f.original_name })} />
<AudioPreview url={f.stream_url} name={f.original_name} active={active} />
)}
{editable && (
<Button variant="ghost" aria-label={t('uploads.edit', { name: f.original_name })} onClick={onEdit}>