mirror of
https://github.com/SrIzan10/mainwebsite.git
synced 2026-06-06 00:56:58 +00:00
feat: add discogs
This commit is contained in:
@@ -14,6 +14,7 @@ import { Image } from 'astro:assets'
|
||||
import type { CollectionEntry } from 'astro:content'
|
||||
import Link from './Link.astro'
|
||||
import { Ratings } from './ui/rating'
|
||||
import { getReleaseData } from '@/lib/discogs'
|
||||
|
||||
interface Props {
|
||||
entry: CollectionEntry<'blog'>
|
||||
@@ -26,6 +27,7 @@ const authors = await parseAuthors(entry.data.authors ?? [])
|
||||
const subpostCount = !isSubpost(entry.id) ? await getSubpostCount(entry.id) : 0
|
||||
|
||||
const rating = entry.data.tags?.find((tag) => tag.startsWith('rating-'))
|
||||
const discogs = entry.data.discogs ? await getReleaseData(entry.data.discogs) : null;
|
||||
---
|
||||
|
||||
<div
|
||||
@@ -36,14 +38,14 @@ const rating = entry.data.tags?.find((tag) => tag.startsWith('rating-'))
|
||||
class="flex flex-col gap-4 sm:flex-row"
|
||||
>
|
||||
{
|
||||
entry.data.image && (
|
||||
<div class="max-w-3xs sm:shrink-0">
|
||||
entry.data.image || (discogs && discogs.images[0]?.resource_url) && (
|
||||
<div class="w-48 max-w-48 sm:shrink-0 h-30">
|
||||
<Image
|
||||
src={entry.data.image}
|
||||
src={entry.data.image || discogs.images[0].resource_url}
|
||||
alt={entry.data.title}
|
||||
width={1200}
|
||||
height={630}
|
||||
class="object-cover"
|
||||
height={400}
|
||||
class="w-full h-full object-cover rounded-lg"
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -12,6 +12,7 @@ const blog = defineCollection({
|
||||
tags: z.array(z.string()).optional(),
|
||||
authors: z.array(z.string()).optional(),
|
||||
draft: z.boolean().optional(),
|
||||
discogs: z.string().optional(),
|
||||
}),
|
||||
})
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ description: 'Random notes I took on a listening session'
|
||||
date: 2025-09-26
|
||||
tags: ['rating-4', 'music', 'radiohead']
|
||||
#image: './banner.png'
|
||||
discogs: '1174296'
|
||||
authors: ['srizan']
|
||||
---
|
||||
|
||||
|
||||
140
src/lib/discogs.ts
Normal file
140
src/lib/discogs.ts
Normal file
@@ -0,0 +1,140 @@
|
||||
export async function getReleaseData(discogsId: string) {
|
||||
const res = await fetch(`https://api.discogs.com/releases/${discogsId}`, {
|
||||
headers: {
|
||||
'User-Agent': 'srizan.dev/1.0 +https://srizan.dev',
|
||||
},
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
throw new Error(`Failed to fetch data from Discogs API: ${res.statusText}`);
|
||||
}
|
||||
|
||||
const data = await res.json() as DiscogsRelease;
|
||||
return data;
|
||||
}
|
||||
|
||||
export interface DiscogsRelease {
|
||||
title: string;
|
||||
id: number;
|
||||
artists: Artist[];
|
||||
data_quality: string;
|
||||
thumb: string;
|
||||
community: Community;
|
||||
companies: Company[];
|
||||
country: string;
|
||||
date_added: string;
|
||||
date_changed: string;
|
||||
estimated_weight: number;
|
||||
extraartists: ExtraArtist[];
|
||||
format_quantity: number;
|
||||
formats: Format[];
|
||||
genres: string[];
|
||||
identifiers: Identifier[];
|
||||
images: Image[];
|
||||
labels: Label[];
|
||||
lowest_price: number;
|
||||
master_id: number;
|
||||
master_url: string;
|
||||
notes: string;
|
||||
num_for_sale: number;
|
||||
released: string;
|
||||
released_formatted: string;
|
||||
resource_url: string;
|
||||
series: any[];
|
||||
status: string;
|
||||
styles: string[];
|
||||
tracklist: Track[];
|
||||
uri: string;
|
||||
videos: Video[];
|
||||
year: number;
|
||||
}
|
||||
|
||||
export interface Artist {
|
||||
anv: string;
|
||||
id: number;
|
||||
join: string;
|
||||
name: string;
|
||||
resource_url: string;
|
||||
role: string;
|
||||
tracks: string;
|
||||
}
|
||||
|
||||
export interface Community {
|
||||
contributors: Contributor[];
|
||||
data_quality: string;
|
||||
have: number;
|
||||
rating: {
|
||||
average: number;
|
||||
count: number;
|
||||
};
|
||||
status: string;
|
||||
submitter: Contributor;
|
||||
want: number;
|
||||
}
|
||||
|
||||
export interface Contributor {
|
||||
resource_url: string;
|
||||
username: string;
|
||||
}
|
||||
|
||||
export interface Company {
|
||||
catno: string;
|
||||
entity_type: string;
|
||||
entity_type_name: string;
|
||||
id: number;
|
||||
name: string;
|
||||
resource_url: string;
|
||||
}
|
||||
|
||||
export interface ExtraArtist {
|
||||
anv: string;
|
||||
id: number;
|
||||
join: string;
|
||||
name: string;
|
||||
resource_url: string;
|
||||
role: string;
|
||||
tracks: string;
|
||||
}
|
||||
|
||||
export interface Format {
|
||||
descriptions: string[];
|
||||
name: string;
|
||||
qty: string;
|
||||
}
|
||||
|
||||
export interface Identifier {
|
||||
type: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
export interface Image {
|
||||
height: number;
|
||||
resource_url: string;
|
||||
type: string;
|
||||
uri: string;
|
||||
uri150: string;
|
||||
width: number;
|
||||
}
|
||||
|
||||
export interface Label {
|
||||
catno: string;
|
||||
entity_type: string;
|
||||
id: number;
|
||||
name: string;
|
||||
resource_url: string;
|
||||
}
|
||||
|
||||
export interface Track {
|
||||
duration: string;
|
||||
position: string;
|
||||
title: string;
|
||||
type_: string;
|
||||
}
|
||||
|
||||
export interface Video {
|
||||
description: string;
|
||||
duration: number;
|
||||
embed: boolean;
|
||||
title: string;
|
||||
uri: string;
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import TOCHeader from '@/components/TOCHeader.astro'
|
||||
import TOCSidebar from '@/components/TOCSidebar.astro'
|
||||
import { badgeVariants } from '@/components/ui/badge'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Ratings } from '@/components/ui/rating'
|
||||
import { Separator } from '@/components/ui/separator'
|
||||
import Layout from '@/layouts/Layout.astro'
|
||||
import {
|
||||
@@ -22,6 +23,7 @@ import {
|
||||
isSubpost,
|
||||
parseAuthors,
|
||||
} from '@/lib/data-utils'
|
||||
import { getReleaseData } from '@/lib/discogs'
|
||||
import { formatDate } from '@/lib/utils'
|
||||
import { Icon } from 'astro-icon/components'
|
||||
import { Image } from 'astro:assets'
|
||||
@@ -51,6 +53,10 @@ const subpostCount = !isCurrentSubpost
|
||||
? await getSubpostCount(currentPostId)
|
||||
: 0
|
||||
const postReadingTime = await getPostReadingTime(currentPostId)
|
||||
const rating = post.data.tags?.find((tag) => tag.startsWith('rating-'))
|
||||
const discogs = post.data.discogs
|
||||
? await getReleaseData(post.data.discogs)
|
||||
: null
|
||||
---
|
||||
|
||||
<Layout>
|
||||
@@ -101,15 +107,16 @@ const postReadingTime = await getPostReadingTime(currentPostId)
|
||||
</div>
|
||||
|
||||
{
|
||||
post.data.image && (
|
||||
<Image
|
||||
src={post.data.image}
|
||||
alt={post.data.title}
|
||||
width={1200}
|
||||
height={630}
|
||||
class="col-span-full mx-auto w-full max-w-5xl object-cover"
|
||||
/>
|
||||
)
|
||||
post.data.image ||
|
||||
(discogs && discogs.images[0]?.resource_url && (
|
||||
<Image
|
||||
src={post.data.image || discogs.images[0].resource_url}
|
||||
alt={post.data.title}
|
||||
width={1200}
|
||||
height={630}
|
||||
class="col-span-full mx-auto max-h-96 w-full max-w-4xl rounded-lg object-contain"
|
||||
/>
|
||||
))
|
||||
}
|
||||
|
||||
<section class="col-start-2 flex flex-col gap-y-6 text-center">
|
||||
@@ -176,17 +183,25 @@ const postReadingTime = await getPostReadingTime(currentPostId)
|
||||
</div>
|
||||
|
||||
<div class="flex flex-wrap justify-center gap-2">
|
||||
{rating && (
|
||||
<Ratings rating={parseFloat(rating.replace('rating-', ''))} size={15} />
|
||||
)}
|
||||
{
|
||||
post.data.tags && post.data.tags.length > 0 ? (
|
||||
post.data.tags.map((tag) => (
|
||||
<a
|
||||
href={`/tags/${tag}`}
|
||||
class={badgeVariants({ variant: 'secondary' })}
|
||||
>
|
||||
<Icon name="lucide:hash" class="size-3" />
|
||||
{tag}
|
||||
</a>
|
||||
))
|
||||
post.data.tags.map((tag) => {
|
||||
if (tag.startsWith('rating-')) return null;
|
||||
return (
|
||||
<div>
|
||||
<a
|
||||
href={`/tags/${tag}`}
|
||||
class={badgeVariants({ variant: 'secondary' })}
|
||||
>
|
||||
<Icon name="lucide:hash" class="size-3" />
|
||||
{tag}
|
||||
</a>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
) : (
|
||||
<span class="text-muted-foreground text-sm">
|
||||
No tags available
|
||||
@@ -257,7 +272,7 @@ const postReadingTime = await getPostReadingTime(currentPostId)
|
||||
|
||||
scrollToTopButton.classList.toggle(
|
||||
'hidden',
|
||||
window.scrollY <= 300 || isFooterVisible,
|
||||
window.scrollY <= 300 || isFooterVisible
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user