landing page sections updated
This commit is contained in:
1 parent
9aca012998
commit
e4e78037f4
13 files changed
+310
-281
No files matched your search
@@ -87,6 +87,17 @@
|
||||
&:hover .card-video-play {
|
||||
color: rgba($white, 0.7);
|
||||
}
|
||||
|
||||
&.card-hover-border-red {
|
||||
&:hover {
|
||||
border: 1px solid $primary;
|
||||
}
|
||||
}
|
||||
|
||||
&.bottom-text-hover {
|
||||
background-color: lighten($panel-inner, 2%);
|
||||
border: 1px solid $primary;
|
||||
}
|
||||
}
|
||||
|
||||
h6 {
|
||||
@@ -97,3 +108,14 @@
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
.card-bottom-text {
|
||||
padding-top: 0.75rem;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.centered-row {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import React from "react";
|
||||
import React, { useState } from "react";
|
||||
import "./Card.scss";
|
||||
|
||||
interface CardProps {
|
||||
@@ -8,6 +8,12 @@ interface CardProps {
|
||||
canHover?: boolean;
|
||||
onMouseEnter?: () => void;
|
||||
onMouseLeave?: () => void;
|
||||
backgroundImage?: string;
|
||||
height?: string;
|
||||
borderWidth?: string;
|
||||
hoverPrimaryColor?: true;
|
||||
aspectRatio?: string;
|
||||
bottomText?: string;
|
||||
}
|
||||
|
||||
export default function Card({
|
||||
@@ -17,17 +23,48 @@ export default function Card({
|
||||
canHover,
|
||||
onMouseEnter,
|
||||
onMouseLeave,
|
||||
backgroundImage,
|
||||
height,
|
||||
borderWidth,
|
||||
hoverPrimaryColor,
|
||||
aspectRatio = "auto",
|
||||
bottomText,
|
||||
}: CardProps) {
|
||||
const [textHovered, setTextHovered] = useState(false);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`card ${padding ? "p-3" : ""} ${
|
||||
onClick || canHover ? "card-clickable" : ""
|
||||
}`}
|
||||
onClick={onClick}
|
||||
onMouseEnter={onMouseEnter}
|
||||
onMouseLeave={onMouseLeave}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
<>
|
||||
<div
|
||||
className={`card ${padding ? "p-3" : ""} ${
|
||||
onClick || canHover ? "card-clickable" : ""
|
||||
} ${hoverPrimaryColor ? "card-hover-border-red" : ""} ${
|
||||
textHovered ? "bottom-text-hover" : ""
|
||||
}`.trim()}
|
||||
style={{
|
||||
backgroundImage: `url(${backgroundImage})`,
|
||||
backgroundSize: "cover",
|
||||
backgroundPosition: "center",
|
||||
height: height || "auto",
|
||||
borderWidth: borderWidth || "1px",
|
||||
borderStyle: "solid",
|
||||
aspectRatio: aspectRatio || "auto",
|
||||
}}
|
||||
onClick={onClick}
|
||||
onMouseEnter={onMouseEnter}
|
||||
onMouseLeave={onMouseLeave}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
{bottomText && (
|
||||
<h6
|
||||
className="card-bottom-text"
|
||||
onClick={onClick}
|
||||
onMouseEnter={() => setTextHovered(true)}
|
||||
onMouseLeave={() => setTextHovered(false)}
|
||||
>
|
||||
{bottomText}
|
||||
</h6>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -4,20 +4,20 @@ export enum Website {
|
||||
}
|
||||
|
||||
export interface DomainConfig {
|
||||
website: Website,
|
||||
logo: string,
|
||||
title: string,
|
||||
link: string,
|
||||
website: Website;
|
||||
logo: string;
|
||||
title: string;
|
||||
link: string;
|
||||
}
|
||||
|
||||
const domainConfigs: Record<string, DomainConfig> = {
|
||||
"storyteller": {
|
||||
fakeyou: {
|
||||
website: Website.StorytellerAi,
|
||||
logo: "/fakeyou/Storyteller-Logo-1.png",
|
||||
title: "Storyteller AI",
|
||||
link: "https://storyteller.ai",
|
||||
},
|
||||
"fakeyou": {
|
||||
storyteller: {
|
||||
website: Website.FakeYou,
|
||||
logo: "/fakeyou/FakeYou-Logo-2.png",
|
||||
title: "FakeYou",
|
||||
@@ -35,7 +35,7 @@ export const getCurrentDomainConfig = (): DomainConfig => {
|
||||
}
|
||||
|
||||
if (window.location.hostname.includes("storyteller")) {
|
||||
return domainConfigs.storyteller;
|
||||
return domainConfigs.storyteller;
|
||||
}
|
||||
|
||||
// Default fallback
|
||||
|
||||
@@ -2,14 +2,12 @@ import React from "react";
|
||||
import { usePrefixedDocumentTitle } from "../../../../common/UsePrefixedDocumentTitle";
|
||||
import { SessionWrapper } from "@storyteller/components/src/session/SessionWrapper";
|
||||
import { SessionSubscriptionsWrapper } from "@storyteller/components/src/session/SessionSubscriptionsWrapper";
|
||||
import {} from "@fortawesome/pro-solid-svg-icons";
|
||||
import { PosthogClient } from "@storyteller/components/src/analytics/PosthogClient";
|
||||
import { Container } from "components/common";
|
||||
import FakeYouLandingHeader from "./fakeyou/FakeYouLandingHeader";
|
||||
import Dashboard from "./Dashboard";
|
||||
import { useDomainConfig } from "context/DomainConfigContext";
|
||||
import StorytellerLanding from "./storyteller/StorytellerLanding";
|
||||
import LandingVideoReel from "./components/LandingVideoReel";
|
||||
import LandingVideoReel from "./components/LandingVideoReel/LandingVideoReel";
|
||||
import {
|
||||
FrontendInferenceJobType,
|
||||
InferenceJob,
|
||||
@@ -20,6 +18,8 @@ import "./LandingPage.scss";
|
||||
import VstSectionV2 from "./components/VstSectionV2";
|
||||
import FakeYouLandingBody from "./fakeyou/FakeYouLandingBody";
|
||||
import { DomainConfig, Website } from "utils/domainConfig";
|
||||
import OnboardingSelection from "./storyteller/OnboardingSelection";
|
||||
import TtsDemoSection from "./components/TtsDemoSection/TtsDemoSection";
|
||||
|
||||
interface Props {
|
||||
sessionWrapper: SessionWrapper;
|
||||
@@ -39,13 +39,15 @@ function LandingPage(props: Props) {
|
||||
|
||||
PosthogClient.recordPageview();
|
||||
|
||||
const domain : DomainConfig = useDomainConfig();
|
||||
const domain: DomainConfig = useDomainConfig();
|
||||
|
||||
const isLoggedIn = props.sessionWrapper.isLoggedIn();
|
||||
|
||||
return (
|
||||
<>
|
||||
{domain.website === Website.StorytellerAi && !isLoggedIn && <LandingVideoReel />}
|
||||
{domain.website === Website.StorytellerAi && !isLoggedIn && (
|
||||
<LandingVideoReel />
|
||||
)}
|
||||
<Container type="panel">
|
||||
{domain.website === Website.FakeYou ? (
|
||||
<>
|
||||
@@ -76,15 +78,23 @@ function LandingPage(props: Props) {
|
||||
<>
|
||||
{/* STORYTELLER,AI */}
|
||||
{!isLoggedIn ? (
|
||||
<StorytellerLanding
|
||||
sessionWrapper={props.sessionWrapper}
|
||||
sessionSubscriptionsWrapper={props.sessionSubscriptionsWrapper}
|
||||
inferenceJobs={props.inferenceJobs}
|
||||
ttsInferenceJobs={props.ttsInferenceJobs}
|
||||
enqueueInferenceJob={props.enqueueInferenceJob}
|
||||
inferenceJobsByCategory={props.inferenceJobsByCategory}
|
||||
enqueueTtsJob={props.enqueueTtsJob}
|
||||
/>
|
||||
<>
|
||||
<OnboardingSelection />
|
||||
<VstSectionV2 />
|
||||
<TtsDemoSection
|
||||
sessionWrapper={props.sessionWrapper}
|
||||
sessionSubscriptionsWrapper={
|
||||
props.sessionSubscriptionsWrapper
|
||||
}
|
||||
inferenceJobs={props.inferenceJobs}
|
||||
ttsInferenceJobs={props.ttsInferenceJobs}
|
||||
enqueueInferenceJob={props.enqueueInferenceJob}
|
||||
inferenceJobsByCategory={props.inferenceJobsByCategory}
|
||||
enqueueTtsJob={props.enqueueTtsJob}
|
||||
/>
|
||||
<Dashboard sessionWrapper={props.sessionWrapper} />
|
||||
<FakeYouLandingBody />
|
||||
</>
|
||||
) : (
|
||||
<Dashboard sessionWrapper={props.sessionWrapper} />
|
||||
)}
|
||||
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
@import "scss/colours.scss";
|
||||
|
||||
.storyteller-landing-reel {
|
||||
display: flex;
|
||||
height: 74vh;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
|
||||
video {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.reel-overlay {
|
||||
z-index: 0;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: rgba(20, 20, 27, 0.6);
|
||||
|
||||
&:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
height: 20%;
|
||||
background: linear-gradient(transparent, $bg);
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
+24
-19
@@ -1,5 +1,7 @@
|
||||
import { faArrowRight } from "@fortawesome/pro-solid-svg-icons";
|
||||
import { Button } from "components/common";
|
||||
import React, { useEffect } from "react";
|
||||
import "./LandingVideoReel.scss";
|
||||
|
||||
interface LandingVideoReelProps {}
|
||||
|
||||
@@ -42,27 +44,30 @@ export default function LandingVideoReel(props: LandingVideoReelProps) {
|
||||
}, [isOnLandingPage]);
|
||||
|
||||
return (
|
||||
<div className="vh-100 d-flex align-items-center justify-content-center position-relative">
|
||||
<video
|
||||
autoPlay
|
||||
muted
|
||||
loop
|
||||
className="position-absolute w-100 h-100"
|
||||
style={{ objectFit: "cover" }}
|
||||
>
|
||||
<div className="storyteller-landing-reel">
|
||||
<video autoPlay muted loop>
|
||||
<source src="/videos/landing-reel.mp4" type="video/mp4" />
|
||||
</video>
|
||||
<div
|
||||
className="position-absolute w-100 h-100"
|
||||
style={{ backgroundColor: "rgba(20, 20, 27, 0.6)", zIndex: 0 }}
|
||||
/>
|
||||
<div className="text-center text-white d-flex flex-column align-items-center zi-2">
|
||||
<h1 className="display-2 fw-bolder">Enabling Anyone to Make Professional Film, Animation, and Music</h1>
|
||||
<h5 className="fw-normal mb-3 mt-2 w-75 lh-base opacity-75">
|
||||
StorytellerAI's powerful new engine combines Generative AI and
|
||||
User Generated Content to radically democratize both audio and video production.
|
||||
</h5>
|
||||
<Button label="Sign Up Now" to="/signup" className="mt-5" />
|
||||
<div className="reel-overlay">
|
||||
<div className="container h-100">
|
||||
<div className="text-center text-white d-flex flex-column justify-content-center align-items-center zi-2 h-100">
|
||||
<h1 className="display-3 fw-bold">
|
||||
Enabling Anyone to Make Professional Film, Animation, and Music
|
||||
</h1>
|
||||
<h5 className="fw-normal mb-2 mt-2 w-75 lh-base opacity-75">
|
||||
StorytellerAI's powerful new engine combines Generative AI and
|
||||
User Generated Content to radically democratize both audio and
|
||||
video production.
|
||||
</h5>
|
||||
<Button
|
||||
icon={faArrowRight}
|
||||
iconFlip={true}
|
||||
label="Sign Up Now"
|
||||
to="/signup"
|
||||
className="mt-4"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from "./LandingVideoReel";
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
import { faArrowRight } from "@fortawesome/pro-solid-svg-icons";
|
||||
import { Button, Panel } from "components/common";
|
||||
import React from "react";
|
||||
import LandingDemo from "../../fakeyou/LandingDemo/FakeYouLandingDemo";
|
||||
import { SessionWrapper } from "@storyteller/components/src/session/SessionWrapper";
|
||||
import { SessionSubscriptionsWrapper } from "@storyteller/components/src/session/SessionSubscriptionsWrapper";
|
||||
import {
|
||||
FrontendInferenceJobType,
|
||||
InferenceJob,
|
||||
} from "@storyteller/components/src/jobs/InferenceJob";
|
||||
import { TtsInferenceJob } from "@storyteller/components/src/jobs/TtsInferenceJobs";
|
||||
|
||||
interface TtsDemoSectionProps {
|
||||
sessionWrapper: SessionWrapper;
|
||||
sessionSubscriptionsWrapper: SessionSubscriptionsWrapper;
|
||||
inferenceJobs: Array<InferenceJob>;
|
||||
ttsInferenceJobs: Array<TtsInferenceJob>;
|
||||
enqueueInferenceJob: (
|
||||
jobToken: string,
|
||||
frontendInferenceJobType: FrontendInferenceJobType
|
||||
) => void;
|
||||
inferenceJobsByCategory: Map<FrontendInferenceJobType, Array<InferenceJob>>;
|
||||
enqueueTtsJob: (jobToken: string) => void;
|
||||
}
|
||||
|
||||
export default function TtsDemoSection(props: TtsDemoSectionProps) {
|
||||
return (
|
||||
<Panel clear={true}>
|
||||
<div className="row g-4 section">
|
||||
<div className="col-12 col-lg-6 d-flex flex-column justify-content-center">
|
||||
<h1 className="fw-bold">Generate Text to Speech</h1>
|
||||
<p className="opacity-75 mb-0">
|
||||
Create audio of any character saying anything you want.
|
||||
</p>
|
||||
<div className="d-flex mt-4">
|
||||
<Button
|
||||
label="Try all 3000+ TTS Voices"
|
||||
icon={faArrowRight}
|
||||
iconFlip={true}
|
||||
to="/tts"
|
||||
small={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-12 col-lg-6">
|
||||
<LandingDemo
|
||||
inferenceJobs={props.inferenceJobs}
|
||||
sessionSubscriptionsWrapper={props.sessionSubscriptionsWrapper}
|
||||
enqueueInferenceJob={props.enqueueInferenceJob}
|
||||
inferenceJobsByCategory={props.inferenceJobsByCategory}
|
||||
ttsInferenceJobs={props.ttsInferenceJobs}
|
||||
enqueueTtsJob={props.enqueueTtsJob}
|
||||
showHanashi={false}
|
||||
autoFocusTextBox={false}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Panel>
|
||||
);
|
||||
}
|
||||
@@ -79,7 +79,7 @@ export default function FakeYouLandingBody(props: FakeYouLandingBodyProps) {
|
||||
<img
|
||||
src="/images/landing/bg-dots.webp"
|
||||
alt="background dots"
|
||||
className="dots-left-bottom me-3"
|
||||
className="dots-right-bottom me-3"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+20
-13
@@ -35,6 +35,8 @@ interface TtsInferencePanelProps {
|
||||
) => void;
|
||||
inferenceJobsByCategory: Map<FrontendInferenceJobType, Array<InferenceJob>>;
|
||||
enqueueTtsJob: (jobToken: string) => void;
|
||||
showHanashi?: boolean;
|
||||
autoFocusTextBox?: boolean;
|
||||
}
|
||||
|
||||
export default function LandingDemo({
|
||||
@@ -44,6 +46,8 @@ export default function LandingDemo({
|
||||
enqueueInferenceJob,
|
||||
enqueueTtsJob,
|
||||
inferenceJobsByCategory,
|
||||
showHanashi = true,
|
||||
autoFocusTextBox = true,
|
||||
}: TtsInferencePanelProps) {
|
||||
const [textBuffer, setTextBuffer] = useState("");
|
||||
const [maybeTtsError, setMaybeTtsError] = useState<
|
||||
@@ -221,18 +225,21 @@ export default function LandingDemo({
|
||||
|
||||
return (
|
||||
<div className="position-relative">
|
||||
<img
|
||||
src={
|
||||
isHanashiHovered
|
||||
? "/images/landing/hanashi-demo-2.webp"
|
||||
: "/images/landing/hanashi-demo-1.webp"
|
||||
}
|
||||
alt="Hanashi Demo"
|
||||
onMouseEnter={() => setIsHanashiHovered(true)}
|
||||
onMouseLeave={() => setIsHanashiHovered(false)}
|
||||
className="hanashi-demo-image"
|
||||
draggable="false"
|
||||
/>
|
||||
{showHanashi && (
|
||||
<img
|
||||
src={
|
||||
isHanashiHovered
|
||||
? "/images/landing/hanashi-demo-2.webp"
|
||||
: "/images/landing/hanashi-demo-1.webp"
|
||||
}
|
||||
alt="Hanashi Demo"
|
||||
onMouseEnter={() => setIsHanashiHovered(true)}
|
||||
onMouseLeave={() => setIsHanashiHovered(false)}
|
||||
className="hanashi-demo-image"
|
||||
draggable="false"
|
||||
/>
|
||||
)}
|
||||
|
||||
<Panel padding={true}>
|
||||
<form className="d-flex flex-column">
|
||||
<div>
|
||||
@@ -265,7 +272,7 @@ export default function LandingDemo({
|
||||
onChange={handleChangeText}
|
||||
rows={4}
|
||||
resize={false}
|
||||
autoFocus={isMobile ? false : true}
|
||||
autoFocus={isMobile ? false : autoFocusTextBox ? true : false}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
import { Panel } from "components/common";
|
||||
import Card from "components/common/Card";
|
||||
import React from "react";
|
||||
import { useHistory } from "react-router-dom";
|
||||
|
||||
interface OnboardingSelectionProps {}
|
||||
|
||||
export default function OnboardingSelection(props: OnboardingSelectionProps) {
|
||||
const history = useHistory();
|
||||
|
||||
const cards = [
|
||||
{
|
||||
text: "Scene 1",
|
||||
backgroundImage: "",
|
||||
onClick: () => {
|
||||
history.push("/studio-intro/");
|
||||
},
|
||||
},
|
||||
{
|
||||
text: "Scene 2",
|
||||
backgroundImage: "",
|
||||
onClick: () => {
|
||||
history.push("/studio-intro/");
|
||||
},
|
||||
},
|
||||
{
|
||||
text: "Scene 3",
|
||||
backgroundImage: "",
|
||||
onClick: () => {
|
||||
history.push("/studio-intro/");
|
||||
},
|
||||
},
|
||||
{
|
||||
text: "Scene 4",
|
||||
backgroundImage: "",
|
||||
onClick: () => {
|
||||
history.push("/studio-intro/");
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<Panel clear={true}>
|
||||
<div className="text-center my-5 pb-5">
|
||||
<h1 className="fw-bold">Explore scene examples</h1>
|
||||
<p className="opacity-75">
|
||||
Try generating a movie by clicking a scene below
|
||||
</p>
|
||||
<div className="row g-3 g-lg-4 mt-3 centered-row">
|
||||
{cards.map((card, index) => (
|
||||
<div className="col-6 col-lg-3" key={index}>
|
||||
<Card
|
||||
backgroundImage={card.backgroundImage}
|
||||
aspectRatio="16/9"
|
||||
canHover={true}
|
||||
borderWidth="2px"
|
||||
hoverPrimaryColor={true}
|
||||
onClick={card.onClick}
|
||||
bottomText={card.text}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</Panel>
|
||||
);
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
export { default } from "./OnboardingSelection";
|
||||
@@ -31,220 +31,5 @@ export default function StorytellerLanding({
|
||||
}: StorytellerLandingProps) {
|
||||
// const { t } = useLocalize("LandingPage");
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* <Container type="panel" className="py-5">
|
||||
<FakeYouLandingHeader
|
||||
sessionWrapper={sessionWrapper}
|
||||
sessionSubscriptionsWrapper={sessionSubscriptionsWrapper}
|
||||
inferenceJobs={inferenceJobs}
|
||||
ttsInferenceJobs={ttsInferenceJobs}
|
||||
enqueueInferenceJob={enqueueInferenceJob}
|
||||
inferenceJobsByCategory={inferenceJobsByCategory}
|
||||
enqueueTtsJob={enqueueTtsJob}
|
||||
/>
|
||||
|
||||
{/* <Container type="panel" className="py-5">
|
||||
<Panel clear={true} className="py-lg-5">
|
||||
<div className="row g-5 g-lg-5 flex-row-reverse">
|
||||
<div className="col-12 col-md-6">
|
||||
<div className="position-relative">
|
||||
<div className="ratio ratio-16x9 video-container">
|
||||
<video
|
||||
autoPlay={true}
|
||||
playsInline={true}
|
||||
loop={true}
|
||||
muted={true}
|
||||
>
|
||||
<source src="/videos/tts-video.mp4" type="video/mp4" />
|
||||
</video>
|
||||
</div>
|
||||
<img
|
||||
src="/images/landing/bg-dots.webp"
|
||||
alt="background dots"
|
||||
className="dots-right-bottom"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-12 col-md-6 d-flex flex-column justify-content-center text-center text-lg-start gap-2">
|
||||
<h1 className="fw-bold display-5">
|
||||
Enabling Anyone to Create Quality Movies with AI
|
||||
</h1>
|
||||
<p className="opacity-75">
|
||||
We are combining generative AI and User Generated Content to
|
||||
radically democratize both audio and video production.
|
||||
</p>
|
||||
<div className="d-flex mt-3 mt-lg-4 gap-3 justify-content-center justify-content-lg-start">
|
||||
<Button
|
||||
icon={faArrowRight}
|
||||
iconFlip={true}
|
||||
label="Sign Up"
|
||||
to="/signup"
|
||||
/>
|
||||
<Button
|
||||
icon={faCompass}
|
||||
label="Explore"
|
||||
variant="secondary"
|
||||
to="/explore"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Panel>
|
||||
</Container> */}
|
||||
|
||||
{/* <div className="panel rounded-0 py-5 my-5">
|
||||
<Container type="panel" className="py-lg-5">
|
||||
<Panel clear={true}>
|
||||
<div className="d-flex flex-column align-items-center rounded-0 mt-lg-4 pt-lg-4">
|
||||
<div className="d-flex flex-column align-items-center text-center cta-container">
|
||||
<h2 className="fw-bold">AI Audio Generation</h2>
|
||||
<p className="mw-300 opacity-75">{t("ctaText")}</p>
|
||||
<div className="d-flex d-lg-none align-items-center mt-2 cta-mobile">
|
||||
<img
|
||||
src="/images/landing/hanashi-before.webp"
|
||||
alt="hanashi before"
|
||||
width={200}
|
||||
height={200}
|
||||
/>
|
||||
<img
|
||||
src="/images/landing/chevrons-red.webp"
|
||||
alt="red chevrons"
|
||||
width={95}
|
||||
height={80}
|
||||
/>
|
||||
<img
|
||||
src="/images/landing/hanashi-after.webp"
|
||||
alt="hanashi after"
|
||||
width={200}
|
||||
height={200}
|
||||
/>
|
||||
</div>
|
||||
<img
|
||||
src="/images/landing/hanashi-before.webp"
|
||||
alt="hanashi before"
|
||||
className="hanashi-before d-none d-lg-block"
|
||||
width={311}
|
||||
height={311}
|
||||
/>
|
||||
<img
|
||||
src="/images/landing/chevrons-grey.webp"
|
||||
alt="grey chevrons"
|
||||
className="chevrons-grey d-none d-lg-block"
|
||||
width={127}
|
||||
height={108}
|
||||
/>
|
||||
<img
|
||||
src="/images/landing/chevrons-red.webp"
|
||||
alt="red chevrons"
|
||||
className="chevrons-red d-none d-lg-block"
|
||||
width={127}
|
||||
height={108}
|
||||
/>
|
||||
<img
|
||||
src="/images/landing/hanashi-after.webp"
|
||||
alt="hanashi after"
|
||||
className="hanashi-after d-none d-lg-block"
|
||||
width={311}
|
||||
height={311}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row gy-4 mt-lg-3">
|
||||
<div className="col-12 col-md-6">
|
||||
<Panel padding={true} className="panel-inner rounded h-100">
|
||||
<div className="d-flex gap-2">
|
||||
<h4 className="fw-semibold mb-4 flex-grow-1">
|
||||
<FontAwesomeIcon icon={faMessageDots} className="me-3" />
|
||||
Text to Speech
|
||||
</h4>
|
||||
<Link to="/tts">
|
||||
Try more voices{" "}
|
||||
<FontAwesomeIcon icon={faArrowRight} className="ms-1" />
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div className="d-flex flex-column gap-3">
|
||||
<Select label="Select a Voice" />
|
||||
<Input
|
||||
label="Your Text"
|
||||
placeholder="Type what you want your character to say"
|
||||
/>
|
||||
<div className="d-flex gap-2 justify-content-end">
|
||||
<Button
|
||||
label="Generate"
|
||||
icon={faArrowRight}
|
||||
iconFlip={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Panel>
|
||||
</div>
|
||||
<div className="col-12 col-md-6">
|
||||
<Panel padding={true} className="panel-inner rounded h-100">
|
||||
<div className="d-flex gap-2">
|
||||
<h4 className="fw-semibold mb-4 flex-grow-1">
|
||||
<FontAwesomeIcon
|
||||
icon={faWaveformLines}
|
||||
className="me-3"
|
||||
/>
|
||||
Voice to Voice
|
||||
</h4>
|
||||
<Link to="/voice-conversion">
|
||||
Try more voices{" "}
|
||||
<FontAwesomeIcon icon={faArrowRight} className="ms-1" />
|
||||
</Link>
|
||||
</div>
|
||||
<div className="d-flex flex-column gap-3">
|
||||
<Select label="Select a Voice" />
|
||||
<div className="d-flex gap-2 justify-content-end">
|
||||
<Button
|
||||
label="Generate"
|
||||
icon={faArrowRight}
|
||||
iconFlip={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Panel>
|
||||
</div>
|
||||
</div>
|
||||
</Panel>
|
||||
</Container>
|
||||
</div> */}
|
||||
|
||||
{/* <Container type="panel" className="pt-5 my-5">
|
||||
<Panel padding={true}>
|
||||
<div className="d-flex flex-column align-items-center py-5">
|
||||
<h2 className="fw-bold mb-2">{t("communityTitle")}</h2>
|
||||
<p className="opacity-75">{t("communityText")}</p>
|
||||
<div className="d-flex mt-4 gap-3">
|
||||
<a
|
||||
href="https://discord.gg/fakeyou"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="btn btn-discord"
|
||||
>
|
||||
<FontAwesomeIcon icon={faDiscord} className="me-2" />
|
||||
{t("communityButtonDiscord")}
|
||||
</a>
|
||||
<a
|
||||
href="https://twitter.com/intent/follow?screen_name=FakeYouApp"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="btn btn-twitter"
|
||||
>
|
||||
<FontAwesomeIcon icon={faTwitter} className="me-2" />
|
||||
{t("communityButtonTwitter")}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<img
|
||||
src="/images/landing/bg-dots.webp"
|
||||
alt="background dots"
|
||||
className="dots-left-bottom me-3"
|
||||
/>
|
||||
</Panel>
|
||||
</Container> */}
|
||||
</>
|
||||
);
|
||||
return <>Test</>;
|
||||
}
|
||||
Reference in new issue
Block a user