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