@@ -31,7 +32,7 @@ export function NowPlaying({ apiRoot, track }: { apiRoot: string; track: QueueIt
)
}
- const coverUrl = `${apiRoot}/tracks/${track.slug}/cover`
+ const coverUrl = `${API_ROOT}/tracks/${track.slug}/cover`
return (
diff --git a/furumi-node-player/client/src/components/PlayerBar.tsx b/furumi-node-player/client/src/components/PlayerBar.tsx
new file mode 100644
index 0000000..48fcdff
--- /dev/null
+++ b/furumi-node-player/client/src/components/PlayerBar.tsx
@@ -0,0 +1,47 @@
+import { NowPlaying } from './NowPlaying'
+import type { QueueItem } from './QueueList'
+
+export function PlayerBar({ track }: { track: QueueItem | null }) {
+ return (
+
+
+
+
+
+
+
+
+
+
+ 0:00
+
+
+
+ 0:00
+
+
+
+
+
+ 🔊
+
+
+
+
+ )
+}
diff --git a/furumi-node-player/client/src/components/QueueList.tsx b/furumi-node-player/client/src/components/QueueList.tsx
index f1529fe..c371f09 100644
--- a/furumi-node-player/client/src/components/QueueList.tsx
+++ b/furumi-node-player/client/src/components/QueueList.tsx
@@ -1,4 +1,5 @@
import { useEffect, useRef, useState } from 'react'
+import { API_ROOT } from '../furumiApi'
export type QueueItem = {
slug: string
@@ -9,7 +10,6 @@ export type QueueItem = {
}
type QueueListProps = {
- apiRoot: string
queue: QueueItem[]
order: number[]
playingOrigIdx: number
@@ -43,7 +43,6 @@ function Cover({ src }: { src: string }) {
}
export function QueueList({
- apiRoot,
queue,
order,
playingOrigIdx,
@@ -78,7 +77,7 @@ export function QueueList({
if (!t) return null
const isPlaying = origIdx === playingOrigIdx
- const coverSrc = t.album_slug ? `${apiRoot}/tracks/${t.slug}/cover` : ''
+ const coverSrc = t.album_slug ? `${API_ROOT}/tracks/${t.slug}/cover` : ''
const dur = t.duration ? fmt(t.duration) : ''
const isDragging = draggingPos === pos
const isDragOver = dragOverPos === pos
diff --git a/furumi-node-player/client/src/furumiApi.ts b/furumi-node-player/client/src/furumiApi.ts
index 412b656..e7518ec 100644
--- a/furumi-node-player/client/src/furumiApi.ts
+++ b/furumi-node-player/client/src/furumiApi.ts
@@ -1,12 +1,49 @@
-export type FurumiApiClient = (path: string) => Promise
+import axios from 'axios'
+import type { Album, Artist, SearchResult, Track, TrackDetail } from './types'
-export function createFurumiApiClient(apiRoot: string): FurumiApiClient {
- const API = apiRoot
+const API_BASE = import.meta.env.VITE_API_BASE_URL ?? ''
+export const API_ROOT = `${API_BASE}/api`
- return async function api(path: string) {
- const r = await fetch(API + path)
- if (!r.ok) return null
- return r.json()
- }
+const API_KEY = import.meta.env.VITE_API_KEY
+
+export const furumiApi = axios.create({
+ baseURL: API_ROOT,
+ headers: API_KEY ? { 'x-api-key': API_KEY } : {},
+})
+
+export async function getArtists(): Promise {
+ const res = await furumiApi.get('/artists').catch(() => null)
+ return res?.data ?? null
+}
+
+export async function getArtistAlbums(artistSlug: string): Promise {
+ const res = await furumiApi.get(`/artists/${artistSlug}/albums`).catch(() => null)
+ return res?.data ?? null
+}
+
+export async function getAlbumTracks(albumSlug: string): Promise