Skip to content

Commit

Permalink
feat: television code sheet.
Browse files Browse the repository at this point in the history
  • Loading branch information
oxyroid committed Jan 21, 2024
1 parent 053c7ec commit 58ca0ff
Show file tree
Hide file tree
Showing 12 changed files with 572 additions and 28 deletions.
2 changes: 2 additions & 0 deletions data/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,6 @@ dependencies {
ksp(libs.androidx.hilt.hilt.compiler)

implementation(libs.parser.m3u)

implementation("org.zeromq:jeromq:0.5.3")
}
41 changes: 41 additions & 0 deletions data/src/main/java/com/m3u/data/net/jetty/JettyClient.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.m3u.data.net.jetty

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.launch
import org.zeromq.SocketType
import org.zeromq.ZContext
import org.zeromq.ZMQ

class JettyClient(private val port: Int) {
private val context: ZContext by lazy { ZContext() }
private var socket: ZMQ.Socket? = null
private val flow = MutableSharedFlow<String>()
private val coroutineScope = CoroutineScope(Dispatchers.IO)

fun start() {
socket?.disconnect("tcp://localhost:$port")
socket = context.createSocket(SocketType.REQ).apply {
connect("tcp://localhost:$port")
while (!Thread.currentThread().isInterrupted) {
val reply: ByteArray = recv(0)
coroutineScope.launch {
flow.emit(String(reply, ZMQ.CHARSET))
}
}
}
}

fun observe(): SharedFlow<String> = flow.asSharedFlow()

fun send(body: String) {
socket?.send(body)
}

fun send(bytes: ByteArray) {
socket?.send(bytes)
}
}
5 changes: 5 additions & 0 deletions data/src/main/java/com/m3u/data/net/jetty/JettyContracts.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.m3u.data.net.jetty

object JettyContracts {
const val PORT = 2239
}
41 changes: 41 additions & 0 deletions data/src/main/java/com/m3u/data/net/jetty/JettyServer.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.m3u.data.net.jetty

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.launch
import org.zeromq.SocketType
import org.zeromq.ZContext
import org.zeromq.ZMQ

class JettyServer(private val port: Int) {
private val context: ZContext by lazy { ZContext() }
private var socket: ZMQ.Socket? = null
private val flow = MutableSharedFlow<String>()
private val coroutineScope = CoroutineScope(Dispatchers.IO)

fun start() {
socket?.unbind("tcp://*:$port")
socket = context.createSocket(SocketType.REP).apply {
bind("tcp://*:$port")
while (!Thread.currentThread().isInterrupted) {
val reply = recv(0)
coroutineScope.launch {
flow.emit(String(reply, ZMQ.CHARSET))
}
}
}
}

fun observe(): SharedFlow<String> = flow.asSharedFlow()

fun send(body: String) {
socket?.send(body)
}

fun send(bytes: ByteArray) {
socket?.send(bytes)
}
}
22 changes: 22 additions & 0 deletions data/src/main/java/com/m3u/data/net/jetty/di/JettyModule.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.m3u.data.net.jetty.di

import com.m3u.data.net.jetty.JettyClient
import com.m3u.data.net.jetty.JettyContracts
import com.m3u.data.net.jetty.JettyServer
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton

@Module
@InstallIn(SingletonComponent::class)
object JettyModule {
@Provides
@Singleton
fun provideJettyServer(): JettyServer = JettyServer(JettyContracts.PORT)

@Provides
@Singleton
fun provideJettyClient(): JettyClient = JettyClient(JettyContracts.PORT)
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.Add
import androidx.compose.material.icons.rounded.Link
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
Expand Down Expand Up @@ -45,10 +47,11 @@ import com.m3u.material.ktx.minus
import com.m3u.material.ktx.only
import com.m3u.material.ktx.thenIf
import com.m3u.material.model.LocalSpacing
import com.m3u.ui.helper.Action
import com.m3u.ui.ConnectBottomSheet
import com.m3u.ui.EventHandler
import com.m3u.ui.helper.LocalHelper
import com.m3u.ui.ResumeEvent
import com.m3u.ui.helper.Action
import com.m3u.ui.helper.LocalHelper
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf

Expand All @@ -73,10 +76,17 @@ fun ForyouRoute(
val details by viewModel.details.collectAsStateWithLifecycle()
val recommend by viewModel.recommend.collectAsStateWithLifecycle()

var isConnectSheetVisible by remember { mutableStateOf(false) }

EventHandler(resume, title) {
helper.deep = 0
helper.title = title.title()
helper.actions = persistentListOf(
Action(
icon = Icons.Rounded.Link,
contentDescription = "link",
onClick = { isConnectSheetVisible = true }
),
Action(
icon = Icons.Rounded.Add,
contentDescription = "add",
Expand All @@ -85,30 +95,43 @@ fun ForyouRoute(
)
}

ForyouScreen(
details = details,
recommend = recommend,
rowCount = pref.rowCount,
contentPadding = contentPadding,
navigateToPlaylist = navigateToPlaylist,
navigateToStream = navigateToStream,
navigateToRecommendPlaylist = navigateToRecommendPlaylist,
navigateToSettingPlaylistManagement = navigateToSettingPlaylistManagement,
unsubscribe = { viewModel.unsubscribe(it) },
rename = { playlistUrl, target -> viewModel.rename(playlistUrl, target) },
modifier = Modifier
.fillMaxSize()
.thenIf(!tv && pref.godMode) {
Modifier.interceptVolumeEvent { event ->
pref.rowCount = when (event) {
KeyEvent.KEYCODE_VOLUME_UP -> (pref.rowCount - 1).coerceAtLeast(1)
KeyEvent.KEYCODE_VOLUME_DOWN -> (pref.rowCount + 1).coerceAtMost(2)
else -> return@interceptVolumeEvent
Background {
ForyouScreen(
details = details,
recommend = recommend,
rowCount = pref.rowCount,
contentPadding = contentPadding,
navigateToPlaylist = navigateToPlaylist,
navigateToStream = navigateToStream,
navigateToRecommendPlaylist = navigateToRecommendPlaylist,
navigateToSettingPlaylistManagement = navigateToSettingPlaylistManagement,
unsubscribe = { viewModel.unsubscribe(it) },
rename = { playlistUrl, target -> viewModel.rename(playlistUrl, target) },
modifier = Modifier
.fillMaxSize()
.thenIf(!tv && pref.godMode) {
Modifier.interceptVolumeEvent { event ->
pref.rowCount = when (event) {
KeyEvent.KEYCODE_VOLUME_UP -> (pref.rowCount - 1).coerceAtLeast(1)
KeyEvent.KEYCODE_VOLUME_DOWN -> (pref.rowCount + 1).coerceAtMost(2)
else -> return@interceptVolumeEvent
}
}
}
}
.then(modifier)
)
.then(modifier)
)
var loading by remember { mutableStateOf(false) }
var code by remember { mutableStateOf("") }
ConnectBottomSheet(
visible = isConnectSheetVisible,
code = code,
loading = loading,
onCode = { code = it },
sheetState = rememberModalBottomSheetState { !loading },
onDismissRequest = { isConnectSheetVisible = false },
onConnect = { loading = true }
)
}
}

@Composable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,7 @@ fun OptionalPreferences(modifier: Modifier = Modifier) {

CheckBoxSharedPreference(
title = string.feat_setting_record,
content = string.feat_setting_not_implementation,
icon = Icons.Rounded.SlowMotionVideo,
enabled = false,
checked = pref.record,
onChanged = { pref.record = !pref.record }
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import com.m3u.core.architecture.viewmodel.BaseViewModel
import com.m3u.data.repository.PlaylistRepository
import com.m3u.data.repository.StreamRepository
import com.m3u.data.manager.PlayerManager
import com.m3u.data.net.jetty.JettyServer
import com.m3u.dlna.DLNACastManager
import com.m3u.dlna.OnDeviceRegistryListener
import com.m3u.dlna.control.DeviceControl
Expand Down Expand Up @@ -37,6 +38,7 @@ import org.jupnp.model.meta.Device
import javax.inject.Inject
import kotlin.math.roundToInt
import kotlin.time.Duration.Companion.milliseconds
import kotlin.time.Duration.Companion.seconds

@HiltViewModel
class StreamViewModel @Inject constructor(
Expand Down Expand Up @@ -216,6 +218,12 @@ class StreamViewModel @Inject constructor(

internal fun record() {
_recording.update { !it }
viewModelScope.launch {
val server = JettyServer(2233)
server.start()
delay(3.seconds)
server.send("123")
}
}

private fun onFavourite(url: String) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,6 @@ internal fun StreamFragment(
if (pref.record) {
MaskButton(
state = maskState,
enabled = false,
icon = if (recording) Icons.Rounded.RadioButtonChecked
else Icons.Rounded.RadioButtonUnchecked,
tint = if (recording) theme.error
Expand Down
2 changes: 2 additions & 0 deletions i18n/src/main/res/values/ui.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,6 @@
<string name="ui_sort_asc">A-Z</string>
<string name="ui_sort_desc">Z-A</string>
<string name="ui_sort_unspecified">Unspecified</string>

<string name="ui_connect">Connect</string>
</resources>
Loading

0 comments on commit 58ca0ff

Please sign in to comment.