stream-chat-react
Version:
React components to create chat conversations or livestream style chat
53 lines (52 loc) • 3.11 kB
JavaScript
import React from 'react';
import { DownloadButton, FileSizeIndicator, PlayButton, ProgressBar } from './components';
import { useAudioPlayer } from '../AudioPlayback';
import { useStateStore } from '../../store';
import { useMessageContext } from '../../context';
// todo: finish creating a BaseAudioPlayer derived from VoiceRecordingPlayerUI and AudioAttachmentUI
const AudioAttachmentUI = ({ audioPlayer }) => {
const dataTestId = 'audio-widget';
const rootClassName = 'str-chat__message-attachment-audio-widget';
const { isPlaying, progress } = useStateStore(audioPlayer?.state, audioPlayerStateSelector) ?? {};
return (React.createElement("div", { className: rootClassName, "data-testid": dataTestId },
React.createElement("div", { className: 'str-chat__message-attachment-audio-widget--play-controls' },
React.createElement(PlayButton, { isPlaying: !!isPlaying, onClick: audioPlayer.togglePlay })),
React.createElement("div", { className: 'str-chat__message-attachment-audio-widget--text' },
React.createElement("div", { className: 'str-chat__message-attachment-audio-widget--text-first-row' },
React.createElement("div", { className: 'str-chat__message-attachment-audio-widget--title' }, audioPlayer.title),
React.createElement(DownloadButton, { assetUrl: audioPlayer.src })),
React.createElement("div", { className: 'str-chat__message-attachment-audio-widget--text-second-row' },
React.createElement(FileSizeIndicator, { fileSize: audioPlayer.fileSize }),
React.createElement(ProgressBar, { onClick: audioPlayer.seek, progress: progress ?? 0 })))));
};
const audioPlayerStateSelector = (state) => ({
isPlaying: state.isPlaying,
progress: state.progressPercent,
});
const UnMemoizedAudio = (props) => {
const { og: { asset_url, file_size, mime_type, title }, } = props;
/**
* Introducing message context. This could be breaking change, therefore the fallback to {} is provided.
* If this component is used outside the message context, then there will be no audio player namespacing
* => scrolling away from the message in virtualized ML would create a new AudioPlayer instance.
*
* Edge case: the requester (message) has multiple attachments with the same assetURL - does not happen
* with the default SDK components, but can be done with custom API calls.In this case all the Audio
* widgets will share the state.
*/
const { message, threadList } = useMessageContext() ?? {};
const audioPlayer = useAudioPlayer({
fileSize: file_size,
mimeType: mime_type,
requester: message?.id &&
`${threadList ? (message.parent_id ?? message.id) : ''}${message.id}`,
src: asset_url,
title,
waveformData: props.og.waveform_data,
});
return audioPlayer ? React.createElement(AudioAttachmentUI, { audioPlayer: audioPlayer }) : null;
};
/**
* Audio attachment with play/pause button and progress bar
*/
export const Audio = React.memo(UnMemoizedAudio);