Basic Discord integration
All checks were successful
Deploy Site / docker (ubuntu-latest, 2.44.0) (push) Successful in 1m47s
All checks were successful
Deploy Site / docker (ubuntu-latest, 2.44.0) (push) Successful in 1m47s
This commit is contained in:
parent
adbc648d05
commit
65f8d0c189
@ -1,7 +1,2 @@
|
||||
# RainnnyCLUB
|
||||
My personal portfolio website hosted [here](https://rainnny.club)
|
||||
|
||||
## TODO
|
||||
- [x] Mobile Responsiveness
|
||||
- [ ] Discord Integration (Status, Activity, etc)
|
||||
- [ ] Add Configuration
|
||||
My personal portfolio website hosted [here](https://rainnny.club)
|
@ -7,6 +7,10 @@ const nextConfig = {
|
||||
protocol: "https",
|
||||
hostname: "cdn.rainnny.club",
|
||||
},
|
||||
{
|
||||
protocol: "https",
|
||||
hostname: "cdn.discordapp.com",
|
||||
},
|
||||
{
|
||||
protocol: "https",
|
||||
hostname: "bonfire.wtf",
|
||||
|
@ -25,7 +25,8 @@
|
||||
"react-dom": "^18",
|
||||
"sharp": "^0.33.5",
|
||||
"tailwind-merge": "^2.5.2",
|
||||
"tailwindcss-animate": "^1.0.7"
|
||||
"tailwindcss-animate": "^1.0.7",
|
||||
"use-lanyard": "^1.5.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5",
|
||||
|
@ -1,6 +1,9 @@
|
||||
import Greeting from "@/components/landing/greeting";
|
||||
import Navbar from "@/components/landing/navbar";
|
||||
import { ReactElement } from "react";
|
||||
import Navigation from "@/components/landing/navigation";
|
||||
import BlurFade from "@/components/ui/blur-fade";
|
||||
import DiscordStatus from "@/components/landing/discord-status";
|
||||
|
||||
const LandingPage = (): ReactElement => (
|
||||
<main className="h-screen flex flex-col">
|
||||
@ -13,6 +16,10 @@ const LandingPage = (): ReactElement => (
|
||||
}}
|
||||
>
|
||||
<Greeting />
|
||||
<BlurFade className="my-7" delay={1.25} inView>
|
||||
<Navigation />
|
||||
</BlurFade>
|
||||
<DiscordStatus />
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
|
89
src/components/landing/discord-status.tsx
Normal file
89
src/components/landing/discord-status.tsx
Normal file
@ -0,0 +1,89 @@
|
||||
"use client";
|
||||
|
||||
import { ReactElement } from "react";
|
||||
import { Activity, Data, DiscordUser, useLanyardWS } from "use-lanyard";
|
||||
import BlurFade from "@/components/ui/blur-fade";
|
||||
import Image from "next/image";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { PlayIcon } from "@heroicons/react/24/outline";
|
||||
|
||||
const statusColors = {
|
||||
online: "bg-green-500",
|
||||
idle: "bg-yellow-500",
|
||||
dnd: "bg-red-500",
|
||||
};
|
||||
|
||||
const DiscordStatus = (): ReactElement => {
|
||||
const discordData: Data | undefined = useLanyardWS("504147739131641857");
|
||||
const discordUser: DiscordUser | undefined = discordData?.discord_user;
|
||||
return (
|
||||
<div className="absolute left-4 bottom-4">
|
||||
{discordData && discordUser && (
|
||||
<BlurFade
|
||||
className="flex select-none pointer-events-none"
|
||||
delay={1.65}
|
||||
inView
|
||||
>
|
||||
{/* Avatar & Status */}
|
||||
<div className="relative z-50">
|
||||
<Image
|
||||
className="scale-110 rounded-full border"
|
||||
src={`https://cdn.discordapp.com/avatars/${discordUser.id}/${discordUser.avatar}.webp`}
|
||||
alt={`${discordUser.username}'s Discord Avatar`}
|
||||
width={60}
|
||||
height={60}
|
||||
/>
|
||||
{discordData.discord_status !== "offline" && (
|
||||
<div
|
||||
className={cn(
|
||||
"absolute bottom-1.5 right-1 w-2.5 h-2.5 bg-red-500 rounded-full",
|
||||
statusColors[discordData.discord_status]
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Username & Basic Activity */}
|
||||
<div className="-translate-x-7 p-2 pl-10 pr-6 flex flex-col justify-center bg-white/55 dark:bg-zinc-800/45 border rounded-r-3xl">
|
||||
<div className="flex gap-1 items-center">
|
||||
<h1 className="text-lg font-bold">
|
||||
{discordUser.display_name}
|
||||
</h1>
|
||||
<h2 className="opacity-65">
|
||||
{discordUser.username}
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
{discordData.activities.length > 0 && (
|
||||
<BasicActivityDisplay
|
||||
activity={discordData.activities[0]}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</BlurFade>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const BasicActivityDisplay = ({
|
||||
activity,
|
||||
}: {
|
||||
activity: Activity;
|
||||
}): ReactElement => {
|
||||
const prefix =
|
||||
activity.type === 0
|
||||
? "Playing"
|
||||
: activity.type === 1
|
||||
? "Streaming"
|
||||
: "Listening to";
|
||||
|
||||
return (
|
||||
<div className="flex gap-1.5 items-center text-sm">
|
||||
<span className="opacity-80">{prefix}</span> {activity.name}{" "}
|
||||
<PlayIcon className="text-blue-500" width={16} height={16} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default DiscordStatus;
|
@ -6,12 +6,12 @@ import moment, { Moment } from "moment";
|
||||
import Image from "next/image";
|
||||
import { ReactElement } from "react";
|
||||
import { FlipWords } from "@/components/ui/flip-words";
|
||||
import Navigation from "./navigation";
|
||||
|
||||
const Greeting = (): ReactElement => {
|
||||
const now: Moment = moment(Date.now());
|
||||
return (
|
||||
<section className="flex flex-col gap-5 items-center">
|
||||
{/* Picture */}
|
||||
<BlurFade delay={0.3} inView>
|
||||
<Image
|
||||
className="shadow-2xl shadow-blue-500 rounded-full scale-90 sm:scale-100 select-none pointer-events-none transition-all transform-gpu"
|
||||
@ -22,6 +22,7 @@ const Greeting = (): ReactElement => {
|
||||
/>
|
||||
</BlurFade>
|
||||
|
||||
{/* Intro */}
|
||||
<BlurFade delay={0.6} inView>
|
||||
<h1
|
||||
className={cn(
|
||||
@ -52,15 +53,11 @@ const Greeting = (): ReactElement => {
|
||||
"text-black dark:!text-transparent bg-clip-text bg-gradient-to-br from-zinc-300/85 to-white"
|
||||
)}
|
||||
words={[
|
||||
`A ${now.diff(moment([2002, 10, 13]), "years")} year old${" "}
|
||||
`A ${now.diff(moment([2002, 10, 13]), "years")} year old
|
||||
passionate software engineer living in Canada with ${moment([2016, 8, 1]).fromNow(true)} of experience!`,
|
||||
]}
|
||||
/>
|
||||
</BlurFade>
|
||||
|
||||
<BlurFade className="mt-3.5" delay={1.25} inView>
|
||||
<Navigation />
|
||||
</BlurFade>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
@ -64,7 +64,12 @@ const Navigation = (): ReactElement => {
|
||||
|
||||
{/* Selected Content */}
|
||||
{selected && (
|
||||
<BlurFade key={selected.name} delay={0.05} inView>
|
||||
<BlurFade
|
||||
key={selected.name}
|
||||
className="flex justify-center"
|
||||
delay={0.05}
|
||||
inView
|
||||
>
|
||||
<div className="mt-5">{selected.content}</div>
|
||||
</BlurFade>
|
||||
)}
|
||||
|
Loading…
x
Reference in New Issue
Block a user