feat ui: support additional audio files (#2112)
This commit is contained in:
parent
07f64ebcae
commit
52d5127d8d
3 changed files with 106 additions and 0 deletions
|
|
@ -0,0 +1,99 @@
|
|||
import { MutedOutlined, SoundOutlined } from '@ant-design/icons';
|
||||
import { Button, Tooltip } from 'antd';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import React, { useRef, useState } from 'react';
|
||||
|
||||
import { PlayerContext } from '../../playerContext';
|
||||
|
||||
function DropdownAudioPlayer({ url }: { url: string }) {
|
||||
const { store } = React.useContext(PlayerContext);
|
||||
const [isVisible, setIsVisible] = useState(false);
|
||||
const [delta, setDelta] = useState(0);
|
||||
const [isMuted, setIsMuted] = useState(false);
|
||||
const lastPlayerTime = React.useRef(0);
|
||||
const audioRef = useRef<HTMLAudioElement>(null);
|
||||
|
||||
const { time = 0, speed = 1, playing } = store?.get() ?? {};
|
||||
|
||||
const toggleMute = () => {
|
||||
if (audioRef.current) {
|
||||
if (audioRef.current?.paused && playing) {
|
||||
audioRef.current?.play();
|
||||
}
|
||||
audioRef.current.muted = !audioRef.current.muted;
|
||||
setIsMuted(!isMuted);
|
||||
}
|
||||
};
|
||||
|
||||
const handleSeek = (timeMs: number) => {
|
||||
if (audioRef.current) {
|
||||
audioRef.current.currentTime = (timeMs + delta) / 1000;
|
||||
}
|
||||
};
|
||||
|
||||
const changePlaybackSpeed = (speed: number) => {
|
||||
if (audioRef.current) {
|
||||
audioRef.current.playbackRate = speed;
|
||||
}
|
||||
};
|
||||
|
||||
React.useEffect(() => {
|
||||
if (Math.abs(lastPlayerTime.current - time) > 1000) {
|
||||
handleSeek(time);
|
||||
}
|
||||
lastPlayerTime.current = time;
|
||||
}, [time]);
|
||||
|
||||
React.useEffect(() => {
|
||||
changePlaybackSpeed(speed);
|
||||
}, [speed]);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (playing) {
|
||||
audioRef.current?.play();
|
||||
} else {
|
||||
audioRef.current?.pause();
|
||||
}
|
||||
}, [playing]);
|
||||
|
||||
return (
|
||||
<div className="relative mr-2">
|
||||
<Tooltip
|
||||
title={`This session contains audio recording. Press to ${
|
||||
isMuted ? 'unmute' : 'mute'
|
||||
}`}
|
||||
>
|
||||
<Button
|
||||
className={'flex items-center justify-center'}
|
||||
onClick={toggleMute}
|
||||
size={'small'}
|
||||
>
|
||||
{isMuted ? <MutedOutlined /> : <SoundOutlined />}
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<div
|
||||
style={{
|
||||
display: isVisible ? 'block' : 'none',
|
||||
zIndex: 2,
|
||||
width: 420,
|
||||
marginRight: 40,
|
||||
right: 0,
|
||||
top: -6,
|
||||
}}
|
||||
className="absolute shadow p-2 shadow-lg bg-white rounded border border-gray-lighter"
|
||||
>
|
||||
<audio
|
||||
ref={audioRef}
|
||||
controls
|
||||
className="w-full"
|
||||
style={{ height: 32 }}
|
||||
>
|
||||
<source src={url} type="audio/mpeg" />
|
||||
Your browser does not support the audio element.
|
||||
</audio>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default observer(DropdownAudioPlayer);
|
||||
|
|
@ -12,6 +12,7 @@ import { BackLink, Link } from 'UI';
|
|||
import { toggleFavorite, setSessionPath } from 'Duck/sessions';
|
||||
import cn from 'classnames';
|
||||
import SessionMetaList from 'Shared/SessionItem/SessionMetaList';
|
||||
import DropdownAudioPlayer from "./AudioPlayer";
|
||||
import UserCard from './EventsBlock/UserCard';
|
||||
import Tabs from 'Components/Session/Tabs';
|
||||
import { PlayerContext } from 'App/components/Session/playerContext';
|
||||
|
|
@ -77,6 +78,7 @@ function PlayerBlockHeader(props: any) {
|
|||
key: tab,
|
||||
}));
|
||||
|
||||
|
||||
return (
|
||||
<div className={cn(stl.header, 'flex justify-between', { hidden: fullscreen })}>
|
||||
<div className="flex w-full items-center">
|
||||
|
|
@ -109,6 +111,8 @@ function PlayerBlockHeader(props: any) {
|
|||
<SessionMetaList className="" metaList={_metaList} maxLength={2} />
|
||||
</div>
|
||||
)}
|
||||
|
||||
{session.audio ? <DropdownAudioPlayer url={session.audio} /> : null}
|
||||
</div>
|
||||
</div>
|
||||
<div className="relative border-l border-l-gray-lighter" style={{ minWidth: '270px' }}>
|
||||
|
|
|
|||
|
|
@ -136,6 +136,7 @@ export interface ISession {
|
|||
timezone?: string;
|
||||
videoURL?: string[]
|
||||
isMobileNative?: boolean
|
||||
audio?: string;
|
||||
}
|
||||
|
||||
const emptyValues = {
|
||||
|
|
@ -221,6 +222,7 @@ export default class Session {
|
|||
timezone?: ISession['timezone'];
|
||||
platform: ISession['platform'];
|
||||
isMobileNative?: ISession['isMobileNative'];
|
||||
audio?: ISession['audio'];
|
||||
|
||||
fileKey: ISession['fileKey'];
|
||||
durationSeconds: number;
|
||||
|
|
@ -343,6 +345,7 @@ export default class Session {
|
|||
frustrations: frustrationList,
|
||||
uxtVideo: uxtVideo[0],
|
||||
durationMs: session.duration,
|
||||
audio: session.audio,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue