diff --git a/package.json b/package.json index 9054e6d..035d157 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "dependencies": { "@types/escape-html": "^1.0.4", "escape-html": "^1.0.3", + "framer-motion": "^11.11.9", "ioredis": "^5.4.1", "next": "14.2.15", "react": "^18", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e5abf57..8893dec 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,6 +14,9 @@ importers: escape-html: specifier: ^1.0.3 version: 1.0.3 + framer-motion: + specifier: ^11.11.9 + version: 11.11.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1) ioredis: specifier: ^5.4.1 version: 5.4.1 @@ -856,6 +859,20 @@ packages: resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} engines: {node: '>=14'} + framer-motion@11.11.9: + resolution: {integrity: sha512-XpdZseuCrZehdHGuW22zZt3SF5g6AHJHJi7JwQIigOznW4Jg1n0oGPMJQheMaKLC+0rp5gxUKMRYI6ytd3q4RQ==} + peerDependencies: + '@emotion/is-prop-valid': '*' + react: ^18.0.0 + react-dom: ^18.0.0 + peerDependenciesMeta: + '@emotion/is-prop-valid': + optional: true + react: + optional: true + react-dom: + optional: true + fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} @@ -2756,6 +2773,13 @@ snapshots: cross-spawn: 7.0.3 signal-exit: 4.1.0 + framer-motion@11.11.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + tslib: 2.8.0 + optionalDependencies: + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + fs.realpath@1.0.0: {} fsevents@2.3.3: diff --git a/src/app/page.tsx b/src/app/page.tsx index 44ecab9..e84256a 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,6 +1,7 @@ "use client"; -import Image from "next/image"; -import React, { useState, useEffect, useRef } from "react"; +import React, { useState, useRef } from "react"; + +import { motion } from "framer-motion"; import { useSmoothCount } from "use-smooth-count"; import useSWR from "swr"; @@ -12,14 +13,17 @@ import Link from "next/link"; export default function Home() { const [userId, setUserId] = useState(null); const [userError, setUserError] = useState(); + const [userData, setUserData] = useState<{ userId: string } | null>(null); const [copyState, setCopyState] = useState("Copy"); const [outputType, setOutputType] = useState<"markdown" | "html">( "markdown", ); + const [isLoading, setIsLoading] = useState(true); + const [onImageLoaded, setOnImageLoaded] = useState(false); const userCount = useSWR("getUserCount", getUserCount); const countRef = useRef(null); - const counter = useSmoothCount({ + useSmoothCount({ ref: countRef, target: userCount.data || 0, duration: 3, @@ -28,9 +32,9 @@ export default function Home() { const outputText = () => { if (outputType === "html") { - return ``; + return ``; } else { - return `[![Discord Presence](https://lanyard-profile-readme.vercel.app/api/${userId})](https://discord.com/users/${userId})`; + return `[![Discord Presence](${window.location.origin}/api/${userData?.userId})](https://discord.com/users/${userData?.userId})`; } }; const copy = () => { @@ -40,17 +44,17 @@ export default function Home() { setTimeout(() => setCopyState("Copy"), 1500); }; - const changeDiscordId = async (e: React.ChangeEvent) => { - e.preventDefault(); - + const submitDiscordId = async () => { + setIsLoading(true); + setOnImageLoaded(false); + setUserData(null); setUserError(undefined); - setUserId(e.target.value); - if (e.target.value === "") return; - if (!isSnowflake(e.target.value)) - return setUserError("Invalid Discord ID"); + if (!userId) return setUserError("Please enter a Discord ID"); - if ((await isUserMonitored(e.target.value)) === false) + if (!isSnowflake(userId)) return setUserError("Invalid Discord ID"); + + if ((await isUserMonitored(userId)) === false) return setUserError( <> User is not being monitored by Lanyard, please join{" "} @@ -64,6 +68,9 @@ export default function Home() { and try again. , ); + + setUserData({ userId }); + setIsLoading(false); }; return ( @@ -78,53 +85,89 @@ export default function Home() { GitHub Profile


- - {userError && ( -

- * {userError} -

- )} - {userId && ( - <> -
- - -
-
- {outputText()} -
-
- - -
- {!userError && ( -
- Your Lanyard banner -
- )} - - )} +
{ + e.preventDefault(); + + submitDiscordId(); + }} + > + setUserId(e.target.value)} + value={userId || ""} + placeholder="Enter your Discord ID" + /> + +
+ + * {userError} + + +
+ + +
+
{outputText()}
+
+ + +
+
+ setOnImageLoaded(true)} + /> +
+