music-app/mobile/app/lofi.tsx
Jarian Cottingham 7e09799859 fix: batch fix all issues
- Add auth middleware (API key) to protect API routes (#5, #7)
- Add WebSocket handlers and cleanup on disconnect (#3, #8)
- Add web Dockerfile (#1)
- Fix memory upload with streaming chunks (#10)
- Move lofi seed to startup, remove per-request seeding (#9)
- Document ffmpeg dependency in README and .env.example (#6)
- Fill in mobile app with API-connected UI (#4)
- Set GENIUS_API_KEY from env var with documentation (#2)
2026-07-05 21:36:59 +00:00

69 lines
2.5 KiB
TypeScript

import { View, Text, ScrollView, TouchableOpacity, ActivityIndicator } from 'react-native'
import { useRouter } from 'expo-router'
import { BottomNavBar } from '../src/components/BottomNavBar'
import { usePlayerStore } from '../src/store/playerStore'
import { useState, useEffect } from 'react'
export default function LofiScreen() {
const router = useRouter()
const [channels, setChannels] = useState([])
const [loading, setLoading] = useState(true)
useEffect(() => {
fetchChannels()
}, [])
const fetchChannels = async () => {
try {
const res = await fetch('/api/lofi/channels')
const data = await res.json()
setChannels(data || [])
} catch {
setChannels([])
} finally {
setLoading(false)
}
}
return (
<View className="flex-1 bg-music-black">
<ScrollView className="flex-1 px-4 pt-4">
<View className="flex-row items-center justify-between mb-6">
<TouchableOpacity onPress={() => router.push('/account' as any)} className="w-10 h-10 rounded-full bg-music-card items-center justify-center">
<Text className="text-music-muted">👤</Text>
</TouchableOpacity>
<Text className="text-xl font-semibold text-music-text">LoFi Channels</Text>
<View className="w-10" />
</View>
{loading ? (
<View className="items-center py-8">
<ActivityIndicator size="large" color="#e94560" />
</View>
) : (
channels.map((ch: any) => (
<TouchableOpacity key={ch.id} className="mb-4 rounded-2xl bg-music-card overflow-hidden">
<View className="h-40 justify-center items-center bg-music-vinyl relative">
<Text className="text-5xl">🎵</Text>
<View className="p-4 bg-black/80 absolute bottom-0 left-0 right-0 rounded-b-2xl">
<Text className="text-xs text-music-accent">LoFi</Text>
<Text className="text-sm font-medium text-music-text">{ch.name}</Text>
<Text className="text-xs text-music-muted mt-1">{ch.description}</Text>
</View>
</View>
</TouchableOpacity>
))
)}
{channels.length === 0 && !loading && (
<View className="items-center py-12">
<Text className="text-4xl mb-2">🌙</Text>
<Text className="text-music-muted">No channels available</Text>
</View>
)}
</ScrollView>
<BottomNavBar />
</View>
)
}