Inbäddad mini-spelare: ▶ på korten spelar direkt i appen
All checks were successful
build-and-push / build (push) Successful in 14s

- GET /api/play?q=: slår upp spelbart videoId via YouTube Data API
  (kategori musik, YOUTUBE_API_KEY i stackens .env)
- MiniPlayer: fast spelare nere till höger (YouTube-embed, autoplay),
  ligger kvar medan man bläddrar; stängs med ✕
- MusicCard: ▶-knapp på artist/album/låt/sångare (genrer behåller sina
  två knappar); YT-länken heter nu 'YT ↗'
- 2 nya tester, totalt 31

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01824ZrvG2mDYYrmwqypLNup
This commit is contained in:
2026-08-01 04:38:33 +02:00
parent 4e89bd1986
commit 9874d383ea
7 changed files with 174 additions and 8 deletions

View File

@@ -235,6 +235,33 @@ export function buildApp(config, deps = {}) {
}
})
// Slår upp ett spelbart video-id för mini-spelaren (YouTube Data API,
// kategori 10 = musik)
app.get('/api/play', async (req, reply) => {
const q = (req.query.q ?? '').trim()
if (!q) return reply.code(400).send({ error: 'sökterm saknas' })
const key = config.youtube?.apiKey
if (!key) return reply.code(500).send({ error: 'YOUTUBE_API_KEY saknas i stackens .env' })
try {
const url =
`https://www.googleapis.com/youtube/v3/search?part=snippet&type=video` +
`&videoCategoryId=10&maxResults=1&q=${encodeURIComponent(q)}&key=${encodeURIComponent(key)}`
const res = await (deps.playFetch ?? fetch)(url)
if (!res.ok) return reply.code(502).send({ error: `YouTube svarade ${res.status}` })
const js = await res.json()
const hit = js.items?.[0]
if (!hit) return reply.code(404).send({ error: 'ingen video hittades' })
return {
videoId: hit.id.videoId,
title: hit.snippet?.title ?? q,
channel: hit.snippet?.channelTitle ?? '',
}
} catch (err) {
req.log.warn({ err }, 'play-uppslag misslyckades')
return reply.code(502).send({ error: 'kunde inte nå YouTube' })
}
})
app.get('/api/suggest/items', async (req) => {
const type = SUGGEST_TYPES.includes(req.query.type) ? req.query.type : 'mix'
return suggest.allItems(type)

View File

@@ -20,6 +20,9 @@ export function loadConfig(env = process.env) {
apiKey: env.GEMINI_API_KEY ?? '',
model: env.GEMINI_MODEL ?? 'gemini-2.5-flash',
},
youtube: {
apiKey: env.YOUTUBE_API_KEY ?? '',
},
youtubarr: {
url: env.YOUTUBARR_URL ?? 'http://youtubarr',
dataDir: env.YOUTUBARR_DATA ?? '/youtubarr-data',