diff --git a/_redirects b/_redirects index 0952f119ba..85b04afb62 100644 --- a/_redirects +++ b/_redirects @@ -12,6 +12,7 @@ /contribute* /index.html 200 /explore* /index.html 200 /face-animator* /index.html 200 +/fbx-to-gltf* /index.html 200 /firehose* /index.html 200 /guide* /index.html 200 /jobs* /index.html 200 @@ -47,6 +48,7 @@ /voice-designer* /index.html 200 /w2l* /index.html 200 /weight* /index.html 200 +/text-to-image* /index.html 200 # Test paths /dev-tts* /index.html 200 diff --git a/packages/components/src/api/ApiConfig.ts b/packages/components/src/api/ApiConfig.ts index 9f1cd38e14..13d937979b 100644 --- a/packages/components/src/api/ApiConfig.ts +++ b/packages/components/src/api/ApiConfig.ts @@ -492,10 +492,14 @@ class ApiConfig { } // =============== Motion Capture / mocap =============== - enqueueVideoMotionCapture(): string{ - return `${this.getApiOrigin()}/v1/mocap/mocapnet/create` + enqueueVideoMotionCapture(): string { + return `${this.getApiOrigin()}/v1/mocap/mocapnet/create`; } + // =============== Convert FBX to glTF =============== + enqueueFbxToGltf(): string { + return `${this.getApiOrigin()}/v1/conversion/enqueue_fbx_to_gltf`; + } // =============== Generic Model Downloads =============== @@ -615,4 +619,4 @@ class ApiConfig { } } -export { ApiConfig }; \ No newline at end of file +export { ApiConfig }; diff --git a/packages/components/src/api/_common/enums/MediaFileType.ts b/packages/components/src/api/_common/enums/MediaFileType.ts index e5bb031fc5..58ae42d128 100644 --- a/packages/components/src/api/_common/enums/MediaFileType.ts +++ b/packages/components/src/api/_common/enums/MediaFileType.ts @@ -2,6 +2,8 @@ export enum MediaFileType { Audio = "audio", Video = "video", Image = "image", - Mocap = "mocap", + BVH = "bvh", + GLTF = "gltf", + FBX = "fbx", None = "none", } diff --git a/packages/components/src/api/file_conversion/EnqueueFbxToGltf.ts b/packages/components/src/api/file_conversion/EnqueueFbxToGltf.ts new file mode 100644 index 0000000000..998cc6f987 --- /dev/null +++ b/packages/components/src/api/file_conversion/EnqueueFbxToGltf.ts @@ -0,0 +1,49 @@ +import { ApiConfig } from "../ApiConfig"; + +export interface EnqueueFbxToGltfRequest { + media_file_token: string; + uuid_idempotency_token: string; +} + +export interface EnqueueFbxToGltfResponse { + success: boolean; + inference_job_token?: string; +} + +const EnqueueFbxToGltfIsSuccess = (response: EnqueueFbxToGltfResponse) => + response.inference_job_token; +const EnqueueFbxToGltfIsError = (response: EnqueueFbxToGltfResponse) => + !response.inference_job_token; + +export { EnqueueFbxToGltfIsSuccess, EnqueueFbxToGltfIsError }; + +export async function EnqueueFbxToGltf( + request: EnqueueFbxToGltfRequest +): Promise { + const endpoint = new ApiConfig().enqueueFbxToGltf(); + + return await fetch(endpoint, { + method: "POST", + headers: { + Accept: "application/json", + "Content-Type": "application/json", + }, + credentials: "include", + body: JSON.stringify(request), + }) + .then(res => res.json()) + .then(res => { + if (!res) { + return { success: false }; + } + + if (res && "success" in res) { + return res; + } else { + return { success: false }; + } + }) + .catch(e => { + return { success: false }; + }); +} diff --git a/packages/components/src/api/image_generation/EnqueueImageGen.ts b/packages/components/src/api/image_generation/EnqueueImageGen.ts index 1e11349f67..b3400df405 100644 --- a/packages/components/src/api/image_generation/EnqueueImageGen.ts +++ b/packages/components/src/api/image_generation/EnqueueImageGen.ts @@ -2,7 +2,7 @@ import { ApiConfig } from "../ApiConfig"; export interface EnqueueImageGenRequest { uuid_idempotency_token: string; - maybe_sd_model_token: string; + maybe_sd_model_token: string | undefined; maybe_lora_model_token: string | null; maybe_prompt: string; maybe_n_prompt: string; diff --git a/packages/components/src/jobs/InferenceJob.ts b/packages/components/src/jobs/InferenceJob.ts index 98324d83d1..ddc39f2646 100644 --- a/packages/components/src/jobs/InferenceJob.ts +++ b/packages/components/src/jobs/InferenceJob.ts @@ -9,7 +9,8 @@ export enum FrontendInferenceJobType { VoiceDesignerCreateVoice, VoiceDesignerTts, ImageGeneration, - VideoMotionCapture + VideoMotionCapture, + ConvertFbxtoGltf, } // NB: Many of these fields are optional despite the response payload containing them diff --git a/packages/fakeyou.com/public/images/header/fbx-to-gltf.png b/packages/fakeyou.com/public/images/header/fbx-to-gltf.png new file mode 100644 index 0000000000..cea0581d23 Binary files /dev/null and b/packages/fakeyou.com/public/images/header/fbx-to-gltf.png differ diff --git a/packages/fakeyou.com/public/images/header/video-mocap.png b/packages/fakeyou.com/public/images/header/video-mocap.png new file mode 100644 index 0000000000..4ff7207c52 Binary files /dev/null and b/packages/fakeyou.com/public/images/header/video-mocap.png differ diff --git a/packages/fakeyou.com/public/images/team/bombay.webp b/packages/fakeyou.com/public/images/team/bombay.webp new file mode 100644 index 0000000000..6b604d80b1 Binary files /dev/null and b/packages/fakeyou.com/public/images/team/bombay.webp differ diff --git a/packages/fakeyou.com/public/images/team/brandon.webp b/packages/fakeyou.com/public/images/team/brandon.webp new file mode 100644 index 0000000000..33a1984781 Binary files /dev/null and b/packages/fakeyou.com/public/images/team/brandon.webp differ diff --git a/packages/fakeyou.com/public/images/team/jose.webp b/packages/fakeyou.com/public/images/team/jose.webp new file mode 100644 index 0000000000..170a2a772a Binary files /dev/null and b/packages/fakeyou.com/public/images/team/jose.webp differ diff --git a/packages/fakeyou.com/public/images/team/michael.webp b/packages/fakeyou.com/public/images/team/michael.webp new file mode 100644 index 0000000000..c2d79120df Binary files /dev/null and b/packages/fakeyou.com/public/images/team/michael.webp differ diff --git a/packages/fakeyou.com/public/images/team/ozzy.webp b/packages/fakeyou.com/public/images/team/ozzy.webp new file mode 100644 index 0000000000..51154a04dd Binary files /dev/null and b/packages/fakeyou.com/public/images/team/ozzy.webp differ diff --git a/packages/fakeyou.com/public/images/team/paul.webp b/packages/fakeyou.com/public/images/team/paul.webp new file mode 100644 index 0000000000..c51b88341f Binary files /dev/null and b/packages/fakeyou.com/public/images/team/paul.webp differ diff --git a/packages/fakeyou.com/public/images/team/ramiro.webp b/packages/fakeyou.com/public/images/team/ramiro.webp new file mode 100644 index 0000000000..271612b9dc Binary files /dev/null and b/packages/fakeyou.com/public/images/team/ramiro.webp differ diff --git a/packages/fakeyou.com/public/images/team/rod.webp b/packages/fakeyou.com/public/images/team/rod.webp new file mode 100644 index 0000000000..acf43a2703 Binary files /dev/null and b/packages/fakeyou.com/public/images/team/rod.webp differ diff --git a/packages/fakeyou.com/public/images/team/rodrigo.webp b/packages/fakeyou.com/public/images/team/rodrigo.webp new file mode 100644 index 0000000000..47e40571e8 Binary files /dev/null and b/packages/fakeyou.com/public/images/team/rodrigo.webp differ diff --git a/packages/fakeyou.com/public/images/team/scott.webp b/packages/fakeyou.com/public/images/team/scott.webp new file mode 100644 index 0000000000..c13dedee54 Binary files /dev/null and b/packages/fakeyou.com/public/images/team/scott.webp differ diff --git a/packages/fakeyou.com/public/mascot/text-to-image.webp b/packages/fakeyou.com/public/mascot/text-to-image.webp new file mode 100644 index 0000000000..8c36b6c9e3 Binary files /dev/null and b/packages/fakeyou.com/public/mascot/text-to-image.webp differ diff --git a/packages/fakeyou.com/public/mascot/video-mocap.webp b/packages/fakeyou.com/public/mascot/video-mocap.webp new file mode 100644 index 0000000000..7224e001ec Binary files /dev/null and b/packages/fakeyou.com/public/mascot/video-mocap.webp differ diff --git a/packages/fakeyou.com/src/App.tsx b/packages/fakeyou.com/src/App.tsx index 8047873590..248fc6b9f2 100644 --- a/packages/fakeyou.com/src/App.tsx +++ b/packages/fakeyou.com/src/App.tsx @@ -208,6 +208,8 @@ function initInferenceJobsByCategoryMap(): Map< ); inferenceJobsByCategory.set(FrontendInferenceJobType.VoiceDesignerTts, []); inferenceJobsByCategory.set(FrontendInferenceJobType.VideoMotionCapture, []); + inferenceJobsByCategory.set(FrontendInferenceJobType.ImageGeneration, []); + inferenceJobsByCategory.set(FrontendInferenceJobType.ConvertFbxtoGltf, []); return inferenceJobsByCategory; } @@ -405,11 +407,11 @@ class App extends React.Component { Accept: "application/json", }, }) - .then((_raw_response) => { + .then(_raw_response => { this.querySession(); this.querySessionSubscriptions(); }) - .catch((e) => { + .catch(e => { /* Ignore. */ }); }; @@ -452,7 +454,7 @@ class App extends React.Component { if (GetModelInferenceJobStatusIsOk(lookupResult)) { let updatedJobs: Array = []; - this.state.inferenceJobs.forEach((existingJob) => { + this.state.inferenceJobs.forEach(existingJob => { if ( existingJob.jobToken !== lookupResult.state!.job_token || !jobStateCanChange(existingJob.jobState) @@ -512,8 +514,8 @@ class App extends React.Component { Accept: "application/json", }, }) - .then((res) => res.json()) - .then((response) => { + .then(res => res.json()) + .then(response => { const jobResponse: TtsInferenceJobStateResponsePayload = response; if (jobResponse === undefined || jobResponse.state === undefined) { @@ -522,7 +524,7 @@ class App extends React.Component { let updatedJobs: Array = []; - this.state.ttsInferenceJobs.forEach((existingJob) => { + this.state.ttsInferenceJobs.forEach(existingJob => { if ( existingJob.jobToken !== jobResponse.state!.job_token || !jobStateCanChange(existingJob.jobState) @@ -539,7 +541,7 @@ class App extends React.Component { ttsInferenceJobs: updatedJobs, }); }) - .catch((e) => { + .catch(e => { /* Ignore. */ }); }; @@ -564,8 +566,8 @@ class App extends React.Component { Accept: "application/json", }, }) - .then((res) => res.json()) - .then((response) => { + .then(res => res.json()) + .then(response => { const jobResponse: TtsModelUploadJobStateResponsePayload = response; if (jobResponse === undefined || jobResponse.state === undefined) { @@ -573,7 +575,7 @@ class App extends React.Component { } let updatedJobs: Array = []; - this.state.ttsModelUploadJobs.forEach((existingJob) => { + this.state.ttsModelUploadJobs.forEach(existingJob => { if ( existingJob.jobToken !== jobResponse.state!.job_token || !jobStateCanChange(existingJob.jobState) @@ -590,7 +592,7 @@ class App extends React.Component { ttsModelUploadJobs: updatedJobs, }); }) - .catch((e) => { + .catch(e => { /* Ignore. */ }); }; @@ -615,8 +617,8 @@ class App extends React.Component { Accept: "application/json", }, }) - .then((res) => res.json()) - .then((response) => { + .then(res => res.json()) + .then(response => { const jobResponse: W2lInferenceJobStateResponsePayload = response; if (jobResponse === undefined || jobResponse.state === undefined) { @@ -624,7 +626,7 @@ class App extends React.Component { } let updatedJobs: Array = []; - this.state.w2lInferenceJobs.forEach((existingJob) => { + this.state.w2lInferenceJobs.forEach(existingJob => { if ( existingJob.jobToken !== jobResponse.state!.job_token || !jobStateCanChange(existingJob.jobState) @@ -641,7 +643,7 @@ class App extends React.Component { w2lInferenceJobs: updatedJobs, }); }) - .catch((e) => { + .catch(e => { /* Ignore. */ }); }; @@ -666,8 +668,8 @@ class App extends React.Component { Accept: "application/json", }, }) - .then((res) => res.json()) - .then((response) => { + .then(res => res.json()) + .then(response => { const jobResponse: W2lTemplateUploadJobStateResponsePayload = response; if (jobResponse === undefined || jobResponse.state === undefined) { @@ -676,7 +678,7 @@ class App extends React.Component { let updatedJobs: Array = []; - this.state.w2lTemplateUploadJobs.forEach((existingJob) => { + this.state.w2lTemplateUploadJobs.forEach(existingJob => { if ( existingJob.jobToken !== jobResponse.state!.job_token || !jobStateCanChange(existingJob.jobState) @@ -695,7 +697,7 @@ class App extends React.Component { w2lTemplateUploadJobs: updatedJobs, }); }) - .catch((e) => { + .catch(e => { /* Ignore. */ }); }; @@ -715,7 +717,7 @@ class App extends React.Component { if (GetRemoteDownloadJobStatusIsOk(lookupResult)) { let updatedJobs: Array = []; - this.state.vocoderUploadJobs.forEach((existingJob) => { + this.state.vocoderUploadJobs.forEach(existingJob => { if ( existingJob.jobToken !== lookupResult.state!.job_token || !jobStateCanChange(existingJob.jobState) @@ -749,7 +751,7 @@ class App extends React.Component { if (GetRemoteDownloadJobStatusIsOk(lookupResult)) { let updatedJobs: Array = []; - this.state.voiceConversionModelUploadJobs.forEach((existingJob) => { + this.state.voiceConversionModelUploadJobs.forEach(existingJob => { if ( existingJob.jobToken !== lookupResult.state!.job_token || !jobStateCanChange(existingJob.jobState) @@ -771,37 +773,37 @@ class App extends React.Component { }; pollJobs = () => { - this.state.inferenceJobs.forEach((job) => { + this.state.inferenceJobs.forEach(job => { if (jobStateCanChange(job.jobState)) { this.checkInferenceJob(job.jobToken); } }); - this.state.ttsInferenceJobs.forEach((job) => { + this.state.ttsInferenceJobs.forEach(job => { if (jobStateCanChange(job.jobState)) { this.checkTtsJob(job.jobToken); } }); - this.state.w2lInferenceJobs.forEach((job) => { + this.state.w2lInferenceJobs.forEach(job => { if (jobStateCanChange(job.jobState)) { this.checkW2lJob(job.jobToken); } }); - this.state.ttsModelUploadJobs.forEach((job) => { + this.state.ttsModelUploadJobs.forEach(job => { if (jobStateCanChange(job.jobState)) { this.checkTtsModelUploadJob(job.jobToken); } }); - this.state.w2lTemplateUploadJobs.forEach((job) => { + this.state.w2lTemplateUploadJobs.forEach(job => { if (jobStateCanChange(job.jobState)) { this.checkW2lTemplateUploadJob(job.jobToken); } }); - this.state.vocoderUploadJobs.forEach((job) => { + this.state.vocoderUploadJobs.forEach(job => { if (jobStateCanChange(job.jobState)) { this.checkVocoderUploadJob(job.jobToken); } }); - this.state.voiceConversionModelUploadJobs.forEach((job) => { + this.state.voiceConversionModelUploadJobs.forEach(job => { if (jobStateCanChange(job.jobState)) { this.checkVoiceConversionModelUploadJob(job.jobToken); } @@ -845,7 +847,7 @@ class App extends React.Component { querySession: this.querySession, querySubscriptions: this.querySessionSubscriptions, sessionWrapper: this.state.sessionWrapper, - sessionFetched: this.state.sessionFetched + sessionFetched: this.state.sessionFetched, }} > diff --git a/packages/fakeyou.com/src/AppNew.scss b/packages/fakeyou.com/src/AppNew.scss index 07cef4f768..784d6847a0 100644 --- a/packages/fakeyou.com/src/AppNew.scss +++ b/packages/fakeyou.com/src/AppNew.scss @@ -38,12 +38,6 @@ $headings-font-family: "Fira Sans", sans-serif; overflow-wrap: anywhere; } - //old wrapper - // .mainwrap { - // max-width: 800px; - // margin: auto; - // } - canvas#spectrogram { margin: 0.5em 0; transform: scaleY(-1); @@ -58,37 +52,10 @@ $headings-font-family: "Fira Sans", sans-serif; box-shadow: none; } - /*p { - a:link, - a:visited { - color: rgb(119, 165, 235); - font-weight: bold; - } - a:hover, - a:active{ - color: rgb(85, 133, 204); - font-weight: bold; - } - }*/ - - // p { - // a:before { - // content: " "; - // } - // } - #main { position: relative; // Footer attachment. min-height: 100vh; overflow: hidden; - - &.low-spec { - .animation-wrapper { - display: none; - visibility: hidden; - content-visibility: hidden; - } - } } .social { @@ -362,6 +329,19 @@ $headings-font-family: "Fira Sans", sans-serif; height: 100%; pointer-events: none; } + + .to-top-button-off-screen { + position: fixed; + width: fit-content; + white-space: nowrap; + top: 5rem; + margin: 0 auto; + left: 0; + right: 0; + z-index: 3; + + box-shadow: 0px 5px 20px rgba($black, 0.3); + } } @media screen and (max-height: 740px) { diff --git a/packages/fakeyou.com/src/components/PremiumLock/PremiumLock.scss b/packages/fakeyou.com/src/components/PremiumLock/PremiumLock.scss new file mode 100644 index 0000000000..0afb96bc78 --- /dev/null +++ b/packages/fakeyou.com/src/components/PremiumLock/PremiumLock.scss @@ -0,0 +1,27 @@ +@import "scss/colours.scss"; + +.fy-premium-lock { + position: relative; + background-color: $panel-inner; + pointer-events: none; + overflow: hidden; + box-shadow: none !important; + + .overlay { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba($panel, 0.8); + display: flex; + justify-content: center; + align-items: center; + color: rgba($white, 0.8); + font-size: 16px; + pointer-events: all; + text-shadow: 0 0 10px rgba(0, 0, 0, 1); + border: 1px solid rgba($primary, 0.4); + border-radius: 0.5rem; + } +} diff --git a/packages/fakeyou.com/src/components/PremiumLock/PremiumLock.tsx b/packages/fakeyou.com/src/components/PremiumLock/PremiumLock.tsx new file mode 100644 index 0000000000..9ac64189e4 --- /dev/null +++ b/packages/fakeyou.com/src/components/PremiumLock/PremiumLock.tsx @@ -0,0 +1,61 @@ +import { Panel } from "components/common"; +import { Link } from "react-router-dom"; +import React from "react"; +import "./PremiumLock.scss"; +import { SessionSubscriptionsWrapper } from "@storyteller/components/src/session/SessionSubscriptionsWrapper"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { faLock } from "@fortawesome/pro-solid-svg-icons"; + +interface PremiumLockProps { + requiredPlan?: "plus" | "pro" | "elite"; + children: React.ReactNode; + session?: any; + sessionSubscriptionsWrapper: SessionSubscriptionsWrapper; +} + +export default function PremiumLock({ + requiredPlan = "plus", + children, + sessionSubscriptionsWrapper, +}: PremiumLockProps) { + const hasAccess = () => { + switch (requiredPlan) { + case "plus": + return ( + sessionSubscriptionsWrapper.hasActivePlusSubscription() || + sessionSubscriptionsWrapper.hasActiveProSubscription() || + sessionSubscriptionsWrapper.hasActiveEliteSubscription() + ); + case "pro": + return ( + sessionSubscriptionsWrapper.hasActiveProSubscription() || + sessionSubscriptionsWrapper.hasActiveEliteSubscription() + ); + case "elite": + return sessionSubscriptionsWrapper.hasActiveEliteSubscription(); + default: + return false; + } + }; + + return ( + <> + {hasAccess() ? ( + children + ) : ( + + {children} +
+
+ +
+ This feature requires a{" "} + {requiredPlan} subscription +
+
+
+
+ )} + + ); +} diff --git a/packages/fakeyou.com/src/components/PremiumLock/index.tsx b/packages/fakeyou.com/src/components/PremiumLock/index.tsx new file mode 100644 index 0000000000..038221ec9f --- /dev/null +++ b/packages/fakeyou.com/src/components/PremiumLock/index.tsx @@ -0,0 +1 @@ +export { default } from "./PremiumLock"; diff --git a/packages/fakeyou.com/src/components/common/Button/Button.tsx b/packages/fakeyou.com/src/components/common/Button/Button.tsx index 060a9cf10b..c276f9214f 100644 --- a/packages/fakeyou.com/src/components/common/Button/Button.tsx +++ b/packages/fakeyou.com/src/components/common/Button/Button.tsx @@ -7,6 +7,7 @@ import Tippy from "@tippyjs/react"; import "tippy.js/dist/tippy.css"; export default function Button({ + buttonRef, label, icon, small, @@ -81,7 +82,7 @@ export default function Button({ {ButtonContent} ) : ( - ); diff --git a/packages/fakeyou.com/src/components/common/Button/ButtonProps.tsx b/packages/fakeyou.com/src/components/common/Button/ButtonProps.tsx index a4680b7be9..9a0936fca5 100644 --- a/packages/fakeyou.com/src/components/common/Button/ButtonProps.tsx +++ b/packages/fakeyou.com/src/components/common/Button/ButtonProps.tsx @@ -2,6 +2,7 @@ import { ButtonHTMLAttributes } from "react"; import { IconDefinition } from "@fortawesome/fontawesome-svg-core"; export default interface ButtonProps extends ButtonHTMLAttributes { + buttonRef?: any; label?: string | null; icon?: IconDefinition; small?: boolean; diff --git a/packages/fakeyou.com/src/components/common/Card/AudioCard/AudioCard.tsx b/packages/fakeyou.com/src/components/common/Card/AudioCard/AudioCard.tsx index be571a3fe0..f23b15c9dd 100644 --- a/packages/fakeyou.com/src/components/common/Card/AudioCard/AudioCard.tsx +++ b/packages/fakeyou.com/src/components/common/Card/AudioCard/AudioCard.tsx @@ -85,15 +85,15 @@ export default function AudioCard({ } } - const onClick = () => { - if (inClick) inClick(data); - }; + // const onClick = () => { + // if (inClick) inClick(data); + // }; const card = ( {type === "media" && ( <> @@ -176,7 +176,7 @@ export default function AudioCard({ variant="link" label="Select" className="fs-7" - onClick={onClick} + onClick={handleSelectModalResultSelect} /> ) : ( - - - ); - viewPricingButton = ( - <> - { - Analytics.ttsClickHeroViewPricing(); - }} - > - - - - ); - - const titleIcon = ; - const title = <>Donald Trump TTS; - const subText = ( - <>FakeYou has the very best Donald Trump AI voice on the internet. Use deep fake Donald Trump to say your favorite memes. - ); - const actionButtons = ( - <> - {signUpButton} - {viewPricingButton} - - ); - - return ( - <> - - - ); -} diff --git a/packages/fakeyou.com/src/v2/view/pages/contribute/ContributeIndexPage.tsx b/packages/fakeyou.com/src/v2/view/pages/contribute/ContributeIndexPage.tsx index 9ec39a81c6..2e19155a5d 100644 --- a/packages/fakeyou.com/src/v2/view/pages/contribute/ContributeIndexPage.tsx +++ b/packages/fakeyou.com/src/v2/view/pages/contribute/ContributeIndexPage.tsx @@ -17,10 +17,12 @@ import { PageHeader } from "../../_common/PageHeader"; import { faFileArrowUp, faHandHoldingHeart, + faImage, + faMicrophone, } from "@fortawesome/pro-solid-svg-icons"; -import { faMicrophoneStand } from "@fortawesome/pro-duotone-svg-icons"; import { faWaveformLines } from "@fortawesome/pro-regular-svg-icons"; import { PosthogClient } from "@storyteller/components/src/analytics/PosthogClient"; +import { Button } from "components/common"; interface Props { sessionWrapper: SessionWrapper; @@ -96,25 +98,39 @@ function ContributeIndexPage(props: Props) {

- - - Upload Voice to Voice Model - + />
- - - {t("pages.contributeIndex.buttonUploadVoice")} - +
- - - Upload Vocoder - +
+
+
+
+
diff --git a/packages/fakeyou.com/src/v2/view/pages/explore/tabs/MediaTab.tsx b/packages/fakeyou.com/src/v2/view/pages/explore/tabs/MediaTab.tsx index 92ca0b7cec..de5912e1eb 100644 --- a/packages/fakeyou.com/src/v2/view/pages/explore/tabs/MediaTab.tsx +++ b/packages/fakeyou.com/src/v2/view/pages/explore/tabs/MediaTab.tsx @@ -2,7 +2,7 @@ import React, { useRef, useState } from "react"; import { useLocation } from "react-router-dom"; import MasonryGrid from "components/common/MasonryGrid/MasonryGrid"; import MediaCards from "components/common/Card/MediaCards"; -import { TempSelect } from "components/common"; +import { Button, TempSelect } from "components/common"; import { faArrowDownWideShort, faFilter, @@ -11,7 +11,7 @@ import AudioPlayerProvider from "components/common/AudioPlayer/AudioPlayerContex import SkeletonCard from "components/common/Card/SkeletonCard"; import { ListMediaFiles } from "@storyteller/components/src/api/media_files/ListMediaFiles"; import { MediaFile } from "@storyteller/components/src/api/media_files/GetMedia"; -import { useBookmarks, useLazyLists, useRatings } from "hooks"; +import { useBookmarks, useLazyLists, useOnScreen, useRatings } from "hooks"; import InfiniteScroll from "react-infinite-scroll-component"; import prepFilter from "resources/prepFilter"; @@ -20,6 +20,9 @@ export default function MediaTab() { const urlQueries = new URLSearchParams(search); const bookmarks = useBookmarks(); const ratings = useRatings(); + const toTopBtnRef = useRef(null); + const onScreen = useOnScreen(toTopBtnRef,"0px"); + const gridContainerRef = useRef(null); const [mediaType, mediaTypeSet] = useState( urlQueries.get("filter_media_type") || "all" @@ -82,7 +85,20 @@ export default function MediaTab() { }} /> + { media.urlCursor ? +