mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-06 10:11:31 +00:00
domain/sidebar logic, new landing for non-logged in
This commit is contained in:
1 parent
eaa6d34730
commit
c6830cf9e3
11 files changed
+1705
-1614
No files matched your search
Binary file not shown.
|
After Width: | Height: | Size: 23 KiB |
@@ -53,6 +53,13 @@ export default function SideNav({
|
||||
const isDevelopmentEnv = fakeYouFrontendEnv.isDevelopment();
|
||||
const wrapper = document.getElementById("wrapper");
|
||||
const isMenuOpen = wrapper?.classList.contains("toggled");
|
||||
const isLoggedIn = sessionWrapper.isLoggedIn();
|
||||
const isOnLandingPage = window.location.pathname === "/";
|
||||
const isOnLoginOrSignUpPage =
|
||||
window.location.pathname === "/login" ||
|
||||
window.location.pathname === "/login/" ||
|
||||
window.location.pathname === "/signup" ||
|
||||
window.location.pathname === "/signup/";
|
||||
|
||||
let history = useHistory();
|
||||
const handleNavLinkClick = () => {
|
||||
@@ -102,17 +109,25 @@ export default function SideNav({
|
||||
};
|
||||
}, []);
|
||||
|
||||
const shouldShowSidebar = windowWidth >= 992;
|
||||
const shouldNotShowSidebar =
|
||||
!isLoggedIn && (isOnLandingPage || isOnLoginOrSignUpPage);
|
||||
const shouldShowSidebar = windowWidth >= 992 && !shouldNotShowSidebar;
|
||||
const sidebarClassName = `sidebar ${
|
||||
shouldShowSidebar ? "visible" : ""
|
||||
}`.trim();
|
||||
|
||||
useEffect(() => {
|
||||
const contentWrapper = document.getElementById("page-content-wrapper");
|
||||
|
||||
if (windowWidth >= 992) {
|
||||
if (
|
||||
(shouldShowSidebar && isLoggedIn) ||
|
||||
(shouldShowSidebar && !isOnLandingPage)
|
||||
) {
|
||||
contentWrapper?.classList.remove("no-padding");
|
||||
} else {
|
||||
contentWrapper?.classList.add("no-padding");
|
||||
}
|
||||
}, [windowWidth]);
|
||||
}, [isLoggedIn, isOnLandingPage, shouldShowSidebar]);
|
||||
|
||||
const [queueStats, setQueueStats] = useState<GetQueueStatsSuccessResponse>({
|
||||
success: true,
|
||||
@@ -256,10 +271,7 @@ export default function SideNav({
|
||||
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
id="sidebar-wrapper"
|
||||
className={`sidebar ${shouldShowSidebar ? "visible" : ""}`}
|
||||
>
|
||||
<div id="sidebar-wrapper" className={sidebarClassName}>
|
||||
<div>
|
||||
<ul className="sidebar-nav">
|
||||
<li>
|
||||
|
||||
@@ -12,6 +12,7 @@ import { Link, useHistory } from "react-router-dom";
|
||||
import { WebUrl } from "common/WebUrl";
|
||||
import { SessionWrapper } from "@storyteller/components/src/session/SessionWrapper";
|
||||
import { Logout } from "@storyteller/components/src/api/session/Logout";
|
||||
import { useDomainConfig } from "context/DomainConfigContext";
|
||||
|
||||
interface TopNavProps {
|
||||
sessionWrapper: SessionWrapper;
|
||||
@@ -25,6 +26,7 @@ export default function TopNav({
|
||||
querySessionCallback,
|
||||
querySessionSubscriptionsCallback,
|
||||
}: TopNavProps) {
|
||||
const domain = useDomainConfig();
|
||||
let history = useHistory();
|
||||
const [isMobileSearchBarVisible, setIsMobileSearchBarVisible] =
|
||||
useState(false);
|
||||
@@ -181,14 +183,14 @@ export default function TopNav({
|
||||
<div className="topbar-nav-left">
|
||||
<Link to="/">
|
||||
<img
|
||||
src="/fakeyou/FakeYou-Logo.png"
|
||||
alt="FakeYou: Cartoon and Celebrity Text to Speech"
|
||||
src={domain.logo}
|
||||
alt={`${domain.title}: Cartoon and Celebrity Text to Speech`}
|
||||
height="34"
|
||||
className="mb-2 d-none d-lg-block"
|
||||
/>
|
||||
<img
|
||||
src="/fakeyou/FakeYou-Logo-Mobile.png"
|
||||
alt="FakeYou: Cartoon and Celebrity Text to Speech"
|
||||
alt={`${domain.title}: Cartoon and Celebrity Text to Speech`}
|
||||
height="36"
|
||||
className="mb-0 d-block d-lg-none"
|
||||
/>
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
import React, { createContext, useContext, ReactNode } from "react";
|
||||
import { getCurrentDomainConfig } from "../utils/domainConfig";
|
||||
|
||||
const DomainConfigContext = createContext(getCurrentDomainConfig());
|
||||
|
||||
export const useDomainConfig = () => useContext(DomainConfigContext);
|
||||
|
||||
interface DomainConfigProviderProps {
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
export default function DomainConfigProvider({
|
||||
children,
|
||||
}: DomainConfigProviderProps) {
|
||||
const domainConfig = getCurrentDomainConfig();
|
||||
|
||||
return (
|
||||
<DomainConfigContext.Provider value={domainConfig}>
|
||||
{children}
|
||||
</DomainConfigContext.Provider>
|
||||
);
|
||||
}
|
||||
@@ -2,5 +2,12 @@ import AccountModalContext from "./AccountModalContext";
|
||||
import InferenceJobsContext from "./InferenceJobsContext";
|
||||
import ModalContext from "./ModalContext";
|
||||
import SessionContext from "./SessionContext";
|
||||
import DomainConfigContext from "./DomainConfigContext";
|
||||
|
||||
export { AccountModalContext, InferenceJobsContext, ModalContext, SessionContext };
|
||||
export {
|
||||
AccountModalContext,
|
||||
InferenceJobsContext,
|
||||
ModalContext,
|
||||
SessionContext,
|
||||
DomainConfigContext,
|
||||
};
|
||||
@@ -60,6 +60,7 @@ $topbar-height: 66px;
|
||||
position: relative;
|
||||
padding-left: 260px;
|
||||
padding-top: $topbar-height;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
/* Sidebar Styles */
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
type DomainConfig = Record<string, any>;
|
||||
|
||||
const domainConfigs: Record<string, DomainConfig> = {
|
||||
"storyteller.ai": {
|
||||
logo: "/fakeyou/Storyteller-Logo.png",
|
||||
title: "Storyteller AI",
|
||||
link: "https://storyteller.ai",
|
||||
},
|
||||
"fakeyou.com": {
|
||||
logo: "/fakeyou/FakeYou-Logo.png",
|
||||
title: "FakeYou",
|
||||
link: "https://fakeyou.com",
|
||||
},
|
||||
// Default to FakeYou.com
|
||||
default: {
|
||||
logo: "/fakeyou/FakeYou-Logo.png",
|
||||
title: "FakeYou",
|
||||
link: "https://fakeyou.com",
|
||||
},
|
||||
};
|
||||
|
||||
export const getCurrentDomainConfig = (): DomainConfig => {
|
||||
const currentHostname = window.location.hostname;
|
||||
|
||||
const matchingConfigKey = Object.keys(domainConfigs).find(
|
||||
key => currentHostname === key || currentHostname.endsWith(`.${key}`)
|
||||
);
|
||||
|
||||
const domainConfig =
|
||||
matchingConfigKey !== undefined
|
||||
? domainConfigs[matchingConfigKey]
|
||||
: domainConfigs["default"];
|
||||
|
||||
return domainConfig;
|
||||
};
|
||||
File diff suppressed because it is too large.
Load diff
@@ -19,12 +19,14 @@ import {
|
||||
} from "@storyteller/components/src/api/server/GetServerInfo";
|
||||
import { useLocalize } from "hooks";
|
||||
import { Container } from "components/common";
|
||||
import { useDomainConfig } from "context/DomainConfigContext";
|
||||
|
||||
interface Props {
|
||||
sessionWrapper: SessionWrapper;
|
||||
}
|
||||
|
||||
function FooterNav(props: Props) {
|
||||
const domain = useDomainConfig();
|
||||
const { t } = useLocalize("Footer");
|
||||
const [serverInfo, setServerInfo] = useState<
|
||||
GetServerInfoSuccessResponse | undefined
|
||||
@@ -84,8 +86,8 @@ function FooterNav(props: Props) {
|
||||
<div className="col-12 col-lg-3 d-flex flex-column gap-4 align-items-center align-items-lg-start">
|
||||
<Link to="/">
|
||||
<img
|
||||
src="/fakeyou/FakeYou-Logo.png"
|
||||
alt="FakeYou: Cartoon and Celebrity Text to Speech"
|
||||
src={domain.logo}
|
||||
alt={`${domain.title}: Cartoon and Celebrity Text to Speech`}
|
||||
height="34"
|
||||
/>
|
||||
</Link>
|
||||
@@ -204,12 +206,17 @@ function FooterNav(props: Props) {
|
||||
</div>
|
||||
|
||||
<div className="d-flex flex-column flex-lg-row pt-2 align-items-center gap-2 gap-xl-4 flex-wrap">
|
||||
<span className="flex-grow-1">
|
||||
© 2023 FakeYou by{" "}
|
||||
<a href="https://storyteller.ai" target="_blank" rel="noreferrer">
|
||||
Storyteller.ai
|
||||
</a>
|
||||
</span>
|
||||
{domain.title === "FakeYou" ? (
|
||||
<span className="flex-grow-1">
|
||||
© 2023 {domain.title} by{" "}
|
||||
<a href={domain.link} target="_blank" rel="noreferrer">
|
||||
Storyteller.ai
|
||||
</a>
|
||||
</span>
|
||||
) : (
|
||||
<span className="flex-grow-1">© 2023 {domain.title}</span>
|
||||
)}
|
||||
|
||||
<div className="d-flex flex-column flex-lg-row align-items-center mt-4 mt-lg-0">
|
||||
{moderationLink}
|
||||
</div>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import React, { useMemo } from "react";
|
||||
import React, { useMemo, useState } from "react";
|
||||
import { usePrefixedDocumentTitle } from "../../../../common/UsePrefixedDocumentTitle";
|
||||
import { Link } from "react-router-dom";
|
||||
import { SessionWrapper } from "@storyteller/components/src/session/SessionWrapper";
|
||||
import { SessionSubscriptionsWrapper } from "@storyteller/components/src/session/SessionSubscriptionsWrapper";
|
||||
import { useLocalize } from "hooks";
|
||||
import { useLocalize, useModal } from "hooks";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import {
|
||||
faStar,
|
||||
@@ -15,11 +15,12 @@ import { WebUrl } from "../../../../common/WebUrl";
|
||||
import {
|
||||
faFileArrowUp,
|
||||
faFlask,
|
||||
faSearch,
|
||||
faSparkles,
|
||||
} from "@fortawesome/pro-solid-svg-icons";
|
||||
import { PosthogClient } from "@storyteller/components/src/analytics/PosthogClient";
|
||||
import Alert from "components/common/Alert/Alert";
|
||||
// import { Analytics } from "../../../../../common/Analytics";
|
||||
import { Button, Container, Panel } from "components/common";
|
||||
|
||||
interface Props {
|
||||
sessionWrapper: SessionWrapper;
|
||||
@@ -28,10 +29,12 @@ interface Props {
|
||||
|
||||
function LandingPage(props: Props) {
|
||||
usePrefixedDocumentTitle("FakeYou Celebrity Voice Generator");
|
||||
|
||||
PosthogClient.recordPageview();
|
||||
|
||||
const { t } = useLocalize("LandingPage");
|
||||
const isLoggedIn = props.sessionWrapper.isLoggedIn();
|
||||
const isSubscribed = props.sessionSubscriptionsWrapper.hasPaidFeatures();
|
||||
// const [isFocused, setIsFocused] = useState(false);
|
||||
const { open, close } = useModal();
|
||||
|
||||
let signUpButton = <></>;
|
||||
let viewPricingButton = <></>;
|
||||
@@ -39,7 +42,7 @@ function LandingPage(props: Props) {
|
||||
let myProfileButton = <></>;
|
||||
let uploadModelSection = <></>;
|
||||
|
||||
if (!props.sessionWrapper.isLoggedIn()) {
|
||||
if (!isLoggedIn) {
|
||||
signUpButton = (
|
||||
<>
|
||||
<Link
|
||||
@@ -71,7 +74,7 @@ function LandingPage(props: Props) {
|
||||
</>
|
||||
);
|
||||
}
|
||||
if (props.sessionWrapper.isLoggedIn()) {
|
||||
if (isLoggedIn) {
|
||||
let displayName = props.sessionWrapper.getDisplayName() as string; // NB: If logged in, should be string
|
||||
let url = WebUrl.userProfilePage(displayName);
|
||||
myProfileButton = (
|
||||
@@ -118,7 +121,7 @@ function LandingPage(props: Props) {
|
||||
</>
|
||||
);
|
||||
|
||||
if (!props.sessionSubscriptionsWrapper.hasPaidFeatures()) {
|
||||
if (!isSubscribed) {
|
||||
upgradeButton = (
|
||||
<>
|
||||
<Link
|
||||
@@ -154,411 +157,339 @@ function LandingPage(props: Props) {
|
||||
return images[Math.floor(Math.random() * images.length)];
|
||||
}, []);
|
||||
|
||||
// const onFocusHandler = () => {
|
||||
// setIsFocused(true);
|
||||
// };
|
||||
|
||||
// const onBlurHandler = () => {
|
||||
// // Search field blur/Unfocusing hack: needs a little bit of delay for the result click event to register
|
||||
// setTimeout(() => {
|
||||
// setIsFocused(false);
|
||||
// }, 100);
|
||||
// };
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="container pb-5 pb-lg-0 pt-lg-4 px-md-5 px-lg-5 px-xl-3">
|
||||
{/* Face Animation Alert Banner */}
|
||||
<Alert
|
||||
id="face-animation-alert"
|
||||
icon={faSparkles}
|
||||
message="Have you tried our new Face Animator? Turn photos of faces into animated lip-synced videos with just a picture and some audio!"
|
||||
alertVariant="new"
|
||||
link="/face-animator"
|
||||
linkText="Try it now"
|
||||
/>
|
||||
|
||||
<div className="row flex-md-row-reverse">
|
||||
<div className="col-12 col-lg-5 p-md-0 d-flex justify-content-center">
|
||||
<img
|
||||
src={randomHeroImage}
|
||||
alt="FakeYou Mascot"
|
||||
height={440}
|
||||
width={447}
|
||||
className="img-fluid"
|
||||
<>
|
||||
{isLoggedIn ? (
|
||||
<Container type="panel">
|
||||
{/* <Panel clear={true}>
|
||||
<Alert
|
||||
id="face-animation-alert"
|
||||
icon={faSparkles}
|
||||
message="Have you tried our new Face Animator? Turn photos of faces into animated lip-synced videos with just a picture and some audio!"
|
||||
alertVariant="new"
|
||||
link="/face-animator"
|
||||
linkText="Try it now"
|
||||
/>
|
||||
</div>
|
||||
<div className="col-12 col-lg-7 d-flex flex-column justify-content-center flex-reverse px-md-5 px-lg-3">
|
||||
<h1 className="fw-bold display-5 text-center text-lg-start px-md-5 px-lg-0">
|
||||
{t("heroTitle")}
|
||||
</h1>
|
||||
<p className="lead opacity-75 pb-4 text-center text-lg-start px-md-5 px-lg-0 pe-lg-5">
|
||||
{t("heroText")}
|
||||
</p>
|
||||
<div className="d-flex flex-column flex-md-row gap-3 mt-3 mb-4 w-100 justify-content-center justify-content-lg-start">
|
||||
{upgradeButton}
|
||||
{signUpButton}
|
||||
{viewPricingButton}
|
||||
{myProfileButton}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* <div className="container-panel pb-5 mb-4">
|
||||
<div className="panel p-3 py-4 p-md-4">
|
||||
<form
|
||||
className="w-100 d-flex flex-column"
|
||||
// onSubmit={handleFormSubmit}
|
||||
>
|
||||
<div className="row gx-5 gy-4">
|
||||
<div className="col-12 col-md-6 d-flex flex-column gap-4">
|
||||
<div>
|
||||
<label className="sub-title">
|
||||
Pick a Voice (xxx to choose from)
|
||||
</label>
|
||||
<div className="input-icon-search pb-4">
|
||||
<span className="form-control-feedback">
|
||||
<FontAwesomeIcon icon={faMicrophone} />
|
||||
</span>
|
||||
|
||||
<VcModelListSearch
|
||||
voiceConversionModels={props.voiceConversionModels}
|
||||
setVoiceConversionModels={props.setVoiceConversionModels}
|
||||
maybeSelectedVoiceConversionModel={
|
||||
props.maybeSelectedVoiceConversionModel
|
||||
}
|
||||
setMaybeSelectedVoiceConversionModel={interceptModelChange}
|
||||
<div className="row flex-md-row-reverse">
|
||||
<div className="col-12 col-lg-5 p-md-0 d-flex justify-content-center">
|
||||
<img
|
||||
src={randomHeroImage}
|
||||
alt="FakeYou Mascot"
|
||||
height={440}
|
||||
width={447}
|
||||
className="img-fluid"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<p className="mt-4">
|
||||
<span className="opacity-75">
|
||||
Pick one to get started, or choose from
|
||||
</span>{" "}
|
||||
<Link to="/tts">thousands more!</Link>
|
||||
</p>
|
||||
</div>
|
||||
<div className="col-12 col-md-6 d-flex flex-column">
|
||||
<label className="sub-title">Select Your Input</label>
|
||||
<div className="d-flex flex-column flex-lg-row gap-3">
|
||||
<button className="btn btn-primary w-100">
|
||||
<FontAwesomeIcon icon={faRightLeft} className="me-2" />
|
||||
Text
|
||||
</button>
|
||||
<button className="btn btn-primary w-100">
|
||||
<FontAwesomeIcon icon={faFileArrowUp} className="me-2" />
|
||||
Upload
|
||||
</button>
|
||||
<button className="btn btn-primary w-100">
|
||||
<FontAwesomeIcon icon={faMicrophone} className="me-2" />
|
||||
Microphone
|
||||
</button>
|
||||
<div className="col-12 col-lg-7 d-flex flex-column justify-content-center flex-reverse px-md-5 px-lg-3">
|
||||
<h1 className="fw-bold display-5 text-center text-lg-start px-md-5 px-lg-0">
|
||||
{t("heroTitle")}
|
||||
</h1>
|
||||
<p className="lead opacity-75 pb-4 text-center text-lg-start px-md-5 px-lg-0 pe-lg-5">
|
||||
{t("heroText")}
|
||||
</p>
|
||||
<div className="d-flex flex-column flex-md-row gap-3 mt-3 mb-4 w-100 justify-content-center justify-content-lg-start">
|
||||
{upgradeButton}
|
||||
{signUpButton}
|
||||
{viewPricingButton}
|
||||
{myProfileButton}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div> */}
|
||||
</Panel> */}
|
||||
|
||||
<div className="container pb-4 px-md-5 px-xl-3">
|
||||
<h2 className="fw-bold mb-4">{t("productsTitle")}</h2>
|
||||
<div className="row g-4 position-relative">
|
||||
<div className="col-12 col-md-4">
|
||||
<Link
|
||||
to="/tts"
|
||||
className="panel panel-select d-flex flex-column align-items-center"
|
||||
>
|
||||
<div className="d-flex px-4 pt-4 align-items-start w-100">
|
||||
<div className="flex-grow-1">
|
||||
<h3 className="fw-bold text-white mb-1">
|
||||
{t("productTtsTitle")}
|
||||
</h3>
|
||||
<h6 className="fw-normal opacity-75 text-white">
|
||||
{t("productTtsText")}
|
||||
</h6>
|
||||
</div>
|
||||
<Link to="/tts" className="btn btn-square mt-1">
|
||||
<FontAwesomeIcon icon={faArrowRight} />
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<img
|
||||
className="img-fluid"
|
||||
src="/images/landing/select-tts.webp"
|
||||
alt="Text to speech"
|
||||
/>
|
||||
</Link>
|
||||
</div>
|
||||
<div className="col-12 col-md-4">
|
||||
<Link
|
||||
to="/voice-conversion"
|
||||
className="panel panel-select d-flex flex-column align-items-center"
|
||||
>
|
||||
<div className="d-flex px-4 pt-4 align-items-start w-100">
|
||||
<div className="flex-grow-1">
|
||||
<h3 className="fw-bold text-white mb-1">
|
||||
{t("productVcTitle")}
|
||||
</h3>
|
||||
<h6 className="fw-normal opacity-75 text-white">
|
||||
{t("productVcText")}
|
||||
</h6>
|
||||
</div>
|
||||
<Link to="/voice-conversion" className="btn btn-square mt-1">
|
||||
<FontAwesomeIcon icon={faArrowRight} />
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<img
|
||||
className="img-fluid"
|
||||
src="/images/landing/select-vc.webp"
|
||||
alt="Voice Conversion"
|
||||
/>
|
||||
</Link>
|
||||
</div>
|
||||
<div className="col-12 col-md-4">
|
||||
<Link
|
||||
to="/voice-designer"
|
||||
className="panel panel-select d-flex flex-column align-items-center"
|
||||
>
|
||||
<div className="d-flex px-4 pt-4 align-items-start w-100">
|
||||
<div className="flex-grow-1">
|
||||
<div className="mb-1">
|
||||
<span className="badge-beta d-inline-flex align-items-center mb-2 me-2">
|
||||
<FontAwesomeIcon icon={faFlask} className="me-1" />
|
||||
BETA
|
||||
</span>
|
||||
|
||||
<h4 className="fw-bold text-white d-inline-flex align-items-center mb-0">
|
||||
<span>Voice Designer</span>
|
||||
</h4>
|
||||
</div>
|
||||
|
||||
<h6 className="fw-normal opacity-75 text-white">
|
||||
Create your own AI voice
|
||||
</h6>
|
||||
</div>
|
||||
<Link to="/voice-designer" className="btn btn-square mt-1">
|
||||
<FontAwesomeIcon icon={faArrowRight} />
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<img
|
||||
className="img-fluid"
|
||||
src="/images/landing/select-vd.webp"
|
||||
alt="Voice Designer"
|
||||
/>
|
||||
</Link>
|
||||
</div>
|
||||
<div className="col-12 col-md-4">
|
||||
<Link
|
||||
to="/face-animator"
|
||||
className="panel panel-select d-flex flex-column align-items-center"
|
||||
>
|
||||
<div className="d-flex px-4 pt-4 align-items-start w-100">
|
||||
<div className="flex-grow-1">
|
||||
<div className="mb-1">
|
||||
<span className="badge-new d-inline-flex align-items-center mb-2 me-2">
|
||||
<FontAwesomeIcon icon={faSparkles} className="me-1" />
|
||||
{t("productNewTag")}
|
||||
</span>
|
||||
|
||||
<h4 className="fw-bold text-white d-inline-flex align-items-center mb-0">
|
||||
<span>{t("productFaceAnimatorTitle")}</span>
|
||||
</h4>
|
||||
</div>
|
||||
|
||||
<h6 className="fw-normal opacity-75 text-white">
|
||||
{t("productFaceAnimatorText")}
|
||||
</h6>
|
||||
</div>
|
||||
<Link to="/face-animator" className="btn btn-square mt-1">
|
||||
<FontAwesomeIcon icon={faArrowRight} />
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<img
|
||||
className="img-fluid"
|
||||
src="/images/landing/select-w2l.webp"
|
||||
alt="Face Animator"
|
||||
/>
|
||||
</Link>
|
||||
</div>
|
||||
<img
|
||||
src="/images/landing/bg-dots.webp"
|
||||
alt="background dots"
|
||||
className="dots-right-top"
|
||||
/>
|
||||
<img
|
||||
src="/images/landing/bg-dots.webp"
|
||||
alt="background dots"
|
||||
className="dots-left-bottom"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{uploadModelSection}
|
||||
</div>
|
||||
|
||||
<div className="container section px-md-5 px-xl-3">
|
||||
<div className="row g-4 g-lg-5 flex-row-reverse">
|
||||
<div className="col-12 col-md-6 col-lg-7">
|
||||
<div className="position-relative">
|
||||
<div className="ratio ratio-16x9 video-container">
|
||||
<video
|
||||
autoPlay={true}
|
||||
playsInline={true}
|
||||
loop={true}
|
||||
muted={true}
|
||||
<Panel clear={true} className="mt-5">
|
||||
<h1 className="fw-bold mb-4">{t("productsTitle")}</h1>
|
||||
<div className="row g-4 position-relative">
|
||||
<div className="col-12 col-md-4">
|
||||
<Link
|
||||
to="/tts"
|
||||
className="panel panel-select d-flex flex-column align-items-center"
|
||||
>
|
||||
<source src="/videos/tts-video.mp4" type="video/mp4" />
|
||||
</video>
|
||||
<div className="d-flex px-4 pt-4 align-items-start w-100">
|
||||
<div className="flex-grow-1">
|
||||
<h3 className="fw-bold text-white mb-1">
|
||||
{t("productTtsTitle")}
|
||||
</h3>
|
||||
<h6 className="fw-normal opacity-75 text-white">
|
||||
{t("productTtsText")}
|
||||
</h6>
|
||||
</div>
|
||||
<Link to="/tts" className="btn btn-square mt-1">
|
||||
<FontAwesomeIcon icon={faArrowRight} />
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<img
|
||||
className="img-fluid"
|
||||
src="/images/landing/select-tts.webp"
|
||||
alt="Text to speech"
|
||||
/>
|
||||
</Link>
|
||||
</div>
|
||||
<div className="col-12 col-md-4">
|
||||
<Link
|
||||
to="/voice-conversion"
|
||||
className="panel panel-select d-flex flex-column align-items-center"
|
||||
>
|
||||
<div className="d-flex px-4 pt-4 align-items-start w-100">
|
||||
<div className="flex-grow-1">
|
||||
<h3 className="fw-bold text-white mb-1">
|
||||
{t("productVcTitle")}
|
||||
</h3>
|
||||
<h6 className="fw-normal opacity-75 text-white">
|
||||
{t("productVcText")}
|
||||
</h6>
|
||||
</div>
|
||||
<Link
|
||||
to="/voice-conversion"
|
||||
className="btn btn-square mt-1"
|
||||
>
|
||||
<FontAwesomeIcon icon={faArrowRight} />
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<img
|
||||
className="img-fluid"
|
||||
src="/images/landing/select-vc.webp"
|
||||
alt="Voice Conversion"
|
||||
/>
|
||||
</Link>
|
||||
</div>
|
||||
<div className="col-12 col-md-4">
|
||||
<Link
|
||||
to="/voice-designer"
|
||||
className="panel panel-select d-flex flex-column align-items-center"
|
||||
>
|
||||
<div className="d-flex px-4 pt-4 align-items-start w-100">
|
||||
<div className="flex-grow-1">
|
||||
<div className="mb-1">
|
||||
<span className="badge-beta d-inline-flex align-items-center mb-2 me-2">
|
||||
<FontAwesomeIcon icon={faFlask} className="me-1" />
|
||||
BETA
|
||||
</span>
|
||||
|
||||
<h4 className="fw-bold text-white d-inline-flex align-items-center mb-0">
|
||||
<span>Voice Designer</span>
|
||||
</h4>
|
||||
</div>
|
||||
|
||||
<h6 className="fw-normal opacity-75 text-white">
|
||||
Create your own AI voice
|
||||
</h6>
|
||||
</div>
|
||||
<Link to="/voice-designer" className="btn btn-square mt-1">
|
||||
<FontAwesomeIcon icon={faArrowRight} />
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<img
|
||||
className="img-fluid"
|
||||
src="/images/landing/select-vd.webp"
|
||||
alt="Voice Designer"
|
||||
/>
|
||||
</Link>
|
||||
</div>
|
||||
<div className="col-12 col-md-4">
|
||||
<Link
|
||||
to="/face-animator"
|
||||
className="panel panel-select d-flex flex-column align-items-center"
|
||||
>
|
||||
<div className="d-flex px-4 pt-4 align-items-start w-100">
|
||||
<div className="flex-grow-1">
|
||||
<div className="mb-1">
|
||||
<span className="badge-new d-inline-flex align-items-center mb-2 me-2">
|
||||
<FontAwesomeIcon icon={faSparkles} className="me-1" />
|
||||
{t("productNewTag")}
|
||||
</span>
|
||||
|
||||
<h4 className="fw-bold text-white d-inline-flex align-items-center mb-0">
|
||||
<span>{t("productFaceAnimatorTitle")}</span>
|
||||
</h4>
|
||||
</div>
|
||||
|
||||
<h6 className="fw-normal opacity-75 text-white">
|
||||
{t("productFaceAnimatorText")}
|
||||
</h6>
|
||||
</div>
|
||||
<Link to="/face-animator" className="btn btn-square mt-1">
|
||||
<FontAwesomeIcon icon={faArrowRight} />
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<img
|
||||
className="img-fluid"
|
||||
src="/images/landing/select-w2l.webp"
|
||||
alt="Face Animator"
|
||||
/>
|
||||
</Link>
|
||||
</div>
|
||||
<img
|
||||
src="/images/landing/bg-dots.webp"
|
||||
alt="background dots"
|
||||
className="dots-right-bottom"
|
||||
className="dots-right-top"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-12 col-md-6 col-lg-5 d-flex flex-column justify-content-center gap-3">
|
||||
<h2 className="fw-bold">{t("contextTitle")}</h2>
|
||||
<p className="opacity-75">{t("contextText")}</p>
|
||||
<div className="d-flex mt-3 gap-3">
|
||||
<Link to="/tts" className="btn btn-primary">
|
||||
{t("contextButtonTts")}
|
||||
</Link>
|
||||
<Link to="/voice-conversion" className="btn btn-primary">
|
||||
{t("contextButtonVc")}
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* <div className="container section px-md-5 px-xl-3">
|
||||
<div className="row g-4 g-lg-5">
|
||||
<div className="col-12 col-md-6 col-lg-7">
|
||||
<div className="position-relative">
|
||||
<div className="ratio ratio-16x9 video-container position-relative">
|
||||
<video
|
||||
autoPlay={true}
|
||||
playsInline={true}
|
||||
loop={true}
|
||||
muted={true}
|
||||
>
|
||||
<source src="/videos/tts-video.webm" type="video/webm" />
|
||||
</video>
|
||||
</div>
|
||||
<img
|
||||
src="/images/landing/bg-dots.webp"
|
||||
alt="background dots"
|
||||
className="dots-left-bottom"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-12 col-md-6 col-lg-5 d-flex flex-column justify-content-center gap-3">
|
||||
<h2 className="fw-bold">Speak as your favorite characters</h2>
|
||||
<p className="opacity-75">
|
||||
Transform your speaking voice into someone else's voice with our
|
||||
cutting-edge voice conversion service. Just upload or record your
|
||||
audio and let our AI-powered technology do the rest. Perfect for
|
||||
entertainment, voiceovers, and language learning materials.
|
||||
</p>
|
||||
<div className="d-flex mt-3">
|
||||
<Link to="/voice-conversion" className="btn btn-primary">
|
||||
Convert your voice
|
||||
</Link>
|
||||
|
||||
{uploadModelSection}
|
||||
</Panel>
|
||||
</Container>
|
||||
) : (
|
||||
<Container type="panel" className="mt-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="/tts"
|
||||
/>
|
||||
<Button
|
||||
icon={faSearch}
|
||||
label="Search for a weight model..."
|
||||
variant="secondary"
|
||||
className="opacity-75 ps-3 pe-5 d-none d-lg-flex"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Panel>
|
||||
|
||||
<div className="d-flex flex-column section align-items-center rounded-0 mb-5">
|
||||
<div className="d-flex flex-column align-items-center text-center cta-container">
|
||||
<div className="d-flex d-lg-none align-items-center mb-4 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>
|
||||
<h2 className="fw-bold">{t("ctaTitle")}</h2>
|
||||
<p className="mw-300 opacity-75">{t("ctaText")}</p>
|
||||
<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>
|
||||
</div> */}
|
||||
|
||||
<div className="d-flex flex-column section align-items-center panel rounded-0 my-5">
|
||||
<div className="d-flex flex-column align-items-center text-center cta-container">
|
||||
<div className="d-flex d-lg-none align-items-center mb-4 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>
|
||||
<h2 className="fw-bold">{t("ctaTitle")}</h2>
|
||||
<p className="mw-300 opacity-75">{t("ctaText")}</p>
|
||||
<div className="d-flex gap-3 justify-content-center mt-4">
|
||||
<Link to="/tts" className="btn btn-primary">
|
||||
{t("ctaButtonTts")}
|
||||
</Link>
|
||||
<Link to="/voice-conversion" className="btn btn-primary">
|
||||
{t("ctaButtonVc")}
|
||||
</Link>
|
||||
</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="py-4">
|
||||
<div className="container text-center community-container">
|
||||
<div className="panel px-4 py-5 d-flex flex-column align-items-center community-container rounded">
|
||||
<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 className="py-4">
|
||||
<div className="container text-center community-container">
|
||||
<div className="panel px-4 py-5 d-flex flex-column align-items-center community-container rounded">
|
||||
<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"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<img
|
||||
src="/images/landing/bg-dots.webp"
|
||||
alt="background dots"
|
||||
className="dots-left-bottom me-3"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Container>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ import { WebUrl } from "../../../../common/WebUrl";
|
||||
import { BeginStripeCheckoutFlow } from "../../../../common/BeginStripeCheckoutFlow";
|
||||
import { usePrefixedDocumentTitle } from "../../../../common/UsePrefixedDocumentTitle";
|
||||
import { PosthogClient } from "@storyteller/components/src/analytics/PosthogClient";
|
||||
import { Container, Panel } from "components/common";
|
||||
|
||||
interface Props {
|
||||
sessionWrapper: SessionWrapper;
|
||||
@@ -147,8 +148,8 @@ function PricingPage(props: Props) {
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="container pt-5 pb-4 text-center">
|
||||
<Container type="panel">
|
||||
<Panel clear={true} className="text-center my-5">
|
||||
<h1 className=" fw-bold">Pricing</h1>
|
||||
{/* <p className="fs-5">
|
||||
By purchasing FakeYou premium, you help us build more!
|
||||
@@ -157,8 +158,9 @@ function PricingPage(props: Props) {
|
||||
<FontAwesomeIcon icon={faHeart} className="text-red me-3" />
|
||||
By purchasing FakeYou premium, you help us build more!
|
||||
</div>
|
||||
</div>
|
||||
<div className="container mb-5">
|
||||
</Panel>
|
||||
|
||||
<Panel clear={true}>
|
||||
<div className="row gx-3 gy-4">
|
||||
{/* Starter Tier */}
|
||||
{/*<div className="col-12 col-sm-6 col-lg-3" >
|
||||
@@ -712,8 +714,8 @@ function PricingPage(props: Props) {
|
||||
</div>
|
||||
</div>
|
||||
</div> */}
|
||||
</div>
|
||||
</div>
|
||||
</Panel>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user