Skip to content

Commit

Permalink
refactor: optimize Spotify Component and Added Tan Stack Query React!
Browse files Browse the repository at this point in the history
  • Loading branch information
Redskull-127 committed Jul 23, 2024
1 parent 4f9c06b commit 90ed81d
Show file tree
Hide file tree
Showing 13 changed files with 346 additions and 112 deletions.
51 changes: 29 additions & 22 deletions app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { TailwindIndicator } from '@/lib/taillwind-indicator';
import { CSPostHogProvider } from '@/lib/client/providers/Posthog';
import { IntroDialogProvider } from '@/lib/client/providers/intro-provider';
import { siteConfig } from '@/site-config';
import TanstackProvider from '@/lib/client/providers/TanstackProvider';
const santoshiSans = localFont({
src: './Satoshi-Variable.woff2',
display: 'swap',
Expand Down Expand Up @@ -84,28 +85,34 @@ export default function RootLayout({ children }: Children) {
santoshiSans.className,
)}
>
<IntroDialogProvider>
<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
<SpeedInsights />
<NextAuthProvider>
<ConnectivityStatus>
<ChromeCastProvider>
<DynamicIsland />
<DriverProvider>
<main className="flex flex-wrap gap-8 h-screen w-screen font-sans p-10 max-xl:gap-5 max-xl:px-5">
<RootComponent />
{children}
<Analytics />
<TailwindIndicator />
</main>
</DriverProvider>
<Toaster />
<Sonner />
</ChromeCastProvider>
</ConnectivityStatus>
</NextAuthProvider>
</ThemeProvider>
</IntroDialogProvider>
<TanstackProvider>
<IntroDialogProvider>
<ThemeProvider
attribute="class"
defaultTheme="system"
enableSystem
>
<SpeedInsights />
<NextAuthProvider>
<ConnectivityStatus>
<ChromeCastProvider>
<DynamicIsland />
<DriverProvider>
<main className="flex flex-wrap gap-8 h-screen w-screen font-sans p-10 max-xl:gap-5 max-xl:px-5">
<RootComponent />
{children}
<Analytics />
<TailwindIndicator />
</main>
</DriverProvider>
<Toaster />
<Sonner />
</ChromeCastProvider>
</ConnectivityStatus>
</NextAuthProvider>
</ThemeProvider>
</IntroDialogProvider>
</TanstackProvider>
</body>
</CSPostHogProvider>
</html>
Expand Down
Binary file modified bun.lockb
Binary file not shown.
30 changes: 21 additions & 9 deletions components/Root-Partials/index.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
import Link from 'next/link';
import { SpotifySelfApi, SpotifyType } from '@/lib/server/functions/spotify';
import { Icons } from '../icons/icons';
import { Discord, GitHub, Gmail, LinkedIn, X } from '../icons/AnimatedIcons';
import SkillModel from './skill/SkillModel';
import { Settings as Controls } from '@/lib/client/functions/settings';
import { GitHubAPI, GitHubType } from '@/lib/server/functions/github';
import { ProjectLists } from './project/ProjectLists';
import SpotifyComponent, {
SpotifyComponentError,
} from './spotify/SpotifyComponent';
import SpotifyComponent from './spotify/SpotifyComponent';
import Avatar3D from './3D-avatar';
import { getTotalVisits } from '@/lib/server/google/apis/search-analytics';
import { siteConfig } from '@/site-config';
import {
QueryClient,
HydrationBoundary,
dehydrate,
} from '@tanstack/react-query';
import { SpotifySelfApi } from '@/lib/server/functions/spotify';

export function HeroCard() {
return (
<div className="max-xl:w-full xl:min-w-[25%] flex flex-col justify-end items-center h-80 shadow-lg shadow-[#248F68] rounded-2xl gap-5 bg-[#248F68] text-white">
Expand Down Expand Up @@ -69,11 +73,19 @@ export function QuickLinks() {
}

export async function SpotifyCard() {
const data: SpotifyType | Error | undefined = await SpotifySelfApi();
if (data instanceof Error || data === undefined || data === null) {
return <SpotifyComponentError />;
}
return <SpotifyComponent {...data} />;
const queryClient = new QueryClient();
await queryClient.prefetchQuery({
queryKey: ['spotifyData'],
queryFn: () => SpotifySelfApi('shuffle'),
});
const dehydratedState = dehydrate(queryClient);

return (
<HydrationBoundary state={dehydratedState}>
{' '}
<SpotifyComponent />{' '}
</HydrationBoundary>
);
}

export function Skills() {
Expand Down
84 changes: 67 additions & 17 deletions components/Root-Partials/spotify/Audio.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { useRef, useState, useEffect, useCallback } from 'react';
import { Icons } from '../../icons/icons';
import { toast } from 'sonner';
import { SkipForward, Volume } from 'lucide-react';
import { SkipForward, VolumeX, Volume1, Volume2, Settings } from 'lucide-react';
import { Slider } from '@/components/ui/slider';
import {
DropdownMenu,
Expand All @@ -11,14 +11,16 @@ import {
DropdownMenuSeparator,
DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import { getNewSong } from '@/lib/server/functions/spotify';
import { Tabs, TabsList, TabsTrigger } from '@/components/ui/tabs';
import {
HoverCard,
HoverCardContent,
HoverCardTrigger,
} from '@/components/ui/hover-card';
import { useCastContext } from '@/lib/client/providers/CastProvider';
import clsx from 'clsx';
import { SwitchModes } from '@/lib/server/functions/spotify-switch';
import { useMutation, useQueryClient } from '@tanstack/react-query';

type AudioButtonType = {
AudioSRC: string;
Expand All @@ -27,6 +29,7 @@ type AudioButtonType = {
image: string;
disabled?: boolean;
status?: 'now-playing' | 'shuffle';
setStatus?: React.Dispatch<React.SetStateAction<'shuffle' | 'now-playing'>>;
};

type AudioButtonProps = 'playing' | 'paused' | 'stopped' | 'new-song';
Expand All @@ -37,6 +40,13 @@ export default function AudioButton(props: AudioButtonType) {
const audioRef = useRef<HTMLAudioElement>(null);
const [audioVolume, setAudioVolume] = useState<number>();
const [audioCurrDuration, setAudioCurrDuration] = useState<number>();
const queryClient = useQueryClient();

const getNewSong = useCallback(async () => {
await queryClient.invalidateQueries({
queryKey: ['spotifyData'],
});
}, [queryClient]);

const handleStop = useCallback(() => {
setPlaying('stopped');
Expand All @@ -45,11 +55,22 @@ export default function AudioButton(props: AudioButtonType) {
action: {
label: 'Play Next',
onClick: async () => {
await getNewSong();
if (props.status === 'now-playing') {
return toast.info('Meer is currently listening to this song!', {
description: 'Switch to shuffle mode to skip to the next song!',
});
} else {
setPlaying('new-song');
return toast.promise(getNewSong(), {
loading: 'Loading next song...',
success: 'Next song loaded!',
error: 'Error loading next song!',
});
}
},
},
});
}, [props.name]);
}, [getNewSong, props.name, props.status]);

const handlePlay = useCallback(() => {
const ref = audioRef.current;
Expand Down Expand Up @@ -168,21 +189,50 @@ export default function AudioButton(props: AudioButtonType) {
<div className="w-full gap-7 flex justify-center items-center">
<DropdownMenu>
<DropdownMenuTrigger>
<Volume className="cursor-pointer h-5 w-5 " />
<Settings className="cursor-pointer h-5 w-5 " />
</DropdownMenuTrigger>
<DropdownMenuContent>
<DropdownMenuLabel>Audio controls</DropdownMenuLabel>
<DropdownMenuContent className="space-y-1">
<DropdownMenuLabel>Settings</DropdownMenuLabel>
<DropdownMenuSeparator />
<Slider
className="p-2"
onValueChange={(e) => {
window.localStorage.setItem('audioVolume', e[0].toString());
setAudioVolume(e[0]);
<Tabs
onValueChange={async (e) => {
toast.promise(
SwitchModes(e as 'shuffle' | 'now-playing', props.setStatus!),
{
loading: 'Switching modes...',
success: `Switched to ${e} mode!`,
error:
e === 'shuffle'
? 'Error switching to shuffle mode!'
: 'Ah snap! Meer is not playing currently :(',
},
);
}}
defaultValue={[audioVolume!]}
max={100}
step={1}
/>
defaultValue={props.status ?? 'shuffle'}
>
<TabsList>
<TabsTrigger value="shuffle">Shuffle</TabsTrigger>
<TabsTrigger value="now-playing">Now Playing</TabsTrigger>
</TabsList>
</Tabs>
<div className="flex p-2 gap-1">
{audioVolume === 0 ? (
<VolumeX className="size-5" />
) : audioVolume! < 50 ? (
<Volume1 className="size-5" />
) : (
<Volume2 className="size-5" />
)}
<Slider
onValueChange={(e) => {
window.localStorage.setItem('audioVolume', e[0].toString());
setAudioVolume(e[0]);
}}
defaultValue={[audioVolume!]}
max={100}
step={1}
/>
</div>
</DropdownMenuContent>
</DropdownMenu>

Expand Down Expand Up @@ -249,7 +299,7 @@ export default function AudioButton(props: AudioButtonType) {
'Meer is currently listening to this song!',
{
description:
'Implementing the mode switching in next update.',
'Switch to shuffle mode to skip to the next song!',
},
);
} else {
Expand Down
16 changes: 6 additions & 10 deletions components/Root-Partials/spotify/LyricsButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,12 @@ export default function LyricsButton({
<DialogDescription>
{song} - {name}
<div className="pt-8">
{lyrics && lyrics !== '' ? (
<ScrollArea className="h-96">
<p
className="text-ternary text-lg whitespace-pre-line"
dangerouslySetInnerHTML={{ __html: lyrics }}
/>
</ScrollArea>
) : (
<p>No lyrics found. :(</p>
)}
<ScrollArea className="h-96">
<p
className="text-ternary text-lg whitespace-pre-line"
dangerouslySetInnerHTML={{ __html: lyrics }}
/>
</ScrollArea>
</div>
</DialogDescription>
</DialogHeader>
Expand Down
Loading

0 comments on commit 90ed81d

Please sign in to comment.