Functional add button for the main activity
All checks were successful
continuous-integration/drone/push Build is passing

Signed-off-by: Balazs Toldi <balazs@toldi.eu>
This commit is contained in:
Balazs Toldi 2021-11-29 12:52:38 +01:00
parent bebde9bc6a
commit 4c88992e5f
Signed by: Bazsalanszky
GPG key ID: 933820884952BE27
3 changed files with 122 additions and 62 deletions

View file

@ -120,27 +120,31 @@ object ChromeCastHelper {
exitStatus = false
callBack.invoke()
} else {
try {
val streamInfo = _streamInfo as VideoInfo
val status = chromeCast.status
if (chromeCast.isAppAvailable(ChromeCastHelper.APP_MEDIA_RECEIVER) && !status.isAppRunning(
ChromeCastHelper.APP_MEDIA_RECEIVER
)
) {
val app: Application =
chromeCast.launchApp(ChromeCastHelper.APP_MEDIA_RECEIVER)
}
while (!chromeCast.status.isAppRunning(ChromeCastHelper.APP_MEDIA_RECEIVER)) {
delay(100)
}
val streamInfo = _streamInfo as VideoInfo
val status = chromeCast.status
if (chromeCast.isAppAvailable(ChromeCastHelper.APP_MEDIA_RECEIVER) && !status.isAppRunning(
ChromeCastHelper.APP_MEDIA_RECEIVER
chromeCast.load(
streamInfo.title,
streamInfo.thumbnail,
streamInfo.url,
null
)
) {
val app: Application = chromeCast.launchApp(ChromeCastHelper.APP_MEDIA_RECEIVER)
} catch (e: Exception) {
Log.e(null, e.stackTraceToString())
} finally {
callBack.invoke()
}
while (!chromeCast.status.isAppRunning(ChromeCastHelper.APP_MEDIA_RECEIVER)) {
delay(100)
}
chromeCast.load(
streamInfo.title,
streamInfo.thumbnail,
streamInfo.url,
null
)
callBack.invoke()
}
}
return exitStatus

View file

@ -6,12 +6,12 @@ import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.viewModels
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.*
import androidx.compose.material.icons.filled.Add
import androidx.compose.material.icons.filled.Refresh
import androidx.compose.runtime.*
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.Alignment
@ -19,17 +19,9 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import eu.toldi.balazs.caster.model.ChromeCastViewModel
import eu.toldi.balazs.caster.ui.theme.CasterTheme
import kotlinx.coroutines.*
import kotlinx.coroutines.Dispatchers.IO
import su.litvak.chromecast.api.v2.Application
import su.litvak.chromecast.api.v2.ChromeCast
import su.litvak.chromecast.api.v2.ChromeCasts
import java.net.Inet4Address
import java.net.InetAddress
import java.net.NetworkInterface
class MainActivity : ComponentActivity() {
@ -44,25 +36,46 @@ class MainActivity : ComponentActivity() {
val chromeCastState = viewModel.chromeCasts.observeAsState(initial = emptyList())
val chromeCasts = chromeCastState.value
Log.e(null,chromeCasts.toString())
Log.e(null, chromeCasts.toString())
// A surface container using the 'background' color from the theme
Surface(color = MaterialTheme.colors.background) {
Column {
MenuBar {
viewModel.refresh()
var isAddChromecastDialogOpen by remember {
mutableStateOf(false)
}
LazyColumn(modifier = Modifier
.padding(all = 4.dp)
.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally) {
MenuBar(
refresh = {
viewModel.refresh()
},
add = {
isAddChromecastDialogOpen = true
})
if (isAddChromecastDialogOpen) {
showAddChromecastDialog(dismiss = {
isAddChromecastDialogOpen = false
}) {
if (it.matches(Regex("^(?:[0-9]{1,3}\\.){3}[0-9]{1,3}\$")))
viewModel.addChromecast(ChromeCast(it).also { chromeCast ->
chromeCast.name = "Chromecast@$it"
})
}
}
LazyColumn(
modifier = Modifier
.padding(all = 4.dp)
.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally
) {
item {
if (chromeCasts.isNotEmpty())
Text(text = "Available chromecasts:")
else {
Column(
modifier = Modifier.fillMaxSize() ,
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally
){
) {
Text("Looking for Chromecasts on your network...")
CircularProgressIndicator()
}
@ -78,22 +91,67 @@ class MainActivity : ComponentActivity() {
}
}
@Composable
fun showAddChromecastDialog(dismiss: () -> Unit, add: (String) -> Unit) {
var ipaddress by remember {
mutableStateOf("")
}
AlertDialog(onDismissRequest = dismiss,
title = {
Text(text = "Add Chromecast")
},
text = {
OutlinedTextField(
value = ipaddress,
onValueChange = {
ipaddress = it
},
label = { Text("IP address of the chromecast") },
modifier = Modifier.padding(vertical = 4.dp)
)
}, buttons = {
Row(
modifier = Modifier.padding(all = 8.dp),
horizontalArrangement = Arrangement.Center
) {
Button(
onClick = {
add(ipaddress)
dismiss()
},
modifier = Modifier.padding(all = 8.dp)
) {
Text(text = "Add Chromecast")
}
Button(onClick = dismiss, modifier = Modifier.padding(all = 8.dp)) {
Text("Cancel")
}
}
})
}
@Composable
fun showChromeCastButton(chromeCast: ChromeCast) {
Button(onClick = {
ChromecastManagerActivity.chromeCast_ = chromeCast
val intent = Intent(this, ChromecastManagerActivity::class.java)
startActivity(intent)
},
modifier = Modifier.padding(5.dp)
Button(
onClick = {
ChromecastManagerActivity.chromeCast_ = chromeCast
val intent = Intent(this, ChromecastManagerActivity::class.java)
startActivity(intent)
},
modifier = Modifier.padding(5.dp)
) {
Text(text = chromeCast.model)
when {
chromeCast.title != null -> Text(text = chromeCast.title)
chromeCast.name != null -> Text(text = chromeCast.name)
else -> Text(text = chromeCast.address)
}
}
}
@Composable
fun MenuBar(refresh: () -> Unit) {
fun MenuBar(refresh: () -> Unit, add: () -> Unit) {
TopAppBar(
title = {
Text("Caster")
@ -107,9 +165,7 @@ class MainActivity : ComponentActivity() {
)
}
IconButton(onClick = {
}) {
IconButton(onClick = add) {
Icon(
Icons.Filled.Add,
contentDescription = "Add"
@ -125,7 +181,7 @@ class MainActivity : ComponentActivity() {
@Composable
fun DefaultPreview() {
CasterTheme {
MenuBar({})
MenuBar({}, {})
}
}
}

View file

@ -1,41 +1,41 @@
package eu.toldi.balazs.caster.model
import android.util.Log
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.launch
import su.litvak.chromecast.api.v2.*
import su.litvak.chromecast.api.v2.ChromeCast
import su.litvak.chromecast.api.v2.ChromeCasts
import su.litvak.chromecast.api.v2.ChromeCastsListener
import java.net.InetAddress
import java.net.NetworkInterface
import javax.jmdns.ServiceEvent
import javax.jmdns.ServiceListener
class ChromeCastViewModel : ViewModel(),ChromeCastsListener {
private val _chromecasts : MutableLiveData<List<ChromeCast>> = MutableLiveData<List<ChromeCast>>(listOf())
val chromeCasts : LiveData<List<ChromeCast>>
private val _chromecasts: MutableLiveData<List<ChromeCast>> =
MutableLiveData<List<ChromeCast>>(listOf())
val chromeCasts: LiveData<List<ChromeCast>>
get() = _chromecasts
init {
ChromeCasts.registerListener(this)
}
fun addChromecast(chromeCast: ChromeCast) {
_chromecasts.postValue(_chromecasts.value!!.plus(chromeCast))
}
override fun newChromeCastDiscovered(chromeCast: ChromeCast?) {
if(chromeCast != null) {
Log.i(null,"Found ${chromeCast.title}")
if (chromeCast != null) {
Log.i(null, "Found ${chromeCast.title}")
_chromecasts.postValue(_chromecasts.value!!.plus(chromeCast))
}
}
override fun chromeCastRemoved(chromeCast: ChromeCast?) {
if(chromeCast != null) {
if (chromeCast != null) {
Log.i(null,"Lost ${chromeCast.title}")
_chromecasts.postValue(_chromecasts.value!!.minus(chromeCast))
}