From 49677bb38fef1889d69e9c15fd0ad9e8dc82ec8e Mon Sep 17 00:00:00 2001
From: James Rich <2199651+jamesarich@users.noreply.github.com>
Date: Tue, 26 Aug 2025 11:57:26 -0500
Subject: [PATCH 1/4] New Crowdin updates (#2856)
---
app/src/main/res/values-de/strings.xml | 1 +
1 file changed, 1 insertion(+)
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index d9de07d1a..b58753d16 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -654,6 +654,7 @@
Überlaufmenü
UV Lux
Unbekannt
+ Dieses Radio wird verwaltet und kann nur durch Fernverwaltung geändert werden.
Knotendatenbank leeren
Knoten älter als %1$d Tage entfernen
Nur unbekannte Knoten entfernen
From f3338e3f0dce647f2f3e0b701dca702eb5299fab Mon Sep 17 00:00:00 2001
From: James Rich <2199651+jamesarich@users.noreply.github.com>
Date: Tue, 26 Aug 2025 14:18:51 -0500
Subject: [PATCH 2/4] fix(ci): improve release workflow and proguard setup
(#2857)
Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
---
.github/workflows/release.yml | 24 +++++++++++++++-----
.github/workflows/reusable-android-build.yml | 8 -------
app/proguard-rules.pro | 6 +----
3 files changed, 19 insertions(+), 19 deletions(-)
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index cc2cc9d74..c9f8315d1 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -161,6 +161,13 @@ jobs:
path: app/build/outputs/apk/google/release/app-google-release.apk
retention-days: 1
+ - name: Upload Mapping File
+ uses: actions/upload-artifact@v4
+ with:
+ name: mapping
+ path: app/build/outputs/mapping/googleRelease/mapping.txt
+ retention-days: 1
+
publish-release:
runs-on: ubuntu-latest
needs: [prepare-build-info, build-fdroid, build-google]
@@ -194,11 +201,16 @@ jobs:
name: google-apk
path: ./build-artifacts/google/apk
+ - name: Download Mapping File
+ uses: actions/download-artifact@v5
+ with:
+ name: mapping
+ path: ./build-artifacts/google/mapping
+
- name: Generate Changelog
id: generate_changelog
uses: mikepenz/release-changelog-builder-action@v5
with:
- configuration: ".github/changelog-config.json"
owner: ${{ github.repository_owner }}
repo: ${{ github.event.repository.name }}
ignorePreReleases: true
@@ -211,8 +223,7 @@ jobs:
if: steps.generate_changelog.outputs.changelog != ''
run: |
mkdir -p play_store_release_notes/en-US
- echo "${{ steps.generate_changelog.outputs.changelog }}" > play_store_release_notes/en-US/default.txt
- echo "${{ steps.generate_changelog.outputs.changelog }}" > changelog.txt # Also create a root changelog.txt for GitHub release
+ echo "${{ steps.generate_changelog.outputs.changelog }}" > whatsnew/whatsnew-en-US/default.txt
- name: Create version_info.txt
run: |
@@ -225,7 +236,7 @@ jobs:
with:
tag_name: ${{ github.ref_name }}
name: Release ${{ github.ref_name }}
- body: ${{ steps.generate_changelog.outputs.changelog }}
+ generate_release_notes: true
files: |
./build-artifacts/google/bundle/app-google-release.aab
./build-artifacts/google/apk/app-google-release.apk
@@ -269,5 +280,6 @@ jobs:
packageName: com.geeksville.mesh
releaseFiles: ./build-artifacts/google/bundle/app-google-release.aab
track: ${{ steps.get_track.outputs.track }}
- status: 'draft'
- whatsNewDirectory: ./play_store_release_notes/en-US/
+ status: ${{ steps.get_track.outputs.track == 'internal' && 'complete' || 'draft' }}
+ whatsNewDirectory: /whatsnew/
+ mappingFile: ./build-artifacts/google/mapping/mapping.txt
diff --git a/.github/workflows/reusable-android-build.yml b/.github/workflows/reusable-android-build.yml
index c296dc996..d6077542e 100644
--- a/.github/workflows/reusable-android-build.yml
+++ b/.github/workflows/reusable-android-build.yml
@@ -85,14 +85,6 @@ jobs:
path: app/build/outputs/apk/google/debug/app-google-debug.apk
retention-days: 14
- - name: Attest Build Provenance
- if: ${{ inputs.upload_artifacts && github.ref_name == 'main' && github.repository == 'meshtastic/Meshtastic-Android' }}
- uses: actions/attest-build-provenance@v2
- with:
- subject-path: |
- app/build/outputs/apk/google/debug/app-google-debug.apk
- app/build/outputs/apk/fdroid/debug/app-fdroid-debug.apk
-
- name: Upload reports
if: ${{ inputs.upload_artifacts }}
uses: actions/upload-artifact@v4
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
index 165eeb2da..d5d90b071 100644
--- a/app/proguard-rules.pro
+++ b/app/proguard-rules.pro
@@ -14,7 +14,7 @@
# Uncomment this to preserve the line number information for
# debugging stack traces.
-#-keepattributes SourceFile,LineNumberTable
+-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
@@ -27,9 +27,6 @@
# eclipse.paho.client
-keep class org.eclipse.paho.client.mqttv3.logging.JSR47Logger { *; }
-# ormlite
--dontwarn com.j256.ormlite.**
-
# OkHttp
-dontwarn okhttp3.internal.platform.**
-dontwarn org.conscrypt.**
@@ -37,7 +34,6 @@
-dontwarn org.openjsse.**
# ?
--dontwarn java.awt.image.**
-dontwarn java.lang.reflect.**
-dontwarn com.google.errorprone.annotations.**
From 2ea2f6e5ab3b5cbadc3df0d09d916b5dffb505e1 Mon Sep 17 00:00:00 2001
From: James Rich <2199651+jamesarich@users.noreply.github.com>
Date: Tue, 26 Aug 2025 17:00:32 -0500
Subject: [PATCH 3/4] build: centralize repository declarations in
settings.gradle.kts (#2858)
Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
---
app/build.gradle.kts | 4 +---
build.gradle.kts | 42 ++++++++++++---------------------------
gradle/libs.versions.toml | 32 ++++++++++-------------------
settings.gradle.kts | 21 ++++++++++++++++++++
4 files changed, 46 insertions(+), 53 deletions(-)
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 7821c3bfc..a2b6360b2 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -31,7 +31,7 @@ plugins {
alias(libs.plugins.devtools.ksp)
alias(libs.plugins.detekt)
alias(libs.plugins.datadog)
- alias(libs.plugins.secrets.gradle.plugin)
+ alias(libs.plugins.secrets)
alias(libs.plugins.spotless)
}
@@ -293,8 +293,6 @@ ksp {
arg("room.schemaLocation", "$projectDir/schemas")
}
-repositories { maven { url = uri("https://jitpack.io") } }
-
detekt {
config.setFrom("../config/detekt/detekt.yml")
baseline = file("../config/detekt/detekt-baseline.xml")
diff --git a/build.gradle.kts b/build.gradle.kts
index 0e50579b5..2906bd24e 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -15,37 +15,21 @@
* along with this program. If not, see .
*/
-buildscript {
- repositories {
- google()
- mavenCentral()
- }
- dependencies {
- classpath(libs.agp)
- classpath(libs.kotlin.gradle.plugin)
- classpath(libs.kotlin.serialization)
- classpath(libs.google.services)
- classpath(libs.firebase.crashlytics.gradle)
- classpath(libs.secrets.gradle.plugin)
- classpath(libs.protobuf.gradle.plugin)
- classpath(libs.hilt.android.gradle.plugin)
- classpath(libs.secrets.gradle.plugin)
- classpath(libs.dd.sdk.android.gradle.plugin)
- }
-}
-
plugins {
- alias(libs.plugins.kotlin.jvm) apply false
- alias(libs.plugins.devtools.ksp) apply false
+ alias(libs.plugins.android.application) apply false
+ alias(libs.plugins.android.library) apply false
alias(libs.plugins.compose) apply false
-}
-
-allprojects {
- repositories {
- google()
- mavenCentral()
- maven { url = uri("https://jitpack.io") }
- }
+ alias(libs.plugins.datadog) apply false
+ alias(libs.plugins.devtools.ksp) apply false
+ alias(libs.plugins.firebase.crashlytics) apply false
+ alias(libs.plugins.google.services) apply false
+ alias(libs.plugins.hilt) apply false
+ alias(libs.plugins.kotlin.android) apply false
+ alias(libs.plugins.kotlin.jvm) apply false
+ alias(libs.plugins.kotlin.parcelize) apply false
+ alias(libs.plugins.kotlin.serialization) apply false
+ alias(libs.plugins.protobuf) apply false
+ alias(libs.plugins.secrets) apply false
}
tasks.register("clean") {
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 496e4cda0..d6542b5e7 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -57,7 +57,6 @@ spotless = "7.2.1"
[libraries]
accompanist-permissions = { module = "com.google.accompanist:accompanist-permissions", version.ref = "accompanistPermissions" }
-agp = { group = "com.android.tools.build", name = "gradle", version.ref = "agp" }
activity = { group = "androidx.activity", name = "activity" }
actvity-ktx = { group = "androidx.activity", name = "activity-ktx" }
activity-compose = { group = "androidx.activity", name = "activity-compose" }
@@ -88,7 +87,6 @@ core-splashscreen = { group = "androidx.core", name = "core-splashscreen", versi
datastore = { group = "androidx.datastore", name = "datastore", version.ref = "datastore" }
datastore-preferences = { group = "androidx.datastore", name = "datastore-preferences", version.ref = "datastore" }
dd-sdk-android-compose = { group = "com.datadoghq", name = "dd-sdk-android-compose", version.ref = "dd-sdk-android" }
-dd-sdk-android-gradle-plugin = { group = "com.datadoghq", name = "dd-sdk-android-gradle-plugin", version.ref = "dd-sdk-android-gradle-plugin" }
dd-sdk-android-logs = { group = "com.datadoghq", name = "dd-sdk-android-logs", version.ref = "dd-sdk-android" }
dd-sdk-android-okhttp = { group = "com.datadoghq", name = "dd-sdk-android-okhttp", version.ref = "dd-sdk-android" }
dd-sdk-android-rum = { group = "com.datadoghq", name = "dd-sdk-android-rum", version.ref = "dd-sdk-android" }
@@ -103,16 +101,11 @@ ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junit-
firebase-analytics = { group = "com.google.firebase", name = "firebase-analytics" }
firebase-bom = { group = "com.google.firebase", name = "firebase-bom", version.ref = "firebase-bom" }
firebase-crashlytics = { group = "com.google.firebase", name = "firebase-crashlytics" }
-firebase-crashlytics-gradle = { group = "com.google.firebase", name = "firebase-crashlytics-gradle", version.ref = "crashlytics" }
-google-services = { group = "com.google.gms", name = "google-services", version.ref = "google-services" }
hilt-android = { group = "com.google.dagger", name = "hilt-android", version.ref = "hilt" }
-hilt-android-gradle-plugin = { group = "com.google.dagger", name = "hilt-android-gradle-plugin", version.ref = "hilt" }
hilt-android-testing = { group = "com.google.dagger", name = "hilt-android-testing", version.ref = "hilt" }
hilt-compiler = { group = "com.google.dagger", name = "hilt-compiler", version.ref = "hilt" }
hilt-navigation-compose = { group = "androidx.hilt", name = "hilt-navigation-compose", version.ref = "hilt-navigation-compose" }
junit = { group = "junit", name = "junit", version.ref = "junit" }
-kotlin-gradle-plugin = { group = "org.jetbrains.kotlin", name = "kotlin-gradle-plugin", version.ref = "kotlin" }
-kotlin-serialization = { group = "org.jetbrains.kotlin", name = "kotlin-serialization", version.ref = "kotlin" }
kotlinx-collections-immutable = { group = "org.jetbrains.kotlinx", name = "kotlinx-collections-immutable", version.ref = "kotlinx-collections-immutable" }
kotlinx-coroutines-android = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-android", version.ref = "kotlinx-coroutines-android" }
kotlinx-coroutines-guava = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-guava", version.ref = "kotlinx-coroutines-android" }
@@ -141,7 +134,6 @@ org-eclipse-paho-client-mqttv3 = { group = "org.eclipse.paho", name = "org.eclip
osmbonuspack = { group = "com.github.MKergall", name = "osmbonuspack", version.ref = "osmbonuspack" }
osmdroid-android = { group = "org.osmdroid", name = "osmdroid-android", version.ref = "osmdroid-android" }
osmdroid-geopackage = { group = "org.osmdroid", name = "osmdroid-geopackage", version.ref = "osmdroid-android" }
-protobuf-gradle-plugin = { group = "com.google.protobuf", name = "protobuf-gradle-plugin", version.ref = "protobuf-gradle-plugin" }
protobuf-kotlin = { group = "com.google.protobuf", name = "protobuf-kotlin", version.ref = "protobuf-kotlin" }
protobuf-protoc = { group = "com.google.protobuf", name = "protoc", version.ref = "protobuf-kotlin" }
retrofit2 = { group = "com.squareup.retrofit2", name = "retrofit", version.ref = "retrofit" }
@@ -150,7 +142,6 @@ room-compiler = { group = "androidx.room", name = "room-compiler", version.ref =
room-ktx = { group = "androidx.room", name = "room-ktx", version.ref = "room" }
room-runtime = { group = "androidx.room", name = "room-runtime", version.ref = "room" }
room-testing = { group = "androidx.room", name = "room-testing", version.ref = "room" }
-secrets-gradle-plugin = { group = "com.google.android.libraries.mapsplatform.secrets-gradle-plugin", name = "secrets-gradle-plugin", version.ref = "secrets-gradle-plugin" }
streamsupport-minifuture = { group = "net.sourceforge.streamsupport", name = "streamsupport-minifuture", version.ref = "streamsupport-minifuture" }
timber = { group = "com.jakewharton.timber", name = "timber", version.ref = "timber" }
usb-serial-android = { group = "com.github.mik3y", name = "usb-serial-for-android", version.ref = "usb-serial-android" }
@@ -214,20 +205,19 @@ retrofit = ["retrofit2", "retrofit2-kotlin-serialization", "okhttp3", "okhttp3-l
coil = ["coil", "coil-network-core", "coil-network-okhttp", "coil-svg"]
[plugins]
-android-application = { id = "com.android.application" }
-android-library = { id = "com.android.library" }
+android-application = { id = "com.android.application", version.ref = "agp" }
+android-library = { id = "com.android.library", version.ref = "agp" }
compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
-datadog = { id = "com.datadoghq.dd-sdk-android-gradle-plugin"}
+datadog = { id = "com.datadoghq.dd-sdk-android-gradle-plugin", version.ref = "dd-sdk-android-gradle-plugin" }
detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detekt" }
devtools-ksp = { id = "com.google.devtools.ksp", version.ref = "devtools-ksp" }
-hilt = { id = "com.google.dagger.hilt.android" }
-kotlin-android = { id = "org.jetbrains.kotlin.android" }
+firebase-crashlytics = { id = "com.google.firebase.crashlytics" , version.ref = "crashlytics" }
+google-services = { id = "com.google.gms.google-services", version.ref = "google-services" }
+hilt = { id = "com.google.dagger.hilt.android" , version.ref = "hilt" }
+kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
-kotlin-parcelize = { id = "org.jetbrains.kotlin.plugin.parcelize" }
-kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization" }
-protobuf = { id = "com.google.protobuf" }
-google-services = { id = "com.google.gms.google-services" }
-firebase-crashlytics = { id = "com.google.firebase.crashlytics" }
-secrets-gradle-plugin = { id = "com.google.android.libraries.mapsplatform.secrets-gradle-plugin"}
+kotlin-parcelize = { id = "org.jetbrains.kotlin.plugin.parcelize", version.ref = "kotlin" }
+kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
+protobuf = { id = "com.google.protobuf", version.ref = "protobuf-gradle-plugin" }
+secrets = { id = "com.google.android.libraries.mapsplatform.secrets-gradle-plugin", version.ref = "secrets-gradle-plugin" }
spotless = { id = "com.diffplug.spotless", version .ref= "spotless" }
-secrets = { id = "com.google.android.libraries.mapsplatform.secrets-gradle-plugin" }
diff --git a/settings.gradle.kts b/settings.gradle.kts
index d47207b3c..8cefe5bb5 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -1,3 +1,5 @@
+import org.gradle.kotlin.dsl.maven
+
/*
* Copyright (c) 2025 Meshtastic LLC
*
@@ -18,6 +20,25 @@
include(":app", ":network", ":mesh_service_example")
rootProject.name = "Meshtastic Android"
+pluginManagement {
+ repositories {
+ google()
+ mavenCentral()
+ gradlePluginPortal()
+ maven { url = uri("https://jitpack.io") }
+ }
+}
+
+@Suppress("UnstableApiUsage")
+dependencyResolutionManagement {
+ repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
+ repositories {
+ google()
+ mavenCentral()
+ maven { url = uri("https://jitpack.io") }
+ }
+}
+
plugins {
id("org.gradle.toolchains.foojay-resolver") version "1.0.0"
id("com.gradle.develocity") version("4.1.1")
From 89cc9e88442e98ca97f03ca03e17f16572ea1af3 Mon Sep 17 00:00:00 2001
From: James Rich <2199651+jamesarich@users.noreply.github.com>
Date: Tue, 26 Aug 2025 17:02:53 -0500
Subject: [PATCH 4/4] refactor: clean up deprecations using recommendations
(#2859)
Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
---
.../mesh/repository/radio/StreamInterface.kt | 32 +++++++++++--------
.../main/java/com/geeksville/mesh/ui/Main.kt | 4 ++-
.../ui/common/components/IndoorAirQuality.kt | 4 +--
.../mesh/ui/intro/NotificationsScreen.kt | 3 +-
.../com/geeksville/mesh/ui/message/Message.kt | 3 +-
.../ui/node/components/NodeStatusIcons.kt | 7 ++--
.../radio/components/AudioConfigItemList.kt | 3 +-
.../components/PacketResponseStateDialog.kt | 5 ++-
8 files changed, 37 insertions(+), 24 deletions(-)
diff --git a/app/src/main/java/com/geeksville/mesh/repository/radio/StreamInterface.kt b/app/src/main/java/com/geeksville/mesh/repository/radio/StreamInterface.kt
index bbd169372..ae0d5ed86 100644
--- a/app/src/main/java/com/geeksville/mesh/repository/radio/StreamInterface.kt
+++ b/app/src/main/java/com/geeksville/mesh/repository/radio/StreamInterface.kt
@@ -20,7 +20,8 @@ package com.geeksville.mesh.repository.radio
import com.geeksville.mesh.android.Logging
/**
- * An interface that assumes we are talking to a meshtastic device over some sort of stream connection (serial or TCP probably)
+ * An interface that assumes we are talking to a meshtastic device over some sort of stream connection (serial or TCP
+ * probably)
*/
abstract class StreamInterface(protected val service: RadioInterfaceService) :
Logging,
@@ -46,12 +47,16 @@ abstract class StreamInterface(protected val service: RadioInterfaceService) :
onDeviceDisconnect(true)
}
- /** Tell MeshService our device has gone away, but wait for it to come back
+ /**
+ * Tell MeshService our device has gone away, but wait for it to come back
*
- * @param waitForStopped if true we should wait for the manager to finish - must be false if called from inside the manager callbacks
- * */
+ * @param waitForStopped if true we should wait for the manager to finish - must be false if called from inside the
+ * manager callbacks
+ */
protected open fun onDeviceDisconnect(waitForStopped: Boolean) {
- service.onDisconnect(isPermanent = true) // if USB device disconnects it is definitely permanently gone, not sleeping)
+ service.onDisconnect(
+ isPermanent = true,
+ ) // if USB device disconnects it is definitely permanently gone, not sleeping)
}
protected open fun connect() {
@@ -84,15 +89,13 @@ abstract class StreamInterface(protected val service: RadioInterfaceService) :
/** Print device serial debug output somewhere */
private fun debugOut(b: Byte) {
- when (val c = b.toChar()) {
- '\r' -> {
- } // ignore
+ when (val c = b.toInt().toChar()) {
+ '\r' -> {} // ignore
'\n' -> {
debug("DeviceLog: $debugLineBuf")
debugLineBuf.clear()
}
- else ->
- debugLineBuf.append(c)
+ else -> debugLineBuf.append(c)
}
}
@@ -133,16 +136,19 @@ abstract class StreamInterface(protected val service: RadioInterfaceService) :
// We've read our header, do one big read for the packet itself
packetLen = (msb shl 8) or lsb
if (packetLen > MAX_TO_FROM_RADIO_SIZE) {
- lostSync() // If packet len is too long, the bytes must have been corrupted, start looking for START1 again
+ lostSync() // If packet len is too long, the bytes must have been corrupted, start looking for
+ // START1 again
} else if (packetLen == 0) {
- deliverPacket() // zero length packets are valid and should be delivered immediately (because there won't be a next byte of payload)
+ deliverPacket() // zero length packets are valid and should be delivered immediately (because there
+ // won't be a next byte of payload)
}
}
else -> {
// We are looking at the packet bytes now
rxPacket[ptr - 4] = c
- // Note: we have to check if ptr +1 is equal to packet length (for example, for a 1 byte packetlen, this code will be run with ptr of4
+ // Note: we have to check if ptr +1 is equal to packet length (for example, for a 1 byte packetlen, this
+ // code will be run with ptr of4
if (ptr - 4 + 1 == packetLen) {
deliverPacket()
}
diff --git a/app/src/main/java/com/geeksville/mesh/ui/Main.kt b/app/src/main/java/com/geeksville/mesh/ui/Main.kt
index f46e00900..0257dfeb8 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/Main.kt
+++ b/app/src/main/java/com/geeksville/mesh/ui/Main.kt
@@ -41,6 +41,7 @@ import androidx.compose.material3.PlainTooltip
import androidx.compose.material3.Scaffold
import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.Text
+import androidx.compose.material3.TooltipAnchorPosition
import androidx.compose.material3.TooltipBox
import androidx.compose.material3.TooltipDefaults
import androidx.compose.material3.adaptive.currentWindowAdaptiveInfo
@@ -268,7 +269,8 @@ fun MainScreen(
item(
icon = {
TooltipBox(
- positionProvider = TooltipDefaults.rememberTooltipPositionProvider(),
+ positionProvider =
+ TooltipDefaults.rememberTooltipPositionProvider(TooltipAnchorPosition.Above),
tooltip = {
PlainTooltip {
Text(
diff --git a/app/src/main/java/com/geeksville/mesh/ui/common/components/IndoorAirQuality.kt b/app/src/main/java/com/geeksville/mesh/ui/common/components/IndoorAirQuality.kt
index c35be8dc9..1ce524abe 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/common/components/IndoorAirQuality.kt
+++ b/app/src/main/java/com/geeksville/mesh/ui/common/components/IndoorAirQuality.kt
@@ -162,7 +162,7 @@ fun IndoorAirQuality(iaq: Int?, displayMode: IaqDisplayMode = IaqDisplayMode.Pil
IaqDisplayMode.Gauge -> {
CircularProgressIndicator(
- progress = iaq / 500f,
+ progress = { iaq / 500f },
modifier = Modifier.size(60.dp).clickable { isLegendOpen = true },
strokeWidth = 8.dp,
color = iaqEnum.color,
@@ -176,7 +176,7 @@ fun IndoorAirQuality(iaq: Int?, displayMode: IaqDisplayMode = IaqDisplayMode.Pil
modifier = Modifier.clickable { isLegendOpen = true },
) {
LinearProgressIndicator(
- progress = iaq / 500f,
+ progress = { iaq / 500f },
modifier = Modifier.fillMaxWidth().height(20.dp),
color = iaqEnum.color,
)
diff --git a/app/src/main/java/com/geeksville/mesh/ui/intro/NotificationsScreen.kt b/app/src/main/java/com/geeksville/mesh/ui/intro/NotificationsScreen.kt
index 481990f8c..bd831e8e7 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/intro/NotificationsScreen.kt
+++ b/app/src/main/java/com/geeksville/mesh/ui/intro/NotificationsScreen.kt
@@ -23,6 +23,7 @@ import android.provider.Settings
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.automirrored.outlined.Message
import androidx.compose.material.icons.filled.Notifications
import androidx.compose.material.icons.outlined.BatteryAlert
import androidx.compose.material.icons.outlined.Message
@@ -61,7 +62,7 @@ internal fun NotificationsScreen(showNextButton: Boolean, onSkip: () -> Unit, on
val features = remember {
listOf(
FeatureUIData(
- icon = Icons.Outlined.Message,
+ icon = Icons.AutoMirrored.Outlined.Message,
titleRes = R.string.incoming_messages,
subtitleRes = R.string.notifications_for_channel_and_direct_messages,
),
diff --git a/app/src/main/java/com/geeksville/mesh/ui/message/Message.kt b/app/src/main/java/com/geeksville/mesh/ui/message/Message.kt
index 622b68dac..4a33d2c02 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/message/Message.kt
+++ b/app/src/main/java/com/geeksville/mesh/ui/message/Message.kt
@@ -48,6 +48,7 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.automirrored.filled.Reply
import androidx.compose.material.icons.automirrored.filled.Send
+import androidx.compose.material.icons.automirrored.filled.SpeakerNotes
import androidx.compose.material.icons.filled.ArrowDownward
import androidx.compose.material.icons.filled.ChatBubbleOutline
import androidx.compose.material.icons.filled.Close
@@ -672,7 +673,7 @@ private fun OverFlowMenu(
if (showQuickChat) {
Icons.Default.SpeakerNotesOff
} else {
- Icons.Default.SpeakerNotes
+ Icons.AutoMirrored.Filled.SpeakerNotes
},
contentDescription = quickChatToggleTitle,
)
diff --git a/app/src/main/java/com/geeksville/mesh/ui/node/components/NodeStatusIcons.kt b/app/src/main/java/com/geeksville/mesh/ui/node/components/NodeStatusIcons.kt
index 7f74f62cd..84d12b5a5 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/node/components/NodeStatusIcons.kt
+++ b/app/src/main/java/com/geeksville/mesh/ui/node/components/NodeStatusIcons.kt
@@ -31,6 +31,7 @@ import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.PlainTooltip
import androidx.compose.material3.Text
+import androidx.compose.material3.TooltipAnchorPosition
import androidx.compose.material3.TooltipBox
import androidx.compose.material3.TooltipDefaults
import androidx.compose.material3.rememberTooltipState
@@ -51,7 +52,7 @@ fun NodeStatusIcons(isThisNode: Boolean, isUnmessageable: Boolean, isFavorite: B
Row(modifier = Modifier.padding(4.dp)) {
if (isThisNode) {
TooltipBox(
- positionProvider = TooltipDefaults.rememberTooltipPositionProvider(),
+ positionProvider = TooltipDefaults.rememberTooltipPositionProvider(TooltipAnchorPosition.Above),
tooltip = {
PlainTooltip {
Text(
@@ -88,7 +89,7 @@ fun NodeStatusIcons(isThisNode: Boolean, isUnmessageable: Boolean, isFavorite: B
if (isUnmessageable) {
TooltipBox(
- positionProvider = TooltipDefaults.rememberTooltipPositionProvider(),
+ positionProvider = TooltipDefaults.rememberTooltipPositionProvider(TooltipAnchorPosition.Above),
tooltip = { PlainTooltip { Text(stringResource(R.string.unmonitored_or_infrastructure)) } },
state = rememberTooltipState(),
) {
@@ -103,7 +104,7 @@ fun NodeStatusIcons(isThisNode: Boolean, isUnmessageable: Boolean, isFavorite: B
}
if (isFavorite && !isThisNode) {
TooltipBox(
- positionProvider = TooltipDefaults.rememberTooltipPositionProvider(),
+ positionProvider = TooltipDefaults.rememberTooltipPositionProvider(TooltipAnchorPosition.Above),
tooltip = { PlainTooltip { Text(stringResource(R.string.favorite)) } },
state = rememberTooltipState(),
) {
diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/AudioConfigItemList.kt b/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/AudioConfigItemList.kt
index ba51c3cec..f0a5dd0f5 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/AudioConfigItemList.kt
+++ b/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/AudioConfigItemList.kt
@@ -20,7 +20,6 @@ package com.geeksville.mesh.ui.settings.radio.components
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.text.KeyboardActions
-import androidx.compose.material3.Divider
import androidx.compose.material3.HorizontalDivider
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
@@ -103,7 +102,7 @@ fun AudioConfigItemList(audioConfig: AudioConfig, enabled: Boolean, onSaveClicke
onItemSelected = { audioInput = audioInput.copy { bitrate = it } },
)
}
- item { Divider() }
+ item { HorizontalDivider() }
item {
EditTextPreference(
diff --git a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/PacketResponseStateDialog.kt b/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/PacketResponseStateDialog.kt
index 1776d6ba0..4578480a7 100644
--- a/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/PacketResponseStateDialog.kt
+++ b/app/src/main/java/com/geeksville/mesh/ui/settings/radio/components/PacketResponseStateDialog.kt
@@ -54,7 +54,10 @@ fun PacketResponseStateDialog(state: ResponseState, onDismiss: () -> Unit
label = "progress",
)
Text("%.0f%%".format(progress * 100))
- LinearProgressIndicator(progress = progress, modifier = Modifier.fillMaxWidth().padding(top = 8.dp))
+ LinearProgressIndicator(
+ progress = { progress },
+ modifier = Modifier.fillMaxWidth().padding(top = 8.dp),
+ )
if (state.total == state.completed) onComplete()
}
if (state is ResponseState.Success) {