2021-07-12 10:14:26 +02:00
|
|
|
package audio.funkwhale.ffa.utils
|
2019-08-19 16:50:33 +02:00
|
|
|
|
2021-08-22 09:48:33 +02:00
|
|
|
import audio.funkwhale.ffa.model.Radio
|
|
|
|
import audio.funkwhale.ffa.model.Track
|
2020-06-14 14:59:50 +02:00
|
|
|
import com.google.android.exoplayer2.offline.Download
|
2020-06-13 16:09:48 +02:00
|
|
|
import com.google.android.exoplayer2.offline.DownloadCursor
|
2020-06-20 22:10:13 +02:00
|
|
|
import kotlinx.coroutines.Dispatchers.IO
|
2019-08-19 16:50:33 +02:00
|
|
|
import kotlinx.coroutines.GlobalScope
|
2019-10-29 23:41:44 +01:00
|
|
|
import kotlinx.coroutines.channels.Channel
|
2022-08-21 00:20:26 +02:00
|
|
|
import kotlinx.coroutines.flow.MutableSharedFlow
|
2022-08-20 10:05:42 +02:00
|
|
|
import kotlinx.coroutines.flow.MutableStateFlow
|
2022-08-21 00:20:26 +02:00
|
|
|
import kotlinx.coroutines.flow.asSharedFlow
|
2022-08-20 10:05:42 +02:00
|
|
|
import kotlinx.coroutines.flow.asStateFlow
|
2019-08-19 16:50:33 +02:00
|
|
|
import kotlinx.coroutines.launch
|
|
|
|
|
|
|
|
sealed class Command {
|
2020-07-09 23:01:35 +02:00
|
|
|
class StartService(val command: Command) : Command()
|
2019-08-19 16:50:33 +02:00
|
|
|
object RefreshService : Command()
|
|
|
|
|
|
|
|
object ToggleState : Command()
|
|
|
|
class SetState(val state: Boolean) : Command()
|
|
|
|
|
|
|
|
object NextTrack : Command()
|
|
|
|
object PreviousTrack : Command()
|
|
|
|
class Seek(val progress: Int) : Command()
|
|
|
|
|
|
|
|
class AddToQueue(val tracks: List<Track>) : Command()
|
2020-09-26 17:58:06 +02:00
|
|
|
class AddToPlaylist(val tracks: List<Track>) : Command()
|
2019-08-19 16:50:33 +02:00
|
|
|
class PlayNext(val track: Track) : Command()
|
2020-05-30 21:16:28 +02:00
|
|
|
class ReplaceQueue(val queue: List<Track>, val fromRadio: Boolean = false) : Command()
|
2019-08-19 16:50:33 +02:00
|
|
|
class RemoveFromQueue(val track: Track) : Command()
|
|
|
|
class MoveFromQueue(val oldPosition: Int, val newPosition: Int) : Command()
|
2019-10-30 22:06:57 +01:00
|
|
|
object ClearQueue : Command()
|
2020-09-01 21:06:00 +02:00
|
|
|
object ShuffleQueue : Command()
|
2020-05-30 21:16:28 +02:00
|
|
|
class PlayRadio(val radio: Radio) : Command()
|
2019-08-19 16:50:33 +02:00
|
|
|
|
2020-05-29 23:42:03 +02:00
|
|
|
class SetRepeatMode(val mode: Int) : Command()
|
|
|
|
|
2019-08-19 16:50:33 +02:00
|
|
|
class PlayTrack(val index: Int) : Command()
|
2020-06-10 16:25:20 +02:00
|
|
|
class PinTrack(val track: Track) : Command()
|
2020-06-13 16:45:58 +02:00
|
|
|
class PinTracks(val tracks: List<Track>) : Command()
|
2020-06-24 14:54:13 +02:00
|
|
|
|
|
|
|
class RefreshTrack(val track: Track?) : Command()
|
2019-08-19 16:50:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
sealed class Event {
|
|
|
|
object LogOut : Event()
|
|
|
|
|
|
|
|
class PlaybackError(val message: String) : Event()
|
|
|
|
object PlaybackStopped : Event()
|
|
|
|
class Buffering(val value: Boolean) : Event()
|
2020-06-01 16:31:58 +02:00
|
|
|
class TrackFinished(val track: Track?) : Event()
|
2019-08-19 16:50:33 +02:00
|
|
|
class StateChanged(val playing: Boolean) : Event()
|
|
|
|
object QueueChanged : Event()
|
2020-06-02 18:50:46 +02:00
|
|
|
object RadioStarted : Event()
|
2020-06-13 19:34:57 +02:00
|
|
|
object ListingsChanged : Event()
|
2020-06-14 14:59:50 +02:00
|
|
|
class DownloadChanged(val download: Download) : Event()
|
2019-08-19 16:50:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
sealed class Request(var channel: Channel<Response>? = null) {
|
|
|
|
object GetState : Request()
|
|
|
|
object GetQueue : Request()
|
|
|
|
object GetCurrentTrack : Request()
|
2020-06-13 16:09:48 +02:00
|
|
|
object GetDownloads : Request()
|
2019-08-19 16:50:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
sealed class Response {
|
|
|
|
class State(val playing: Boolean) : Response()
|
|
|
|
class Queue(val queue: List<Track>) : Response()
|
|
|
|
class CurrentTrack(val track: Track?) : Response()
|
2020-06-13 16:09:48 +02:00
|
|
|
class Downloads(val cursor: DownloadCursor) : Response()
|
2019-08-19 16:50:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
object EventBus {
|
2022-08-21 00:20:26 +02:00
|
|
|
private var _events = MutableSharedFlow<Event>()
|
|
|
|
val events = _events.asSharedFlow()
|
2019-08-19 16:50:33 +02:00
|
|
|
fun send(event: Event) {
|
2020-06-20 22:10:13 +02:00
|
|
|
GlobalScope.launch(IO) {
|
2022-08-21 00:20:26 +02:00
|
|
|
_events.emit(event)
|
2019-08-19 16:50:33 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-21 00:20:26 +02:00
|
|
|
fun get() = events
|
2019-08-19 16:50:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
object CommandBus {
|
2022-08-21 02:04:54 +02:00
|
|
|
private var _commands = MutableSharedFlow<Command>()
|
|
|
|
var commands = _commands.asSharedFlow()
|
2019-08-19 16:50:33 +02:00
|
|
|
fun send(command: Command) {
|
2020-06-25 01:26:15 +02:00
|
|
|
GlobalScope.launch(IO) {
|
2022-12-06 09:31:09 +01:00
|
|
|
_commands.emit(command)
|
2019-08-19 16:50:33 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-21 02:04:54 +02:00
|
|
|
fun get() = commands
|
2019-08-19 16:50:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
object RequestBus {
|
2022-08-21 02:18:47 +02:00
|
|
|
private var _requests = MutableSharedFlow<Request>()
|
|
|
|
var requests = _requests.asSharedFlow()
|
2019-08-19 16:50:33 +02:00
|
|
|
fun send(request: Request): Channel<Response> {
|
|
|
|
return Channel<Response>().also {
|
2020-06-22 21:48:31 +02:00
|
|
|
GlobalScope.launch(IO) {
|
2019-08-19 16:50:33 +02:00
|
|
|
request.channel = it
|
|
|
|
|
2022-08-21 02:18:47 +02:00
|
|
|
_requests.emit(request)
|
2019-08-19 16:50:33 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-21 02:18:47 +02:00
|
|
|
fun get() = requests
|
2019-08-19 16:50:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
object ProgressBus {
|
2022-08-20 10:05:42 +02:00
|
|
|
private var _progress = MutableStateFlow(Triple(0, 0, 0))
|
|
|
|
val progress = _progress.asStateFlow()
|
2019-08-19 16:50:33 +02:00
|
|
|
fun send(current: Int, duration: Int, percent: Int) {
|
2022-08-20 10:05:42 +02:00
|
|
|
_progress.value = Triple(current, duration, percent)
|
2019-08-19 16:50:33 +02:00
|
|
|
}
|
|
|
|
|
2022-08-20 10:05:42 +02:00
|
|
|
fun get() = progress
|
2019-08-19 16:50:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
suspend inline fun <reified T> Channel<Response>.wait(): T? {
|
|
|
|
return when (val response = this.receive()) {
|
|
|
|
is T -> response
|
|
|
|
else -> null
|
|
|
|
}
|
|
|
|
}
|