/* eslint-disable jsx-a11y/media-has-caption */ import { Badge, Chip, Icon, IconButton, Icons, ProgressBar, Spinner, Text, as, toRem } from 'folds'; import React, { useCallback, useRef, useState } from 'react'; import { EncryptedAttachmentInfo } from 'browser-encrypt-attachment'; import { Range } from 'react-range'; import { useMatrixClient } from '../../../hooks/useMatrixClient'; import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback'; import { getFileSrcUrl } from './util'; import { IAudioInfo } from '../../../../types/matrix/common'; import { MediaControl } from '../../../components/media'; import { PlayTimeCallback, useMediaLoading, useMediaPlay, useMediaPlayTimeCallback, useMediaSeek, useMediaVolume, } from '../../../hooks/media'; import { useThrottle } from '../../../hooks/useThrottle'; import { secondsToMinutesAndSeconds } from '../../../utils/common'; const PLAY_TIME_THROTTLE_OPS = { wait: 500, immediate: true, }; export type AudioContentProps = { mimeType: string; url: string; info: IAudioInfo; encInfo?: EncryptedAttachmentInfo; }; export const AudioContent = as<'div', AudioContentProps>( ({ mimeType, url, info, encInfo, ...props }, ref) => { const mx = useMatrixClient(); const [srcState, loadSrc] = useAsyncCallback( useCallback( () => getFileSrcUrl(mx.mxcUrlToHttp(url) ?? '', mimeType, encInfo), [mx, url, mimeType, encInfo] ) ); const audioRef = useRef(null); const [currentTime, setCurrentTime] = useState(0); // duration in seconds. (NOTE: info.duration is in milliseconds) const infoDuration = info.duration ?? 0; const [duration, setDuration] = useState((infoDuration >= 0 ? infoDuration : 0) / 1000); const getAudioRef = useCallback(() => audioRef.current, []); const { loading } = useMediaLoading(getAudioRef); const { playing, setPlaying } = useMediaPlay(getAudioRef); const { seek } = useMediaSeek(getAudioRef); const { volume, mute, setMute, setVolume } = useMediaVolume(getAudioRef); const handlePlayTimeCallback: PlayTimeCallback = useCallback((d, ct) => { setDuration(d); setCurrentTime(ct); }, []); useMediaPlayTimeCallback( getAudioRef, useThrottle(handlePlayTimeCallback, PLAY_TIME_THROTTLE_OPS) ); const handlePlay = () => { if (srcState.status === AsyncStatus.Success) { setPlaying(!playing); } else if (srcState.status !== AsyncStatus.Loading) { loadSrc(); } }; return ( seek(values[0])} renderTrack={(params) => (
{params.children}
)} renderThumb={(params) => ( )} /> } leftControl={ <> ) : ( ) } > {playing ? 'Pause' : 'Play'} {`${secondsToMinutesAndSeconds( currentTime )} / ${secondsToMinutesAndSeconds(duration)}`} } rightControl={ <> setMute(!mute)} aria-pressed={mute} > setVolume(values[0])} renderTrack={(params) => (
{params.children}
)} renderThumb={(params) => ( )} /> } {...props} ref={ref} >
); } );