Functional add button for the main activity
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
Signed-off-by: Balazs Toldi <balazs@toldi.eu>
This commit is contained in:
parent
bebde9bc6a
commit
4c88992e5f
3 changed files with 122 additions and 62 deletions
|
@ -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
|
||||
|
|
|
@ -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({}, {})
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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))
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue