From c568b0435402c43034f6fc58b279d01dc1216506 Mon Sep 17 00:00:00 2001 From: geeksville Date: Tue, 18 Feb 2020 12:22:45 -0800 Subject: [PATCH] Setting owner name approximately works --- .../java/com/geeksville/mesh/MainActivity.kt | 2 +- .../java/com/geeksville/mesh/model/UIState.kt | 19 ++++- .../java/com/geeksville/mesh/ui/Messages.kt | 45 +++++------ .../java/com/geeksville/mesh/ui/Settings.kt | 36 ++++++++- .../com/geeksville/mesh/ui/StyledTextField.kt | 75 +++++++++++++++++++ 5 files changed, 143 insertions(+), 34 deletions(-) create mode 100644 app/src/main/java/com/geeksville/mesh/ui/StyledTextField.kt diff --git a/app/src/main/java/com/geeksville/mesh/MainActivity.kt b/app/src/main/java/com/geeksville/mesh/MainActivity.kt index 6cb1f5991..3df06dead 100644 --- a/app/src/main/java/com/geeksville/mesh/MainActivity.kt +++ b/app/src/main/java/com/geeksville/mesh/MainActivity.kt @@ -175,7 +175,7 @@ class MainActivity : AppCompatActivity(), Logging, super.onCreate(savedInstanceState) val prefs = getSharedPreferences("ui-prefs", Context.MODE_PRIVATE) - UIState.ownerName = prefs.getString("owner", "Unknown Owner")!! + UIState.ownerName = prefs.getString("owner", "")!! // Ensures Bluetooth is available on the device and it is enabled. If not, // displays a dialog requesting user permission to enable Bluetooth. diff --git a/app/src/main/java/com/geeksville/mesh/model/UIState.kt b/app/src/main/java/com/geeksville/mesh/model/UIState.kt index 8d6766821..4a3c62291 100644 --- a/app/src/main/java/com/geeksville/mesh/model/UIState.kt +++ b/app/src/main/java/com/geeksville/mesh/model/UIState.kt @@ -1,6 +1,7 @@ package com.geeksville.mesh.model import android.content.Context +import android.os.RemoteException import android.util.Base64 import androidx.compose.mutableStateOf import androidx.core.content.edit @@ -24,7 +25,8 @@ object UIState { /// our name in hte radio /// Note, we generate owner initials automatically for now - var ownerName: String = "fixme readfromprefs" + /// our activity will read this from prefs or set it to the empty string + var ownerName: String = "MrInIDE Ownername" /// Return an URL that represents the current channel values val channelUrl @@ -37,9 +39,11 @@ object UIState { // clean up all this nasty owner state management FIXME fun setOwner(context: Context, s: String? = null) { - + if (s != null) { ownerName = s + + // note: we allow an empty userstring to be written to prefs val prefs = context.getSharedPreferences("ui-prefs", Context.MODE_PRIVATE) prefs.edit(commit = true) { putString("owner", s) @@ -47,6 +51,15 @@ object UIState { } // Note: we are careful to not set a new unique ID - meshService!!.setOwner(null, ownerName, getInitials(ownerName)) + if (ownerName.isNotEmpty()) + try { + meshService?.setOwner( + null, + ownerName, + getInitials(ownerName) + ) // Note: we use ?. here because we might be running in the emulator + } catch (ex: RemoteException) { + error("Can't set username on device, is device offline? ${ex.message}") + } } } diff --git a/app/src/main/java/com/geeksville/mesh/ui/Messages.kt b/app/src/main/java/com/geeksville/mesh/ui/Messages.kt index 15904bc71..375045957 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/Messages.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/Messages.kt @@ -4,9 +4,7 @@ import androidx.compose.Composable import androidx.compose.state import androidx.ui.core.Modifier import androidx.ui.core.Text -import androidx.ui.core.TextField import androidx.ui.foundation.VerticalScroller -import androidx.ui.foundation.shape.corner.RoundedCornerShape import androidx.ui.graphics.Color import androidx.ui.input.ImeAction import androidx.ui.layout.Column @@ -16,7 +14,6 @@ import androidx.ui.layout.Row import androidx.ui.material.Emphasis import androidx.ui.material.MaterialTheme import androidx.ui.material.ProvideEmphasis -import androidx.ui.material.surface.Surface import androidx.ui.text.TextStyle import androidx.ui.tooling.preview.Preview import androidx.ui.unit.dp @@ -47,7 +44,7 @@ fun MessageCard(msg: TextMessage, modifier: Modifier = Modifier.None) { val nodes = NodeDB.nodes // If we can't find the sender, just use the ID - val node = nodes?.get(msg.from) + val node = nodes.get(msg.from) val user = node?.user val senderName = user?.longName ?: msg.from Text(text = senderName) @@ -67,6 +64,7 @@ fun MessageCard(msg: TextMessage, modifier: Modifier = Modifier.None) { } } + @Composable fun MessagesContent() { Column(modifier = LayoutSize.Fill) { @@ -93,30 +91,23 @@ fun MessagesContent() { // Spacer(LayoutFlexible(1f)) - val message = state { "text message" } - val backgroundColor = palette.secondary.copy(alpha = 0.12f) - Surface( - modifier = LayoutPadding(8.dp), - color = backgroundColor, - shape = RoundedCornerShape(4.dp) - ) { - TextField( - value = message.value, - onValueChange = { message.value = it }, - textStyle = TextStyle( - color = palette.onSecondary.copy(alpha = 0.8f) - ), - imeAction = ImeAction.Send, - onImeActionPerformed = { - MessagesState.info("did IME action") + val message = state { "" } + StyledTextField( + value = message.value, + onValueChange = { message.value = it }, + textStyle = TextStyle( + color = palette.onSecondary.copy(alpha = 0.8f) + ), + imeAction = ImeAction.Send, + onImeActionPerformed = { + MessagesState.info("did IME action") - val str = message.value - MessagesState.sendMessage(str) - message.value = "" // blow away the string the user just entered - }, - modifier = LayoutPadding(4.dp) - ) - } + val str = message.value + MessagesState.sendMessage(str) + message.value = "" // blow away the string the user just entered + }, + hintText = "Type your message here..." + ) } } diff --git a/app/src/main/java/com/geeksville/mesh/ui/Settings.kt b/app/src/main/java/com/geeksville/mesh/ui/Settings.kt index 804a607b6..78670c153 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/Settings.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/Settings.kt @@ -1,13 +1,19 @@ package com.geeksville.mesh.ui import androidx.compose.Composable -import androidx.ui.layout.Column -import androidx.ui.layout.LayoutPadding -import androidx.ui.layout.LayoutSize +import androidx.compose.ambient +import androidx.compose.state +import androidx.ui.core.ContextAmbient +import androidx.ui.core.Text +import androidx.ui.input.ImeAction +import androidx.ui.layout.* import androidx.ui.material.MaterialTheme +import androidx.ui.text.TextStyle import androidx.ui.tooling.preview.Preview import androidx.ui.unit.dp import com.geeksville.android.Logging +import com.geeksville.mesh.model.MessagesState +import com.geeksville.mesh.model.UIState object SettingsLog : Logging @@ -16,8 +22,32 @@ object SettingsLog : Logging fun SettingsContent() { val typography = MaterialTheme.typography() + val context = ambient(ContextAmbient) Column(modifier = LayoutSize.Fill + LayoutPadding(16.dp)) { + Row { + Text("Your name ", modifier = LayoutGravity.Center) + + val name = state { UIState.ownerName } + StyledTextField( + value = name.value, + onValueChange = { name.value = it }, + textStyle = TextStyle( + color = palette.onSecondary.copy(alpha = 0.8f) + ), + imeAction = ImeAction.Done, + onImeActionPerformed = { + MessagesState.info("did IME action") + val n = name.value.trim() + if (n.isNotEmpty()) + UIState.setOwner(context, n) + }, + hintText = "Type your name here...", + modifier = LayoutGravity.Center + ) + } + + BTScanScreen() } } diff --git a/app/src/main/java/com/geeksville/mesh/ui/StyledTextField.kt b/app/src/main/java/com/geeksville/mesh/ui/StyledTextField.kt new file mode 100644 index 000000000..70a64994f --- /dev/null +++ b/app/src/main/java/com/geeksville/mesh/ui/StyledTextField.kt @@ -0,0 +1,75 @@ +package com.geeksville.mesh.ui + +import androidx.compose.Composable +import androidx.compose.state +import androidx.ui.core.Modifier +import androidx.ui.core.TextField +import androidx.ui.foundation.shape.corner.RoundedCornerShape +import androidx.ui.graphics.Color +import androidx.ui.input.ImeAction +import androidx.ui.input.KeyboardType +import androidx.ui.input.VisualTransformation +import androidx.ui.layout.LayoutPadding +import androidx.ui.material.Emphasis +import androidx.ui.material.EmphasisLevels +import androidx.ui.material.ProvideEmphasis +import androidx.ui.material.surface.Surface +import androidx.ui.text.TextStyle +import androidx.ui.unit.dp + + +val HintEmphasis = object : Emphasis { + override fun emphasize(color: Color) = color.copy(alpha = 0.05f) +} + + +/// A text field that visually conveys that it is editable - FIXME, once Compose has material +/// design text fields use that instead. +@Composable +fun StyledTextField( + value: String, + modifier: Modifier = Modifier.None, + onValueChange: (String) -> Unit = {}, + textStyle: TextStyle? = null, + keyboardType: KeyboardType = KeyboardType.Text, + imeAction: ImeAction = ImeAction.Unspecified, + onFocus: () -> Unit = {}, + onBlur: () -> Unit = {}, + focusIdentifier: String? = null, + onImeActionPerformed: (ImeAction) -> Unit = {}, + visualTransformation: VisualTransformation? = null, + hintText: String = "" +) { + val backgroundColor = palette.secondary.copy(alpha = 0.12f) + Surface( + modifier = LayoutPadding(8.dp), + color = backgroundColor, + shape = RoundedCornerShape(4.dp) + ) { + val showingHint = state { value.isEmpty() } + val level = if (showingHint.value) HintEmphasis else EmphasisLevels().medium + + ProvideEmphasis(level) { + TextField( + value.ifEmpty { if (showingHint.value) hintText else "" }, + modifier + LayoutPadding(4.dp), + onValueChange, + textStyle, + keyboardType, + imeAction, + { + showingHint.value = false // Stop showing the hint now + onFocus() + }, + { + // if the string is empty again, return to the hint text + showingHint.value = value.isEmpty() + onBlur() + }, + focusIdentifier, + onImeActionPerformed, + visualTransformation + ) + } + } +}