Merge pull request #195 from storytold/bflat-fy-profile-feed

updated profile tts results
This commit is contained in:
Brandon Thomas authored and GitHub committed 2023-03-16 14:17:45 -04:00
commit f79408fd37
5 files changed
+134 -60

No files matched your search

@@ -1017,6 +1017,14 @@ styles with important tags:
font-size: 13px;
padding: 0;
}
.profile-model-title {
color: $white !important;
&:hover {
color: $primary !important;
}
}
}
select {
@@ -0,0 +1,70 @@
import React, { useState, useCallback } from "react";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faPause, faPlay } from "@fortawesome/free-solid-svg-icons";
import Wavesurfer from "react-wavesurfer.js";
interface Props {
filename: string;
}
function ProfileTtsAudioPlayer(props: Props) {
const [isPlaying, setIsPlaying] = useState(false);
const [position, setPosition] = useState(0);
const handleTogglePlay = useCallback(() => {
if (!isPlaying) {
setIsPlaying(true);
} else {
setIsPlaying(false);
}
}, [isPlaying]);
const handleFinish = useCallback(() => {
setIsPlaying(false);
setPosition(0);
return [setIsPlaying, setPosition];
}, []);
let playButtonText = <FontAwesomeIcon icon={faPlay} />;
if (isPlaying) {
playButtonText = (
<>
<FontAwesomeIcon icon={faPause} />
</>
);
}
return (
<div className="d-flex w-100 align-items-center gap-3 zi-1">
<button
className="btn btn-primary btn-session-tts-play align-items-center justify-content-center"
onClick={() => handleTogglePlay()}
type="button"
>
{playButtonText}
</button>
<div className="w-100 h-100 overflow-hidden">
<Wavesurfer
onFinish={handleFinish}
pos={position}
src={props.filename}
// barWidth={2}
// barRadius={1}
// barGap={2}
// barMinHeight={1}
// barHeight={2}
height={50}
progressColor="#fc8481"
waveColor="#b09e9e"
cursorColor="#fc8481"
playing={isPlaying}
responsive={true}
normalize={true}
/>
</div>
</div>
);
}
export { ProfileTtsAudioPlayer };
@@ -473,7 +473,7 @@ function ProfilePage(props: Props) {
</button>
</li>
</ul>
<div className="tab-content p-3 p-lg-4" id="myTabContent">
<div className="tab-content" id="myTabContent">
<div
className="tab-pane fade show active"
id="ttsresults"
@@ -483,7 +483,7 @@ function ProfilePage(props: Props) {
<ProfileTtsInferenceResultsListFc username={userData.username} />
</div>
<div
className="tab-pane fade"
className="tab-pane fade p-3 p-lg-4"
id="w2lresults"
role="tabpanel"
aria-labelledby="w2lresults-tab"
@@ -491,7 +491,7 @@ function ProfilePage(props: Props) {
<ProfileW2lInferenceResultsListFc username={userData.username} />
</div>
<div
className="tab-pane fade"
className="tab-pane fade p-3 p-lg-4"
id="uploadedtts"
role="tabpanel"
aria-labelledby="uploadedtts-tab"
@@ -499,7 +499,7 @@ function ProfilePage(props: Props) {
<ProfileTtsModelListFc username={userData.username} />
</div>
<div
className="tab-pane fade"
className="tab-pane fade p-3 p-lg-4"
id="uploadedw2l"
role="tabpanel"
aria-labelledby="uploadedw2l-tab"
@@ -507,7 +507,7 @@ function ProfilePage(props: Props) {
<ProfileW2lTemplateListFc username={userData.username} />
</div>
<div
className="tab-pane fade"
className="tab-pane fade p-3 p-lg-4"
id="badges"
role="tabpanel"
aria-labelledby="badges-tab"
@@ -7,12 +7,14 @@ import { Link } from "react-router-dom";
import { formatDistance } from "date-fns";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import {
faCirclePlay,
faArrowLeft,
faArrowRight,
faEye,
faEyeSlash,
} from "@fortawesome/free-solid-svg-icons";
import { BucketConfig } from "@storyteller/components/src/api/BucketConfig";
import { ProfileTtsAudioPlayer } from "../../../_common/ProfileTtsAudioPlayer";
import { TextExpander } from "../../../_common/TextExpander";
const Fade = require("react-reveal/Fade");
@@ -31,6 +33,8 @@ interface TtsInferenceResult {
raw_inference_text: string;
public_bucket_wav_audio_path: string;
maybe_creator_user_token?: string;
maybe_creator_username?: string;
maybe_creator_display_name?: string;
@@ -106,14 +110,16 @@ function ProfileTtsInferenceResultsListFc(props: Props) {
ttsResults.slice(0, 10).forEach((result) => {
const duration_seconds = result.duration_millis / 1000;
const audioLink = new BucketConfig().getGcsUrl(
result.public_bucket_wav_audio_path
);
const wavesurfer = <ProfileTtsAudioPlayer filename={audioLink} />;
const inferenceLink = `/tts/result/${result.tts_result_token}`;
const modelLink = `/tts/${result.tts_model_token}`;
const text =
result.raw_inference_text.length < 5
? `Result: ${result.raw_inference_text}`
: result.raw_inference_text;
const text = (
<TextExpander text={result.raw_inference_text} cutLength={250} />
);
const createTime = new Date(result.created_at);
const relativeCreateTime = formatDistance(createTime, now, {
@@ -129,20 +135,40 @@ function ProfileTtsInferenceResultsListFc(props: Props) {
rows.push(
<tr key={result.tts_result_token}>
<td>{result.maybe_creator_result_id}</td>
<td>{visibilityIcon}</td>
<th className="overflow-fix">
<Link to={inferenceLink}>
<FontAwesomeIcon icon={faCirclePlay} className="me-2" />
{text}
</Link>
&nbsp;
</th>
<th>
<Link to={modelLink}>Model: {result.tts_model_title}</Link>
</th>
<td>{duration_seconds} s</td>
<td>{relativeCreateTime}</td>
<td className="p-4 p-lg-4 overflow-fix">
<div className="d-flex flex-column gap-4">
<div>
<div className="d-flex flex-column flex-lg-row mb-2 pb-1 gap-2 align-items-lg-center">
<h5 className="mb-0 fw-medium">
<Link
to={modelLink}
className="fw-medium profile-model-title"
>
{result.tts_model_title}
</Link>
</h5>
<span className="opacity-50 d-none d-lg-block">—</span>
<Link className="fw-medium fs-6" to={inferenceLink}>
View Details / Download
</Link>
</div>
<p>{text}</p>
</div>
{wavesurfer}
<div className="d-flex flex-column flex-lg-row gap-2 gap-lg-0">
<p className="opacity-75">
#{result.maybe_creator_result_id}
<span className="px-2">·</span>
{visibilityIcon}
<span className="px-2">·</span>
{duration_seconds} s<span className="px-2">·</span>
{relativeCreateTime}
</p>
</div>
</div>
</td>
</tr>
);
});
@@ -157,43 +183,13 @@ function ProfileTtsInferenceResultsListFc(props: Props) {
<div>
<div className="table-responsive">
<table className="table">
<thead>
<tr>
<th>
<abbr title="Number">#</abbr>
</th>
<th>
<abbr title="Visibility">
<FontAwesomeIcon icon={faEye} />
</abbr>
</th>
<th className="table-mw">
<abbr title="Download">Download &amp; Play Link</abbr>
</th>
<th>
<abbr title="Model">Model</abbr>
</th>
<th>
<abbr title="Duration">Duration</abbr>
</th>
<th>
<abbr title="Created">Creation Time</abbr>
</th>
</tr>
</thead>
<Fade cascade bottom duration="200" distance="10px">
<tbody>{rows}</tbody>
<tbody className="">{rows}</tbody>
</Fade>
</table>
</div>
<p className="text-center py-3">
Note: Results marked public (<FontAwesomeIcon icon={faEye} />) are
visible by anyone visiting your profile.
{/*You can change this by editing results. You can also set a default preference for new results.*/}
</p>
<div className="justify-content-center d-flex gap-3">
<div className="justify-content-center d-flex gap-3 p-3 p-lg-4">
<button
className="btn btn-secondary w-100"
onClick={() => getPage(previousCursor, true)}
@@ -433,7 +433,7 @@ function TtsResultViewPage(props: Props) {
<motion.div initial="hidden" animate="visible" variants={container}>
<div className="container py-5">
<div className="d-flex flex-column">
<motion.h1 className="display-5 fw-bold mb-3" variants={item}>
<motion.h1 className="display-5 fw-bold mb-2" variants={item}>
{headingTitle}
</motion.h1>
{/* Rate Result Buttons */}
@@ -477,10 +477,10 @@ function TtsResultViewPage(props: Props) {
</div>
</div>*/}
<motion.p className="mb-3 result-text mt-4 pt-2">
<motion.p className="mb-3 result-text pt-2">
<TextExpander
text={ttsInferenceResult.raw_inference_text}
cutLength={250}
cutLength={240}
/>
</motion.p>
</div>