mirror of
https://github.com/jorgev259/soc_site-astro.git
synced 2025-06-29 07:57:41 +00:00
409 lines
15 KiB
Text
409 lines
15 KiB
Text
---
|
|
import prismaClient from 'utils/prisma-client'
|
|
import * as m from 'paraglide/messages'
|
|
import { getImage, Image } from 'astro:assets'
|
|
import { AlbumStatus } from '@prisma/client'
|
|
import { SEO } from 'astro-seo'
|
|
|
|
import BaseLayout from 'layouts/base.astro'
|
|
import TrackList from 'components/albumPage/TrackList'
|
|
import DownloadBtn from 'components/albumPage/DownloadBtn.astro'
|
|
import AlbumBox from 'components/AlbumBox.astro'
|
|
|
|
import kofi from 'img/socials/ko-fi-donate-button.png'
|
|
import discord from 'img/socials/discord.png'
|
|
import vgmdbLogo from 'img/assets/vgmdb-logo.png'
|
|
import flyIcon from 'img/assets/fly-icon.png'
|
|
import ouoIcon from 'img/assets/ouo-icon.png'
|
|
|
|
const { id } = Astro.params
|
|
const { permissions } = Astro.locals
|
|
|
|
const hasDirect = permissions.includes('SKIP_ADS')
|
|
const hasUpdate = permissions.includes('UPDATE')
|
|
const hiddenCondition = !hasUpdate ? { status: AlbumStatus.SHOW } : {}
|
|
|
|
const album = await prismaClient.albums.findUnique({
|
|
where: { id: Number(id), ...hiddenCondition },
|
|
include: {
|
|
artists: { select: { artist: true } },
|
|
categories: { select: { categoryName: true } },
|
|
classifications: { select: { classificationName: true } },
|
|
platforms: { select: { platform: { select: { id: true, name: true } } } },
|
|
games: { select: { game: { select: { slug: true, name: true } } } },
|
|
animations: { select: { animation: { select: { id: true, title: true } } } },
|
|
stores: { select: { url: true, provider: true }, where: { NOT: { provider: 'SOON' } } },
|
|
discs: { select: { number: true, body: true } },
|
|
downloads: {
|
|
select: {
|
|
title: true,
|
|
links: { select: { id: true, url: true, url2: true, provider: true, directUrl: hasDirect } }
|
|
}
|
|
},
|
|
relatedAlbums: { select: { relatedAlbum: { select: { id: true, title: true } } } }
|
|
}
|
|
})
|
|
|
|
if (!album) {
|
|
Astro.response.status = 404
|
|
Astro.response.statusText = 'Not found'
|
|
}
|
|
|
|
const { currentLocale } = Astro
|
|
const coverImage = await getImage({
|
|
src: `https://cdn.sittingonclouds.net/album/${album?.id}.png`,
|
|
height: 150,
|
|
width: 150
|
|
})
|
|
---
|
|
|
|
<style>
|
|
tr {
|
|
th {
|
|
display: ruby;
|
|
}
|
|
}
|
|
</style>
|
|
|
|
<SEO
|
|
slot='head'
|
|
titleDefault='Sitting on Clouds'
|
|
title={album?.title ?? undefined}
|
|
description='Largest Video Game & Animation Soundtrack サウンドトラック Archive'
|
|
openGraph={{
|
|
basic: {
|
|
title: album?.title ?? '',
|
|
type: 'website',
|
|
image: `https://www.sittingonclouds.net${coverImage.src}`,
|
|
url: Astro.url.pathname
|
|
},
|
|
optional: {
|
|
description: album?.subTitle || album?.artists.map((a) => a.artist.name).join(' - '),
|
|
siteName: 'Sitting on Clouds'
|
|
}
|
|
}}
|
|
extend={{
|
|
meta: [{ name: 'theme-color', content: album?.headerColor }]
|
|
}}
|
|
/>
|
|
|
|
{album?.status === AlbumStatus.HIDDEN ? (
|
|
<script>
|
|
import toast from 'react-hot-toast'
|
|
toast('This page is currently hidden', { duration: Infinity })
|
|
</script>
|
|
) : null}
|
|
|
|
<BaseLayout>
|
|
<div
|
|
class={`w-full min-h-100vh bg-fixed bg-center bg-cover`}
|
|
style={`
|
|
background-image: url('https://cdn.sittingonclouds.net/album/${album?.id}.png');
|
|
`}
|
|
>
|
|
<div class='bg-dark/75 w-full min-h-100vh'>
|
|
<div class='flex flex-col flex-1 max-w-[1440px] mx-auto p-3'>
|
|
<div class='flex flex-wrap md:flex-nowrap gap-x-3'>
|
|
<div class='flex-1 flex-wrap md:flex-5/12'>
|
|
<div class='size-full relative cursor-pointer'>
|
|
<Image
|
|
src={`https://cdn.sittingonclouds.net/album/${album?.id}.png`}
|
|
alt={`${album?.title} cover`}
|
|
class='rounded-sm size-full object-contain h-fit mb-2 md:min-h-96 px-10'
|
|
quality='mid'
|
|
width={500}
|
|
height={500}
|
|
/>
|
|
</div>
|
|
</div>
|
|
<div class='flex-1 flex-wrap md:flex-7/12'>
|
|
<div class='bg-dark/85 rounded-xl py-4 px-6'>
|
|
<div class='font-medium text-4xl text-center'>{album?.title}</div>
|
|
<div class='text-center'>
|
|
{album?.subTitle ? <h6 style={{ whiteSpace: 'pre-wrap ' }}>{album?.subTitle}</h6> : null}
|
|
</div>
|
|
<table class='mt-4 border-spacing-y-4 border-separate w-full'>
|
|
<tbody>
|
|
{
|
|
album?.releaseDate ? (
|
|
<tr>
|
|
<th class='width-row'>{m.releaseDate()}</th>
|
|
<td>
|
|
{new Intl.DateTimeFormat(currentLocale, { dateStyle: 'medium' }).format(album?.releaseDate)}
|
|
</td>
|
|
</tr>
|
|
) : null
|
|
}
|
|
|
|
{
|
|
(album?.artists.length ?? 0) > 0 && (
|
|
<tr>
|
|
<th class='mr-2'>{m.artists()}</th>
|
|
<td>{album?.artists.map(({ artist }) => artist.name).join(', ')}</td>
|
|
</tr>
|
|
)
|
|
}
|
|
|
|
<tr>
|
|
<th class='mr-2'>{m.classification()}</th>
|
|
<td>
|
|
{
|
|
[
|
|
album?.categories
|
|
.map(({ categoryName }) => m[`${categoryName}Osts` as keyof typeof m]())
|
|
.join(' & '),
|
|
album?.classifications.map(({ classificationName }) => classificationName).join(', ')
|
|
]
|
|
.filter((f) => f !== '')
|
|
.join(' - ')
|
|
}
|
|
</td>
|
|
</tr>
|
|
{
|
|
album?.label && (
|
|
<tr>
|
|
<th class='mr-2'>{m.publishedBy()}</th>
|
|
<td>
|
|
<a class='btn btn-link p-0' href={`/publisher/${album?.label}`}>
|
|
{album?.label}
|
|
</a>
|
|
</td>
|
|
</tr>
|
|
)
|
|
}
|
|
{
|
|
(album?.platforms.length ?? 0) > 0 && (
|
|
<tr>
|
|
<th class='mr-2'>{m.platforms()}</th>
|
|
<td>
|
|
{album?.platforms.map(({ platform }, i) => (
|
|
<Fragment key={platform.id}>
|
|
{id === '29' ? (
|
|
<span class='btn p-0' style={{ color: 'white' }}>
|
|
{platform.name}
|
|
</span>
|
|
) : (
|
|
<a class='btn btn-link p-0' href={`/platform/${id}`}>
|
|
{platform.name}
|
|
</a>
|
|
)}
|
|
{i !== album?.platforms.length - 1 && ', '}
|
|
</Fragment>
|
|
))}
|
|
</td>
|
|
</tr>
|
|
)
|
|
}
|
|
{
|
|
(album?.games.length ?? 0) > 0 && (
|
|
<tr>
|
|
<th class='mr-2'>{m.games()}</th>
|
|
<td>
|
|
{album?.games.map(({ game }, i) => (
|
|
<Fragment key={game.slug}>
|
|
<a class='btn btn-link p-0' href={`/game/${game.slug}`}>
|
|
{game.name}
|
|
</a>
|
|
{i !== album?.games.length - 1 && ', '}
|
|
</Fragment>
|
|
))}
|
|
</td>
|
|
</tr>
|
|
)
|
|
}
|
|
{
|
|
(album?.animations.length ?? 0) > 0 && (
|
|
<tr>
|
|
<th class='mr-2'>{m.animations()}</th>
|
|
<td>
|
|
{album?.animations.map(({ animation }, i) => (
|
|
<Fragment key={id}>
|
|
<a class='btn btn-link p-0' href={`/anim/${id}`}>
|
|
{animation.title}
|
|
</a>
|
|
{i !== album?.animations.length - 1 && ', '}
|
|
</Fragment>
|
|
))}
|
|
</td>
|
|
</tr>
|
|
)
|
|
}
|
|
|
|
<tr>
|
|
<th class='mr-2'>{m.avgRating()}</th>
|
|
<td>
|
|
<!-- <StarCounter album?.Id={album?.id} /> -->
|
|
</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
{
|
|
album?.vgmdb && (
|
|
<div class='mt-2 mb-3 ml-2 flex'>
|
|
<span class='text-lg'>{m.checkVGMDB()}:</span>
|
|
<a href={album?.vgmdb} class='ml-2' target='_blank' rel='noopener noreferrer'>
|
|
<Image width={100} height={30} alt={'VGMdb'} src={vgmdbLogo} />
|
|
</a>
|
|
</div>
|
|
)
|
|
}
|
|
<!-- <UserButtons id={album?.id} /> -->
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<hr />
|
|
<div class='flex flex-wrap md:flex-nowrap gap-x-3'>
|
|
<div class='flex-1 bg-dark/85 rounded-xl p-4'>
|
|
<h1 class='text-center uppercase text-4xl font-semibold'>
|
|
{m.tracklist()}
|
|
</h1>
|
|
|
|
<div class='px-3'>
|
|
<TrackList discs={album?.discs ?? []} client:only='react' />
|
|
</div>
|
|
</div>
|
|
<div class='flex-1 bg-dark/85 rounded-xl p-3'>
|
|
<!-- {
|
|
album?.vgmdb && (
|
|
<div class='mt-2 mb-3 ml-2 flex'>
|
|
<span class='text-xl'>{m.checkVGMDB()}:</span>
|
|
<a href={album?.vgmdb} class='ml-2' target='_blank' rel='noopener noreferrer'>
|
|
<Image width={100} height={30} alt={'VGMdb'} src={vgmdbLogo} />
|
|
</a>
|
|
</div>
|
|
)
|
|
} -->
|
|
{
|
|
(album?.stores.length ?? 0) > 0 && (
|
|
<div class='row mt-2 px-3'>
|
|
<div class='bg-red-500 text-white text-4xl rounded-md px-3 py-4'>
|
|
<h1 class='text-center text-3xl uppercase font-semibold drop-shadow-lg'>{m.buyOriginal()}</h1>
|
|
<hr class='my-2.5' />
|
|
<div class='flex justify-center flex-wrap gap-4'>
|
|
{album?.stores.map(({ url, provider }, i) => (
|
|
<a target='_blank' rel='noopener noreferrer' href={url}>
|
|
<Image
|
|
class='rounded-md'
|
|
width={130}
|
|
height={50}
|
|
style={{ height: 'auto', width: '130px' }}
|
|
alt={provider}
|
|
src={`/img/provider/${provider}.jpg`}
|
|
/>
|
|
</a>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
<hr />
|
|
<div>
|
|
{
|
|
album?.downloads?.map((download) => {
|
|
const { links, title } = download
|
|
|
|
return (
|
|
<div class=''>
|
|
<h2 class='text-center text-3xl'>{title}</h2>
|
|
{links.map((link) => {
|
|
const { id: linkId, url, url2, provider, directUrl } = link
|
|
|
|
return (
|
|
<Fragment key={linkId}>
|
|
<div class='flex gap-2 my-2'>
|
|
<div>
|
|
<Image
|
|
class='rounded-md'
|
|
width={30}
|
|
height={30}
|
|
alt={provider}
|
|
src={`/img/provider/${provider}.png`}
|
|
/>
|
|
</div>
|
|
{url2 && (
|
|
<DownloadBtn href={url2} alt='fly inc' icon={flyIcon}>
|
|
Fly.inc
|
|
</DownloadBtn>
|
|
)}
|
|
{url ? (
|
|
<DownloadBtn href={url} alt='ouo' icon={ouoIcon}>
|
|
ouo.io
|
|
</DownloadBtn>
|
|
) : null}
|
|
|
|
<DownloadBtn href={directUrl} direct hasDirect={hasDirect}>
|
|
{m.direct()}
|
|
</DownloadBtn>
|
|
</div>
|
|
</Fragment>
|
|
)
|
|
})}
|
|
<hr />
|
|
</div>
|
|
)
|
|
})
|
|
}
|
|
</div>
|
|
|
|
<div>
|
|
<div>
|
|
<h4 class='text-2xl'>{m.donationCall()}</h4>
|
|
<div>
|
|
<span> {m.donationSteps()} </span>
|
|
<a href='https://discord.gg/AQc9vwGM' target='_blank' rel='noopener noreferrer'>Discord</a>
|
|
</div>
|
|
</div>
|
|
<div class='mt-1'>
|
|
<a target='_blank' rel='noopener noreferrer' href='https://ko-fi.com/sittingonclouds'>
|
|
<Image style={{ height: 'auto', width: '200px' }} alt='Support me on Ko-fi' src={kofi} />
|
|
</a>
|
|
</div>
|
|
</div>
|
|
<hr />
|
|
<div class='text-xl'>
|
|
<div class='flex items-center'>
|
|
<span>{m.brokenLinkContact()}</span>
|
|
<a class='' href='https://discord.gg/x23SFbE' target='_blank' rel='noopener noreferrer'>
|
|
<Image
|
|
alt='Join our Discord!'
|
|
class='rounded-md ml-2'
|
|
style={{
|
|
height: 'auto',
|
|
width: '130px'
|
|
}}
|
|
src={discord}
|
|
/>
|
|
</a>
|
|
</div>
|
|
<div class='mt-2'>
|
|
<span>{m.mediafirePermission()}</span>
|
|
<a class='ml-1 text-link hover:underline' href='https://www.youtube.com/watch?v=d6-hcbEozAQ'>
|
|
{m.mediafirePermissionGuide()}
|
|
</a>
|
|
</div>
|
|
</div>
|
|
<hr />
|
|
</div>
|
|
</div>
|
|
<!-- Comment List here -->
|
|
<div class='mt-2 bg-dark/85 rounded-xl uppercase text-4xl font-semibold text-center py-2 px-1.5'>
|
|
{m.relatedAlbums()}
|
|
</div>
|
|
<div class='mt-2'>
|
|
<div class='grid grid-cols-2 md:grid-cols-4 gap-x-1.5 justify-items-center'>
|
|
{
|
|
album?.relatedAlbums.map(({ relatedAlbum }) => (
|
|
<AlbumBox
|
|
title={relatedAlbum?.title}
|
|
href={`/album/${relatedAlbum?.id}`}
|
|
image={`/album/${relatedAlbum?.id}.png`}
|
|
/>
|
|
))
|
|
}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</BaseLayout>
|