feat(chat): integrate podcast support into chat components

- Updated ChatMessage and ChatWindow components to handle podcast content alongside films and songs.
- Enhanced useContentPanel to extract and manage podcasts, allowing for richer media interactions.
- Added PodcastCard and PodcastGrid components for displaying podcast information.
- Improved UI elements to accommodate podcast selection and detail viewing.
- Updated styles for empty state icons and added new CSS for podcast-related elements.

Made-with: Cursor
This commit is contained in:
Dorian
2026-03-02 19:57:44 +00:00
parent 7a0e42bf63
commit 49ec6c09b6
18 changed files with 890 additions and 39 deletions
+15 -2
View File
@@ -8,6 +8,7 @@ const OPENROUTER_PATH = '/api/openrouter/api/v1/chat/completions'
import { mockFilms } from '@/mocks/films'
import { mockSongs } from '@/mocks/songs'
import { mockPodcasts } from '@/mocks/podcasts'
const filmContext = mockFilms.map((f) =>
`- [${f.id}] "${f.title}" (${f.year}) dir. ${f.director} | ${f.genres.join(', ')} | ${f.rating}/10 | On: ${f.sources.map(s => s.type).join(', ')}`
@@ -17,7 +18,11 @@ const songContext = mockSongs.map((s) =>
`- [${s.id}] "${s.title}" by ${s.artist}${s.album ? ` (${s.album})` : ''}${s.year ? ` (${s.year})` : ''} | ${(s.genres ?? []).join(', ')} | On: ${(s.sources ?? []).map(x => x.type).join(', ')}`
).join('\n')
const SYSTEM_PROMPT = `You are AIUI, a helpful AI assistant with access to the user's media library (films and songs).
const podcastContext = mockPodcasts.map((p) =>
`- [${p.id}] "${p.title}" by ${p.host ?? 'Unknown'}${p.year ? ` (${p.year})` : ''} | ${(p.genres ?? []).join(', ')} | On: ${p.sources.map(x => x.type).join(', ')}`
).join('\n')
const SYSTEM_PROMPT = `You are AIUI, a helpful AI assistant with access to the user's media library (films, songs, and podcasts).
**Films:** When recommending or discussing films from the user's library, use [[film:ID]] where ID is the film's id. For films NOT in the library, use [[film_ext:Title|Year|Director]], e.g. [[film_ext:Brokeback Mountain|2005|Ang Lee]].
@@ -26,6 +31,11 @@ const SYSTEM_PROMPT = `You are AIUI, a helpful AI assistant with access to the u
- Other songs: [[song_ext:Title|Artist|Year]] (year optional), e.g. [[song_ext:Never Meant|American Football|1999]].
Never list songs in plain text only—each recommendation must have a tag so the UI can show playable cards.
**Podcasts:** When recommending or discussing podcasts, use tags:
- Library podcasts: [[podcast:ID]] where ID is the podcast's id (e.g. [[podcast:p1]]).
- Other podcasts: [[podcast_ext:Title|Host|Year]] (year optional), e.g. [[podcast_ext:What Bitcoin Did|Peter McCormack|2018]].
Prioritize Podcasting 2.0friendly platforms: Fountain.fm, Podcast Index, Castopod, Odysee, Rumble, YouTube, Podverse.
**Music discovery:** For genre-based requests (e.g. "best math rock"), pick from the user's library when relevant, or use [[song_ext:...]] for others. Prioritize indie-friendly platforms: Wavlake, Bandcamp, Internet Archive, SoundCloud, Odysee, Jamendo.
Always include these tags so the UI can render rich cards. Write a brief reason why each is worth checking out.
@@ -34,7 +44,10 @@ The user's film library:
${filmContext}
The user's song library:
${songContext}`
${songContext}
The user's podcast library:
${podcastContext}`
const openrouterApiKey = import.meta.env.VITE_OPENROUTER_API_KEY ?? ''
const hasOpenRouter = !!openrouterApiKey