61 lines
1.9 KiB
TypeScript
61 lines
1.9 KiB
TypeScript
"use client"
|
|
|
|
import { useState } from "react"
|
|
import { useNostrEvents } from "nostr-react"
|
|
import AudioBubble from "@/components/audio-bubble"
|
|
import VoidCanvas from "@/components/void-canvas"
|
|
import AudioPlayer from "@/components/audio-player"
|
|
|
|
export default function Home() {
|
|
// const now = useRef(new Date()) // Make sure current time isn't re-rendered
|
|
const [selectedAudio, setSelectedAudio] = useState<string | null>(null)
|
|
const [playingEventId, setPlayingEventId] = useState<string | null>(null)
|
|
|
|
// Fetch audio events according to NIP-94
|
|
const { events } = useNostrEvents({
|
|
filter: {
|
|
// since: dateToUnix(now.current), // all new events from now
|
|
// kinds: [1063], // NIP-94 audio events
|
|
kinds: [1222], // yakbak audio events
|
|
// "#m": ["audio/mpeg", "audio/ogg", "audio/wav", "audio/webm"], // Audio MIME types
|
|
// "#m": ["audio/mpeg", "audio/ogg", "audio/wav"], // Audio MIME types
|
|
limit: 10
|
|
},
|
|
})
|
|
|
|
const handleBubbleClick = (url: string, eventId: string) => {
|
|
setSelectedAudio(url)
|
|
setPlayingEventId(eventId)
|
|
}
|
|
|
|
const handleAudioEnd = () => {
|
|
setSelectedAudio(null)
|
|
setPlayingEventId(null)
|
|
}
|
|
|
|
return (
|
|
<div className="relative w-full h-screen bg-black overflow-hidden">
|
|
<VoidCanvas>
|
|
{events.map((event) => {
|
|
// Extract audio URL from NIP-94 event
|
|
// const url = event.tags.find((tag) => tag[0] === "url")?.[1]
|
|
const url = event.content
|
|
if (!url) return null
|
|
|
|
return (
|
|
<AudioBubble
|
|
key={event.id}
|
|
eventId={event.id}
|
|
url={url}
|
|
isPlaying={event.id === playingEventId}
|
|
onClick={handleBubbleClick}
|
|
/>
|
|
)
|
|
})}
|
|
</VoidCanvas>
|
|
|
|
{selectedAudio && <AudioPlayer url={selectedAudio} onEnded={handleAudioEnd} />}
|
|
</div>
|
|
)
|
|
}
|