Use JSON file for track rendering

This commit is contained in:
thiloho
2025-04-28 03:58:54 +02:00
parent 4a4e1a0ae9
commit 27c42cbe6f
3 changed files with 195 additions and 35 deletions

View File

@@ -1,5 +1,5 @@
import { defineCollection, z } from "astro:content";
import { glob } from "astro/loaders";
import { glob, file } from "astro/loaders";
const blog = defineCollection({
loader: glob({ pattern: "**/*.md", base: "./src/content/blog" }),
@@ -11,4 +11,17 @@ const blog = defineCollection({
}),
});
export const collections = { blog };
const tracks = defineCollection({
loader: file("./src/content/tracks.json"),
schema: ({ image }) =>
z.object({
id: z.number().positive(),
title: z.string(),
youtubeLink: z.string().url(),
artist: z.string(),
album: z.string(),
cover: image(),
}),
});
export const collections = { blog, tracks };

170
src/content/tracks.json Normal file
View File

@@ -0,0 +1,170 @@
[
{
"id": 1,
"title": "And So It Was",
"youtubeLink": "https://www.youtube.com/watch?v=xf7iQ5YtvxQ",
"artist": "Black Smurf",
"album": "Black Smurf, Vol. 2",
"cover": "/src/content/album-covers/Black Smurf - And So It Was.jpeg"
},
{
"id": 2,
"title": "Clouds",
"youtubeLink": "https://www.youtube.com/watch?v=CNbzyHDxdTs",
"artist": "Miscél, Hanz",
"album": "The Other Side",
"cover": "/src/content/album-covers/Miscél, Hanz - Clouds.jpeg"
},
{
"id": 3,
"title": "Desire",
"youtubeLink": "https://www.youtube.com/watch?v=VQEhIQxvRXQ",
"artist": "BOCIGE, DYLAN",
"album": "Desire",
"cover": "/src/content/album-covers/BOCIGE, DYLAN - Desire.jpeg"
},
{
"id": 4,
"title": "Destiny",
"youtubeLink": "https://www.youtube.com/watch?v=p-7_FSwTGs4",
"artist": "NEFFEX",
"album": "Destiny: The Collection",
"cover": "/src/content/album-covers/NEFFEX - Destiny.jpeg"
},
{
"id": 5,
"title": "DREAMIN",
"youtubeLink": "https://www.youtube.com/watch?v=Ns07wmgL8dY",
"artist": "SLIGHT",
"album": "SLIGHT COLLECTION VOL. 1",
"cover": "/src/content/album-covers/SLIGHT - DREAMIN.jpeg"
},
{
"id": 6,
"title": "Ewig",
"youtubeLink": "https://www.youtube.com/watch?v=yYHSwBXzD84",
"artist": "makko",
"album": "Lieb mich oder lass es, Pt.1+2",
"cover": "/src/content/album-covers/makko - Ewig.jpeg"
},
{
"id": 7,
"title": "Festnetz",
"youtubeLink": "https://www.youtube.com/watch?v=5GXUEJsYVRA",
"artist": "Dead Dawg, BHZ, Monk",
"album": "Festnetz",
"cover": "/src/content/album-covers/Dead Dawg, BHZ, Monk - Festnetz.jpeg"
},
{
"id": 8,
"title": "hide",
"youtubeLink": "https://www.youtube.com/watch?v=O6jx0yVB5O4",
"artist": "arya x",
"album": "hide",
"cover": "/src/content/album-covers/arya x - hide.jpeg"
},
{
"id": 9,
"title": "Jinzo",
"youtubeLink": "https://www.youtube.com/watch?v=q83S-l9NrMA",
"artist": "YFG Pave",
"album": "Jinzo",
"cover": "/src/content/album-covers/YFG Pave - Jinzo.jpeg"
},
{
"id": 10,
"title": "lights in a hall",
"youtubeLink": "https://www.youtube.com/watch?v=2D60wMAOF_E",
"artist": "Beamon",
"album": "LIGHTS IN A HALL",
"cover": "/src/content/album-covers/Beamon - lights in a hall.jpeg"
},
{
"id": 11,
"title": "Lost In Da Wind",
"youtubeLink": "https://www.youtube.com/watch?v=DNUwhgqCI9U",
"artist": "Jgrxxn, Lil Xav",
"album": "Lost In Da Wind",
"cover": "/src/content/album-covers/Jgrxxn, Lil Xav - Lost In Da Wind.jpeg"
},
{
"id": 12,
"title": "Miracle",
"youtubeLink": "https://www.youtube.com/watch?v=ba4MlsG_Ce8",
"artist": "Calvin Harris, Ellie Goulding",
"album": "Miracle",
"cover": "/src/content/album-covers/Calvin Harris, Ellie Goulding - Miracle.jpeg"
},
{
"id": 13,
"title": "My Girl",
"youtubeLink": "https://www.youtube.com/watch?v=lC5UbInswAs",
"artist": "ilyTOMMY",
"album": "My Girl",
"cover": "/src/content/album-covers/ilyTOMMY - My Girl.jpeg"
},
{
"id": 14,
"title": "Sweet Child O' Mine",
"youtubeLink": "https://www.youtube.com/watch?v=oMfMUfgjiLg",
"artist": "Guns N' Roses",
"album": "Appetite For Destruction",
"cover": "/src/content/album-covers/Guns N' Roses - Sweet Child O' Mine.jpeg"
},
{
"id": 15,
"title": "Ticket nach Ketama",
"youtubeLink": "https://www.youtube.com/watch?v=aNVkkJmwAYE",
"artist": "ARY, Liaze",
"album": "Ticket nach Ketama",
"cover": "/src/content/album-covers/ARY, Liaze - Ticket nach Ketama.jpeg"
},
{
"id": 16,
"title": "Too Lost To Be Found",
"youtubeLink": "https://www.youtube.com/watch?v=G9G_T3NWqf0",
"artist": "CH4YN",
"album": "Too Lost To Be Found",
"cover": "/src/content/album-covers/CH4YN - Too Lost To Be Found.jpeg"
},
{
"id": 17,
"title": "Toronto 2014",
"youtubeLink": "https://www.youtube.com/watch?v=RaaccfAJiOo",
"artist": "Daniel Caesar, Mustafa",
"album": "NEVER ENOUGH",
"cover": "/src/content/album-covers/Daniel Caesar, Mustafa - Toronto 2014.jpeg"
},
{
"id": 18,
"title": "Underworld",
"youtubeLink": "https://www.youtube.com/watch?v=wRoJ4Wp7phU",
"artist": "GDS, Juice Wrld",
"album": "Moonlight",
"cover": "/src/content/album-covers/GDS, Juice Wrld - Underworld.jpeg"
},
{
"id": 19,
"title": "vice city",
"youtubeLink": "https://www.youtube.com/watch?v=yf5Y20Ls7WE",
"artist": "XXXTENTACION",
"album": "vice city",
"cover": "/src/content/album-covers/XXXTENTACION - vice city.jpeg"
},
{
"id": 20,
"title": "War Clips",
"youtubeLink": "https://www.youtube.com/watch?v=dxu0N7mz5Ok",
"artist": "Motat",
"album": "War Clips",
"cover": "/src/content/album-covers/Motat - War Clips.jpeg"
},
{
"id": 21,
"title": "Weather Man",
"youtubeLink": "https://www.youtube.com/watch?v=4BFCN7dg51E",
"artist": "Xavier Wulf, Bones",
"album": "Caves",
"cover": "/src/content/album-covers/Xavier Wulf, Bones - Weather Man.jpeg"
}
]

View File

@@ -1,31 +1,9 @@
---
import PageLayout from "../layouts/PageLayout.astro";
import { Image } from "astro:assets";
import { parse } from "node:path";
import { getCollection } from "astro:content";
const albumCovers = await Astro.glob("../content/album-covers/*");
const processedAlbumCovers = albumCovers.map((cover) => {
const filePathWithoutParams = cover.default.src.split("?")[0];
const filename = parse(filePathWithoutParams).name;
const lastDashIndex = filename.lastIndexOf(" - ");
let artists =
lastDashIndex !== -1 ? filename.substring(0, lastDashIndex) : filename;
let title = lastDashIndex !== -1 ? filename.substring(lastDashIndex + 3) : "";
if (import.meta.env.PROD) {
title = title.replace(/\..{8}$/, "");
artists = artists.replaceAll("_", ",");
}
return { cover, artists, title };
});
const sortedAlbumCovers = processedAlbumCovers.sort((a, b) =>
a.title.localeCompare(b.title),
);
const tracks = await getCollection("tracks");
---
<PageLayout
@@ -35,26 +13,25 @@ const sortedAlbumCovers = processedAlbumCovers.sort((a, b) =>
<p class="mb-8">
This is a collection of some of my favourite music tracks, each listed by
artist and song title. Click on an album cover to go straight to the song on
YouTube Music!
YouTube!
</p>
<div
class="not-prose relative start-1/2 -ms-[min(50vw-1rem,50ch)] grid max-w-[calc(min(100vw-2rem,100ch))] grid-cols-[repeat(auto-fit,minmax(min(100%,200px),1fr))] place-content-center gap-4"
>
{
sortedAlbumCovers.map(({ cover, artists, title }) => (
tracks.map((track) => (
<figure>
<a
href={`https://music.youtube.com/search?q=${encodeURIComponent(`${title} - ${artists}`)}`}
>
<a href={track.data.youtubeLink}>
<Image
src={cover.default}
alt={`Cover for the song '${title}' by artist(s) '${artists}'`}
src={track.data.cover}
alt={`Cover for the song '${track.data.title}' by artist(s) '${track.data.artist}'`}
class="border border-neutral-400 duration-300 hover:scale-105 dark:border-neutral-500"
/>
</a>
<figcaption class="flex flex-col p-4 text-center">
<p class="text-lg font-bold">{title}</p>
<p>{artists}</p>
<p class="text-lg font-bold">{track.data.title}</p>
<p>{track.data.artist}</p>
<p class="text-sm">{track.data.album}</p>
</figcaption>
</figure>
))