mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-20 22:23:37 +00:00
refactor(ble): Centralize BLE logic into a core module (#4550)
Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
This commit is contained in:
parent
7a68802bc2
commit
6bfa5b5f70
214 changed files with 3471 additions and 2405 deletions
|
|
@ -25,9 +25,9 @@ import kotlinx.parcelize.TypeParceler
|
|||
import kotlinx.serialization.Serializable
|
||||
import okio.ByteString
|
||||
import okio.ByteString.Companion.toByteString
|
||||
import org.meshtastic.core.common.util.nowMillis
|
||||
import org.meshtastic.core.model.util.ByteStringParceler
|
||||
import org.meshtastic.core.model.util.ByteStringSerializer
|
||||
import org.meshtastic.core.model.util.nowMillis
|
||||
import org.meshtastic.proto.MeshPacket
|
||||
import org.meshtastic.proto.PortNum
|
||||
import org.meshtastic.proto.Waypoint
|
||||
|
|
|
|||
|
|
@ -19,10 +19,10 @@ package org.meshtastic.core.model
|
|||
import android.graphics.Color
|
||||
import android.os.Parcelable
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import org.meshtastic.core.common.util.nowSeconds
|
||||
import org.meshtastic.core.model.util.anonymize
|
||||
import org.meshtastic.core.model.util.bearing
|
||||
import org.meshtastic.core.model.util.latLongToMeter
|
||||
import org.meshtastic.core.model.util.nowSeconds
|
||||
import org.meshtastic.core.model.util.onlineTimeThreshold
|
||||
import org.meshtastic.proto.Config
|
||||
import org.meshtastic.proto.HardwareModel
|
||||
|
|
|
|||
|
|
@ -16,6 +16,9 @@
|
|||
*/
|
||||
package org.meshtastic.core.model.util
|
||||
|
||||
import org.meshtastic.core.common.util.nowInstant
|
||||
import org.meshtastic.core.common.util.toDate
|
||||
import org.meshtastic.core.common.util.toInstant
|
||||
import org.meshtastic.core.model.util.TimeConstants.HOURS_PER_DAY
|
||||
import java.text.DateFormat
|
||||
import kotlin.time.Duration
|
||||
|
|
|
|||
|
|
@ -86,3 +86,35 @@ fun Telemetry.hasValidEnvironmentMetrics(): Boolean {
|
|||
val metrics = this.environment_metrics ?: return false
|
||||
return metrics.relative_humidity != null && metrics.temperature != null && !metrics.temperature!!.isNaN()
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a human name, strip out the first letter of the first three words and return that as the initials for that
|
||||
* user, ignoring emojis. If the original name is only one word, strip vowels from the original name and if the result
|
||||
* is 3 or more characters, use the first three characters. If not, just take the first 3 characters of the original
|
||||
* name.
|
||||
*/
|
||||
@Suppress("MagicNumber")
|
||||
fun getInitials(fullName: String): String {
|
||||
val maxInitialLength = 4
|
||||
val minWordCountForInitials = 2
|
||||
val name = fullName.trim().withoutEmojis()
|
||||
val words = name.split(Regex("\\s+")).filter { it.isNotEmpty() }
|
||||
|
||||
val initials =
|
||||
when (words.size) {
|
||||
in 0 until minWordCountForInitials -> {
|
||||
val nameWithoutVowels =
|
||||
if (name.isNotEmpty()) {
|
||||
name.first() + name.drop(1).filterNot { c -> c.lowercase() in "aeiou" }
|
||||
} else {
|
||||
""
|
||||
}
|
||||
if (nameWithoutVowels.length >= maxInitialLength) nameWithoutVowels else name
|
||||
}
|
||||
|
||||
else -> words.map { it.first() }.joinToString("")
|
||||
}
|
||||
return initials.take(maxInitialLength)
|
||||
}
|
||||
|
||||
fun String.withoutEmojis(): String = filterNot { char -> char.isSurrogate() }
|
||||
|
|
|
|||
|
|
@ -21,6 +21,9 @@ import androidx.annotation.RequiresApi
|
|||
import kotlinx.datetime.TimeZone
|
||||
import kotlinx.datetime.toJavaZoneId
|
||||
import kotlinx.datetime.toLocalDateTime
|
||||
import org.meshtastic.core.common.util.nowInstant
|
||||
import org.meshtastic.core.common.util.nowMillis
|
||||
import org.meshtastic.core.common.util.systemTimeZone
|
||||
import java.time.ZoneId
|
||||
import java.time.ZoneOffset
|
||||
import java.time.ZonedDateTime
|
||||
|
|
|
|||
|
|
@ -1,58 +0,0 @@
|
|||
/*
|
||||
* 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.util
|
||||
|
||||
import kotlinx.datetime.TimeZone
|
||||
import java.util.Date
|
||||
import java.util.concurrent.CountDownLatch
|
||||
import java.util.concurrent.TimeUnit
|
||||
import kotlin.time.Clock
|
||||
import kotlin.time.Duration
|
||||
import kotlin.time.Instant
|
||||
|
||||
/**
|
||||
* Awaits the latch for the given [Duration].
|
||||
*
|
||||
* @param timeout The maximum time to wait.
|
||||
* @return `true` if the count reached zero and `false` if the waiting time elapsed before the count reached zero.
|
||||
*/
|
||||
fun CountDownLatch.await(timeout: Duration): Boolean = this.await(timeout.inWholeMilliseconds, TimeUnit.MILLISECONDS)
|
||||
|
||||
/** Accessor for the current time in milliseconds. */
|
||||
val nowMillis: Long
|
||||
get() = nowInstant.toEpochMilliseconds()
|
||||
|
||||
/** Accessor for the current time as a stable [Instant]. */
|
||||
val nowInstant: Instant
|
||||
get() = Clock.System.now()
|
||||
|
||||
/** Accessor for the current time in seconds. */
|
||||
val nowSeconds: Long
|
||||
get() = nowInstant.epochSeconds
|
||||
|
||||
/** Accessor for the system default time zone. */
|
||||
val systemTimeZone: TimeZone
|
||||
get() = TimeZone.currentSystemDefault()
|
||||
|
||||
/** Converts this [Instant] to a legacy [Date]. */
|
||||
fun Instant.toDate(): Date = Date(this.toEpochMilliseconds())
|
||||
|
||||
/** Converts these milliseconds to an [Instant]. */
|
||||
fun Long.toInstant(): Instant = Instant.fromEpochMilliseconds(this)
|
||||
|
||||
/** Converts these seconds to an [Instant]. */
|
||||
fun Int.secondsToInstant(): Instant = Instant.fromEpochSeconds(this.toLong())
|
||||
|
|
@ -20,6 +20,12 @@ import kotlinx.datetime.TimeZone
|
|||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Test
|
||||
import org.meshtastic.core.common.util.await
|
||||
import org.meshtastic.core.common.util.nowMillis
|
||||
import org.meshtastic.core.common.util.nowSeconds
|
||||
import org.meshtastic.core.common.util.secondsToInstant
|
||||
import org.meshtastic.core.common.util.toDate
|
||||
import org.meshtastic.core.common.util.toInstant
|
||||
import java.util.concurrent.CountDownLatch
|
||||
import kotlin.time.Clock
|
||||
import kotlin.time.Duration.Companion.milliseconds
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue