From ff529ebf31ff2f828cf68369f2f055b26cc8a0a0 Mon Sep 17 00:00:00 2001 From: BFlat Date: Sat, 14 Oct 2023 17:06:12 +0700 Subject: [PATCH] updates and audio player --- .../components/common/DataTable/DataTable.tsx | 10 +- .../layout/PageHeader/PageHeader.tsx | 6 + .../v2/view/pages/media/AudioComponent.tsx | 20 --- .../view/pages/media/MediaAudioComponent.tsx | 17 ++ .../v2/view/pages/media/MediaAudioPlayer.tsx | 150 ++++++++++++++++++ ...eComponent.tsx => MediaImageComponent.tsx} | 12 +- .../src/v2/view/pages/media/MediaPage.tsx | 103 +++++++++--- ...oComponent.tsx => MediaVideoComponent.tsx} | 7 +- 8 files changed, 277 insertions(+), 48 deletions(-) delete mode 100644 packages/fakeyou.com/src/v2/view/pages/media/AudioComponent.tsx create mode 100644 packages/fakeyou.com/src/v2/view/pages/media/MediaAudioComponent.tsx create mode 100644 packages/fakeyou.com/src/v2/view/pages/media/MediaAudioPlayer.tsx rename packages/fakeyou.com/src/v2/view/pages/media/{ImageComponent.tsx => MediaImageComponent.tsx} (55%) rename packages/fakeyou.com/src/v2/view/pages/media/{VideoComponent.tsx => MediaVideoComponent.tsx} (70%) diff --git a/packages/fakeyou.com/src/components/common/DataTable/DataTable.tsx b/packages/fakeyou.com/src/components/common/DataTable/DataTable.tsx index 28ff89d7e4..539e82317e 100644 --- a/packages/fakeyou.com/src/components/common/DataTable/DataTable.tsx +++ b/packages/fakeyou.com/src/components/common/DataTable/DataTable.tsx @@ -1,9 +1,11 @@ import React from "react"; import "./DataTable.scss"; +import { Link } from "react-router-dom"; type Data = { property: string; value: string; + link?: string; }; interface DataTableProps { @@ -17,7 +19,13 @@ export default function DataTable({ data }: DataTableProps) { {data.map((row, index) => ( {row.property} - {row.value} + {row.link ? ( + + {row.value} + + ) : ( + {row.value} + )} ))} diff --git a/packages/fakeyou.com/src/components/layout/PageHeader/PageHeader.tsx b/packages/fakeyou.com/src/components/layout/PageHeader/PageHeader.tsx index 464328c665..f62b1cade1 100644 --- a/packages/fakeyou.com/src/components/layout/PageHeader/PageHeader.tsx +++ b/packages/fakeyou.com/src/components/layout/PageHeader/PageHeader.tsx @@ -14,6 +14,8 @@ interface PageHeaderProps { buttonLabel?: string; buttonVariant?: "primary" | "secondary" | "danger"; buttonTo?: string; + buttonIcon?: IconDefinition; + buttonOnClick?: () => void; } export default function PageHeader({ @@ -26,6 +28,8 @@ export default function PageHeader({ buttonLabel, buttonVariant = "primary", buttonTo, + buttonIcon, + buttonOnClick, }: PageHeaderProps) { const icon = ( <>{titleIcon && } @@ -44,9 +48,11 @@ export default function PageHeader({
{showButton && (
diff --git a/packages/fakeyou.com/src/v2/view/pages/media/AudioComponent.tsx b/packages/fakeyou.com/src/v2/view/pages/media/AudioComponent.tsx deleted file mode 100644 index dc2763baad..0000000000 --- a/packages/fakeyou.com/src/v2/view/pages/media/AudioComponent.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import MediaData from "./MediaDataTypes"; - -import React from "react"; - -interface AudioComponentProps { - mediaData: MediaData; -} - -const AudioComponent: React.FC = ({ mediaData }) => { - return ( -
- -
- ); -}; - -export default AudioComponent; diff --git a/packages/fakeyou.com/src/v2/view/pages/media/MediaAudioComponent.tsx b/packages/fakeyou.com/src/v2/view/pages/media/MediaAudioComponent.tsx new file mode 100644 index 0000000000..38c09fae4a --- /dev/null +++ b/packages/fakeyou.com/src/v2/view/pages/media/MediaAudioComponent.tsx @@ -0,0 +1,17 @@ +import MediaData from "./MediaDataTypes"; +import React from "react"; +import AudioPlayer from "./MediaAudioPlayer"; + +interface MediaAudioComponentProps { + mediaData: MediaData; +} + +export default function MediaAudioComponent({ + mediaData, +}: MediaAudioComponentProps) { + return ( +
+ +
+ ); +} diff --git a/packages/fakeyou.com/src/v2/view/pages/media/MediaAudioPlayer.tsx b/packages/fakeyou.com/src/v2/view/pages/media/MediaAudioPlayer.tsx new file mode 100644 index 0000000000..958d05790b --- /dev/null +++ b/packages/fakeyou.com/src/v2/view/pages/media/MediaAudioPlayer.tsx @@ -0,0 +1,150 @@ +import React from "react"; +import WaveSurfer from "wavesurfer.js"; +import { useEffect, useState } from "react"; +import { BucketConfig } from "@storyteller/components/src/api/BucketConfig"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { faPlay, faPause } from "@fortawesome/pro-solid-svg-icons"; +import MediaData from "./MediaDataTypes"; + +enum PlaybackSpeed { + HALF, + NORMAL, + DOUBLE, +} + +interface MediaAudioPlayerProps { + mediaData: MediaData; +} + +export default function MediaAudioPlayer({ mediaData }: MediaAudioPlayerProps) { + let [isPlaying, setIsPlaying] = useState(false); + let [isRepeating, setIsRepeating] = useState(false); + let [playbackSpeed, setPlaybackSpeed] = useState(PlaybackSpeed.NORMAL); + let [waveSurfer, setWaveSurfer] = useState(null); + + useEffect(() => { + const wavesurferInstance = WaveSurfer.create({ + container: "#waveform", // Previousy I used 'this.ref.current' and React.createRef() + height: 200, + + responsive: true, + waveColor: "#cbcbcb", + progressColor: "#fc8481", + cursorColor: "#fc6b68", + cursorWidth: 2, + normalize: false, + }); + + setWaveSurfer(wavesurferInstance); + }, []); + + useEffect(() => { + const audioLink = new BucketConfig().getGcsUrl( + mediaData.public_bucket_path + ); + if (waveSurfer) { + waveSurfer.load(audioLink); + } + }, [waveSurfer, mediaData]); + + useEffect(() => { + if (waveSurfer) { + waveSurfer.unAll(); // NB: Otherwise we keep reinstalling the hooks and cause chaos + waveSurfer.on("pause", () => { + setIsPlaying(waveSurfer!.isPlaying()); + }); + waveSurfer.on("play", () => { + setIsPlaying(waveSurfer!.isPlaying()); + }); + waveSurfer.on("finish", () => { + if (waveSurfer && isRepeating) { + waveSurfer!.play(); + } + }); + } + }, [waveSurfer, isRepeating]); + + const togglePlayPause = () => { + if (waveSurfer) { + waveSurfer.playPause(); + } + }; + + const toggleIsRepeating = () => { + setIsRepeating(!isRepeating); + }; + + const togglePlaybackSpeed = () => { + let nextSpeed = PlaybackSpeed.NORMAL; + switch (playbackSpeed) { + case PlaybackSpeed.NORMAL: + nextSpeed = PlaybackSpeed.DOUBLE; + waveSurfer!.setPlaybackRate(1.5); // Okay, so a lie... + break; + case PlaybackSpeed.DOUBLE: + nextSpeed = PlaybackSpeed.HALF; + waveSurfer!.setPlaybackRate(0.5); + break; + case PlaybackSpeed.HALF: + nextSpeed = PlaybackSpeed.NORMAL; + waveSurfer!.setPlaybackRate(1.0); + break; + } + setPlaybackSpeed(nextSpeed); + }; + + let playButtonText = ( + <> + + + ); + if (isPlaying) { + playButtonText = ( + <> + + + ); + } + + let repeatButtonText = isRepeating ? "Repeat" : "NoRepeat"; + + let speedButtonText = "1x"; + switch (playbackSpeed) { + case PlaybackSpeed.NORMAL: + speedButtonText = "1x"; + break; + case PlaybackSpeed.DOUBLE: + speedButtonText = "2x"; + break; + case PlaybackSpeed.HALF: + speedButtonText = "1/2x"; + break; + } + + return ( +
+
+
+
+ + + + + +
+
+
+ ); +} diff --git a/packages/fakeyou.com/src/v2/view/pages/media/ImageComponent.tsx b/packages/fakeyou.com/src/v2/view/pages/media/MediaImageComponent.tsx similarity index 55% rename from packages/fakeyou.com/src/v2/view/pages/media/ImageComponent.tsx rename to packages/fakeyou.com/src/v2/view/pages/media/MediaImageComponent.tsx index e14dc65d51..4e55f75596 100644 --- a/packages/fakeyou.com/src/v2/view/pages/media/ImageComponent.tsx +++ b/packages/fakeyou.com/src/v2/view/pages/media/MediaImageComponent.tsx @@ -1,21 +1,21 @@ import React from "react"; import MediaData from "./MediaDataTypes"; -interface ImageComponentProps { +interface MediaImageComponentProps { mediaData: MediaData; } -const ImageComponent: React.FC = ({ mediaData }) => { +export default function MediaImageComponent({ + mediaData, +}: MediaImageComponentProps) { return (
test
); -}; - -export default ImageComponent; +} diff --git a/packages/fakeyou.com/src/v2/view/pages/media/MediaPage.tsx b/packages/fakeyou.com/src/v2/view/pages/media/MediaPage.tsx index 4a6e111a3b..ca26156f1b 100644 --- a/packages/fakeyou.com/src/v2/view/pages/media/MediaPage.tsx +++ b/packages/fakeyou.com/src/v2/view/pages/media/MediaPage.tsx @@ -1,8 +1,8 @@ import React, { useEffect, useState } from "react"; import { Link, useParams } from "react-router-dom"; -import AudioComponent from "./AudioComponent"; -import VideoComponent from "./VideoComponent"; -import ImageComponent from "./ImageComponent"; +import MediaAudioComponent from "./MediaAudioComponent"; +import MediaVideoComponent from "./MediaVideoComponent"; +import MediaImageComponent from "./MediaImageComponent"; import MediaData from "./MediaDataTypes"; import { SessionWrapper } from "@storyteller/components/src/session/SessionWrapper"; import Container from "components/common/Container"; @@ -10,11 +10,16 @@ import Panel from "components/common/Panel"; import PageHeader from "components/layout/PageHeader"; import Skeleton from "components/common/Skeleton"; import Button from "components/common/Button"; -import { faCircleExclamation } from "@fortawesome/pro-solid-svg-icons"; +import { + faCircleExclamation, + faArrowDownToLine, +} from "@fortawesome/pro-solid-svg-icons"; import Accordion from "components/common/Accordion"; import DataTable from "components/common/DataTable"; import { Gravatar } from "@storyteller/components/src/elements/Gravatar"; import useTimeAgo from "hooks/useTimeAgo"; +// import { RatingButtons } from "v2/view/_common/ratings/RatingButtons"; +// import { RatingStats } from "v2/view/_common/ratings/RatingStats"; interface MediaPageProps { sessionWrapper: SessionWrapper; @@ -69,16 +74,16 @@ export default function MediaPage({ sessionWrapper }: MediaPageProps) { function renderMediaComponent(data: MediaData) { switch (data.media_type) { case "audio": - return ; + return ; case "video": return (
- +
); case "image": - return ; + return ; default: return
Unsupported media type
; } @@ -124,29 +129,94 @@ export default function MediaPage({ sessionWrapper }: MediaPageProps) { ); - const mediaDetails = [ + const audioDetails = [ { property: "Type", value: mediaData.media_type }, { property: "Created at", value: mediaData.created_at }, { property: "Visibility", value: mediaData.creator_set_visibility }, + { + property: "Model", + value: mediaData.model_used, + link: mediaData.model_link, + }, + { + property: "Vocoder", + value: "Test", + }, + { + property: "Language", + value: mediaData.model_used, + }, { property: "Model", value: mediaData.model_used, }, ]; + const videoDetails = [ + { property: "Type", value: mediaData.media_type }, + { property: "Created at", value: mediaData.created_at }, + { property: "Visibility", value: mediaData.creator_set_visibility }, + ]; + + let pageTitle = "Result"; + let pageSubText = "This is the result of your media."; + let mediaDetails = undefined; + + switch (mediaData.media_type) { + case "audio": + pageTitle = "Audio Result"; + pageSubText = mediaData.token; + mediaDetails = ( + + + + ); + break; + case "video": + pageTitle = "Video Result"; + pageSubText = mediaData.token; + mediaDetails = ( + + + + ); + break; + case "image": + pageTitle = "Image Model"; + pageSubText = "Image Model SubText"; + break; + default: + } + + // const resultRatings = ( + //
+ //
+ // + //
+ // + //
+ // ); + return ( - +
- {renderMediaComponent(mediaData)} +
+ {renderMediaComponent(mediaData)} +
-
+
+
+ {mediaDetails} +
- - - - -
diff --git a/packages/fakeyou.com/src/v2/view/pages/media/VideoComponent.tsx b/packages/fakeyou.com/src/v2/view/pages/media/MediaVideoComponent.tsx similarity index 70% rename from packages/fakeyou.com/src/v2/view/pages/media/VideoComponent.tsx rename to packages/fakeyou.com/src/v2/view/pages/media/MediaVideoComponent.tsx index 7cdd161ce4..313b4c72f5 100644 --- a/packages/fakeyou.com/src/v2/view/pages/media/VideoComponent.tsx +++ b/packages/fakeyou.com/src/v2/view/pages/media/MediaVideoComponent.tsx @@ -1,10 +1,13 @@ import React from "react"; import MediaData from "./MediaDataTypes"; -interface VideoComponentProps { + +interface MediaVideoComponentProps { mediaData: MediaData; } -export default function VideoComponent({ mediaData }: VideoComponentProps) { +export default function MediaVideoComponent({ + mediaData, +}: MediaVideoComponentProps) { return (