Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ENG-3589 chore(portal): add terminal text animation to the big bang #825

Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
136 changes: 92 additions & 44 deletions apps/portal/app/routes/the-big-bang.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { useEffect, useMemo, useState } from 'react'

import {
Button,
ButtonSize,
Expand All @@ -9,12 +11,13 @@ import { ApiError, IdentitiesService } from '@0xintuition/api'

import PrivyLogout from '@client/privy-logout'
import { Header } from '@components/header'
import { PATHS } from '@consts/paths'
import { getMaintenanceMode } from '@lib/utils/maintenance'
import { LoaderFunctionArgs, redirect } from '@remix-run/node'
import { json, Link, useLoaderData } from '@remix-run/react'
import { fetchWrapper } from '@server/api'
import { requireUserWallet } from '@server/auth'
import { PATHS } from 'app/consts'
import { motion } from 'framer-motion'

export async function loader({ request }: LoaderFunctionArgs) {
getMaintenanceMode()
Expand Down Expand Up @@ -48,59 +51,104 @@ export async function loader({ request }: LoaderFunctionArgs) {
return json({ wallet })
}

const TerminalText = ({
text,
delay = 50,
}: {
text: string
delay?: number
}) => {
const [displayText, setDisplayText] = useState('')

useEffect(() => {
let currentIndex = 0
const intervalId = setInterval(() => {
if (currentIndex <= text.length) {
setDisplayText(text.slice(0, currentIndex))
currentIndex++
} else {
clearInterval(intervalId)
}
}, delay)

return () => {
clearInterval(intervalId)
}
}, [text, delay])

return <span>{displayText}</span>
}

export default function WelcomePage() {
const { wallet } = useLoaderData<typeof loader>()
const [currentParagraph, setCurrentParagraph] = useState(0)
const paragraphs = useMemo(
() => [
'In the beginning, there was nothing. Then suddenly - everything.',
'All that the universe would ever be composed of, birthed into existence, in an instant.',
'A single spec of condensed matter, exploding into a vast universe.',
'While energy would neither be created nor destroyed, the interplay between these newly created atoms would go on to create something beautiful...',
'What was made separate would once again become whole. And what would be created in the process would be even more beautiful than what came before...',
"Our story begins with the 'atom'.",
'The fundamental building block of our universe.',
"And our 'atoms' begin with you.",
],
[],
)

useEffect(() => {
if (currentParagraph < paragraphs.length - 1) {
const timer = setTimeout(() => {
setCurrentParagraph((prevParagraph) => prevParagraph + 1)
}, paragraphs[currentParagraph].length * 50)

return () => {
clearTimeout(timer)
}
}
}, [currentParagraph, paragraphs])

const allParagraphsDisplayed = currentParagraph === paragraphs.length - 1

return (
<div className="flex flex-col min-h-screen w-full p-8">
<Header />
<div className="flex-grow flex justify-center items-center">
<div className="flex-col justify-start items-start inline-flex gap-6">
<h1 className="text-4xl font-bold mb-6 text-center md:text-left">
<div className="flex-col justify-start items-start inline-flex gap-6 relative">
<h1 className="text-4xl font-bold mb-4 md:mb-6 text-center md:text-left">
Chapter 0: The Big Bang
</h1>
<div className="max-w-2xl space-y-2">
<Text variant={TextVariant.bodyLarge} className="text-primary/70">
In the beginning, there was nothing. Then suddenly - everything.
</Text>
<Text variant={TextVariant.bodyLarge} className="text-primary/70">
All that the universe would ever be composed of, birthed into
existence, in an instant.
</Text>
<Text variant={TextVariant.bodyLarge} className="text-primary/70">
A single spec of condensed matter, exploding into a vast universe.
</Text>
<Text variant={TextVariant.bodyLarge} className="text-primary/70">
While energy would neither be created nor destroyed, the interplay
between these newly created atoms would go on to create something
beautiful...
</Text>
<Text variant={TextVariant.bodyLarge} className="text-primary/70">
What was made separate would once again become whole. And what
would be created in the process would be even more beautiful than
what came before...
</Text>
</div>
<div className="mt-6 space-y-2">
<Text variant={TextVariant.bodyLarge} className="text-primary/70">
Our story begins with the &lsquo;atom&rsquo;.
</Text>
<Text variant={TextVariant.bodyLarge} className="text-primary/70">
The fundamental building block of our universe.
</Text>
<Text variant={TextVariant.bodyLarge} className="text-primary/70">
And our &lsquo;atoms&rsquo; begin with you.
</Text>
<div className="w-full md:w-[675px] h-[600px] md:h-[360px] space-y-1.5 md:space-y-2 relative">
{paragraphs
.slice(0, currentParagraph + 1)
.map((paragraph, index) => (
<Text
key={index}
variant={TextVariant.bodyLarge}
className="text-primary/70"
>
<TerminalText text={paragraph} />
</Text>
))}
{allParagraphsDisplayed && (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ delay: 2, duration: 3 }}
className="absolute bottom-[-10px] left-0 right-0 mt-8 md:bottom-[-60px] md:left-0 md:right-0"
>
<Link to="/create">
<Button
variant={ButtonVariant.primary}
size={ButtonSize.lg}
className="w-40 m-auto"
>
Begin
</Button>
</Link>
</motion.div>
)}
</div>
<Link to="/create" className="m-auto mt-6">
<Button
variant={ButtonVariant.primary}
size={ButtonSize.lg}
className="w-40 m-auto"
>
Begin
</Button>
</Link>
</div>
</div>
<PrivyLogout wallet={wallet} />
Expand Down
Loading