File size: 2,623 Bytes
d092f57
 
 
 
 
 
deb2808
d092f57
 
 
595e328
d092f57
595e328
d092f57
 
595e328
 
d092f57
deb2808
 
 
 
d092f57
 
595e328
d092f57
595e328
d092f57
 
 
 
 
 
595e328
d092f57
 
 
 
 
595e328
 
d092f57
595e328
d092f57
 
 
 
deb2808
595e328
deb2808
d092f57
 
595e328
 
d092f57
595e328
d092f57
 
 
595e328
d092f57
 
 
 
 
 
595e328
d092f57
595e328
 
d092f57
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
595e328
 
 
 
 
 
 
 
 
deb2808
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import {
  MediaElement,
  PlayerState,
  Playlist,
  RoomState,
  UserState,
  ChatMessage,
} from "./types"
import io, { Socket } from "socket.io-client"

// Events the server emits to the client
export interface ServerToClientEvents {
  // Optional legacy granular updates (your server mainly emits `update`)
  playlistUpdate: (playlist: Playlist) => void
  userUpdates: (users: UserState[]) => void

  // Primary room update payload
  update: (room: RoomState) => void

  // Chat events
  chatNew: (msg: ChatMessage) => void
  chatHistory: (msgs: ChatMessage[]) => void
}

// Events the client emits to the server
export interface ClientToServerEvents {
  // Playlist and user updates
  playItemFromPlaylist: (index: number) => void
  updatePlaylist: (playlist: Playlist) => void
  updatePlayer: (player: PlayerState) => void
  updatePlaying: (playing: MediaElement) => void
  updateUser: (user: UserState) => void

  // Player controls
  setPaused: (paused: boolean) => void
  setLoop: (loop: boolean) => void
  setProgress: (progress: number) => void
  setPlaybackRate: (playbackRate: number) => void
  seek: (progress: number) => void

  // Playback and fetching
  playUrl: (src: string) => void
  addToPlaylist: (url: string) => void // NEW: add without playing
  playAgain: () => void
  playEnded: () => void
  fetch: () => void
  error: () => void

  // Chat
  chatMessage: (text: string) => void
}

export type TypedSocket = Socket<ServerToClientEvents, ClientToServerEvents>

export function playItemFromPlaylist(
  socket: TypedSocket,
  playlist: Playlist,
  index: number
) {
  if (!playlist || !Array.isArray(playlist.items) || !playlist.items[index]) {
    console.error("Impossible to play", index, "from", playlist)
    return
  }
  socket.emit("playItemFromPlaylist", index)
}

export function createClientSocket(roomId: string): TypedSocket {
  console.log("Trying to join room", roomId)
  const socket: TypedSocket = io({
    query: { roomId },
    transports: ["websocket"],
    path: "/api/socketio",
  })

  socket.on("connect", () => {
    console.log("Established ws connection to io server", socket.id)
  })

  socket.on("disconnect", (reason) => {
    if (!["io client disconnect", "io server disconnect"].includes(reason)) {
      console.error(
        "Socket connection closed due to:",
        reason,
        "socket:",
        socket
      )
    }
  })

  return socket
}

// Convenience helpers
export function playNow(socket: TypedSocket, url: string) {
  socket.emit("playUrl", url)
}

export function queueUrl(socket: TypedSocket, url: string) {
  socket.emit("addToPlaylist", url)
}