feat: added cors for web-player-backend

This commit is contained in:
Boris Cherepanov
2026-03-23 12:34:27 +03:00
parent f26135ca25
commit 310f0061d3
10 changed files with 323 additions and 39 deletions
+14 -23
View File
@@ -1,19 +1,15 @@
import { useEffect, useRef, useState, type MouseEvent as ReactMouseEvent } from 'react'
import './furumi-player.css'
import { createFurumiApiClient } from './furumiApi'
import { API_ROOT, furumiApi } from './furumiApi'
import { SearchDropdown } from './components/SearchDropdown'
import { Breadcrumbs } from './components/Breadcrumbs'
import { LibraryList } from './components/LibraryList'
import { QueueList, type QueueItem } from './components/QueueList'
import { NowPlaying } from './components/NowPlaying'
type FurumiPlayerProps = {
apiRoot: string
}
type Crumb = { label: string; action?: () => void }
export function FurumiPlayer({ apiRoot }: FurumiPlayerProps) {
export function FurumiPlayer() {
const [breadcrumbs, setBreadcrumbs] = useState<Array<{ label: string; action?: () => void }>>(
[],
)
@@ -106,16 +102,12 @@ export function FurumiPlayer({ apiRoot }: FurumiPlayerProps) {
nextTrack()
})
// --- API helper ---
const API = apiRoot
const api = createFurumiApiClient(API)
// --- Library navigation ---
async function showArtists() {
setBreadcrumb([{ label: 'Artists', action: showArtists }])
setLibraryLoading(true)
setLibraryError(null)
const artists = await api('/artists')
const artists = (await furumiApi.get('/artists').catch(() => null))?.data ?? null
if (!artists) {
setLibraryLoading(false)
setLibraryError('Error')
@@ -141,7 +133,7 @@ export function FurumiPlayer({ apiRoot }: FurumiPlayerProps) {
])
setLibraryLoading(true)
setLibraryError(null)
const albums = await api('/artists/' + artistSlug + '/albums')
const albums = (await furumiApi.get('/artists/' + artistSlug + '/albums').catch(() => null))?.data ?? null
if (!albums) {
setLibraryLoading(false)
setLibraryError('Error')
@@ -190,7 +182,7 @@ export function FurumiPlayer({ apiRoot }: FurumiPlayerProps) {
])
setLibraryLoading(true)
setLibraryError(null)
const tracks = await api('/albums/' + albumSlug)
const tracks = (await furumiApi.get('/albums/' + albumSlug).catch(() => null))?.data ?? null
if (!tracks) {
setLibraryLoading(false)
setLibraryError('Error')
@@ -260,7 +252,7 @@ export function FurumiPlayer({ apiRoot }: FurumiPlayerProps) {
}
async function addAlbumToQueue(albumSlug: string, playFirst?: boolean) {
const tracks = await api('/albums/' + albumSlug)
const tracks = (await furumiApi.get('/albums/' + albumSlug).catch(() => null))?.data ?? null
if (!tracks || !(tracks as any[]).length) return
const list = tracks as any[]
let firstIdx = queue.length
@@ -280,7 +272,7 @@ export function FurumiPlayer({ apiRoot }: FurumiPlayerProps) {
}
async function playAllArtistTracks(artistSlug: string) {
const tracks = await api('/artists/' + artistSlug + '/tracks')
const tracks = (await furumiApi.get('/artists/' + artistSlug + '/tracks').catch(() => null))?.data ?? null
if (!tracks || !(tracks as any[]).length) return
const list = tracks as any[]
clearQueue()
@@ -302,7 +294,7 @@ export function FurumiPlayer({ apiRoot }: FurumiPlayerProps) {
if (i < 0 || i >= queue.length) return
queueIndex = i
const track = queue[i]
audio.src = `${API}/stream/${track.slug}`
audio.src = `${API_ROOT}/stream/${track.slug}`
void audio.play().catch(() => {})
updateNowPlaying(track)
updateQueueModel()
@@ -320,7 +312,7 @@ export function FurumiPlayer({ apiRoot }: FurumiPlayerProps) {
document.title = `${track.title} — Furumi`
const coverUrl = `${API}/tracks/${track.slug}/cover`
const coverUrl = `${API_ROOT}/tracks/${track.slug}/cover`
if ('mediaSession' in navigator) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
navigator.mediaSession.metadata = new window.MediaMetadata({
@@ -495,7 +487,7 @@ export function FurumiPlayer({ apiRoot }: FurumiPlayerProps) {
return
}
searchTimer = window.setTimeout(async () => {
const results = await api('/search?q=' + encodeURIComponent(q))
const results = (await furumiApi.get('/search?q=' + encodeURIComponent(q)).catch(() => null))?.data ?? null
if (!results || !(results as any[]).length) {
closeSearch()
return
@@ -519,7 +511,7 @@ export function FurumiPlayer({ apiRoot }: FurumiPlayerProps) {
{ slug, title: '', artist: '', album_slug: null, duration: null },
true,
)
void api('/stream/' + slug).catch(() => null)
void furumiApi.get('/stream/' + slug).catch(() => null)
}
}
searchSelectRef.current = onSearchSelect
@@ -625,7 +617,7 @@ export function FurumiPlayer({ apiRoot }: FurumiPlayerProps) {
const url = new URL(window.location.href)
const urlSlug = url.searchParams.get('t')
if (urlSlug) {
const info = await api('/tracks/' + urlSlug)
const info = (await furumiApi.get('/tracks/' + urlSlug).catch(() => null))?.data ?? null
if (info) {
addTrackToQueue(
{
@@ -647,7 +639,7 @@ export function FurumiPlayer({ apiRoot }: FurumiPlayerProps) {
queueActionsRef.current = null
audio.pause()
}
}, [apiRoot])
}, [])
return (
<div className="furumi-root">
@@ -701,7 +693,6 @@ export function FurumiPlayer({ apiRoot }: FurumiPlayerProps) {
</div>
<div className="queue-list" id="queueList">
<QueueList
apiRoot={apiRoot}
queue={queueItemsView}
order={queueOrderView}
playingOrigIdx={queuePlayingOrigIdxView}
@@ -719,7 +710,7 @@ export function FurumiPlayer({ apiRoot }: FurumiPlayerProps) {
</div>
<div className="player-bar">
<NowPlaying apiRoot={apiRoot} track={nowPlayingTrack} />
<NowPlaying track={nowPlayingTrack} />
<div className="controls">
<div className="ctrl-btns">
<button className="ctrl-btn" id="btnPrev">