Skip to content

Commit a31f4f9

Browse files
Minimal update
Mainly just UI fixes and some backend stuff that doesn't really matter. Tomorrow I will add support for mobile in a way similar to music players. So, when you go to your notification tray, there will the album cover, title, the option to skip, go back, etc. It will be really cool to use the website after this. Maybe I can even turn this into a community driven platform for all sorts of albums. Also, now Yandhi is fully fixed, so now I can continue to add more albums. Sorting options in main page coming soon!
1 parent 0790e42 commit a31f4f9

18 files changed

+270
-103
lines changed

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ If you have any suggestions on missing songs/albums, please, create an issue tic
77
## Goals
88

99
### Missing albums
10-
- [x] Yandhi (kinda done because some songs are missing)
10+
- [x] Yandhi
1111
- [ ] Turbografx 16
1212
- [ ] Swish
1313
- [ ] Good Ass Job
@@ -33,7 +33,7 @@ If you have any suggestions on missing songs/albums, please, create an issue tic
3333
- [x] Full mobile music player experience
3434
- [x] Good home page with all the necessary stuff
3535
- [ ] Proper backstory of each album
36-
- [x] Continuous playback and shuffle support (kinda eefy but works)
36+
- [x] Continuous playback ~~and shuffle support~~ (kinda eefy but works)
3737
- [x] Search bar
3838
- [ ] Sort albums by latest or oldest
3939
- [ ] Backend for explanation of albums

app/album/[id]/page.tsx

+10-6
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import { Input } from '@/components/ui/input';
1010
import AlbumCover from '@/components/getAverageColor';
1111
import { SongControls } from '@/components/songControls';
1212

13+
import '@public/CSS/song-controls.css';
14+
1315
interface Song {
1416
title: string;
1517
artist: string;
@@ -35,7 +37,7 @@ export default function Page({ params }: { params: Promise<{ id: string }> }) {
3537
const [songVal, setSongVal] = useState("");
3638
const [queue, setQueue] = useState<string[]>([]);
3739
const [currentSongIndex, setCurrentSongIndex] = useState(-1);
38-
const [albumName, setAlbumName] = useState(id);
40+
const [albumName, setAlbumName] = useState(id.replace('-', ' '));
3941
const [albumCreator, setAlbumCreator] = useState("Kanye West");
4042
const [credits, setCredits] = useState("");
4143
const [imageSize, setImageSize] = useState(250);
@@ -183,7 +185,7 @@ export default function Page({ params }: { params: Promise<{ id: string }> }) {
183185
const handleSongEnd = () => {
184186
if (!songRef.current || songs.length === 0) return;
185187
const newIndex = currentSongIndex + 1;
186-
188+
187189
setCurrentSongIndex(newIndex);
188190
setSongVal(songs[newIndex].songLocation);
189191
setSongCreator(songs[newIndex].artist);
@@ -231,7 +233,7 @@ export default function Page({ params }: { params: Promise<{ id: string }> }) {
231233
<div className='flex flex-col md:flex-row items-center gap-5'>
232234
<Image src={`/song-files/covers/${id.toLowerCase()}.jpg`} alt={id} width={imageSize} height={imageSize} className='md:mt-4 rounded-xl outline outline-primary/10' />
233235
<div className='flex flex-col gap-2'>
234-
<div className='text-4xl font-bold text-center md:text-left'>{albumName}</div>
236+
<div className='text-4xl font-semibold text-center md:text-left'>{albumName}</div>
235237
<div className='inline-flex items-center justify-center md:justify-normal'>
236238
<div className='text-md md:text-xl text-primary/75 whitespace-pre text-center md:text-left'>{albumCreator}</div>
237239
<Dot className='text-primary/75' />
@@ -261,7 +263,7 @@ export default function Page({ params }: { params: Promise<{ id: string }> }) {
261263
<Search size={16} strokeWidth={2} className=' text-muted-foreground/80' />
262264
</div>
263265
</div>
264-
<div className='border-2 border-secondary rounded-lg bg-primary-foreground/60 mb-20 md:mb-24'>
266+
<div className='border-2 border-secondary rounded-lg bg-primary-foreground/60 mb-20 md:mb-20'>
265267
{filteredContent.map((element, index) => (
266268
<div key={index} className={`flex gap-2 border-b-2 px-2 border-b-secondary last-of-type:border-b-transparent p-2 items-center transition-colors list-${index} ${currentSongIndex === index ? 'bg-primary/20 border-b-transparent' : ''}`} onClick={() => handleClickEvent(element, index)}>
267269
<div className='flex items-center gap-4'>
@@ -270,8 +272,10 @@ export default function Page({ params }: { params: Promise<{ id: string }> }) {
270272
</div>
271273
<div className='relative w-full items-center ml-6 md:ml-2 select-none'>
272274
<div className='flex justify-between w-full'>
273-
<div className='flex items-center'>
274-
<div className='text-sm md:text-md font-bold'>{element.title}</div>
275+
<div className="flex items-center w-full">
276+
<div className="text-sm md:text-md font-semibold whitespace-nowrap overflow-hidden text-ellipsis tracking-wide">
277+
{element.title}
278+
</div>
275279
<Dot className='-mx-1 hidden md:block text-primary/60' />
276280
<div className='text-sm md:text-md hidden md:block text-primary/50'>({element.songLocation.toString().split('/song-files/songs/')})</div>
277281
</div>

app/globals.css

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
@tailwind utilities;
44

55
body {
6-
font-family: 'Geist', Helvetica, sans-serif;
6+
font-family: var(--font-inter-sans), var(--font-geist-sans), Helvetica, sans-serif;
77
transition: scale opacity;
88
transition-timing-function: ease-in-out;
99
transition-duration: 400ms;

app/layout.tsx

+17-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { Metadata } from "next";
22
import localFont from 'next/font/local'
3-
import { IBM_Plex_Mono, Geist, Geist_Mono } from 'next/font/google'
3+
import { IBM_Plex_Mono, Geist, Geist_Mono, Inter } from 'next/font/google'
44
import "./globals.css";
55
import { ThemeProvider } from "@/components/themeProvider"
66
import NextTopLoader from 'nextjs-toploader';
@@ -10,8 +10,21 @@ const yeezy = localFont({
1010
})
1111

1212
const IBMPlexMono = IBM_Plex_Mono({ weight: ['400'], subsets: ['latin'] })
13-
const geist = Geist({ subsets: ['latin'] })
14-
const geistMono = Geist_Mono({ subsets: ['latin'] })
13+
const geistSans = Geist({
14+
variable: "--font-geist-sans",
15+
subsets: ["latin"],
16+
});
17+
18+
const geistMono = Geist_Mono({
19+
variable: "--font-geist-mono",
20+
subsets: ["latin"],
21+
});
22+
23+
const inter = Inter({
24+
weight: ['400', '900'],
25+
subsets: ['latin'],
26+
variable: "--font-inter-sans"
27+
})
1528

1629
export const metadata: Metadata = {
1730
title: "UnYeleased",
@@ -26,7 +39,7 @@ export default function RootLayout({
2639
return (
2740
<html lang="en" suppressHydrationWarning>
2841
<body
29-
className={`${geist.className} antialiased overflow-x-hidden`}
42+
className={`${inter.variable} ${geistSans.variable} ${geistMono.variable} antialiased overflow-x-hidden`}
3043
>
3144
<ThemeProvider
3245
attribute="class"

components/overrideComponents.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
function CustomH1({ children }: { children: React.ReactNode }) {
22
return (
3-
<h1 className='text-5xl py-4 font-bold mt-10'>{children}</h1>
3+
<h1 className='text-4xl py-4 font-semibold mt-10'>{children}</h1>
44
)
55
}
66

@@ -18,7 +18,7 @@ function CustomH3({ children }: { children: React.ReactNode }) {
1818

1919
function CustomP({ children }: { children: React.ReactNode }) {
2020
return (
21-
<p className='text-xl py-4'>{children}</p>
21+
<p className='text-md py-4 line leading-8'>{children}</p>
2222
)
2323
}
2424

components/songControls.tsx

+87-56
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import AlbumCover from "@/components/getAverageColor";
99
import { Drawer, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerTitle, DrawerTrigger } from "./ui/drawer";
1010
import { Progress } from "./ui/progress";
1111

12+
import '@public/CSS/song-controls.css';
13+
1214
interface songControlsInterface {
1315
songRef: any;
1416
songVal: string;
@@ -138,8 +140,8 @@ export const SongControls = ({
138140
<>
139141
{!mediumScreen ? (
140142
<div
141-
className={`fixed bottom-2 rounded-2xl w-full max-w-[93.5vw]
142-
left-1/2 -translate-x-1/2 py-6 px-5 bg-primary-foreground/80 backdrop-blur-lg border-2 border-t-secondary
143+
className={`fixed bottom-2 rounded-2xl w-full max-w-[93vw]
144+
left-1/2 -translate-x-1/2 py-3 px-3 bg-primary-foreground/80 backdrop-blur-lg border-2 border-secondary
143145
flex items-center transition-all duration-500 shadow-lg ${appearBar ? "translate-y-0" : "translate-y-24"
144146
}`}
145147
// onClick={hideControls}
@@ -168,8 +170,8 @@ export const SongControls = ({
168170
<Drawer>
169171
<DrawerTrigger asChild>
170172
<div
171-
className={`fixed bottom-2 rounded-2xl w-full max-w-[93.5vw] left-1/2 -translate-x-1/2
172-
py-3 px-3 bg-primary-foreground/80 backdrop-blur-lg border-2 border-secondary flex items-center transition-all duration-500 shadow-lg
173+
className={`fixed bottom-2 rounded-2xl w-full max-w-[88vw] left-1/2 -translate-x-1/2
174+
bg-primary-foreground/80 backdrop-blur-lg border-2 border-secondary flex items-center transition-all duration-500 shadow-lg overflow-hidden
173175
${appearBar ? "translate-y-0" : "translate-y-24"
174176
}`}
175177
>
@@ -188,10 +190,6 @@ export const SongControls = ({
188190
setOptAppear={setOptAppear}
189191
id={id}
190192
/>
191-
<Progress
192-
value={sliderValue}
193-
className="w-[96%] absolute bottom-1 left-2 transition-all duration-1000"
194-
/>
195193
</div>
196194
</DrawerTrigger>
197195
<DrawerContent className="">
@@ -307,34 +305,32 @@ const DefaultSongControls = ({
307305
};
308306
}, [handleSkipSong, hideControls]);
309307

310-
console.log(songTime);
311-
312308
return (
313309
<>
314310
<div className="flex w-full justify-between items-center">
315-
<div className="flex items-center gap-2 select-none w-full">
311+
<div className="flex items-center gap-3 select-none w-full">
316312
<Image src={image} alt={image} width={80} height={80} className="rounded-lg" />
317313
<div>
318-
<div className="font-bold">
314+
<div className="font-semibold tracking-wide">
319315
{songVal !== "" ? songVal : "No Track Found"}
320316
</div>
321317
<div className="text-sm text-muted-foreground">{songCreator}</div>
322318
</div>
323319
</div>
324320

325-
<div className="flex flex-col justify-center gap-3">
321+
<div className="flex flex-col justify-center gap-1 w-full">
326322
<div className="flex justify-center gap-2 ml-2">
327323
<Button
328324
size="icon"
329-
className={`p-6 rounded-full ${songVal !== "" ? "" : "opacity-50 cursor-not-allowed"}`}
325+
className={`p-5 rounded-full ${songVal !== "" ? "" : "opacity-50 cursor-not-allowed"}`}
330326
variant="ghost"
331327
onClick={() => handleSkipSong(true)}
332328
onKeyDown={() => pressedKeyOne}
333329
>
334330
<SkipBack />
335331
</Button>
336332
<Button
337-
className={`p-6 rounded-full ${songVal !== "" ? "" : "opacity-50 cursor-not-allowed"}`}
333+
className={`p-5 rounded-full ${songVal !== "" ? "" : "opacity-50 cursor-not-allowed"}`}
338334
size="icon"
339335
onClick={() => setIsPlaying(songVal !== "" && !isPlaying)}
340336
onKeyDown={() => pressedKeyOne}
@@ -343,7 +339,7 @@ const DefaultSongControls = ({
343339
</Button>
344340
<Button
345341
size="icon"
346-
className={`p-6 rounded-full ${songVal !== "" ? "" : "opacity-50 cursor-not-allowed"}`}
342+
className={`p-5 rounded-full ${songVal !== "" ? "" : "opacity-50 cursor-not-allowed"}`}
347343
variant="ghost"
348344
onClick={() => handleSkipSong(false)}
349345
onKeyDown={() => pressedKeyOne}
@@ -352,10 +348,10 @@ const DefaultSongControls = ({
352348
</Button>
353349
</div>
354350
<div className="flex items-center gap-2">
355-
<div className="text-sm text-muted-foreground/80 w-8 text-right">{formatTime(currentTimeVal)}</div>
351+
<div className="text-sm text-muted-foreground/80 w-12 text-right">{formatTime(currentTimeVal)}</div>
356352
<Progress
357353
value={sliderValue}
358-
className="w-72 transition-all"
354+
className="transition-all h-1.5"
359355
/>
360356
<div className="text-sm text-muted-foreground/80">{isNaN(songTime) ? '00:00' : formatTime(songTime)}</div>
361357
</div>
@@ -392,43 +388,78 @@ const SongControlsSmall = ({
392388
setOptAppear,
393389
id,
394390
}: songControlsInterface) => {
391+
const [sliderValue, setSliderValue] = useState(0);
392+
393+
const useEffectConst = () => {
394+
const song = songRef.current;
395+
if (!song) return;
396+
397+
const updateTime = () => {
398+
if (song.duration) {
399+
setSliderValue(Number(((song.currentTime / song.duration) * 100).toFixed(0)));
400+
}
401+
};
402+
403+
song.addEventListener("timeupdate", updateTime);
404+
405+
return () => {
406+
song.removeEventListener("timeupdate", updateTime);
407+
};
408+
}
409+
410+
useEffect(() => {
411+
useEffectConst();
412+
}, []);
413+
414+
useEffect(() => {
415+
useEffectConst();
416+
}, [handleSkipSong]);
417+
395418
return (
396419
<>
397-
<div className="flex items-center gap-2 flex-1 select-none mb-2">
398-
<Image
399-
src={image}
400-
alt={image}
401-
width={60}
402-
height={60}
403-
className="rounded-lg"
404-
/>
405-
<div>
406-
<div className="font-bold overflow-hidden whitespace-nowrap text-ellipsis w-[47vw]">
407-
{songVal !== "" ? songVal : "No Track Found"}
420+
<div className="flex flex-col">
421+
<div className="flex items-center py-3 px-3">
422+
<div className="flex items-center gap-2 flex-1 select-none">
423+
<Image
424+
src={image}
425+
alt={image}
426+
width={60}
427+
height={60}
428+
className="rounded-lg"
429+
/>
430+
<div>
431+
<div className="font-semibold overflow-hidden whitespace-nowrap text-ellipsis w-[40vw]">
432+
{songVal !== "" ? songVal : "No Track Found"}
433+
</div>
434+
<div className="text-sm text-muted-foreground">{songCreator}</div>
435+
</div>
408436
</div>
409-
<div className="text-sm text-muted-foreground">{songCreator}</div>
410-
</div>
411-
</div>
412437

413-
<div
414-
className="flex justify-center gap-1 mb-2"
415-
onClick={(e) => e.stopPropagation()}
416-
>
417-
<Button
418-
className={`p-5 rounded-full ${songVal !== "" ? "" : "opacity-50 cursor-not-allowed"}`}
419-
size="icon"
420-
onClick={() => setIsPlaying(songVal !== "" && !isPlaying)}
421-
>
422-
{!isPlaying ? <Play size='36' /> : <Pause size='36' />}
423-
</Button>
424-
<Button
425-
size="icon"
426-
className={`p-5 rounded-full ${songVal !== "" ? "" : "opacity-50 cursor-not-allowed"}`}
427-
variant="ghost"
428-
onClick={() => handleSkipSong(false)}
429-
>
430-
<SkipForward />
431-
</Button>
438+
<div
439+
className="flex justify-center gap-1"
440+
onClick={(e) => e.stopPropagation()}
441+
>
442+
<Button
443+
className={`p-5 rounded-full ${songVal !== "" ? "" : "opacity-50 cursor-not-allowed"}`}
444+
size="icon"
445+
onClick={() => setIsPlaying(songVal !== "" && !isPlaying)}
446+
>
447+
{!isPlaying ? <Play size='36' /> : <Pause size='36' />}
448+
</Button>
449+
<Button
450+
size="icon"
451+
className={`p-5 rounded-full ${songVal !== "" ? "" : "opacity-50 cursor-not-allowed"}`}
452+
variant="ghost"
453+
onClick={() => handleSkipSong(false)}
454+
>
455+
<SkipForward />
456+
</Button>
457+
</div>
458+
</div>
459+
<Progress
460+
value={sliderValue}
461+
className="transition-all duration-1000 h-1 rounded-none w-full"
462+
/>
432463
</div>
433464
</>
434465
);
@@ -486,7 +517,7 @@ const MiniPlayer = ({
486517

487518
return (
488519
<div
489-
className={`overflow-y-auto overflow-x-hidden p-8 flex flex-col gap-2 transition-all bg-primary-foreground`}
520+
className={`p-8 flex flex-col gap-2 transition-all bg-primary-foreground`}
490521
>
491522
{/* <Button variant='outline' size='icon' onClick={() => setAppear(false)} className="bg-transparent border-none cursor-pointer absolute top-3 left-3 rounded-full">
492523
<ChevronDown />
@@ -502,9 +533,9 @@ const MiniPlayer = ({
502533
className="rounded-xl shadow-lg"
503534
/>
504535
</div>
505-
<div className="flex flex-col">
506-
<div className="text-xl font-bold">{songVal || "Unknown"}</div>
507-
<div className="text-lg text-muted-foreground -translate-y-1">
536+
<div className="flex flex-col overflow-hidden">
537+
<div className="text-2xl font-semibold w-full overflow-hidden whitespace-pre scrolling-text relative">{songVal || "Unknown"}</div>
538+
<div className="text-md text-muted-foreground -translate-y-1">
508539
{songCreator || "Unknown"}
509540
</div>
510541
</div>
@@ -555,7 +586,7 @@ const MiniPlayer = ({
555586
className="w-full h-full rounded-xl px-4 py-3 mt-8"
556587
style={{ background: albumAverageColorFR }}
557588
>
558-
<div className="text-lg font-bold">Lyrics</div>
589+
<div className="text-lg font-semibold">Lyrics</div>
559590
<div className="text-primary/80">
560591
<div>WIP</div>
561592
</div>

components/ui/progress.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ const Progress = React.forwardRef<
1818
{...props}
1919
>
2020
<ProgressPrimitive.Indicator
21-
className="h-full w-full flex-1 bg-primary transition-all rounded-full"
21+
className="h-full w-full flex-1 bg-primary transition-all"
2222
style={{ transform: `translateX(-${100 - (value || 0)}%)` }}
2323
/>
2424
</ProgressPrimitive.Root>

0 commit comments

Comments
 (0)