79 lines
2.6 KiB
Kotlin
79 lines
2.6 KiB
Kotlin
package com.radiola.data.remote
|
|
|
|
import com.radiola.domain.model.Track
|
|
import io.socket.client.IO
|
|
import io.socket.client.Socket
|
|
import kotlinx.coroutines.flow.MutableStateFlow
|
|
import kotlinx.coroutines.flow.StateFlow
|
|
import kotlinx.serialization.json.Json
|
|
import kotlinx.serialization.json.jsonObject
|
|
import kotlinx.serialization.json.jsonPrimitive
|
|
import javax.inject.Inject
|
|
import javax.inject.Singleton
|
|
|
|
@Singleton
|
|
class NowPlayingSocketClient @Inject constructor(
|
|
private val json: Json
|
|
) {
|
|
private val _nowPlaying = MutableStateFlow<Map<Int, Track>>(emptyMap())
|
|
val nowPlaying: StateFlow<Map<Int, Track>> = _nowPlaying
|
|
|
|
private var socket: Socket? = null
|
|
|
|
fun connect() {
|
|
if (socket != null) return
|
|
try {
|
|
val opts = IO.Options().apply {
|
|
transports = arrayOf("websocket")
|
|
}
|
|
socket = IO.socket("http://121.127.37.212:3000/now-playing", opts)
|
|
socket?.on("now-playing") { args ->
|
|
if (args.isNotEmpty()) {
|
|
val data = args[0] as? String ?: return@on
|
|
handleNowPlayingEvent(data)
|
|
}
|
|
}
|
|
socket?.on(Socket.EVENT_CONNECT) {
|
|
android.util.Log.d("NowPlayingSocket", "Connected")
|
|
}
|
|
socket?.on(Socket.EVENT_DISCONNECT) {
|
|
android.util.Log.d("NowPlayingSocket", "Disconnected")
|
|
}
|
|
socket?.on(Socket.EVENT_CONNECT_ERROR) { args ->
|
|
android.util.Log.e("NowPlayingSocket", "Connect error: ${args.joinToString()}")
|
|
}
|
|
socket?.connect()
|
|
} catch (e: Exception) {
|
|
android.util.Log.e("NowPlayingSocket", "Failed to connect", e)
|
|
}
|
|
}
|
|
|
|
fun disconnect() {
|
|
socket?.disconnect()
|
|
socket = null
|
|
}
|
|
|
|
private fun handleNowPlayingEvent(data: String) {
|
|
try {
|
|
val obj = json.parseToJsonElement(data).jsonObject
|
|
val stationId = obj["stationId"]?.jsonPrimitive?.content?.toIntOrNull() ?: return
|
|
val song = obj["song"]?.jsonPrimitive?.content ?: return
|
|
val artist = obj["artist"]?.jsonPrimitive?.content ?: return
|
|
val coverUrl = obj["coverUrl"]?.jsonPrimitive?.content
|
|
|
|
val track = Track(
|
|
artist = artist,
|
|
song = song,
|
|
coverUrl = coverUrl,
|
|
stationName = ""
|
|
)
|
|
|
|
_nowPlaying.value = _nowPlaying.value.toMutableMap().apply {
|
|
put(stationId, track)
|
|
}
|
|
} catch (e: Exception) {
|
|
android.util.Log.e("NowPlayingSocket", "Failed to parse event", e)
|
|
}
|
|
}
|
|
}
|