mirror of
https://github.com/BradNut/personal-website-sveltekit
synced 2025-09-08 23:20:18 +00:00
Adding fetch bandcamp albums and showing them on the main home page, also caching response.
This commit is contained in:
parent
a0bebf3f5a
commit
0f5248bee0
9 changed files with 163 additions and 6 deletions
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"cSpell.words": [
|
||||
"Bandcamp",
|
||||
"bradleyshellnut",
|
||||
"iconify",
|
||||
"Mullvad",
|
||||
|
|
|
|||
90
src/lib/components/bandcamp/index.svelte
Normal file
90
src/lib/components/bandcamp/index.svelte
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
<script lang="ts">
|
||||
import type { Album } from "$root/lib/types/album";
|
||||
|
||||
|
||||
export let albums: Album[];
|
||||
const displayAlbums =
|
||||
albums?.length > 6 ? albums.slice(0, 6) : albums;
|
||||
</script>
|
||||
|
||||
<div>
|
||||
<h2>Currently listening to:</h2>
|
||||
<div class="albumsStyles">
|
||||
{#each displayAlbums as album}
|
||||
<div>
|
||||
<figure>
|
||||
<a
|
||||
title={`Link to ${album.title} by ${album.artist}`}
|
||||
target="_blank"
|
||||
href={album.url}
|
||||
rel="noreferrer"
|
||||
>
|
||||
<img
|
||||
src={`https://images.weserv.nl/?url=${encodeURIComponent(
|
||||
album.artwork
|
||||
)}&w=230&h=230`}
|
||||
alt={`Album art for ${album.title}`}
|
||||
/>
|
||||
</a>
|
||||
</figure>
|
||||
<a
|
||||
target="_blank"
|
||||
href={album.url}
|
||||
rel="noreferrer"
|
||||
>
|
||||
<h3>{album.title.length > 20 ? `${album.title.slice(0, 20)}...` : album.title}</h3>
|
||||
<h3>by {album.artist}</h3>
|
||||
</a>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style lang="postcss">
|
||||
.albumsStyles {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(auto, 1fr));
|
||||
gap: 1rem;
|
||||
|
||||
@media (max-width: 1000px) {
|
||||
grid-template-columns: repeat(2, minmax(150px, 1fr));
|
||||
img {
|
||||
width: 230px;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 575px) {
|
||||
height: 500px;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
::-webkit-scrollbar {
|
||||
width: 12px;
|
||||
}
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: var(--lightGrey) var(--darkGrey);
|
||||
::-webkit-scrollbar-track {
|
||||
background: var(--darkGrey);
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
background-color: var(--lightGrey);
|
||||
border-radius: 6px;
|
||||
border: 3px solid var(--darkGrey);
|
||||
}
|
||||
grid-template-columns: minmax(230px, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
.albumStyles {
|
||||
display: grid;
|
||||
justify-content: center;
|
||||
text-align: center;
|
||||
|
||||
@media (max-width: 550px) {
|
||||
grid-template-columns: 0.75fr 0.75fr;
|
||||
font-size: 1rem;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
6
src/lib/types/album.ts
Normal file
6
src/lib/types/album.ts
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
export type Album = {
|
||||
url: string;
|
||||
artwork: string;
|
||||
title: string;
|
||||
artist: string;
|
||||
};
|
||||
40
src/lib/util/fetchBandcampAlbums.ts
Normal file
40
src/lib/util/fetchBandcampAlbums.ts
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
// import * as htmlparser2 from 'htmlparser2';
|
||||
import scrapeIt from 'scrape-it';
|
||||
import type { Album } from '../types/album';
|
||||
|
||||
export async function fetchBandcampAlbums() {
|
||||
try {
|
||||
const { data } = await scrapeIt('https://bandcamp.com/royvalentine', {
|
||||
collectionItems: {
|
||||
listItem: '.collection-item-container',
|
||||
data: {
|
||||
url: {
|
||||
selector: '.collection-title-details > a.item-link',
|
||||
attr: 'href'
|
||||
},
|
||||
artwork: {
|
||||
selector: 'div.collection-item-art-container a img',
|
||||
attr: 'src'
|
||||
},
|
||||
title: {
|
||||
selector: 'span.item-link-alt > div.collection-item-title'
|
||||
},
|
||||
artist: {
|
||||
selector: 'span.item-link-alt > div.collection-item-artist'
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const albums: Album[] = data?.collectionItems || [];
|
||||
console.log(`Albums ${JSON.stringify(albums)}`);
|
||||
|
||||
if (albums && albums?.length > 0) {
|
||||
return albums;
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
12
src/routes/+page.server.ts
Normal file
12
src/routes/+page.server.ts
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
import type { PageServerLoad } from './lib/$types';
|
||||
import { fetchBandcampAlbums } from '$root/lib/util/fetchBandcampAlbums';
|
||||
|
||||
export const load: PageServerLoad = async ({ setHeaders }) => {
|
||||
const albums = await fetchBandcampAlbums();
|
||||
setHeaders({
|
||||
'cache-control': 'max-age=43200'
|
||||
});
|
||||
return {
|
||||
albums
|
||||
};
|
||||
};
|
||||
|
|
@ -1,7 +1,13 @@
|
|||
<script lang="ts">
|
||||
import SEO from '$root/lib/components/SEO.svelte';
|
||||
import type { PageData } from './$types';
|
||||
import Bandcamp from '$lib/components/bandcamp/index.svelte';
|
||||
import SEO from '$lib/components/SEO.svelte';
|
||||
import type { Album } from '$root/lib/types/album';
|
||||
|
||||
export let data: PageData;
|
||||
let albums: Album[];
|
||||
$: ({ albums } = data);
|
||||
|
||||
// export let data: PageData;
|
||||
const userNames = {
|
||||
github: 'BradNut',
|
||||
linkedIn: 'bradley-shellnut',
|
||||
|
|
@ -57,7 +63,7 @@
|
|||
</p>
|
||||
</div>
|
||||
<div class="social-info">
|
||||
<!-- <Bandcamp /> -->
|
||||
<Bandcamp {albums} />
|
||||
<!-- <Articles /> -->
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ export async function fetchArticlesApi(
|
|||
articles.push({
|
||||
tags,
|
||||
title: article.title,
|
||||
url: article.url,
|
||||
url: new URL(article.url),
|
||||
hashed_url: article.hashed_url,
|
||||
reading_time: article.reading_time,
|
||||
preview_picture: article.preview_picture,
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
<a
|
||||
target="_blank"
|
||||
aria-label={`Link to ${article.title}`}
|
||||
href={article.url.href}
|
||||
href={article.url}
|
||||
rel="noreferrer"
|
||||
>
|
||||
{article.title}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,9 @@
|
|||
import shellnutArchitectWebsiteBlurred from "$lib/assets/images/Mark_Shellnut_Architect.png?w=100&png&blur=10";
|
||||
</script>
|
||||
|
||||
<SEO title="Portfolio" />
|
||||
<svelte:head>
|
||||
<title>Portfolio | Bradley Shellnut</title>
|
||||
</svelte:head>
|
||||
|
||||
<h1>Portfolio!</h1>
|
||||
<div class="portfolioTabStyles">
|
||||
|
|
|
|||
Loading…
Reference in a new issue