From 52d5127d8db5296847c94327bfc682d6cf2ee39d Mon Sep 17 00:00:00 2001 From: Delirium Date: Fri, 19 Apr 2024 17:30:17 +0200 Subject: [PATCH] feat ui: support additional audio files (#2112) --- .../Player/ReplayPlayer/AudioPlayer.tsx | 99 +++++++++++++++++++ .../Player/ReplayPlayer/PlayerBlockHeader.tsx | 4 + frontend/app/types/session/session.ts | 3 + 3 files changed, 106 insertions(+) create mode 100644 frontend/app/components/Session/Player/ReplayPlayer/AudioPlayer.tsx diff --git a/frontend/app/components/Session/Player/ReplayPlayer/AudioPlayer.tsx b/frontend/app/components/Session/Player/ReplayPlayer/AudioPlayer.tsx new file mode 100644 index 000000000..b45aaecf7 --- /dev/null +++ b/frontend/app/components/Session/Player/ReplayPlayer/AudioPlayer.tsx @@ -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(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 ( +
+ + + +
+ +
+
+ ); +} + +export default observer(DropdownAudioPlayer); diff --git a/frontend/app/components/Session/Player/ReplayPlayer/PlayerBlockHeader.tsx b/frontend/app/components/Session/Player/ReplayPlayer/PlayerBlockHeader.tsx index 1fcf8e8ae..3cb5c28ec 100644 --- a/frontend/app/components/Session/Player/ReplayPlayer/PlayerBlockHeader.tsx +++ b/frontend/app/components/Session/Player/ReplayPlayer/PlayerBlockHeader.tsx @@ -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 (
@@ -109,6 +111,8 @@ function PlayerBlockHeader(props: any) {
)} + + {session.audio ? : null}
diff --git a/frontend/app/types/session/session.ts b/frontend/app/types/session/session.ts index 59fbc4a85..ae55fb13d 100644 --- a/frontend/app/types/session/session.ts +++ b/frontend/app/types/session/session.ts @@ -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, }); }