allow deleting of recent nodes, use long name (#2456)

Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
Co-authored-by: James Rich <2199651+jamesarich@users.noreply.github.com>
This commit is contained in:
DaneEvans 2025-07-21 00:48:34 +10:00 committed by GitHub
parent 5e5fc19fc0
commit be30757720
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 119 additions and 30 deletions

View file

@ -127,8 +127,8 @@ class BTScanModel @Inject constructor(
}
// Include saved IP connections
recent.forEach { address ->
addDevice(DeviceListEntry(context.getString(R.string.meshtastic), address, true))
recent.forEach { (address, name) ->
addDevice(DeviceListEntry(name, address, true))
}
usb.forEach { (_, d) ->
@ -295,27 +295,58 @@ class BTScanModel @Inject constructor(
}.launchIn(viewModelScope)
}
private fun getRecentAddresses(): List<String> {
private fun getRecentAddresses(): List<Pair<String, String>> {
val jsonAddresses = preferences.getString("recent-ip-addresses", "[]") ?: "[]"
val listAddresses = JSONArray(jsonAddresses).let { jsonArray ->
List(jsonArray.length()) { index -> jsonArray.getString(index) }
val jsonArray = JSONArray(jsonAddresses)
val listAddresses = mutableListOf<Pair<String, String>>()
var needsMigration = false
for (i in 0 until jsonArray.length()) {
val item = jsonArray.get(i)
if (item is org.json.JSONObject) {
val address = item.getString("address")
val name = item.getString("name")
listAddresses.add(address to name)
} else if (item is String) {
// Old format: just the address, use default name and mark for migration
listAddresses.add(item to context.getString(R.string.meshtastic))
needsMigration = true
}
}
// If migration is needed, rewrite the storage in the new format
if (needsMigration) {
setRecentAddresses(listAddresses)
}
return listAddresses
}
private fun setRecentAddresses(addresses: List<String>) {
private fun setRecentAddresses(addresses: List<Pair<String, String>>) {
val jsonArray = JSONArray()
addresses.forEach { (address, name) ->
val obj = org.json.JSONObject()
obj.put("address", address)
obj.put("name", name)
jsonArray.put(obj)
}
preferences.edit {
putString("recent-ip-addresses", addresses.toString())
putString("recent-ip-addresses", jsonArray.toString())
}
recentIpAddresses.value = addresses
}
fun addRecentAddress(address: String) {
// Remove 'name' parameter from addRecentAddress and related logic
fun addRecentAddress(address: String, overrideName: String? = null) {
if (!address.startsWith("t")) return
val existingItems = getRecentAddresses()
val updatedList = mutableListOf<String>()
updatedList.add(address)
updatedList.addAll(existingItems.filter { it != address }.take(2))
val updatedList = mutableListOf<Pair<String, String>>()
val displayName = overrideName ?: context.getString(R.string.meshtastic)
updatedList.add(address to displayName)
updatedList.addAll(existingItems.filter { it.first != address }.take(2))
setRecentAddresses(updatedList)
}
fun removeRecentAddress(address: String) {
val existingItems = getRecentAddresses()
val updatedList = existingItems.filter { it.first != address }
setRecentAddresses(updatedList)
}
@ -324,7 +355,7 @@ class BTScanModel @Inject constructor(
fun onSelected(it: DeviceListEntry): Boolean {
// If the device is paired, let user select it, otherwise start the pairing flow
if (it.bonded) {
addRecentAddress(it.fullAddress)
addRecentAddress(it.fullAddress, connectedNodeLongName)
changeDeviceAddress(it.fullAddress)
return true
} else {
@ -345,6 +376,9 @@ class BTScanModel @Inject constructor(
private val _spinner = MutableStateFlow(false)
val spinner: StateFlow<Boolean> get() = _spinner.asStateFlow()
// Add a new property to hold the connected node's long name
var connectedNodeLongName: String? = null
}
const val NO_DEVICE_SELECTED = "n"