Skip to content

Commit

Permalink
Move composables to separate files
Browse files Browse the repository at this point in the history
  • Loading branch information
Danand committed Mar 28, 2024
1 parent 76e8c80 commit 7711984
Show file tree
Hide file tree
Showing 24 changed files with 1,131 additions and 908 deletions.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.danand.juicynoise.composables

import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState

@Composable
fun AlertError(
errorState: MutableState<String?>,
) {
if (errorState.value != null) {
AlertDialog(
onDismissRequest = {
errorState.value = null
},
title = {
Text("ERROR")
},
text = {
Text(errorState.value.toString())
},
confirmButton = {
Button(
onClick = {
errorState.value = null
},
) {
Text("OK")
}
}
)
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
@file:OptIn(
ExperimentalMaterial3Api::class,
ExperimentalComposeUiApi::class,
ExperimentalMaterial3Api::class,
)

package com.danand.juicynoise.composables
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package com.danand.juicynoise.composables

import com.danand.juicynoise.data.SettingsState

import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp

@Composable
fun AudioSettings(
settingsState: SettingsState,
isShowingAudioSettings: MutableState<Boolean>,
) {
Spacer(modifier = Modifier.height(24.dp))

LabelledCheckBox(
label = "Show settings",
checked = isShowingAudioSettings.value,
onCheckedChange = {
isShowingAudioSettings.value = it
},
)

if (isShowingAudioSettings.value) {
InputFloat(
"Stereo Separation",
settingsState.stereoSeparation.value
) {
settingsState.stereoSeparation.value = it
}

InputFloat(
"Frequency Min",
settingsState.frequencyMin.value
) {
settingsState.frequencyMin.value = it
}

InputFloat(
"Sensitivity A",
settingsState.sensitivityA.value
) {
settingsState.sensitivityA.value = it
}

InputFloat(
"Sensitivity B",
settingsState.sensitivityB.value,
) {
settingsState.sensitivityB.value = it
}

InputFloat(
"Sensitivity C",
settingsState.sensitivityC.value,
) {
settingsState.sensitivityC.value = it
}

InputFloat(
"Sensitivity D",
settingsState.sensitivityD.value,
) {
settingsState.sensitivityD.value = it
}

InputInt(
"Rhythm Seed A",
settingsState.rhythmSeedA.value,
) {
settingsState.rhythmSeedA.value = it
}

InputInt(
"Rhythm Seed B",
settingsState.rhythmSeedB.value,
) {
settingsState.rhythmSeedB.value = it
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.danand.juicynoise.composables

import com.danand.juicynoise.data.AudioBufferSize

import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp

@Composable
fun BufferSettings(
sampleRateState: MutableState<Int>,
audioBufferSizeState: MutableState<AudioBufferSize>,
) {
InputInt(
"Sample Rate",
sampleRateState.value
) {
sampleRateState.value = it
}

Spacer(modifier = Modifier.height(16.dp))

AudioBufferSizeTextField(
selectedBufferSize = audioBufferSizeState.value,
onItemSelected = { audioBufferSizeState.value = it }
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
package com.danand.juicynoise.composables

import com.danand.juicynoise.data.AudioBufferSize
import com.danand.juicynoise.data.Sensors
import com.danand.juicynoise.utils.runReadingLocation

import android.util.Log

import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.ui.unit.dp

import com.google.android.gms.location.FusedLocationProviderClient
import com.google.gson.GsonBuilder

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch

import java.io.DataOutputStream
import java.net.Socket
import java.nio.ByteBuffer
import java.nio.ByteOrder

import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine
import kotlin.math.floor

@Composable
fun ButtonConnect(
ip: String,
port: UShort,
isRunningState: MutableState<Boolean>,
errorState: MutableState<String?>,
sensorsState: MutableState<Sensors>,
audioBufferSizeState: MutableState<AudioBufferSize>,
sampleRateState: MutableState<Int>,
locationClient: FusedLocationProviderClient,
validator: () -> Boolean
) {
Button(
onClick = {
isRunningState.value = true

runReadingLocation(
locationClient,
isRunningState,
sensorsState,
)

startSendingSensors(
ip,
port,
isRunningState,
errorState,
sensorsState,
audioBufferSizeState,
sampleRateState,
)
},
colors = ButtonDefaults.textButtonColors(
containerColor = MaterialTheme.colorScheme.primaryContainer
),
elevation = ButtonDefaults.buttonElevation(
defaultElevation = 0.dp,
pressedElevation = 16.dp,
disabledElevation = 0.dp,
),
enabled = validator()
) {
if (validator()) {
Text("Connect to $ip:$port")
} else {
Text("Invalid address")
}
}
}

fun startSendingSensors(
ip: String,
port: UShort,
isRunningState: MutableState<Boolean>,
errorState: MutableState<String?>,
sensorsState: MutableState<Sensors>,
audioBufferSizeState: MutableState<AudioBufferSize>,
sampleRateState: MutableState<Int>,
) {
val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())

scope.launch(Dispatchers.IO) {
try {
val socket = Socket(ip, port.toInt())
val socketStream = socket.getOutputStream()
val dataOutputStream = DataOutputStream(socketStream)

val gson = GsonBuilder().setPrettyPrinting().create()

while (isRunningState.value) {
dataOutputStream.writeFloatWithLittleEndian(sensorsState.value.longitude)
dataOutputStream.writeFloatWithLittleEndian(sensorsState.value.latitude)
dataOutputStream.writeFloatWithLittleEndian(sensorsState.value.angularSpeedX)
dataOutputStream.writeFloatWithLittleEndian(sensorsState.value.angularSpeedY)
dataOutputStream.writeFloatWithLittleEndian(sensorsState.value.angularSpeedZ)
dataOutputStream.writeFloatWithLittleEndian(sensorsState.value.accelerationX)
dataOutputStream.writeFloatWithLittleEndian(sensorsState.value.accelerationY)
dataOutputStream.writeFloatWithLittleEndian(sensorsState.value.accelerationZ)
dataOutputStream.writeFloatWithLittleEndian(sensorsState.value.rotationX)
dataOutputStream.writeFloatWithLittleEndian(sensorsState.value.rotationY)
dataOutputStream.writeFloatWithLittleEndian(sensorsState.value.rotationZ)
dataOutputStream.writeFloatWithLittleEndian(sensorsState.value.gravityX)
dataOutputStream.writeFloatWithLittleEndian(sensorsState.value.gravityY)
dataOutputStream.writeFloatWithLittleEndian(sensorsState.value.gravityZ)
dataOutputStream.writeFloatWithLittleEndian(sensorsState.value.magneticX)
dataOutputStream.writeFloatWithLittleEndian(sensorsState.value.magneticY)
dataOutputStream.writeFloatWithLittleEndian(sensorsState.value.magneticZ)
dataOutputStream.writeFloatWithLittleEndian(sensorsState.value.light)
dataOutputStream.writeFloatWithLittleEndian(sensorsState.value.pressure)
dataOutputStream.writeFloatWithLittleEndian(sensorsState.value.proximity)
dataOutputStream.writeFloatWithLittleEndian(sensorsState.value.cellSignalStrength)
dataOutputStream.writeFloatWithLittleEndian(sensorsState.value.wifiSignalStrength)

dataOutputStream.flush()

val delayDuration = floor(audioBufferSizeState.value.value / (sampleRateState.value / 1000.0)).toLong()

Log.d("Sensors", gson.toJson(sensorsState.value))

delay(delayDuration)
}

dataOutputStream.close()
socketStream.close()
socket.close()
} catch (exception: Exception) {
errorState.value = exception.message
}
finally {
isRunningState.value = false
}
}
}

fun DataOutputStream.writeFloatWithLittleEndian(value: Float) {
val buffer = ByteBuffer.allocate(Float.SIZE_BYTES).order(
ByteOrder.LITTLE_ENDIAN)

buffer.putFloat(value)

val bytes = buffer.array()

this.write(bytes)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.danand.juicynoise.composables

import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.ui.unit.dp

@Composable
fun ButtonDisconnect(
isRunning: MutableState<Boolean>,
) {
Button(
onClick = {
isRunning.value = false
},
colors = ButtonDefaults.textButtonColors(
containerColor = MaterialTheme.colorScheme.primaryContainer
),
elevation = ButtonDefaults.buttonElevation(
defaultElevation = 0.dp,
pressedElevation = 16.dp,
disabledElevation = 0.dp,
),
) {
Text("Disconnect")
}
}
Loading

0 comments on commit 7711984

Please sign in to comment.