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) {