mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-03-30 03:33:50 -04:00
@@ -28,8 +28,8 @@ android {
|
||||
applicationId "com.geeksville.mesh"
|
||||
minSdkVersion 21 // The oldest emulator image I have tried is 22 (though 21 probably works)
|
||||
targetSdkVersion 29
|
||||
versionCode 10901 // format is Mmmss (where M is 1+the numeric major number
|
||||
versionName "0.9.01"
|
||||
versionCode 10902 // format is Mmmss (where M is 1+the numeric major number
|
||||
versionName "0.9.02"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
buildTypes {
|
||||
@@ -112,7 +112,7 @@ dependencies {
|
||||
implementation 'androidx.fragment:fragment-ktx:1.2.5'
|
||||
implementation 'androidx.cardview:cardview:1.0.0'
|
||||
implementation 'androidx.recyclerview:recyclerview:1.1.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta8'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.0.0-rc1'
|
||||
implementation 'com.google.android.material:material:1.2.0-rc01'
|
||||
implementation 'androidx.viewpager2:viewpager2:1.0.0'
|
||||
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
|
||||
|
||||
@@ -750,7 +750,7 @@ class MainActivity : AppCompatActivity(), Logging,
|
||||
// Init our messages table with the service's record of past text messages
|
||||
val msgs = service.oldMessages
|
||||
debug("Service provided ${msgs.size} messages")
|
||||
model.messagesState.messages.value = msgs
|
||||
model.messagesState.setMessages(msgs)
|
||||
val connectionState =
|
||||
MeshService.ConnectionState.valueOf(service.connectionState())
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import com.google.zxing.BarcodeFormat
|
||||
import com.google.zxing.MultiFormatWriter
|
||||
import com.journeyapps.barcodescanner.BarcodeEncoder
|
||||
import java.net.MalformedURLException
|
||||
import kotlin.experimental.xor
|
||||
|
||||
/** Utility function to make it easy to declare byte arrays - FIXME move someplace better */
|
||||
fun byteArrayOfInts(vararg ints: Int) = ByteArray(ints.size) { pos -> ints[pos].toByte() }
|
||||
@@ -52,6 +53,17 @@ data class Channel(
|
||||
val name: String get() = settings.name
|
||||
val modemConfig: MeshProtos.ChannelSettings.ModemConfig get() = settings.modemConfig
|
||||
|
||||
/**
|
||||
* Return a name that is formatted as #channename-suffix
|
||||
*
|
||||
* Where suffix indicates the hash of the PSK
|
||||
*/
|
||||
val humanName: String
|
||||
get() {
|
||||
val code = settings.psk.fold(0.toByte(), { acc, x -> acc xor x })
|
||||
return "#${settings.name}-${'A' + (code % 26)}"
|
||||
}
|
||||
|
||||
/// Can this channel be changed right now?
|
||||
var editable = false
|
||||
|
||||
|
||||
@@ -20,40 +20,44 @@ class MessagesState(private val ui: UIViewModel) : Logging {
|
||||
)
|
||||
)
|
||||
|
||||
/// This is the inner storage for messages
|
||||
private val messagesList = (if (isEmulator) testTexts else emptyList()).toMutableList()
|
||||
|
||||
// If the following (unused otherwise) line is commented out, the IDE preview window works.
|
||||
// if left in the preview always renders as empty.
|
||||
val messages =
|
||||
object : MutableLiveData<List<DataPacket>>(if (isEmulator) testTexts else emptyList()) {
|
||||
object : MutableLiveData<List<DataPacket>>(messagesList) {
|
||||
|
||||
}
|
||||
|
||||
fun setMessages(m: List<DataPacket>) {
|
||||
messagesList.clear()
|
||||
messagesList.addAll(m)
|
||||
messages.value = messagesList
|
||||
}
|
||||
|
||||
/// add a message our GUI list of past msgs
|
||||
fun addMessage(m: DataPacket) {
|
||||
debug("Adding message to view id=${m.id}")
|
||||
// FIXME - don't just slam in a new list each time, it probably causes extra drawing.
|
||||
|
||||
// FIXME - possible kotlin bug in 1.3.72 - it seems that if we start with the (globally shared) emptyList,
|
||||
// then adding items are affecting that shared list rather than a copy. This was causing aliasing of
|
||||
// recentDataPackets with messages.value in the GUI. So if the current list is empty we are careful to make a new list
|
||||
messages.value = if (messages.value.isNullOrEmpty())
|
||||
listOf(m)
|
||||
else
|
||||
messages.value!! + m
|
||||
messagesList.add(m)
|
||||
|
||||
messages.value = messagesList
|
||||
}
|
||||
|
||||
fun updateStatus(id: Int, status: MessageStatus) {
|
||||
// Super inefficent but this is rare
|
||||
debug("Handling message status change $id: $status")
|
||||
val msgs = messages.value!!
|
||||
|
||||
msgs.find { it.id == id }?.let { p ->
|
||||
messagesList.find { it.id == id }?.let { p ->
|
||||
// Note: it seems that the service is keeping only a reference to our original packet (so it has already updated p.status)
|
||||
// This seems to be an AIDL optimization when both the service and the client are in the same process. But we still want to trigger
|
||||
// a GUI update
|
||||
// if (p.status != status) {
|
||||
p.status = status
|
||||
// Trigger an expensive complete redraw FIXME
|
||||
messages.value = msgs
|
||||
messages.value = messagesList
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ class ChannelFragment : ScreenFragment("Channel"), Logging {
|
||||
if (channel != null) {
|
||||
qrView.visibility = View.VISIBLE
|
||||
channelNameEdit.visibility = View.VISIBLE
|
||||
channelNameEdit.setText(channel.name)
|
||||
channelNameEdit.setText(channel.humanName)
|
||||
|
||||
// For now, we only let the user edit/save channels while the radio is awake - because the service
|
||||
// doesn't cache radioconfig writes.
|
||||
@@ -134,7 +134,12 @@ class ChannelFragment : ScreenFragment("Channel"), Logging {
|
||||
}
|
||||
|
||||
editableCheckbox.setOnCheckedChangeListener { _, checked ->
|
||||
if (!checked) {
|
||||
if (checked) {
|
||||
// User just unlocked for editing - remove the # goo around the channel name
|
||||
UIViewModel.getChannel(model.radioConfig.value)?.let { channel ->
|
||||
channelNameEdit.setText(channel.name)
|
||||
}
|
||||
} else {
|
||||
// User just locked it, we should warn and then apply changes to radio
|
||||
MaterialAlertDialogBuilder(requireContext())
|
||||
.setTitle(R.string.change_channel)
|
||||
@@ -177,7 +182,7 @@ class ChannelFragment : ScreenFragment("Channel"), Logging {
|
||||
// Since we are writing to radioconfig, that will trigger the rest of the GUI update (QR code etc)
|
||||
} catch (ex: RemoteException) {
|
||||
errormsg("ignoring channel problem", ex)
|
||||
|
||||
|
||||
setGUIfromModel() // Throw away user edits
|
||||
|
||||
// Tell the user to try again
|
||||
|
||||
Reference in New Issue
Block a user