yacwc
This commit is contained in:
2
.idea/kotlinc.xml
generated
2
.idea/kotlinc.xml
generated
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="KotlinJpsPluginSettings">
|
<component name="KotlinJpsPluginSettings">
|
||||||
<option name="version" value="2.0.0" />
|
<option name="version" value="2.0.20" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
1
.idea/misc.xml
generated
1
.idea/misc.xml
generated
@@ -1,4 +1,3 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
|
||||||
|
|||||||
@@ -55,6 +55,6 @@ litert = { group = "com.google.ai.edge.litert", name = "litert", version.ref = "
|
|||||||
|
|
||||||
[plugins]
|
[plugins]
|
||||||
android-application = { id = "com.android.application", version.ref = "agp" }
|
android-application = { id = "com.android.application", version.ref = "agp" }
|
||||||
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
|
kotlin-android = { id = "org.jetbrains.kotlin.android", version = "2.0.20" }
|
||||||
kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
|
kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
|
||||||
|
|
||||||
|
|||||||
@@ -359,7 +359,8 @@ class SoundClassifier(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
val sharedPref = PreferenceManager.getDefaultSharedPreferences(mContext)
|
val sharedPref = PreferenceManager.getDefaultSharedPreferences(mContext)
|
||||||
val highPass = sharedPref.getInt("high_pass", 0)
|
// val highPass = sharedPref.getInt("high_pass", 0)
|
||||||
|
val highPass = 300;
|
||||||
val butterworth = Butterworth()
|
val butterworth = Butterworth()
|
||||||
butterworth.highPass(6, 48000.0, highPass.toDouble())
|
butterworth.highPass(6, 48000.0, highPass.toDouble())
|
||||||
|
|
||||||
|
|||||||
1
wear/TileService.kt
Normal file
1
wear/TileService.kt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
class TileService {}
|
||||||
@@ -9,12 +9,16 @@ import androidx.compose.runtime.Composable
|
|||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.navigation.NavHostController
|
||||||
import androidx.wear.compose.material.CompactChip
|
import androidx.wear.compose.material.CompactChip
|
||||||
import androidx.wear.compose.material.MaterialTheme
|
import androidx.wear.compose.material.MaterialTheme
|
||||||
import androidx.wear.compose.material.Text
|
import androidx.wear.compose.material.Text
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ControlDashboard(controlDashboardUiState: ControlDashboardUiState, onMicClicked: () -> Unit, modifier: Modifier = Modifier) {
|
fun ControlDashboard(controlDashboardUiState: ControlDashboardUiState,
|
||||||
|
onMicClicked: () -> Unit,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
navController: NavHostController) {
|
||||||
Box(contentAlignment = Alignment.Center, modifier = modifier.fillMaxSize()) {
|
Box(contentAlignment = Alignment.Center, modifier = modifier.fillMaxSize()) {
|
||||||
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||||
|
|
||||||
@@ -35,22 +39,17 @@ private fun ControlDashboardButton(buttonState: ControlDashboardButtonUiState,
|
|||||||
onClick: () -> Unit,
|
onClick: () -> Unit,
|
||||||
labelText: String,
|
labelText: String,
|
||||||
modifier: Modifier = Modifier) {
|
modifier: Modifier = Modifier) {
|
||||||
CompactChip(
|
CompactChip(modifier = Modifier,
|
||||||
modifier = Modifier,
|
onClick = onClick,
|
||||||
onClick = onClick ,
|
|
||||||
enabled = true,
|
enabled = true,
|
||||||
contentPadding = PaddingValues(5.dp, 1.dp, 5.dp, 1.dp),
|
contentPadding = PaddingValues(5.dp, 1.dp, 5.dp, 1.dp),
|
||||||
shape = MaterialTheme.shapes.small,
|
shape = MaterialTheme.shapes.small,
|
||||||
label = {
|
label = {
|
||||||
Text(
|
Text(text = labelText)
|
||||||
text = labelText
|
})
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Button(modifier = modifier, enabled = buttonState.enabled && buttonState.visible, onClick = onClick) {
|
// Button(modifier = modifier, enabled = buttonState.enabled && buttonState.visible, onClick = onClick) {
|
||||||
// Text(contentDescription);
|
// Text(contentDescription);
|
||||||
//// Icon(imageVector = imageVector, contentDescription = contentDescription)
|
//// Icon(imageVector = imageVector, contentDescription = contentDescription)
|
||||||
|
|||||||
@@ -15,19 +15,39 @@ import androidx.activity.compose.ManagedActivityResultLauncher
|
|||||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||||
import androidx.activity.compose.setContent
|
import androidx.activity.compose.setContent
|
||||||
import androidx.activity.result.contract.ActivityResultContracts.RequestPermission
|
import androidx.activity.result.contract.ActivityResultContracts.RequestPermission
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.rememberScrollState
|
||||||
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
|
import androidx.navigation.NavHostController
|
||||||
|
import androidx.wear.compose.material.Text
|
||||||
import androidx.wear.compose.navigation.SwipeDismissableNavHost
|
import androidx.wear.compose.navigation.SwipeDismissableNavHost
|
||||||
import androidx.wear.compose.navigation.composable
|
import androidx.wear.compose.navigation.composable
|
||||||
import androidx.wear.compose.navigation.rememberSwipeDismissableNavController
|
import androidx.wear.compose.navigation.rememberSwipeDismissableNavController
|
||||||
|
import androidx.wear.compose.ui.tooling.preview.WearPreviewDevices
|
||||||
|
import androidx.wear.compose.ui.tooling.preview.WearPreviewFontScales
|
||||||
import com.birdsounds.identify.presentation.theme.IdentifyTheme
|
import com.birdsounds.identify.presentation.theme.IdentifyTheme
|
||||||
import com.google.android.horologist.annotations.ExperimentalHorologistApi
|
import com.google.android.horologist.annotations.ExperimentalHorologistApi
|
||||||
import com.google.android.horologist.audio.ui.VolumeViewModel
|
import com.google.android.horologist.audio.ui.VolumeViewModel
|
||||||
|
import com.google.android.horologist.compose.layout.ScalingLazyColumn
|
||||||
|
import com.google.android.horologist.compose.layout.ScalingLazyColumnDefaults
|
||||||
|
import com.google.android.horologist.compose.layout.ScreenScaffold
|
||||||
|
import com.google.android.horologist.compose.layout.rememberResponsiveColumnState
|
||||||
|
import com.google.android.horologist.compose.material.Chip
|
||||||
|
import com.google.android.horologist.compose.material.ListHeaderDefaults.firstItemPadding
|
||||||
|
import com.google.android.horologist.compose.material.ResponsiveListHeader
|
||||||
|
import com.google.android.horologist.compose.rotaryinput.rotaryWithScroll
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
@@ -40,11 +60,9 @@ val Any.TAG: String
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class MainActivity : ComponentActivity() {
|
class MainActivity : ComponentActivity() {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
installSplashScreen()
|
installSplashScreen()
|
||||||
|
|
||||||
@@ -69,16 +87,13 @@ fun WearApp() {
|
|||||||
|
|
||||||
|
|
||||||
val volumeViewModel: VolumeViewModel = viewModel(factory = VolumeViewModel.Factory)
|
val volumeViewModel: VolumeViewModel = viewModel(factory = VolumeViewModel.Factory)
|
||||||
val navController = rememberSwipeDismissableNavController()
|
|
||||||
|
|
||||||
val mainState = remember(activity) {
|
val mainState = remember(activity) {
|
||||||
MainState(
|
MainState(activity = activity, requestPermission = {
|
||||||
activity = activity,
|
|
||||||
requestPermission = {
|
|
||||||
requestPermissionLauncher.launch(Manifest.permission.RECORD_AUDIO)
|
requestPermissionLauncher.launch(Manifest.permission.RECORD_AUDIO)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
requestPermissionLauncher = rememberLauncherForActivityResult(RequestPermission()) {
|
requestPermissionLauncher = rememberLauncherForActivityResult(RequestPermission()) {
|
||||||
scope.launch {
|
scope.launch {
|
||||||
@@ -86,25 +101,14 @@ fun WearApp() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val lifecycleOwner = androidx.lifecycle.compose.LocalLifecycleOwner.current
|
val navController: NavHostController = rememberSwipeDismissableNavController()
|
||||||
|
mainState.setNavController(navController);
|
||||||
|
SwipeDismissableNavHost(navController = navController, startDestination = "speaker") {
|
||||||
|
|
||||||
// AppScaffold {
|
|
||||||
// DisposableEffect(mainState, scope, lifecycleOwner) {
|
|
||||||
// val lifecycleObserver = object : DefaultLifecycleObserver {
|
|
||||||
// override fun onStop(owner: LifecycleOwner) {
|
|
||||||
// super.onStop(owner)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// lifecycleOwner.lifecycle.addObserver(lifecycleObserver)
|
|
||||||
//
|
|
||||||
// onDispose {
|
|
||||||
// lifecycleOwner.lifecycle.removeObserver(lifecycleObserver)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
var sdnv = SwipeDismissableNavHost(navController = navController, startDestination = "speaker") {
|
|
||||||
composable("speaker") {
|
composable("speaker") {
|
||||||
StartRecordingScreen(
|
StartRecordingScreen(
|
||||||
context = context,
|
context = context,
|
||||||
|
navController = navController,
|
||||||
appState = mainState.appState,
|
appState = mainState.appState,
|
||||||
isPermissionDenied = mainState.isPermissionDenied,
|
isPermissionDenied = mainState.isPermissionDenied,
|
||||||
onMicClicked = {
|
onMicClicked = {
|
||||||
@@ -114,16 +118,117 @@ fun WearApp() {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
// }
|
|
||||||
|
composable("species_list") {
|
||||||
|
SpeciesListView(context = context)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// var sdnv = SwipeDismissableNavHost(navController = navController, startDestination = "list") {
|
||||||
|
// composable("speaker") {
|
||||||
|
// StartRecordingScreen(
|
||||||
|
// context = context,
|
||||||
|
// appState = mainState.appState,
|
||||||
|
// isPermissionDenied = mainState.isPermissionDenied,
|
||||||
|
// onMicClicked = {
|
||||||
|
// scope.launch {
|
||||||
|
// mainState.onMicClicked()
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// )
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
tailrec fun Context.findActivity(): Activity = when (this) {
|
||||||
|
is Activity -> this
|
||||||
|
is ContextWrapper -> baseContext.findActivity()
|
||||||
|
else -> throw IllegalStateException("findActivity should be called in the context of an Activity")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@OptIn(ExperimentalHorologistApi::class)
|
||||||
|
@Composable
|
||||||
|
fun MessageDetail(id: String) {
|
||||||
|
val scrollState = rememberScrollState()
|
||||||
|
|
||||||
|
ScreenScaffold(scrollState = scrollState) {
|
||||||
|
val padding =
|
||||||
|
ScalingLazyColumnDefaults.padding(first = ScalingLazyColumnDefaults.ItemType.Text, last = ScalingLazyColumnDefaults.ItemType.Text)()
|
||||||
|
Column(modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.verticalScroll(scrollState)
|
||||||
|
.rotaryWithScroll(scrollState)
|
||||||
|
.padding(padding),
|
||||||
|
verticalArrangement = Arrangement.Center) {
|
||||||
|
Text(text = id, textAlign = TextAlign.Center, modifier = Modifier.fillMaxSize())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tailrec fun Context.findActivity(): Activity =
|
@OptIn(ExperimentalHorologistApi::class)
|
||||||
when (this) {
|
@Composable
|
||||||
is Activity -> this
|
fun MessageList(onMessageClick: (String) -> Unit) {
|
||||||
is ContextWrapper -> baseContext.findActivity()
|
val columnState =
|
||||||
else -> throw IllegalStateException(
|
rememberResponsiveColumnState(contentPadding = ScalingLazyColumnDefaults.padding(first = ScalingLazyColumnDefaults.ItemType.Text,
|
||||||
"findActivity should be called in the context of an Activity"
|
last = ScalingLazyColumnDefaults.ItemType.Chip))
|
||||||
)
|
|
||||||
|
ScreenScaffold(scrollState = columnState) {
|
||||||
|
ScalingLazyColumn(columnState = columnState, modifier = Modifier.fillMaxSize()) {
|
||||||
|
item {
|
||||||
|
ResponsiveListHeader(contentPadding = firstItemPadding()) {
|
||||||
|
Text(text = "Hey hey hey")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
item {
|
||||||
|
Chip(label = "Message 1", onClick = { onMessageClick("message1") })
|
||||||
|
}
|
||||||
|
item {
|
||||||
|
Chip(label = "Message 2", onClick = { onMessageClick("message2") })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@OptIn(ExperimentalHorologistApi::class)
|
||||||
|
@Composable
|
||||||
|
fun MessageList2(onMessageClick: (String) -> Unit) {
|
||||||
|
val columnState =
|
||||||
|
rememberResponsiveColumnState(contentPadding = ScalingLazyColumnDefaults.padding(first = ScalingLazyColumnDefaults.ItemType.Text,
|
||||||
|
last = ScalingLazyColumnDefaults.ItemType.Chip))
|
||||||
|
|
||||||
|
ScreenScaffold(scrollState = columnState) {
|
||||||
|
ScalingLazyColumn(columnState = columnState, modifier = Modifier.fillMaxSize()) {
|
||||||
|
item {
|
||||||
|
ResponsiveListHeader(contentPadding = firstItemPadding()) {
|
||||||
|
Text(text = "Hey hey hey")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
item {
|
||||||
|
Chip(label = "Message 3", onClick = { onMessageClick("message3") })
|
||||||
|
}
|
||||||
|
item {
|
||||||
|
Chip(label = "Message 4", onClick = { onMessageClick("message4") })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@WearPreviewDevices
|
||||||
|
@WearPreviewFontScales
|
||||||
|
@Composable
|
||||||
|
fun MessageDetailPreview() {
|
||||||
|
MessageDetail("test")
|
||||||
|
}
|
||||||
|
|
||||||
|
@WearPreviewDevices
|
||||||
|
@WearPreviewFontScales
|
||||||
|
@Composable
|
||||||
|
fun MessageListPreview() {
|
||||||
|
MessageList(onMessageClick = {})
|
||||||
|
}
|
||||||
@@ -1,9 +1,7 @@
|
|||||||
package com.birdsounds.identify.presentation
|
package com.birdsounds.identify.presentation
|
||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.Context
|
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.annotation.RequiresPermission
|
import androidx.annotation.RequiresPermission
|
||||||
@@ -11,24 +9,13 @@ import androidx.compose.foundation.MutatorMutex
|
|||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.platform.LocalContext
|
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import co.touchlab.stately.collections.ConcurrentMutableCollection
|
import androidx.navigation.NavHostController
|
||||||
import com.google.android.gms.tasks.Tasks
|
|
||||||
import com.google.android.gms.wearable.ChannelClient
|
import com.google.android.gms.wearable.ChannelClient
|
||||||
import com.google.android.gms.wearable.ChannelClient.ChannelCallback
|
import com.google.android.gms.wearable.ChannelClient.ChannelCallback
|
||||||
import com.google.android.gms.wearable.Wearable
|
|
||||||
import kotlinx.coroutines.Dispatchers.IO
|
|
||||||
import kotlinx.coroutines.coroutineScope
|
import kotlinx.coroutines.coroutineScope
|
||||||
import kotlinx.coroutines.delay
|
|
||||||
import kotlinx.coroutines.flow.Flow
|
|
||||||
import kotlinx.coroutines.flow.flow
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.tasks.await
|
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
import java.time.LocalDateTime
|
|
||||||
import java.util.concurrent.ExecutionException
|
|
||||||
|
|
||||||
|
|
||||||
class MainState(private val activity: Activity, private val requestPermission: () -> Unit) {
|
class MainState(private val activity: Activity, private val requestPermission: () -> Unit) {
|
||||||
@@ -40,7 +27,10 @@ class MainState(private val activity: Activity, private val requestPermission: (
|
|||||||
var isPermissionDenied by mutableStateOf(false)
|
var isPermissionDenied by mutableStateOf(false)
|
||||||
private set
|
private set
|
||||||
private val soundRecorder = SoundRecorder(activity, "audiorecord.opus")
|
private val soundRecorder = SoundRecorder(activity, "audiorecord.opus")
|
||||||
|
private var navController: NavHostController? = null
|
||||||
|
public fun setNavController(_navController: NavHostController) {
|
||||||
|
navController = _navController
|
||||||
|
}
|
||||||
suspend fun onMicClicked() {
|
suspend fun onMicClicked() {
|
||||||
playbackStateMutatorMutex.mutate {
|
playbackStateMutatorMutex.mutate {
|
||||||
when (appState) {
|
when (appState) {
|
||||||
@@ -48,8 +38,7 @@ class MainState(private val activity: Activity, private val requestPermission: (
|
|||||||
(ContextCompat.checkSelfPermission(activity, Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED) -> {
|
(ContextCompat.checkSelfPermission(activity, Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED) -> {
|
||||||
Log.e(TAG, "Permissions granted, continuing to record")
|
Log.e(TAG, "Permissions granted, continuing to record")
|
||||||
appState = AppState.Recording
|
appState = AppState.Recording
|
||||||
|
navController?.navigate("species_list")
|
||||||
|
|
||||||
record(activity = activity, soundRecorder = soundRecorder, setProgress = { progress -> recordingProgress = progress })
|
record(activity = activity, soundRecorder = soundRecorder, setProgress = { progress -> recordingProgress = progress })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ package com.birdsounds.identify.presentation
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import co.touchlab.stately.collections.ConcurrentMutableSet
|
import co.touchlab.stately.collections.ConcurrentMutableSet
|
||||||
import com.google.android.gms.tasks.Tasksx
|
import com.google.android.gms.tasks.Tasks
|
||||||
import com.google.android.gms.wearable.Wearable
|
import com.google.android.gms.wearable.Wearable
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
|||||||
@@ -1,15 +1,17 @@
|
|||||||
package com.birdsounds.identify.presentation
|
package com.birdsounds.identify.presentation
|
||||||
|
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import androidx.compose.runtime.MutableState
|
||||||
|
import androidx.compose.runtime.snapshots.SnapshotStateList
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
|
|
||||||
|
|
||||||
class AScore(
|
class AScore(
|
||||||
_species: String,
|
_species: String,
|
||||||
_score: Float,
|
_score: Float,
|
||||||
_timestamp: Long
|
_timestamp: Long,
|
||||||
|
|
||||||
) {
|
) {
|
||||||
|
|
||||||
var split_stuff = _species.split("_")
|
var split_stuff = _species.split("_")
|
||||||
val species = split_stuff[0]
|
val species = split_stuff[0]
|
||||||
@@ -31,32 +33,46 @@ class AScore(
|
|||||||
object SpeciesList {
|
object SpeciesList {
|
||||||
var internal_list = mutableListOf<AScore>()
|
var internal_list = mutableListOf<AScore>()
|
||||||
var do_add_observation = false
|
var do_add_observation = false
|
||||||
|
var _list_on_ui: SnapshotStateList<MutableState<String>>? = null
|
||||||
|
fun setSpeciecsShow_list(list_in: SnapshotStateList<MutableState<String>>) {
|
||||||
|
_list_on_ui = list_in;
|
||||||
|
}
|
||||||
|
|
||||||
fun add_observation(species_in: AScore) {
|
fun add_observation(species_in: AScore) {
|
||||||
|
Log.w(TAG,"In add obsergation")
|
||||||
do_add_observation = false
|
do_add_observation = false
|
||||||
var idx = 0
|
var idx = 0
|
||||||
var idx_replace = -1
|
var idx_replace = -1
|
||||||
for (i in internal_list)
|
for (i in internal_list) {
|
||||||
{
|
if (i.species == species_in.species) {
|
||||||
if (i.species == species_in.species)
|
|
||||||
{
|
|
||||||
do_add_observation = false
|
do_add_observation = false
|
||||||
idx_replace = idx
|
idx_replace = idx
|
||||||
}
|
}
|
||||||
idx+=1
|
idx += 1
|
||||||
}
|
}
|
||||||
if (idx_replace >= 0)
|
if (idx_replace >= 0) {
|
||||||
{
|
|
||||||
Log.w(TAG, "Replacing")
|
Log.w(TAG, "Replacing")
|
||||||
internal_list[idx_replace] = species_in
|
internal_list[idx_replace] = species_in // _list_on_ui?.removeAt(idx_replace)
|
||||||
|
// _list_on_ui?.add(species_in);
|
||||||
|
// if (_list_on_ui != null) {
|
||||||
|
// _list_on_ui?.removeAt(idx_replace)
|
||||||
|
// _list_on_ui.add(idx_replace, species_in);
|
||||||
|
// }
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
internal_list.add(species_in)
|
internal_list.add(species_in)
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
// val list_reranked = internal_list.withIndex().sortedBy { it -> it.value.age() }
|
|
||||||
internal_list = internal_list.sortedBy({ (it.age()) }).toMutableList()
|
internal_list = internal_list.sortedBy({ (it.age()) }).toMutableList()
|
||||||
|
|
||||||
|
for ((index, value) in internal_list.withIndex()) {
|
||||||
|
_list_on_ui?.get(index)?.value = value.common_name;
|
||||||
|
}
|
||||||
|
|
||||||
Log.w(TAG, internal_list.toString())
|
Log.w(TAG, internal_list.size.toString())
|
||||||
// internal_list.add(species_in)
|
Log.w(TAG, _list_on_ui?.size.toString()) // internal_list.add(species_in)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package com.birdsounds.identify.presentation
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.MutableState
|
||||||
|
import androidx.compose.runtime.mutableStateListOf
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.snapshots.SnapshotStateList
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.wear.compose.foundation.lazy.items
|
||||||
|
import androidx.wear.compose.material.Text
|
||||||
|
import com.google.android.horologist.annotations.ExperimentalHorologistApi
|
||||||
|
import com.google.android.horologist.compose.layout.ScalingLazyColumn
|
||||||
|
import com.google.android.horologist.compose.layout.ScalingLazyColumnDefaults
|
||||||
|
import com.google.android.horologist.compose.layout.ScreenScaffold
|
||||||
|
import com.google.android.horologist.compose.layout.rememberResponsiveColumnState
|
||||||
|
|
||||||
|
|
||||||
|
@OptIn(ExperimentalHorologistApi::class)
|
||||||
|
@Composable
|
||||||
|
fun SpeciesListView(context: Context,
|
||||||
|
) {
|
||||||
|
val text: MutableState<String> = mutableStateOf("text")
|
||||||
|
//text.toString()
|
||||||
|
val species_list_show = mutableStateListOf<MutableState<String>>()
|
||||||
|
for (i in 1..10)
|
||||||
|
{
|
||||||
|
val hi = mutableStateOf("hi")
|
||||||
|
species_list_show.add(hi);
|
||||||
|
}
|
||||||
|
SpeciesList.setSpeciecsShow_list(species_list_show)
|
||||||
|
val species_show: SnapshotStateList<MutableState<String>> = remember { species_list_show }
|
||||||
|
|
||||||
|
val columnState =
|
||||||
|
rememberResponsiveColumnState(contentPadding = ScalingLazyColumnDefaults.padding(first = ScalingLazyColumnDefaults.ItemType.Text,
|
||||||
|
last = ScalingLazyColumnDefaults.ItemType.Chip))
|
||||||
|
|
||||||
|
ScreenScaffold(scrollState = columnState) {
|
||||||
|
ScalingLazyColumn(columnState = columnState, modifier = Modifier.fillMaxSize()) {
|
||||||
|
items(species_show) { aSpec -> Text(text = aSpec.value)
|
||||||
|
} // Dynamically display the chips
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -3,49 +3,40 @@ package com.birdsounds.identify.presentation
|
|||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
|
||||||
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
|
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
|
||||||
import androidx.wear.compose.ui.tooling.preview.WearPreviewDevices
|
import androidx.navigation.NavHostController
|
||||||
import androidx.wear.compose.ui.tooling.preview.WearPreviewFontScales
|
|
||||||
import com.google.android.horologist.compose.layout.ScreenScaffold
|
import com.google.android.horologist.compose.layout.ScreenScaffold
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun StartRecordingScreen(
|
fun StartRecordingScreen(
|
||||||
context: Context,
|
context: Context,
|
||||||
appState: AppState,
|
appState: AppState,
|
||||||
|
navController: NavHostController,
|
||||||
isPermissionDenied: Boolean,
|
isPermissionDenied: Boolean,
|
||||||
onMicClicked: () -> Unit
|
onMicClicked: () -> Unit
|
||||||
) {
|
) {
|
||||||
ScreenScaffold {
|
ScreenScaffold {
|
||||||
val controlDashboardUiState = computeControlDashboardUiState(
|
val controlDashboardUiState = computeControlDashboardUiState(
|
||||||
appState = appState,
|
appState = appState,
|
||||||
isPermissionDenied = isPermissionDenied
|
|
||||||
)
|
)
|
||||||
ControlDashboard(
|
ControlDashboard(
|
||||||
controlDashboardUiState = controlDashboardUiState,
|
controlDashboardUiState = controlDashboardUiState,
|
||||||
onMicClicked = onMicClicked
|
onMicClicked = onMicClicked,
|
||||||
|
navController = navController
|
||||||
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun computeControlDashboardUiState(
|
private fun computeControlDashboardUiState(
|
||||||
appState: AppState,
|
appState: AppState,
|
||||||
isPermissionDenied: Boolean
|
|
||||||
): ControlDashboardUiState =
|
): ControlDashboardUiState =
|
||||||
when (appState) {
|
when (appState) {
|
||||||
AppState.Ready -> ControlDashboardUiState(
|
AppState.Ready -> ControlDashboardUiState(
|
||||||
micState = ControlDashboardButtonUiState(
|
micState = ControlDashboardButtonUiState(expanded = false, visible = true, enabled = true),
|
||||||
expanded = false,
|
|
||||||
enabled = !isPermissionDenied,
|
|
||||||
visible = true
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
AppState.Recording -> ControlDashboardUiState(
|
AppState.Recording -> ControlDashboardUiState(
|
||||||
micState = ControlDashboardButtonUiState(
|
micState = ControlDashboardButtonUiState(expanded = true, visible = true, enabled = true),
|
||||||
expanded = true,
|
|
||||||
enabled = true,
|
|
||||||
visible = true
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user