useSimpleUserSongs.ts
1 import { useState, useEffect } from 'react' 2 import { useAccount } from 'wagmi' 3 import { usePGLite } from '../contexts/PGLiteContext' 4 import { gunDBService } from '../services/database/gundb' 5 6 interface UserSong { 7 songId: number 8 title: string 9 artist: string 10 artwork_thumbnail: string | null 11 newCount: number 12 learningCount: number 13 dueCount: number 14 } 15 16 /** 17 * Simple hook to get user's songs from PGLite 18 */ 19 export function useSimpleUserSongs() { 20 const { isConnected } = useAccount() 21 const { readService, isReady } = usePGLite() 22 const [userSongs, setUserSongs] = useState<UserSong[]>([]) 23 const [totalStats, setTotalStats] = useState({ new: 0, learning: 0, due: 0 }) 24 const [isLoading, setIsLoading] = useState(true) 25 26 // Load user songs and stats from PGLite 27 useEffect(() => { 28 const loadUserSongs = async () => { 29 if (!isConnected || !isReady) { 30 setUserSongs([]) 31 setTotalStats({ new: 0, learning: 0, due: 0 }) 32 setIsLoading(false) 33 return 34 } 35 36 try { 37 setIsLoading(true) 38 39 // Get song stats from PGLite 40 const songStats = await readService.getSongStats() 41 42 // Calculate total stats 43 let newTotal = 0 44 let learningTotal = 0 45 let dueTotal = 0 46 47 songStats.forEach(stat => { 48 newTotal += stat.new_cards 49 learningTotal += stat.learning_cards 50 dueTotal += stat.due_cards 51 }) 52 53 setTotalStats({ 54 new: newTotal, 55 learning: learningTotal, 56 due: dueTotal 57 }) 58 59 // Convert to UserSong format and fetch artwork 60 const songsWithArtwork = await Promise.all( 61 songStats.map(async (stat) => { 62 let artwork_thumbnail = null 63 try { 64 const songData = await gunDBService.getSongByGeniusId(stat.song_id) 65 artwork_thumbnail = songData?.artwork_thumbnail || null 66 } catch (error) { 67 console.warn(`Failed to fetch metadata for song ${stat.song_id}:`, error) 68 } 69 70 return { 71 songId: stat.song_id, 72 title: stat.song_title || 'Unknown Song', 73 artist: stat.artist_name || 'Unknown Artist', 74 artwork_thumbnail, 75 newCount: stat.new_cards, 76 learningCount: stat.learning_cards, 77 dueCount: stat.due_cards 78 } 79 }) 80 ) 81 82 // Sort by due cards 83 const sortedSongs = songsWithArtwork.sort((a, b) => { 84 if (a.dueCount !== b.dueCount) { 85 return b.dueCount - a.dueCount 86 } 87 const totalA = a.newCount + a.learningCount + a.dueCount 88 const totalB = b.newCount + b.learningCount + b.dueCount 89 return totalB - totalA 90 }) 91 92 setUserSongs(sortedSongs) 93 } catch (error) { 94 console.error('Failed to load songs from PGLite:', error) 95 } finally { 96 setIsLoading(false) 97 } 98 } 99 100 loadUserSongs() 101 }, [isConnected, isReady, readService]) 102 103 return { 104 userSongs, 105 totalStats, 106 isLoading 107 } 108 }