Only show the Discord status component when no navigation tab is active
All checks were successful
Deploy Site / docker (ubuntu-latest, 2.44.0) (push) Successful in 59s
All checks were successful
Deploy Site / docker (ubuntu-latest, 2.44.0) (push) Successful in 59s
This commit is contained in:
parent
e607a26197
commit
b04586caf2
@ -3,7 +3,6 @@ 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">
|
||||
@ -19,9 +18,6 @@ const LandingPage = (): ReactElement => (
|
||||
<BlurFade className="my-7" delay={1.25} inView>
|
||||
<Navigation />
|
||||
</BlurFade>
|
||||
<BlurFade delay={1.85} inView>
|
||||
<DiscordStatus />
|
||||
</BlurFade>
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
|
@ -11,9 +11,10 @@ import {
|
||||
import DCDNUser from "@/types/dcdn";
|
||||
import axios from "axios";
|
||||
import Image from "next/image";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { cn, truncateText } from "@/lib/utils";
|
||||
import moment from "moment";
|
||||
import { PuzzlePieceIcon } from "@heroicons/react/24/outline";
|
||||
import SimpleTooltip from "@/components/ui/simple-tooltip";
|
||||
|
||||
const statusColors = {
|
||||
online: "bg-green-500",
|
||||
@ -25,15 +26,26 @@ const statusColors = {
|
||||
const userBadges = {
|
||||
// Nitro
|
||||
"https://cdn.discordapp.com/badge-icons/2ba85e8026a8614b640c2837bcdfe21b.png":
|
||||
(dcdnUser: DCDNUser) => dcdnUser.premiumType,
|
||||
{
|
||||
name: "Nitro Subscriber",
|
||||
predicate: (dcdnUser: DCDNUser) => dcdnUser.premiumType,
|
||||
},
|
||||
|
||||
// Early Supporter
|
||||
"https://cdn.discordapp.com/badge-icons/7060786766c9c840eb3019e725d2b358.png":
|
||||
(dcdnUser: DCDNUser) => (dcdnUser.flags & (1 << 9)) === 1 << 9,
|
||||
{
|
||||
name: "Early Supporter",
|
||||
predicate: (dcdnUser: DCDNUser) =>
|
||||
(dcdnUser.flags & (1 << 9)) === 1 << 9,
|
||||
},
|
||||
|
||||
// Active Developer
|
||||
"https://cdn.discordapp.com/badge-icons/6bdc42827a38498929a4920da12695d9.png":
|
||||
(dcdnUser: DCDNUser) => (dcdnUser.flags & (1 << 22)) === 1 << 22,
|
||||
{
|
||||
name: "Active Developer",
|
||||
predicate: (dcdnUser: DCDNUser) =>
|
||||
(dcdnUser.flags & (1 << 22)) === 1 << 22,
|
||||
},
|
||||
};
|
||||
|
||||
const DiscordStatus = (): ReactElement | undefined => {
|
||||
@ -141,21 +153,24 @@ const BannerAvatar = ({
|
||||
);
|
||||
|
||||
const Bio = ({ dcdnUser }: { dcdnUser: DCDNUser }): ReactElement => (
|
||||
<div className="p-2 bg-zinc-950/65 text-sm rounded-xl">{dcdnUser.bio}</div>
|
||||
<div className="p-2 bg-zinc-950/65 text-sm rounded-xl">
|
||||
{truncateText(dcdnUser.bio, 15)}
|
||||
</div>
|
||||
);
|
||||
|
||||
const Badges = ({ dcdnUser }: { dcdnUser: DCDNUser }): ReactElement => (
|
||||
<div className="ml-auto flex gap-1">
|
||||
{Object.entries(userBadges)
|
||||
.filter(([_, predicate]) => predicate(dcdnUser))
|
||||
.map(([badge], index) => (
|
||||
<Image
|
||||
key={index}
|
||||
src={badge}
|
||||
alt="Discord Profile Badge"
|
||||
width={22}
|
||||
height={22}
|
||||
/>
|
||||
.filter(([_, badge]) => badge.predicate(dcdnUser))
|
||||
.map(([badgeIcon, badge], index) => (
|
||||
<SimpleTooltip key={index} content={badge.name}>
|
||||
<Image
|
||||
src={badgeIcon}
|
||||
alt="Discord Profile Badge"
|
||||
width={22}
|
||||
height={22}
|
||||
/>
|
||||
</SimpleTooltip>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
@ -177,17 +192,16 @@ const SpotifyActivity = ({ spotify }: { spotify: Spotify }): ReactElement => {
|
||||
const startTimestamp: number = spotify.timestamps.start; // Example start timestamp
|
||||
const endTimestamp: number = spotify.timestamps.end; // Example end timestamp
|
||||
const [songProgress, setSongProgress] = useState<string | undefined>();
|
||||
const songDuration: string = moment(endTimestamp - startTimestamp).format(
|
||||
"m:ss"
|
||||
);
|
||||
const songDuration: number = endTimestamp - startTimestamp;
|
||||
|
||||
// Update the song progress every second
|
||||
useEffect(() => {
|
||||
const interval = setInterval(() => {
|
||||
const songProgress: string = moment(
|
||||
Date.now() - startTimestamp
|
||||
).format("m:ss");
|
||||
setSongProgress(songProgress);
|
||||
const songProgress = Date.now() - startTimestamp;
|
||||
if (songProgress > songDuration) {
|
||||
return;
|
||||
}
|
||||
setSongProgress(moment(songProgress).format("m:ss"));
|
||||
}, 1000);
|
||||
return () => clearInterval(interval);
|
||||
}, [startTimestamp]);
|
||||
@ -206,10 +220,14 @@ const SpotifyActivity = ({ spotify }: { spotify: Spotify }): ReactElement => {
|
||||
|
||||
{/* Track Info */}
|
||||
<div className="flex flex-col text-sm">
|
||||
<h1 className="font-bold leading-none">{spotify.song}</h1>
|
||||
<h2 className="font-light opacity-70">{spotify.artist}</h2>
|
||||
<h1 className="font-bold leading-none">
|
||||
{truncateText(spotify.song, 24)}
|
||||
</h1>
|
||||
<h2 className="font-light opacity-70">
|
||||
{truncateText(spotify.artist.replace(";", ","), 26)}
|
||||
</h2>
|
||||
<p className="text-xs font-light opacity-70">
|
||||
{songProgress} / {songDuration}
|
||||
{songProgress} / {moment(songDuration).format("m:ss")}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -9,6 +9,7 @@ import { ReactElement } from "react";
|
||||
import Project from "@/types/project";
|
||||
import { ScrollArea } from "@/components/ui/scroll-area";
|
||||
import Image from "next/image";
|
||||
import { truncateText } from "@/lib/utils";
|
||||
|
||||
const projects: Project[] = [
|
||||
{
|
||||
@ -111,8 +112,8 @@ const MyWork = (): ReactElement => {
|
||||
</div>
|
||||
|
||||
{/* Description */}
|
||||
<p className="mt-2.5 line-clamp-3 text-black dark:!text-transparent bg-clip-text bg-gradient-to-br from-zinc-300/80 to-white">
|
||||
{project.description}
|
||||
<p className="mt-2.5 text-black dark:!text-transparent bg-clip-text bg-gradient-to-br from-zinc-300/80 to-white">
|
||||
{truncateText(project.description, 136)}
|
||||
</p>
|
||||
</MagicCard>
|
||||
</Link>
|
||||
|
@ -23,7 +23,7 @@ import BlurFade from "@/components/ui/blur-fade";
|
||||
|
||||
const Navbar = (): ReactElement => (
|
||||
<BlurFade className="pt-1 z-50" delay={1.35} inView>
|
||||
<nav className="px-3 xs:px-7 py-4 flex gap-3 xs:gap-10 sm:gap-14 justify-center items-center bg-background border-b transition-all transform-gpu">
|
||||
<nav className="px-3 xs:px-7 py-3 flex gap-3 xs:gap-10 sm:gap-14 justify-center items-center bg-background border-b transition-all transform-gpu">
|
||||
<Branding />
|
||||
<Links />
|
||||
<ThemeSwitcher />
|
||||
|
@ -13,6 +13,7 @@ import HomelabContent from "./nav-content/homelab";
|
||||
import Skills from "./nav-content/skills";
|
||||
import MyWork from "./nav-content/my-work";
|
||||
import NavigationItem from "@/types/navigation";
|
||||
import DiscordStatus from "@/components/landing/discord-status";
|
||||
|
||||
const items: NavigationItem[] = [
|
||||
{
|
||||
@ -63,16 +64,20 @@ const Navigation = (): ReactElement => {
|
||||
</div>
|
||||
|
||||
{/* Selected Content */}
|
||||
{selected && (
|
||||
<BlurFade
|
||||
key={selected.name}
|
||||
className="flex justify-center"
|
||||
delay={0.05}
|
||||
inView
|
||||
>
|
||||
<div className="mt-5">{selected.content}</div>
|
||||
</BlurFade>
|
||||
)}
|
||||
<BlurFade className="mt-5" delay={1.85} inView>
|
||||
{selected ? (
|
||||
<BlurFade
|
||||
key={selected.name}
|
||||
className="flex justify-center"
|
||||
delay={0.05}
|
||||
inView
|
||||
>
|
||||
{selected.content}
|
||||
</BlurFade>
|
||||
) : (
|
||||
<DiscordStatus />
|
||||
)}
|
||||
</BlurFade>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -4,3 +4,15 @@ import { twMerge } from "tailwind-merge";
|
||||
export function cn(...inputs: ClassValue[]) {
|
||||
return twMerge(clsx(inputs));
|
||||
}
|
||||
|
||||
export function truncateText(
|
||||
text: string | undefined,
|
||||
maxLength: number
|
||||
): string | undefined {
|
||||
if (!text) {
|
||||
return undefined;
|
||||
}
|
||||
return text.length > maxLength
|
||||
? text.slice(0, maxLength - 3).trim() + "..."
|
||||
: text;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user