mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-20 22:23:37 +00:00
feat: Add mute node functionality (#4181)
Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
This commit is contained in:
parent
42fe7e9b2e
commit
a67b519abd
34 changed files with 2174 additions and 458 deletions
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (c) 2025-2026 Meshtastic LLC
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.meshtastic.core.model
|
||||
|
||||
/**
|
||||
* Defines the capabilities and feature support based on the device firmware version.
|
||||
*
|
||||
* This class provides a centralized way to check if specific features are supported by the connected node's firmware.
|
||||
* Add new features here to ensure consistency across the app.
|
||||
*/
|
||||
data class Capabilities(val firmwareVersion: String?) {
|
||||
private val version = firmwareVersion?.let { DeviceVersion(it) }
|
||||
|
||||
/**
|
||||
* Ability to mute notifications from specific nodes via admin messages.
|
||||
*
|
||||
* Note: This is currently not available in firmware but defined here for future support.
|
||||
*/
|
||||
val canMuteNode: Boolean
|
||||
get() = version != null && version >= DeviceVersion("2.8.0")
|
||||
|
||||
/** Ability to request neighbor information from other nodes. Supported since firmware v2.7.15. */
|
||||
val canRequestNeighborInfo: Boolean
|
||||
get() = version != null && version >= DeviceVersion("2.7.15")
|
||||
|
||||
/** Ability to send verified shared contacts. Supported since firmware v2.7.12. */
|
||||
val canSendVerifiedContacts: Boolean
|
||||
get() = version != null && version >= DeviceVersion("2.7.12")
|
||||
|
||||
/** Ability to toggle device telemetry globally via module config. Supported since firmware v2.7.12. */
|
||||
val canToggleTelemetryEnabled: Boolean
|
||||
get() = version != null && version >= DeviceVersion("2.7.12")
|
||||
|
||||
/** Ability to toggle the 'is_unmessageable' flag in user config. Supported since firmware v2.6.9. */
|
||||
val canToggleUnmessageable: Boolean
|
||||
get() = version != null && version >= DeviceVersion("2.6.9")
|
||||
|
||||
/** Support for sharing contact information via QR codes. Supported since firmware v2.6.8. */
|
||||
val supportsQrCodeSharing: Boolean
|
||||
get() = version != null && version >= DeviceVersion("2.6.8")
|
||||
}
|
||||
|
|
@ -16,7 +16,6 @@
|
|||
*/
|
||||
package org.meshtastic.core.model.util
|
||||
|
||||
import android.widget.EditText
|
||||
import org.meshtastic.core.model.BuildConfig
|
||||
import org.meshtastic.proto.ConfigProtos
|
||||
import org.meshtastic.proto.MeshProtos
|
||||
|
|
@ -66,18 +65,6 @@ fun Any.toPIIString() = if (!BuildConfig.DEBUG) {
|
|||
|
||||
fun ByteArray.toHexString() = joinToString("") { "%02x".format(it) }
|
||||
|
||||
@Suppress("MagicNumber")
|
||||
fun formatAgo(lastSeenUnix: Int, currentTimeMillis: Long = System.currentTimeMillis()): String {
|
||||
val timeInMillis = lastSeenUnix * 1000L
|
||||
return android.text.format.DateUtils.getRelativeTimeSpanString(
|
||||
timeInMillis,
|
||||
currentTimeMillis,
|
||||
android.text.format.DateUtils.MINUTE_IN_MILLIS,
|
||||
android.text.format.DateUtils.FORMAT_ABBREV_RELATIVE,
|
||||
)
|
||||
.toString()
|
||||
}
|
||||
|
||||
private const val MPS_TO_KMPH = 3.6f
|
||||
private const val KM_TO_MILES = 0.621371f
|
||||
|
||||
|
|
@ -92,13 +79,3 @@ fun Int.mpsToMph(): Float {
|
|||
val mph = this * MPS_TO_KMPH * KM_TO_MILES
|
||||
return mph
|
||||
}
|
||||
|
||||
// Allows usage like email.onEditorAction(EditorInfo.IME_ACTION_NEXT, { confirm() })
|
||||
fun EditText.onEditorAction(actionId: Int, func: () -> Unit) {
|
||||
setOnEditorActionListener { _, receivedActionId, _ ->
|
||||
if (actionId == receivedActionId) {
|
||||
func()
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Copyright (c) 2025-2026 Meshtastic LLC
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package org.meshtastic.core.model
|
||||
|
||||
import org.junit.Assert.assertFalse
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Test
|
||||
|
||||
class CapabilitiesTest {
|
||||
|
||||
@Test
|
||||
fun `canMuteNode requires v2 8 0`() {
|
||||
assertFalse(Capabilities("2.7.15").canMuteNode)
|
||||
assertFalse(Capabilities("2.7.99").canMuteNode)
|
||||
assertTrue(Capabilities("2.8.0").canMuteNode)
|
||||
assertTrue(Capabilities("2.8.1").canMuteNode)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `canRequestNeighborInfo requires v2 7 15`() {
|
||||
assertFalse(Capabilities("2.7.14").canRequestNeighborInfo)
|
||||
assertTrue(Capabilities("2.7.15").canRequestNeighborInfo)
|
||||
assertTrue(Capabilities("2.8.0").canRequestNeighborInfo)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `canSendVerifiedContacts requires v2 7 12`() {
|
||||
assertFalse(Capabilities("2.7.11").canSendVerifiedContacts)
|
||||
assertTrue(Capabilities("2.7.12").canSendVerifiedContacts)
|
||||
assertTrue(Capabilities("2.7.15").canSendVerifiedContacts)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `canToggleTelemetryEnabled requires v2 7 12`() {
|
||||
assertFalse(Capabilities("2.7.11").canToggleTelemetryEnabled)
|
||||
assertTrue(Capabilities("2.7.12").canToggleTelemetryEnabled)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `canToggleUnmessageable requires v2 6 9`() {
|
||||
assertFalse(Capabilities("2.6.8").canToggleUnmessageable)
|
||||
assertTrue(Capabilities("2.6.9").canToggleUnmessageable)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `supportsQrCodeSharing requires v2 6 8`() {
|
||||
assertFalse(Capabilities("2.6.7").supportsQrCodeSharing)
|
||||
assertTrue(Capabilities("2.6.8").supportsQrCodeSharing)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `null firmware returns all false`() {
|
||||
val caps = Capabilities(null)
|
||||
assertFalse(caps.canMuteNode)
|
||||
assertFalse(caps.canRequestNeighborInfo)
|
||||
assertFalse(caps.canSendVerifiedContacts)
|
||||
assertFalse(caps.canToggleTelemetryEnabled)
|
||||
assertFalse(caps.canToggleUnmessageable)
|
||||
assertFalse(caps.supportsQrCodeSharing)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `invalid firmware returns all false`() {
|
||||
val caps = Capabilities("invalid")
|
||||
assertFalse(caps.canMuteNode)
|
||||
assertFalse(caps.canRequestNeighborInfo)
|
||||
assertFalse(caps.canSendVerifiedContacts)
|
||||
assertFalse(caps.canToggleTelemetryEnabled)
|
||||
assertFalse(caps.canToggleUnmessageable)
|
||||
assertFalse(caps.supportsQrCodeSharing)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue