Meshtastic-Android/app/src/main/java/com/geeksville/mesh/model/UIState.kt

131 lines
4.4 KiB
Kotlin
Raw Normal View History

2020-02-17 13:34:52 -08:00
package com.geeksville.mesh.model
import android.app.Application
2020-02-18 10:40:02 -08:00
import android.content.Context
2020-03-02 08:41:16 -08:00
import android.content.SharedPreferences
2020-03-17 11:35:19 -07:00
import android.net.Uri
2020-02-18 12:22:45 -08:00
import android.os.RemoteException
2020-02-18 10:40:02 -08:00
import androidx.core.content.edit
import androidx.lifecycle.AndroidViewModel
2020-04-07 17:42:31 -07:00
import androidx.lifecycle.MutableLiveData
2020-03-15 18:44:10 -07:00
import com.geeksville.android.BuildUtils.isEmulator
import com.geeksville.android.Logging
import com.geeksville.mesh.IMeshService
2020-02-17 13:34:52 -08:00
import com.geeksville.mesh.MeshProtos
import com.geeksville.mesh.service.MeshService
/// Given a human name, strip out the first letter of the first three words and return that as the initials for
/// that user.
fun getInitials(name: String): String {
val words = name.split(Regex("\\s+")).filter { it.isNotEmpty() }.take(3).map { it.first() }
.joinToString("")
return words
}
2020-03-15 16:30:12 -07:00
class UIViewModel(app: Application) : AndroidViewModel(app), Logging {
2020-04-07 17:42:31 -07:00
init {
debug("ViewModel created")
}
companion object {
/**
* Return the current channel info
* FIXME, we should sim channels at the MeshService level if we are running on an emulator,
* for now I just fake it by returning a canned channel.
*/
fun getChannel(c: MeshProtos.RadioConfig?): Channel? {
val channel = c?.channelSettings?.let { Channel(it) }
return if (channel == null && isEmulator)
Channel.emulated
else
channel
}
fun getPreferences(context: Context): SharedPreferences =
context.getSharedPreferences("ui-prefs", Context.MODE_PRIVATE)
}
private val context = app.applicationContext
2020-04-07 17:42:31 -07:00
var meshService: IMeshService? = null
val nodeDB = NodeDB(this)
val messagesState = MessagesState(this)
2020-04-07 17:42:31 -07:00
/// Are we connected to our radio device
2020-04-08 08:16:06 -07:00
val isConnected =
object :
MutableLiveData<MeshService.ConnectionState>(MeshService.ConnectionState.DISCONNECTED) {
2020-04-08 08:16:06 -07:00
}
2020-04-07 17:42:31 -07:00
/// various radio settings (including the channel)
2020-04-08 08:16:06 -07:00
val radioConfig = object : MutableLiveData<MeshProtos.RadioConfig?>(null) {
}
2020-04-07 17:42:31 -07:00
override fun onCleared() {
super.onCleared()
debug("ViewModel cleared")
}
2020-04-07 17:42:31 -07:00
/// Set the radio config (also updates our saved copy in preferences)
fun setRadioConfig(c: MeshProtos.RadioConfig) {
2020-04-07 17:42:31 -07:00
debug("Setting new radio config!")
meshService?.radioConfig = c.toByteArray()
radioConfig.value = c
getPreferences(context).edit(commit = true) {
this.putString("channel-url", getChannel(c)!!.getChannelUrl().toString())
2020-04-07 17:42:31 -07:00
}
}
2020-02-17 13:34:52 -08:00
/** Update just the channel settings portion of our config (both in the device and in saved preferences) */
fun setChannel(c: MeshProtos.ChannelSettings) {
// When running on the emulator, radio config might not really be available, in that case, just ignore attempts to change the config
radioConfig.value?.toBuilder()?.let { config ->
config.channelSettings = c
setRadioConfig(config.build())
}
}
2020-02-17 13:34:52 -08:00
/// Kinda ugly - created in the activity but used from Compose - figure out if there is a cleaner way GIXME
// lateinit var googleSignInClient: GoogleSignInClient
/// our name in hte radio
/// Note, we generate owner initials automatically for now
2020-02-18 12:22:45 -08:00
/// our activity will read this from prefs or set it to the empty string
val ownerName = object : MutableLiveData<String>("MrIDE Test") {
2020-03-15 18:44:10 -07:00
}
2020-03-15 16:30:12 -07:00
2020-02-18 10:40:02 -08:00
/// If the app was launched because we received a new channel intent, the Url will be here
var requestedChannelUrl: Uri? = null
2020-02-18 10:40:02 -08:00
// clean up all this nasty owner state management FIXME
fun setOwner(s: String? = null) {
2020-02-18 12:22:45 -08:00
2020-02-18 10:40:02 -08:00
if (s != null) {
ownerName.value = s
2020-02-18 12:22:45 -08:00
// note: we allow an empty userstring to be written to prefs
2020-03-02 08:41:16 -08:00
getPreferences(context).edit(commit = true) {
2020-02-18 10:40:02 -08:00
putString("owner", s)
}
}
// Note: we are careful to not set a new unique ID
if (ownerName.value!!.isNotEmpty())
2020-02-18 12:22:45 -08:00
try {
meshService?.setOwner(
null,
ownerName.value,
getInitials(ownerName.value!!)
2020-02-18 12:22:45 -08:00
) // Note: we use ?. here because we might be running in the emulator
} catch (ex: RemoteException) {
errormsg("Can't set username on device, is device offline? ${ex.message}")
2020-02-18 12:22:45 -08:00
}
2020-02-18 10:40:02 -08:00
}
2020-02-17 13:34:52 -08:00
}