refactor: KMP Migration, Messaging Modularization, and Handshake Robustness (#4631)

Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
This commit is contained in:
James Rich 2026-02-24 06:37:33 -06:00 committed by GitHub
parent b3f88bd94f
commit d408964f07
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
144 changed files with 1460 additions and 664 deletions

View file

@ -19,7 +19,6 @@
package org.meshtastic.core.ui.component
import android.graphics.Bitmap
import android.graphics.Color
import android.net.Uri
import androidx.compose.runtime.Composable
import co.touchlab.kermit.Logger
@ -28,6 +27,7 @@ import com.google.zxing.MultiFormatWriter
import com.google.zxing.WriterException
import com.google.zxing.common.BitMatrix
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.common.util.toPlatformUri
import org.meshtastic.core.database.model.Node
import org.meshtastic.core.model.util.getSharedContactUrl
import org.meshtastic.core.resources.Res
@ -44,7 +44,8 @@ import org.meshtastic.proto.SharedContact
fun SharedContactDialog(contact: Node?, onDismiss: () -> Unit) {
if (contact == null) return
val contactToShare = SharedContact(user = contact.user, node_num = contact.num)
val uri = contactToShare.getSharedContactUrl()
val commonUri = contactToShare.getSharedContactUrl()
val uri = commonUri.toPlatformUri() as Uri
QrDialog(title = stringResource(Res.string.share_contact), uri = uri, qrCode = uri.qrCode, onDismiss = onDismiss)
}
@ -80,7 +81,8 @@ private fun BitMatrix.toBitmap(): Bitmap {
for (y in 0 until height) {
val offset = y * width
for (x in 0 until width) {
pixels[offset + x] = if (get(x, y)) Color.BLACK else Color.WHITE
// Black: 0xFF000000, White: 0xFFFFFFFF
pixels[offset + x] = if (get(x, y)) 0xFF000000.toInt() else 0xFFFFFFFF.toInt()
}
}
val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)

View file

@ -16,7 +16,6 @@
*/
package org.meshtastic.core.ui.component
import android.util.Base64
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
@ -198,7 +197,7 @@ private fun KeyStatusDialog(title: StringResource, text: StringResource, key: By
if (isMismatch) {
stringResource(Res.string.error)
} else {
Base64.encodeToString(key.toByteArray(), Base64.NO_WRAP)
key.base64()
}
Text(
text = stringResource(Res.string.config_security_public_key) + ":",

View file

@ -16,7 +16,7 @@
*/
package org.meshtastic.core.ui.util
import android.text.format.DateUtils
import org.meshtastic.core.common.util.DateFormatter
import org.meshtastic.core.common.util.nowMillis
import org.meshtastic.core.resources.Res
import org.meshtastic.core.resources.getString
@ -29,9 +29,8 @@ import kotlin.time.Duration.Companion.seconds
/**
* Formats a given Unix timestamp (in seconds) into a relative "time ago" string.
*
* For durations less than a minute, it returns "now". For longer durations, it uses Android's
* `DateUtils.getRelativeTimeSpanString` to generate a concise, localized, and abbreviated representation (e.g., "5m
* ago", "2h ago").
* For durations less than a minute, it returns "now". For longer durations, it uses DateFormatter to generate a
* concise, localized representation (e.g., "5m ago", "2h ago").
*
* @param lastSeenUnixSeconds The Unix timestamp in seconds to be formatted.
* @return A [String] representing the relative time that has passed.
@ -46,12 +45,6 @@ fun formatAgo(lastSeenUnixSeconds: Int): String {
return if (diff < 1.minutes) {
getString(Res.string.now)
} else {
DateUtils.getRelativeTimeSpanString(
lastSeenDuration.inWholeMilliseconds,
currentDuration.inWholeMilliseconds,
DateUtils.MINUTE_IN_MILLIS,
DateUtils.FORMAT_ABBREV_RELATIVE,
)
.toString()
DateFormatter.formatRelativeTime(lastSeenDuration.inWholeMilliseconds)
}
}

View file

@ -16,10 +16,9 @@
*/
package org.meshtastic.core.ui.util
import android.text.format.DateUtils
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalContext
import org.jetbrains.compose.resources.stringResource
import org.meshtastic.core.common.util.DateFormatter
import org.meshtastic.core.common.util.nowMillis
import org.meshtastic.core.resources.Res
import org.meshtastic.core.resources.unknown_age
@ -40,11 +39,7 @@ fun Position.formatPositionTime(): String {
if (isOlderThanSixMonths) {
stringResource(Res.string.unknown_age)
} else {
DateUtils.formatDateTime(
LocalContext.current,
(time ?: 0) * SECONDS_TO_MILLIS,
DateUtils.FORMAT_SHOW_DATE or DateUtils.FORMAT_SHOW_TIME or DateUtils.FORMAT_ABBREV_ALL,
)
DateFormatter.formatDateTime((time ?: 0) * SECONDS_TO_MILLIS)
}
return timeText
}