Skip to content

Commit

Permalink
feat: fetch albums from Last.fm, show them in sidebar
Browse files Browse the repository at this point in the history
  • Loading branch information
Miguel Parramón Teixidó committed Apr 19, 2023
1 parent ac90b8b commit 7b69edc
Show file tree
Hide file tree
Showing 9 changed files with 75 additions and 29 deletions.
29 changes: 24 additions & 5 deletions src/albums.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,30 @@ import sortBy from 'sort-by'

export async function getAlbums(query?: string) {
await fakeNetwork(`getAlbums:${query ?? ''}`)
let albums = (await localforage.getItem<Album[]>('albums')) ?? []
if (query) {
albums = matchSorter(albums, query, { keys: ['first', 'last'] })
}
return albums.sort(sortBy('-last', 'createdAt'))

// Use fetch to make an HTTP request to the Last.fm API
const response = await fetch(
'http://ws.audioscrobbler.com/2.0/' +
'?method=artist.gettopalbums' +
'&artist=David Bowie' +
'&api_key=035db7391c866de91ad8767bbb32c4f7' +
'&format=json'
)

const data = await response.json()

const albums = data.topalbums.album.map((album: Album) => ({
id: album.mbid || `${album.artist.name}-${album.name}}`,
name: album.name,
artist: album.artist,
createdAt: Date.now()
}))

const sortedAlbums = query
? matchSorter(albums, query, { keys: ['first', 'last'] })
: albums

return sortedAlbums.sort(sortBy('-last', 'createdAt'))
}

export async function createAlbum() {
Expand Down
2 changes: 1 addition & 1 deletion src/data/albums/davidBowie1969Album.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export const davidBowie1969Album: Album = {
artist: 'David Bowie',
artist: { name: 'David Bowie' },
mbid: '',
tags: {
tag: [
Expand Down
3 changes: 2 additions & 1 deletion src/routes.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import ErrorPage from './error-page'
import './index.css'
import Album from './routes/album'
import Root from './routes/root'
import Root, { loader as rootLoader } from './routes/root'

export const routes = [
{
path: '/',
element: <Root />,
errorElement: <ErrorPage />,
loader: rootLoader,
children: [
{
path: '/albums/:albumId',
Expand Down
12 changes: 1 addition & 11 deletions src/routes/album.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,7 @@ export default function Album() {
</h1>

{/* TODO link to artist */}
{album.artist && (
<p>
{/* <a
target="_blank"
href={`https://twitter.com/${album.artist}`}
rel="noreferrer"
> */}
{album.artist}
{/* </a> */}
</p>
)}
{album.artist && <p>{album.artist.name}</p>}

{album.wiki?.summary && (
<AlbumSummary>{album.wiki.summary}</AlbumSummary>
Expand Down
38 changes: 29 additions & 9 deletions src/routes/root.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
import { Link, Outlet } from 'react-router-dom'
import type { LoaderFunction } from 'react-router-dom'
import { Link, Outlet, useLoaderData } from 'react-router-dom'
import { getAlbums } from '../albums'
import { LoaderData } from '../types/react-router-extra-types'

// change this to use funtion:
export const loader = (async () => {
const albums = await getAlbums()
return { albums }
}) satisfies LoaderFunction

export default function Root() {
const { albums }: { albums: Album[] } = useLoaderData() as LoaderData<
typeof loader
>
return (
<>
<div id="sidebar">
Expand All @@ -22,14 +34,22 @@ export default function Root() {
</form>
</div>
<nav>
<ul>
<li>
<Link to="/albums/1">David Bowie (1969)</Link>
</li>
{/* <li>
<Link to="/albums/2">The Man Who Sold the World</Link>
</li> */}
</ul>
{albums.length ? (
<ul>
{albums.map((album) => (
<li key={album.id}>
<Link to={`albums/${album.id}`}>
{album.name ? album.name : <i>No Name</i>}{' '}
{album.favorite && <span></span>}
</Link>
</li>
))}
</ul>
) : (
<p>
<i>No albums</i>
</p>
)}
</nav>
</div>
<div id="detail">
Expand Down
2 changes: 1 addition & 1 deletion src/types/album.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ interface Album {
favorite?: boolean

// Last.fm properties
artist: string
artist: Artist
mbid: string
tags: {
tag: {
Expand Down
9 changes: 9 additions & 0 deletions src/types/artist.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
interface Artist {
// webapp properties
id?: string
favorite?: boolean

// Last.fm properties
name: string
// TODO
}
7 changes: 7 additions & 0 deletions src/types/react-router-extra-types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { LoaderFunction } from 'react-router-dom'

export type LoaderData<TLoaderFn extends LoaderFunction> = Awaited<
ReturnType<TLoaderFn>
> extends Response | infer D
? D
: never
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@
"noEmit": true,
"jsx": "react-jsx"
},
"include": ["src", ".eslintrc.js", "src/*.d.ts"]
"include": ["src", ".eslintrc.js", "src/**/*.d.ts"]
}

1 comment on commit 7b69edc

@vercel
Copy link

@vercel vercel bot commented on 7b69edc Apr 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

aladdin-sane – ./

aladdin-sane-git-main-mparramont.vercel.app
aladdin-sane-mparramont.vercel.app
aladdin-sane.vercel.app

Please sign in to comment.