Skip to content

[WIP] Fix hardcoded URL in Party Mode for API requests#9

Merged
Wilooper merged 1 commit into
mainfrom
copilot/fix-party-mode-api-usage
Mar 9, 2026
Merged

[WIP] Fix hardcoded URL in Party Mode for API requests#9
Wilooper merged 1 commit into
mainfrom
copilot/fix-party-mode-api-usage

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 9, 2026

  • Update lib/audio-context.tsx:
    • Add PARTY_SERVER constant from env var
    • Add partyHostId state variable
    • Add partyHostId to AudioContextType interface
    • Import getPartyUsername from @/lib/storage
    • Rewrite startParty to use new party server API
    • Rewrite stopParty to call DELETE on party server
    • Rewrite addToPartyQueue to use new party server API
    • Rewrite host polling useEffect to use new party server API
    • Add useEffect for syncing current song to party server when host changes song
    • Expose partyHostId in provider value
  • Update app/party/[id]/page.tsx:
    • Add PARTY_SERVER constant
    • Add guest join on mount via POST /party/:id/join
    • Update poll to use GET /party/:id from party server
    • Update addSong to use POST /party/:id/queue on party server
    • Keep chat/vote/reaction on local /api/party
Original prompt

Problem

Party Mode is broken because lib/audio-context.tsx hardcodes https://jsonblob.com/api/jsonBlob URLs instead of using the NEXT_PUBLIC_PARTY_SERVER environment variable defined in .env.local (currently set to https://y-brown-two.vercel.app).

The env var NEXT_PUBLIC_PARTY_SERVER is never referenced anywhere in the codebase. All party functions need to be rewritten to use the actual party server API.

Party Server API Documentation (Full Reference)

The party server is deployed at the URL in NEXT_PUBLIC_PARTY_SERVER. Here is the complete API:

Health check

GET /
→ { service, status, parties, uptime }

Create a party (host)

POST /party
Body: { currentSong?: Song }

→ {
    id: string,       ← share this with guests
    hostId: string,   ← keep this SECRET — used for all host operations
    partyUrl: string
  }

Get party state (anyone)

GET /party/:id
→ {
    id, currentSong, guestCount, guests, queue,
    createdAt, updatedAt
  }

Note: hostId is never exposed here.

Update currently playing song (host only)

PUT /party/:id/song?hostId=<hostId>
Body: { song: Song | null }
→ { ok: true }

Guest adds a song to the queue

POST /party/:id/queue
Body: { song: Song, guestName?: string }
→ { ok: true, queueLength: number }

Returns 409 if the same song is already waiting in the queue.

Host polls + flushes the queue (host only)

GET /party/:id/queue?hostId=<hostId>
→ { songs: Song[] }

This returns all pending guest-queued songs and clears them in one step. The host should call this every ~5 seconds.

Guest joins party

POST /party/:id/join
Body: { guestName?: string }
→ full public party state (same shape as GET /party/:id)

Increments guestCount and returns current party state so the guest immediately knows what song is playing without a second request.

End party (host only)

DELETE /party/:id?hostId=<hostId>
→ { ok: true }

Song data structure

{
  "id":        "videoId",
  "title":     "Song Title",
  "artist":    "Artist Name",
  "thumbnail": "https://...",
  "type":      "musiva",
  "videoId":   "videoId",
  "duration":  "3:45"
}

Required Changes

1. lib/audio-context.tsx — Party Mode Logic

This is the main file that needs changes. Define a base URL constant:

const PARTY_SERVER = process.env.NEXT_PUBLIC_PARTY_SERVER || ""

a) startParty function (currently at ~line 729)

Current: Calls https://jsonblob.com/api/jsonBlob with POST, reads Location header.
Fix: Call POST ${PARTY_SERVER}/party with { currentSong } body. The response returns { id, hostId, partyUrl }. Store id as partyId and store hostId in a new state variable partyHostId (this is SECRET, used for host-only operations). Also need to add a new state: const [partyHostId, setPartyHostId] = useState<string | null>(null).

const startParty = useCallback(async () => {
  try {
    const song = currentSong || null
    const res = await fetch(`${PARTY_SERVER}/party`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ currentSong: song })
    })
    if (!res.ok) return null
    const data = await res.json()
    if (data.id) {
      setPartyId(data.id)
      setPartyHostId(data.hostId)
      setIsPartyHost(true)
      return data.id
    }
  } catch (err) {
    console.error("Failed to start party:", err)
  }
  return null
}, [currentSong])

b) addToPartyQueue function (currently at ~line 762)

Current: Fetches from jsonblob.com, pushes song, PUTs back.
Fix: Call POST ${PARTY_SERVER}/party/${partyId}/queue with { song, guestName }.

const addToPartyQueue = useCallback(async (song: Song) => {
  if (!partyId) return false
  try {
    const res = await fetch(`${PARTY_SERVER}/party/${partyId}/queue`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ song, guestName: getPartyUsername() })
    })
    return res.ok
  } catch (err) {
    console.error("Failed to add to party queue:", err)
    return false
  }
}, [partyId])

c) Host polling interval (currently at ~line 779)

Current: Polls jsonblob.com, reads songs, clears blob.
Fix: Call GET ${PARTY_SERVER}/party/${partyId}/queue?hostId=${partyHostId}. This returns { songs: Song[] } and auto-clears the queue on the server. Poll every 5 seconds.

useEffect(() => {
  if (isPartyHost && partyId && partyHostId) {
    partyIntervalRef.current = setInterval(async () => {
      try {
        const res = await fetch(`${PARTY_SERVER}/party/${partyId}/queue?hostId=${partyHostId}`)
        if (!res.ok) return
        const data = await res.json()
        if (data.songs && data.songs.length > 0) {
          data.songs.forEach((s: Song) => {
            setQueue(prev => {
              if (prev.some(x => x.id === s.id)) return prev
              const next = [....

</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

*This pull request was created from Copilot chat.*
>

<!-- START COPILOT CODING AGENT TIPS -->
---

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more [Copilot coding agent tips](https://gh.io/copilot-coding-agent-tips) in the docs.

@vercel
Copy link
Copy Markdown

vercel Bot commented Mar 9, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
lyricanet Ready Ready Preview, Comment Mar 9, 2026 0:06am

@Wilooper Wilooper marked this pull request as ready for review March 9, 2026 12:10
Copilot AI review requested due to automatic review settings March 9, 2026 12:10
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review any files in this pull request.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@Wilooper Wilooper merged commit 4a8309c into main Mar 9, 2026
2 of 3 checks passed
Copilot stopped work on behalf of Wilooper due to an error March 9, 2026 12:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants