-
-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
33 changed files
with
665 additions
and
601 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
212 changes: 212 additions & 0 deletions
212
composeApp/src/commonMain/kotlin/dev/datlag/burningseries/other/K2Kast.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,212 @@ | ||
package dev.datlag.burningseries.other | ||
|
||
import dev.datlag.burningseries.model.Series | ||
import dev.datlag.burningseries.model.SeriesData | ||
import dev.datlag.burningseries.model.serializer.SerializableImmutableSet | ||
import dev.datlag.k2k.Host | ||
import dev.datlag.k2k.connect.Connection | ||
import dev.datlag.k2k.connect.connection | ||
import dev.datlag.k2k.discover.Discovery | ||
import dev.datlag.k2k.discover.discovery | ||
import dev.datlag.nanoid.NanoIdUtils | ||
import dev.datlag.skeo.DirectLink | ||
import dev.datlag.tooling.async.suspendCatching | ||
import dev.datlag.tooling.compose.ioDispatcher | ||
import io.github.aakira.napier.Napier | ||
import kotlinx.collections.immutable.ImmutableCollection | ||
import kotlinx.collections.immutable.ImmutableSet | ||
import kotlinx.collections.immutable.persistentSetOf | ||
import kotlinx.collections.immutable.toImmutableSet | ||
import kotlinx.coroutines.CoroutineScope | ||
import kotlinx.coroutines.DelicateCoroutinesApi | ||
import kotlinx.coroutines.GlobalScope | ||
import kotlinx.coroutines.cancel | ||
import kotlinx.coroutines.delay | ||
import kotlinx.coroutines.flow.MutableStateFlow | ||
import kotlinx.coroutines.flow.SharingStarted | ||
import kotlinx.coroutines.flow.StateFlow | ||
import kotlinx.coroutines.flow.combine | ||
import kotlinx.coroutines.flow.stateIn | ||
import kotlinx.coroutines.flow.update | ||
import kotlinx.coroutines.plus | ||
import kotlinx.serialization.ExperimentalSerializationApi | ||
import kotlinx.serialization.Serializable | ||
import kotlinx.serialization.encodeToByteArray | ||
import kotlinx.serialization.protobuf.ProtoBuf | ||
|
||
data object K2Kast : AutoCloseable { | ||
|
||
private lateinit var showClient: Discovery | ||
private lateinit var searchClient: Discovery | ||
|
||
private lateinit var connection: Connection | ||
|
||
private var scope: CoroutineScope? = null | ||
private val connectedHost = MutableStateFlow<Host?>(null) | ||
|
||
val code: String by lazy { | ||
NanoIdUtils.randomNanoId( | ||
alphabet = "0123456789".toCharArray(), | ||
size = 6 | ||
) | ||
} | ||
|
||
@OptIn(DelicateCoroutinesApi::class) | ||
val devices: StateFlow<ImmutableSet<Device>> | ||
get() = if (::searchClient.isInitialized) { | ||
combine( | ||
connectedHost, | ||
searchClient.peers | ||
) { selected, all -> | ||
all.map { | ||
Device( | ||
host = it, | ||
selected = selected == it | ||
) | ||
}.toImmutableSet() | ||
}.stateIn( | ||
scope = scope ?: (GlobalScope + ioDispatcher()), | ||
started = SharingStarted.WhileSubscribed(), | ||
initialValue = searchClient.peers.value.map(::Device).toImmutableSet() | ||
) | ||
} else { | ||
MutableStateFlow(persistentSetOf()) | ||
} | ||
|
||
val connectedDevice: Device? | ||
get() = devices.value.firstOrNull { it.selected } | ||
|
||
fun initialize(scope: CoroutineScope) { | ||
this.scope = scope | ||
|
||
initializeShow(scope) | ||
initializeSearch(scope) | ||
initializeConnection(scope) | ||
} | ||
|
||
private fun initializeShow(scope: CoroutineScope) { | ||
if (::showClient.isInitialized) { | ||
return | ||
} | ||
|
||
showClient = scope.discovery { | ||
setShowTimeout(0L) | ||
setPort(7330) | ||
} | ||
} | ||
|
||
private fun initializeSearch(scope: CoroutineScope) { | ||
if (::searchClient.isInitialized) { | ||
return | ||
} | ||
|
||
searchClient = scope.discovery { | ||
setSearchTimeout(0L) | ||
setPort(7330) | ||
} | ||
} | ||
|
||
private fun initializeConnection(scope: CoroutineScope) { | ||
if (::connection.isInitialized) { | ||
return | ||
} | ||
|
||
connection = scope.connection { | ||
setPort(7332) | ||
noDelay() | ||
} | ||
} | ||
|
||
fun show(name: String) { | ||
showClient.show(name = name, filterMatch = code) | ||
} | ||
|
||
fun hide() { | ||
showClient.hide() | ||
} | ||
|
||
fun search(code: String?) { | ||
if (code.isNullOrBlank() || code.length != 6) { | ||
searchClient.lose() | ||
return | ||
} | ||
|
||
searchClient.search( | ||
filter = "^$code$".toRegex() | ||
) | ||
} | ||
|
||
fun lose() { | ||
searchClient.lose() | ||
} | ||
|
||
fun connect(host: Host) { | ||
connectedHost.update { host } | ||
} | ||
|
||
fun connect(device: Device) = connect(device.host) | ||
|
||
fun disconnect() { | ||
connectedHost.update { null } | ||
} | ||
|
||
fun receive(listener: suspend (ByteArray) -> Unit) = connection.receive(listener) | ||
|
||
suspend fun send(byteArray: ByteArray, host: Host? = connectedDevice?.host) { | ||
if (host == null) { | ||
return | ||
} | ||
|
||
suspendCatching { | ||
connection.sendNow(byteArray, host) | ||
} | ||
} | ||
suspend fun send(byteArray: ByteArray, device: Device? = connectedDevice) = send(byteArray, device?.host) | ||
|
||
suspend fun watch( | ||
episode: Series.Episode, | ||
host: Host? = connectedDevice?.host | ||
) = send( | ||
byteArray = episode.href.encodeToByteArray(), | ||
host = host | ||
) | ||
|
||
suspend fun watch( | ||
episode: Series.Episode, | ||
device: Device? = connectedDevice | ||
) = watch( | ||
episode = episode, | ||
host = device?.host | ||
) | ||
|
||
override fun close() { | ||
this.scope?.cancel() | ||
this.scope = null | ||
|
||
closeShow() | ||
closeSearch() | ||
} | ||
|
||
private fun closeShow() { | ||
if (!::showClient.isInitialized) { | ||
return | ||
} | ||
|
||
showClient.close() | ||
} | ||
|
||
private fun closeSearch() { | ||
if (!::searchClient.isInitialized) { | ||
return | ||
} | ||
|
||
searchClient.close() | ||
} | ||
|
||
@Serializable | ||
data class Device( | ||
val host: Host, | ||
val name: String = host.name, | ||
val selected: Boolean = connectedHost.value == host | ||
) | ||
} |
3 changes: 3 additions & 0 deletions
3
composeApp/src/commonMain/kotlin/dev/datlag/burningseries/other/StateSaver.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,8 @@ | ||
package dev.datlag.burningseries.other | ||
|
||
import kotlinx.coroutines.flow.MutableStateFlow | ||
|
||
data object StateSaver { | ||
var sekretLibraryLoaded: Boolean = false | ||
val defaultHome = MutableStateFlow(false) | ||
} |
6 changes: 6 additions & 0 deletions
6
composeApp/src/commonMain/kotlin/dev/datlag/burningseries/ui/navigation/K2KastComponent.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package dev.datlag.burningseries.ui.navigation | ||
|
||
interface K2KastComponent : Component { | ||
|
||
suspend fun k2kastLoad(href: String?) | ||
} |
Oops, something went wrong.