Nest songs under circles
This commit is contained in:
parent
e8b653f8f3
commit
28bde28f46
|
@ -27,5 +27,5 @@ export default defineConfig({
|
|||
integrations: [
|
||||
mdx(),
|
||||
solid(),
|
||||
],
|
||||
]
|
||||
});
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
import { defineMarkdocConfig } from '@astrojs/markdoc/config';
|
||||
import Lyrics from './src/components/markdown/lyrics/Lyrics.astro';
|
||||
|
||||
|
||||
export default defineMarkdocConfig({
|
||||
tags: {
|
||||
lyrics: {
|
||||
render: Lyrics,
|
||||
attributes: {
|
||||
type: { type: String },
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
15
src/components/markdown/Album.astro
Normal file
15
src/components/markdown/Album.astro
Normal file
|
@ -0,0 +1,15 @@
|
|||
---
|
||||
interface Props {
|
||||
album: {
|
||||
title: string;
|
||||
cover: string;
|
||||
url: string;
|
||||
}
|
||||
}
|
||||
|
||||
const { album } = Astro.props;
|
||||
---
|
||||
<a class="c-album" href={album.url}>
|
||||
<img class="c-album__image" src={album.cover} alt=""/>
|
||||
<div class="c-album__title">{album.title}</div>
|
||||
</a>
|
|
@ -5,7 +5,7 @@ interface Props {
|
|||
title: string;
|
||||
cat: string;
|
||||
track: number;
|
||||
circle: string;
|
||||
name: string;
|
||||
composer?: string;
|
||||
lyrics?: string;
|
||||
vocal?: string[];
|
||||
|
@ -33,7 +33,7 @@ const { metadata } = Astro.props;
|
|||
</tr>
|
||||
<tr>
|
||||
<td>Circle</td>
|
||||
<td>{metadata.circle}</td>
|
||||
<td>{metadata.name}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Composer</td>
|
||||
|
|
12
src/content/_templates/_song.md
Normal file
12
src/content/_templates/_song.md
Normal file
|
@ -0,0 +1,12 @@
|
|||
---
|
||||
title: Title
|
||||
composer: Composer
|
||||
lyrics: Lirycist
|
||||
origin:
|
||||
- Original title
|
||||
album:
|
||||
ARCD0051:
|
||||
track: 7
|
||||
vocal:
|
||||
- Vocalist
|
||||
---
|
13
src/content/songs/arcd0054/beautiful sky.md
Normal file
13
src/content/songs/arcd0054/beautiful sky.md
Normal file
|
@ -0,0 +1,13 @@
|
|||
---
|
||||
slug: beautiful-sky
|
||||
title: Beautiful Sky
|
||||
composer: Masayoshi Minoshima
|
||||
lyrics: Mei Ayakura
|
||||
origin:
|
||||
- U.N.オーエンは彼女なのか?
|
||||
album:
|
||||
ARCD0054:
|
||||
track: 2
|
||||
vocal:
|
||||
- nachi
|
||||
---
|
|
@ -1,10 +1,13 @@
|
|||
---
|
||||
slug: dont-lose
|
||||
title: "Don't lose"
|
||||
origin:
|
||||
- 亡き王女の為のセプテット
|
||||
album:
|
||||
ARCD0054:
|
||||
track: 7
|
||||
vocal:
|
||||
- nomico
|
||||
---
|
||||
|
||||
# Japanese
|
|
@ -1,12 +1,22 @@
|
|||
---
|
||||
slug: dream-again
|
||||
title: "Dream Again"
|
||||
composer: Camellia
|
||||
lyrics: Camellia
|
||||
origin:
|
||||
- the Last Judgment
|
||||
album:
|
||||
ARCD0054:
|
||||
track: 5
|
||||
vocal:
|
||||
- Mei Ayakura
|
||||
---
|
||||
|
||||
# Japanese
|
||||
- 秒針の音が響空間 狭くて安心するほど
|
||||
- 割り込んだ感覚に目を閉じる 光がまた眩かしすぎて
|
||||
|
||||
- どこまでも続いていく階段 [降]{くだ}った途方もないほど
|
||||
- 行きたい場所はもう決まっている 幻想の声のする所
|
||||
|
||||
- 夢溢れる海へ
|
|
@ -1,4 +1,5 @@
|
|||
---
|
||||
slug: black-eyes
|
||||
title: Black Eyes
|
||||
composer: Kirin (EastNewSound)
|
||||
lyrics: Mei Ayakura
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"Alstroemeria Records": {
|
||||
"alstroemeria-records": {
|
||||
"name": "Alstroemeria Records",
|
||||
"albums": {
|
||||
"ARCD0051": {
|
||||
"title": "Engaged Dancehall",
|
||||
|
|
39
src/pages/songs/[circle].astro
Normal file
39
src/pages/songs/[circle].astro
Normal file
|
@ -0,0 +1,39 @@
|
|||
---
|
||||
import Base from "@layouts/Base.astro";
|
||||
import Album from "@components/markdown/Album.astro";
|
||||
import Header from "@components/headers/Base.astro";
|
||||
import { CIRCLES } from "@utils/songs/data";
|
||||
|
||||
|
||||
export async function getStaticPaths() {
|
||||
return Object.keys(CIRCLES)
|
||||
.map(circle => ({
|
||||
params: { circle },
|
||||
props: { albums: CIRCLES[circle].albums }
|
||||
}))
|
||||
}
|
||||
|
||||
interface Props {
|
||||
albums: typeof CIRCLES[string]['albums'];
|
||||
}
|
||||
|
||||
const circle = Astro.params.circle!;
|
||||
const albums = Astro.props.albums;
|
||||
const items = Object.keys(albums)
|
||||
.map(slug => ({
|
||||
title: albums[slug].title,
|
||||
cover: albums[slug].cover,
|
||||
url: `/songs/${circle}/${slug}/`
|
||||
}))
|
||||
---
|
||||
|
||||
<Base>
|
||||
<main>
|
||||
<article>
|
||||
<Header title={CIRCLES[circle].name} />
|
||||
<section class="l-album-grid">
|
||||
{items.map(album => <Album album={album} />)}
|
||||
</section>
|
||||
</article>
|
||||
</main>
|
||||
</Base>
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
import Base from "../../layouts/Base.astro";
|
||||
import Header from '../../components/headers/Base.astro';
|
||||
import Base from "@layouts/Base.astro";
|
||||
import Header from '@components/headers/Base.astro';
|
||||
import { CollectionEntry, getCollection } from 'astro:content';
|
||||
import { ALBUMS, getAllCats } from "../../utils/songs/data";
|
||||
import { ALBUMS, getAllCats, order } from "@utils/songs/data";
|
||||
|
||||
|
||||
export async function getStaticPaths() {
|
||||
|
@ -10,11 +10,15 @@ export async function getStaticPaths() {
|
|||
const cats = getAllCats(songs);
|
||||
|
||||
return [...cats].map(cat => ({
|
||||
params: {cat},
|
||||
params: { circle: ALBUMS[cat].circle, cat },
|
||||
props: {
|
||||
songs: songs
|
||||
.filter(entry => cat in entry.data.album)
|
||||
.map(song => ({ frontmatter: song.data, slug: `/songs/${cat}/${song.slug}/` }))
|
||||
.sort(order(cat))
|
||||
.map(song => ({
|
||||
frontmatter: song.data,
|
||||
slug: `/songs/${ALBUMS[cat].circle}/${cat}/${song.slug}/`
|
||||
}))
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
@ -34,7 +38,7 @@ const album = ALBUMS[cat!];
|
|||
<Base>
|
||||
<main class="l-songs-cat">
|
||||
<article class="l-songs-cat__article">
|
||||
<Header title={`${cat} - ${album.title}`} />
|
||||
<Header title={album.title} />
|
||||
<div class="l-songs-cat__list">
|
||||
{songs.map(song => [
|
||||
<span>{song.frontmatter.album[cat!].track}</span>
|
|
@ -1,15 +1,18 @@
|
|||
---
|
||||
import Base from "../../layouts/Base.astro";
|
||||
import Song from "../../components/markdown/Song.astro";
|
||||
import Lyrics from "../../components/markdown/Lyrics.astro";
|
||||
import Base from "@layouts/Base.astro";
|
||||
import Song from "@components/markdown/Song.astro";
|
||||
import Lyrics from "@components/markdown/Lyrics.astro";
|
||||
import { CollectionEntry, getCollection } from "astro:content";
|
||||
import { ALBUMS } from "../../utils/songs/data";
|
||||
import { ALBUMS } from "@utils/songs/data";
|
||||
|
||||
|
||||
export async function getStaticPaths() {
|
||||
return (await getCollection('songs'))
|
||||
.map(song => Object.keys(song.data.album)
|
||||
.map(cat => ({ params: {slug: `${cat}/${song.slug}`}, props: {song, cat} })))
|
||||
.map(cat => ({
|
||||
params: { circle: ALBUMS[cat].circle, cat, song: song.slug},
|
||||
props: { song, cat }
|
||||
})))
|
||||
.flat()
|
||||
}
|
||||
|
|
@ -1,16 +1,11 @@
|
|||
---
|
||||
import List from "../../layouts/List.astro";
|
||||
import { getCollection } from 'astro:content';
|
||||
import { ALBUMS, getAllCats } from "../../utils/songs/data";
|
||||
import { CIRCLES } from "../../utils/songs/data";
|
||||
|
||||
|
||||
const pages = [...getAllCats(await getCollection('songs'))]
|
||||
.sort((a, b) => a < b ? 1 : -1)
|
||||
.map(catalog => ({
|
||||
title: `${catalog} - ${ALBUMS[catalog].title}`,
|
||||
slug: `/songs/${catalog}/`
|
||||
}));
|
||||
|
||||
const pages = Object.keys(CIRCLES)
|
||||
.map(slug => ({ title: CIRCLES[slug].name, slug: `/songs/${slug}/` }))
|
||||
.sort((a, b) => a.title < b.title ? -1 : 1)
|
||||
---
|
||||
|
||||
<List title="Albums" pages={pages} />
|
||||
<List title="Circles" pages={pages}/>
|
||||
|
|
5
src/schema.d.ts
vendored
5
src/schema.d.ts
vendored
|
@ -1,9 +1,10 @@
|
|||
/** @file src/data/circles.json */
|
||||
interface CirclesSchema {
|
||||
/** Circle name */
|
||||
/** slug */
|
||||
[key: string]: {
|
||||
name: string,
|
||||
albums: {
|
||||
/** Catalog number */
|
||||
/** catalog number */
|
||||
[key: string]: {
|
||||
title: string;
|
||||
cover: string;
|
||||
|
|
16
src/styles/components/_album.scss
Normal file
16
src/styles/components/_album.scss
Normal file
|
@ -0,0 +1,16 @@
|
|||
.c-album {
|
||||
padding: 0.5em;
|
||||
background-color: white;
|
||||
border-radius: 0.5em;
|
||||
box-shadow: var(--shadow-l);
|
||||
transition: box-shadow ease-in-out 0.2s;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
box-shadow: var(--shadow-m);
|
||||
}
|
||||
|
||||
&__image {
|
||||
width: 16em;
|
||||
}
|
||||
}
|
|
@ -1,3 +1,14 @@
|
|||
.l-album-grid {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 2em;
|
||||
|
||||
&__item img {
|
||||
width: 20em;
|
||||
height: 20em;
|
||||
}
|
||||
}
|
||||
|
||||
.l-songs-cat {
|
||||
padding: 1.5em;
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
@use 'components/tab';
|
||||
@use 'components/lyrics';
|
||||
@use 'components/song';
|
||||
@use 'components/album';
|
||||
|
||||
// Partials
|
||||
@use 'partials/nav';
|
||||
|
|
|
@ -6,8 +6,10 @@ type Song = CollectionEntry<'songs'>;
|
|||
|
||||
interface Metadata {
|
||||
[key: string]: {
|
||||
/** Circle slug */
|
||||
circle: string;
|
||||
/** Circle name */
|
||||
circle: string,
|
||||
name: string,
|
||||
/** Album title */
|
||||
title: string,
|
||||
/** Path to album cover image */
|
||||
|
@ -16,6 +18,10 @@ interface Metadata {
|
|||
}
|
||||
|
||||
|
||||
export function order(cat: string) {
|
||||
return (a: Song, b: Song) => a.data.album[cat].track < b.data.album[cat].track ? -1 : 1;
|
||||
}
|
||||
|
||||
export function getAllCats(songs: Song[]): Set<string> {
|
||||
return songs.reduce(
|
||||
(cats, next) => (
|
||||
|
@ -32,10 +38,10 @@ function createMetadata(circles: CirclesSchema): Metadata {
|
|||
for (const circle of Object.keys(circles)) {
|
||||
const data = circles[circle];
|
||||
for (const cat of Object.keys(data.albums))
|
||||
metadata[cat] = { circle, ...data.albums[cat] }
|
||||
metadata[cat] = { circle, name: data.name, ...data.albums[cat] }
|
||||
}
|
||||
return metadata;
|
||||
}
|
||||
|
||||
|
||||
export const CIRCLES: CirclesSchema = circles;
|
||||
export const ALBUMS: Metadata = createMetadata(circles);
|
||||
|
|
|
@ -15,6 +15,7 @@ function increaseStack(data: Stack, lang: string) {
|
|||
|
||||
function fromMarkdown(markdown: string): Stack {
|
||||
const stack: Stack = {};
|
||||
if (!markdown) return stack;
|
||||
|
||||
let space = true;
|
||||
let lang = '';
|
||||
|
|
|
@ -3,6 +3,12 @@
|
|||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"jsx": "preserve",
|
||||
"jsxImportSource": "solid-js"
|
||||
}
|
||||
"jsxImportSource": "solid-js",
|
||||
"baseUrl": "src",
|
||||
"paths": {
|
||||
"@layouts/*": ["layouts/*"],
|
||||
"@components/*": ["components/*"],
|
||||
"@utils/*": ["utils/*"],
|
||||
}
|
||||
},
|
||||
}
|
Loading…
Reference in a new issue