fix(uploads): pause previous audio preview when another starts
This commit is contained in:
1 parent
7d62531c02
commit
af06cf1e75
3 files changed
+44
-2
No files matched your search
@@ -5,6 +5,9 @@ import { refreshIcon } from '../../shared/ui/icons';
|
||||
import { Button } from '../../shared/ui/ui';
|
||||
import u from '../../pages/uploads/uploads.module.css';
|
||||
|
||||
// Preview elements may belong to different batches, but only one may play.
|
||||
const previews = new Set<HTMLAudioElement>();
|
||||
|
||||
export function AudioPreview({ url, name, active }: { url: string; name: string; active: boolean }) {
|
||||
const { t } = useTranslation('admin');
|
||||
const queryClient = useQueryClient();
|
||||
@@ -12,6 +15,16 @@ export function AudioPreview({ url, name, active }: { url: string; name: string;
|
||||
const [error, setError] = useState<number | null>(null);
|
||||
const [httpStatus, setHttpStatus] = useState<number | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const element = audio.current;
|
||||
if (!element) return;
|
||||
previews.add(element);
|
||||
return () => { previews.delete(element); element.pause(); };
|
||||
}, []);
|
||||
useEffect(() => {
|
||||
if (!active) audio.current?.pause();
|
||||
}, [active]);
|
||||
|
||||
useEffect(() => { setError(null); setHttpStatus(null); }, [url]);
|
||||
useEffect(() => {
|
||||
if (error === null) return;
|
||||
@@ -37,6 +50,12 @@ export function AudioPreview({ url, name, active }: { url: string; name: string;
|
||||
return <div className={u.preview}>
|
||||
<audio ref={audio} controls preload={active ? 'metadata' : 'none'} src={url}
|
||||
aria-label={t('uploads.listen', { name })}
|
||||
onPlay={(event) => {
|
||||
if (event.currentTarget.paused) return;
|
||||
for (const other of previews) {
|
||||
if (other !== event.currentTarget && !other.paused) other.pause();
|
||||
}
|
||||
}}
|
||||
onLoadedMetadata={() => { setError(null); setHttpStatus(null); }}
|
||||
onError={(event) => setError(event.currentTarget.error?.code ?? 0)} />
|
||||
{error !== null && <div className={u.previewError}>
|
||||
|
||||
Reference in new issue
Block a user