mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-20 22:23:37 +00:00
refactor(ui): compose resources, domain layer (#4628)
Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>
This commit is contained in:
parent
96adc70401
commit
2676a51647
322 changed files with 3031 additions and 2790 deletions
|
|
@ -34,7 +34,7 @@ BarcodeScanner(
|
|||
```mermaid
|
||||
graph TB
|
||||
:core:barcode[barcode]:::android-library
|
||||
:core:barcode -.-> :core:strings
|
||||
:core:barcode -.-> :core:resources
|
||||
|
||||
classDef android-application fill:#CAFFBF,stroke:#000,stroke-width:2px,color:#000;
|
||||
classDef android-application-compose fill:#CAFFBF,stroke:#000,stroke-width:2px,color:#000;
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ configure<LibraryExtension> {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(":core:strings"))
|
||||
implementation(project(":core:resources"))
|
||||
|
||||
implementation(libs.androidx.activity.compose)
|
||||
implementation(libs.androidx.compose.material3)
|
||||
|
|
|
|||
|
|
@ -64,8 +64,8 @@ import com.google.zxing.MultiFormatReader
|
|||
import com.google.zxing.PlanarYUVLuminanceSource
|
||||
import com.google.zxing.common.HybridBinarizer
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.close
|
||||
import org.meshtastic.core.resources.Res
|
||||
import org.meshtastic.core.resources.close
|
||||
import java.nio.ByteBuffer
|
||||
import java.util.concurrent.Executors
|
||||
|
||||
|
|
|
|||
|
|
@ -64,8 +64,8 @@ import com.google.mlkit.vision.barcode.BarcodeScanning
|
|||
import com.google.mlkit.vision.barcode.common.Barcode
|
||||
import com.google.mlkit.vision.common.InputImage
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.close
|
||||
import org.meshtastic.core.resources.Res
|
||||
import org.meshtastic.core.resources.close
|
||||
import java.util.concurrent.Executors
|
||||
|
||||
@Composable
|
||||
|
|
|
|||
|
|
@ -53,7 +53,8 @@ constructor(
|
|||
hasPermissions = true,
|
||||
),
|
||||
)
|
||||
val state: StateFlow<BluetoothState> = _state.asStateFlow()
|
||||
val state: StateFlow<BluetoothState>
|
||||
get() = _state.asStateFlow()
|
||||
|
||||
init {
|
||||
processLifecycle.coroutineScope.launch(dispatchers.default) {
|
||||
|
|
|
|||
|
|
@ -67,9 +67,11 @@ constructor(
|
|||
// 1. Emit cached data first, regardless of staleness.
|
||||
// This gives the UI something to show immediately.
|
||||
val cachedRelease = localDataSource.getLatestRelease(releaseType)
|
||||
cachedRelease?.let {
|
||||
Logger.d { "Emitting cached firmware for $releaseType (isStale=${it.isStale()})" }
|
||||
emit(it.asExternalModel())
|
||||
if (cachedRelease != null) {
|
||||
Logger.d { "Emitting cached firmware for $releaseType (isStale=${cachedRelease.isStale()})" }
|
||||
emit(cachedRelease.asExternalModel())
|
||||
} else {
|
||||
emit(null)
|
||||
}
|
||||
|
||||
// 2. If the cache was fresh and we are not forcing a refresh, we're done.
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ graph TB
|
|||
:core:database -.-> :core:di
|
||||
:core:database -.-> :core:model
|
||||
:core:database -.-> :core:proto
|
||||
:core:database -.-> :core:strings
|
||||
:core:database -.-> :core:resources
|
||||
|
||||
classDef android-application fill:#CAFFBF,stroke:#000,stroke-width:2px,color:#000;
|
||||
classDef android-application-compose fill:#CAFFBF,stroke:#000,stroke-width:2px,color:#000;
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ dependencies {
|
|||
implementation(projects.core.di)
|
||||
implementation(projects.core.model)
|
||||
implementation(projects.core.proto)
|
||||
implementation(projects.core.strings)
|
||||
implementation(projects.core.resources)
|
||||
|
||||
implementation(libs.androidx.room.paging)
|
||||
implementation(libs.kotlinx.serialization.json)
|
||||
|
|
|
|||
|
|
@ -19,33 +19,33 @@ package org.meshtastic.core.database.model
|
|||
import org.jetbrains.compose.resources.StringResource
|
||||
import org.meshtastic.core.database.entity.Reaction
|
||||
import org.meshtastic.core.model.MessageStatus
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.delivery_confirmed
|
||||
import org.meshtastic.core.strings.error
|
||||
import org.meshtastic.core.strings.message_delivery_status
|
||||
import org.meshtastic.core.strings.message_status_enroute
|
||||
import org.meshtastic.core.strings.message_status_queued
|
||||
import org.meshtastic.core.strings.message_status_sfpp_confirmed
|
||||
import org.meshtastic.core.strings.message_status_sfpp_routing
|
||||
import org.meshtastic.core.strings.routing_error_admin_bad_session_key
|
||||
import org.meshtastic.core.strings.routing_error_admin_public_key_unauthorized
|
||||
import org.meshtastic.core.strings.routing_error_bad_request
|
||||
import org.meshtastic.core.strings.routing_error_duty_cycle_limit
|
||||
import org.meshtastic.core.strings.routing_error_got_nak
|
||||
import org.meshtastic.core.strings.routing_error_max_retransmit
|
||||
import org.meshtastic.core.strings.routing_error_no_channel
|
||||
import org.meshtastic.core.strings.routing_error_no_interface
|
||||
import org.meshtastic.core.strings.routing_error_no_response
|
||||
import org.meshtastic.core.strings.routing_error_no_route
|
||||
import org.meshtastic.core.strings.routing_error_none
|
||||
import org.meshtastic.core.strings.routing_error_not_authorized
|
||||
import org.meshtastic.core.strings.routing_error_pki_failed
|
||||
import org.meshtastic.core.strings.routing_error_pki_send_fail_public_key
|
||||
import org.meshtastic.core.strings.routing_error_pki_unknown_pubkey
|
||||
import org.meshtastic.core.strings.routing_error_rate_limit_exceeded
|
||||
import org.meshtastic.core.strings.routing_error_timeout
|
||||
import org.meshtastic.core.strings.routing_error_too_large
|
||||
import org.meshtastic.core.strings.unrecognized
|
||||
import org.meshtastic.core.resources.Res
|
||||
import org.meshtastic.core.resources.delivery_confirmed
|
||||
import org.meshtastic.core.resources.error
|
||||
import org.meshtastic.core.resources.message_delivery_status
|
||||
import org.meshtastic.core.resources.message_status_enroute
|
||||
import org.meshtastic.core.resources.message_status_queued
|
||||
import org.meshtastic.core.resources.message_status_sfpp_confirmed
|
||||
import org.meshtastic.core.resources.message_status_sfpp_routing
|
||||
import org.meshtastic.core.resources.routing_error_admin_bad_session_key
|
||||
import org.meshtastic.core.resources.routing_error_admin_public_key_unauthorized
|
||||
import org.meshtastic.core.resources.routing_error_bad_request
|
||||
import org.meshtastic.core.resources.routing_error_duty_cycle_limit
|
||||
import org.meshtastic.core.resources.routing_error_got_nak
|
||||
import org.meshtastic.core.resources.routing_error_max_retransmit
|
||||
import org.meshtastic.core.resources.routing_error_no_channel
|
||||
import org.meshtastic.core.resources.routing_error_no_interface
|
||||
import org.meshtastic.core.resources.routing_error_no_response
|
||||
import org.meshtastic.core.resources.routing_error_no_route
|
||||
import org.meshtastic.core.resources.routing_error_none
|
||||
import org.meshtastic.core.resources.routing_error_not_authorized
|
||||
import org.meshtastic.core.resources.routing_error_pki_failed
|
||||
import org.meshtastic.core.resources.routing_error_pki_send_fail_public_key
|
||||
import org.meshtastic.core.resources.routing_error_pki_unknown_pubkey
|
||||
import org.meshtastic.core.resources.routing_error_rate_limit_exceeded
|
||||
import org.meshtastic.core.resources.routing_error_timeout
|
||||
import org.meshtastic.core.resources.routing_error_too_large
|
||||
import org.meshtastic.core.resources.unrecognized
|
||||
import org.meshtastic.proto.MeshPacket
|
||||
import org.meshtastic.proto.Routing
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2025 Meshtastic LLC
|
||||
* 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
|
||||
|
|
@ -14,18 +14,17 @@
|
|||
* 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.database.model
|
||||
|
||||
import org.jetbrains.compose.resources.StringResource
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.node_sort_alpha
|
||||
import org.meshtastic.core.strings.node_sort_channel
|
||||
import org.meshtastic.core.strings.node_sort_distance
|
||||
import org.meshtastic.core.strings.node_sort_hops_away
|
||||
import org.meshtastic.core.strings.node_sort_last_heard
|
||||
import org.meshtastic.core.strings.node_sort_via_favorite
|
||||
import org.meshtastic.core.strings.node_sort_via_mqtt
|
||||
import org.meshtastic.core.resources.Res
|
||||
import org.meshtastic.core.resources.node_sort_alpha
|
||||
import org.meshtastic.core.resources.node_sort_channel
|
||||
import org.meshtastic.core.resources.node_sort_distance
|
||||
import org.meshtastic.core.resources.node_sort_hops_away
|
||||
import org.meshtastic.core.resources.node_sort_last_heard
|
||||
import org.meshtastic.core.resources.node_sort_via_favorite
|
||||
import org.meshtastic.core.resources.node_sort_via_mqtt
|
||||
|
||||
enum class NodeSortOption(val sqlValue: String, val stringRes: StringResource) {
|
||||
LAST_HEARD("last_heard", Res.string.node_sort_last_heard),
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# `:core:strings`
|
||||
# `:core:resources`
|
||||
|
||||
## Overview
|
||||
The `:core:strings` module is the centralized source for all UI strings and localizable resources. It uses the **Compose Multiplatform Resource** library to provide a type-safe way to access strings.
|
||||
The `:core:resources` module is the centralized source for all UI strings and localizable resources. It uses the **Compose Multiplatform Resource** library to provide a type-safe way to access strings.
|
||||
|
||||
## Key Features
|
||||
|
||||
|
|
@ -13,8 +13,8 @@ The library provides a standard way to access strings in Jetpack Compose.
|
|||
|
||||
```kotlin
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.your_string_key
|
||||
import org.meshtastic.core.resources.Res
|
||||
import org.meshtastic.core.resources.your_string_key
|
||||
|
||||
Text(text = stringResource(Res.string.your_string_key))
|
||||
```
|
||||
|
|
@ -24,7 +24,7 @@ Text(text = stringResource(Res.string.your_string_key))
|
|||
<!--region graph-->
|
||||
```mermaid
|
||||
graph TB
|
||||
:core:strings[strings]:::kmp-library
|
||||
:core:resources[strings]:::kmp-library
|
||||
|
||||
classDef android-application fill:#CAFFBF,stroke:#000,stroke-width:2px,color:#000;
|
||||
classDef android-application-compose fill:#CAFFBF,stroke:#000,stroke-width:2px,color:#000;
|
||||
|
|
@ -29,5 +29,5 @@ kotlin {
|
|||
|
||||
compose.resources {
|
||||
publicResClass = true
|
||||
packageOfResClass = "org.meshtastic.core.strings"
|
||||
packageOfResClass = "org.meshtastic.core.resources"
|
||||
}
|
||||
|
|
@ -14,7 +14,7 @@
|
|||
* 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.strings
|
||||
package org.meshtastic.core.resources
|
||||
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.jetbrains.compose.resources.StringResource
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="960"
|
||||
android:viewportHeight="960">
|
||||
<path
|
||||
android:pathData="M620,440q-25,0 -42.5,-17.5T560,380q0,-17 9.5,-34.5t20.5,-32q11,-14.5 20.5,-24l9.5,-9.5 9.5,9.5q9.5,9.5 20.5,24t20.5,32Q680,363 680,380q0,25 -17.5,42.5T620,440ZM780,320q-25,0 -42.5,-17.5T720,260q0,-17 9.5,-34.5t20.5,-32q11,-14.5 20.5,-24l9.5,-9.5 9.5,9.5q9.5,9.5 20.5,24t20.5,32Q840,243 840,260q0,25 -17.5,42.5T780,320ZM780,560q-25,0 -42.5,-17.5T720,500q0,-17 9.5,-34.5t20.5,-32q11,-14.5 20.5,-24l9.5,-9.5 9.5,9.5q9.5,9.5 20.5,24t20.5,32Q840,483 840,500q0,25 -17.5,42.5T780,560ZM360,840q-83,0 -141.5,-58.5T160,640q0,-48 21,-89.5t59,-70.5v-240q0,-50 35,-85t85,-35q50,0 85,35t35,85v240q38,29 59,70.5t21,89.5q0,83 -58.5,141.5T360,840ZM240,640h240q0,-29 -12.5,-54T432,544l-32,-24v-280q0,-17 -11.5,-28.5T360,200q-17,0 -28.5,11.5T320,240v280l-32,24q-23,17 -35.5,42T240,640Z"
|
||||
android:fillColor="#e8eaed"/>
|
||||
</vector>
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M21,11a1,1 0,0 1,1 1a10,10 0,0 1,-5 8.656a1,1 0,0 1,-1.302 -0.268l-0.064,-0.098l-3,-5.19a0.995,0.995 0,0 1,-0.133 -0.542l0.01,-0.11l0.023,-0.106l0.034,-0.106l0.046,-0.1l0.056,-0.094l0.067,-0.089a0.994,0.994 0,0 1,0.165 -0.155l0.098,-0.064a2,2 0,0 0,0.993 -1.57l0.007,-0.163a1,1 0,0 1,0.883 -0.994l0.117,-0.007h6z" />
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M7,3.344a10,10 0,0 1,10 0a1,1 0,0 1,0.418 1.262l-0.052,0.104l-3,5.19l-0.064,0.098a0.994,0.994 0,0 1,-0.155 0.165l-0.089,0.067a1,1 0,0 1,-0.195 0.102l-0.105,0.034l-0.107,0.022a1.003,1.003 0,0 1,-0.547 -0.07l-0.104,-0.052a2,2 0,0 0,-1.842 -0.082l-0.158,0.082a1,1 0,0 1,-1.302 -0.268l-0.064,-0.098l-3,-5.19a1,1 0,0 1,0.366 -1.366z" />
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M9,11a1,1 0,0 1,0.993 0.884l0.007,0.117a2,2 0,0 0,0.861 1.645l0.237,0.152a0.994,0.994 0,0 1,0.165 0.155l0.067,0.089l0.056,0.095l0.045,0.099c0.014,0.036 0.026,0.07 0.035,0.106l0.022,0.107l0.011,0.11a0.994,0.994 0,0 1,-0.08 0.437l-0.053,0.104l-3,5.19a1,1 0,0 1,-1.366 0.366a10,10 0,0 1,-5 -8.656a1,1 0,0 1,0.883 -0.993l0.117,-0.007h6z" />
|
||||
</vector>
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="200dp" android:viewportHeight="32" android:viewportWidth="32" android:width="200dp">
|
||||
|
||||
<path android:fillColor="#000000" android:pathData="M24.5,30a5.202,5.202 0,0 1,-4.626 -8.08L23.49,16.538a1.217,1.217 0,0 1,2.02 0L29.06,21.815A5.492,5.492 0,0 1,30 24.751,5.385 5.385,0 0,1 24.5,30ZM24.5,18.62 L21.564,22.987A3.208,3.208 0,0 0,24.5 28,3.385 3.385,0 0,0 28,24.751a3.435,3.435 0,0 0,-0.63 -1.867Z"/>
|
||||
|
||||
<path android:fillColor="#000000" android:pathData="M11,16V11h1a4.004,4.004 0,0 0,4 -4V4H13a3.978,3.978 0,0 0,-2.747 1.107A6.003,6.003 0,0 0,5 2H2V5a6.007,6.007 0,0 0,6 6H9v5H2v2H16V16ZM13,6h1V7a2.002,2.002 0,0 1,-2 2H11V8A2.002,2.002 0,0 1,13 6ZM8,9A4.004,4.004 0,0 1,4 5V4H5A4.004,4.004 0,0 1,9 8V9Z"/>
|
||||
|
||||
<path android:fillColor="#000000" android:pathData="M2,21h14v2h-14z"/>
|
||||
|
||||
<path android:fillColor="#000000" android:pathData="M2,26h14v2h-14z"/>
|
||||
|
||||
</vector>
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="200dp" android:viewportHeight="32" android:viewportWidth="32" android:width="200dp">
|
||||
|
||||
<path android:fillColor="#000000" android:pathData="M11,16V11h1a4.004,4.004 0,0 0,4 -4V4H13a3.978,3.978 0,0 0,-2.747 1.107A6.003,6.003 0,0 0,5 2H2V5a6.007,6.007 0,0 0,6 6H9v5H2v2H16V16ZM13,6h1V7a2.002,2.002 0,0 1,-2 2H11V8A2.002,2.002 0,0 1,13 6ZM8,9A4.004,4.004 0,0 1,4 5V4H5A4.004,4.004 0,0 1,9 8V9Z"/>
|
||||
|
||||
<path android:fillColor="#000000" android:pathData="M2,21h14v2h-14z"/>
|
||||
|
||||
<path android:fillColor="#000000" android:pathData="M2,26h14v2h-14z"/>
|
||||
|
||||
<path android:fillColor="#000000" android:pathData="M25,30a4.986,4.986 0,0 1,-3 -8.98L22,15a3,3 0,0 1,6 0v6.02A4.986,4.986 0,0 1,25 30ZM25,14a1.001,1.001 0,0 0,-1 1v7.13l-0.497,0.289A2.968,2.968 0,0 0,22 25a3,3 0,0 0,6 0,2.968 2.968,0 0,0 -1.503,-2.581L26,22.13L26,15A1.001,1.001 0,0 0,25 14Z"/>
|
||||
|
||||
</vector>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M23,11.99l-2.44,-2.79l0.34,-3.69l-3.61,-0.82L15.4,1.5L12,2.96L8.6,1.5L6.71,4.69L3.1,5.5L3.44,9.2L1,11.99l2.44,2.79l-0.34,3.7l3.61,0.82L8.6,22.5l3.4,-1.47l3.4,1.46l1.89,-3.19l3.61,-0.82l-0.34,-3.69L23,11.99zM19.05,13.47l-0.56,0.65l0.08,0.85l0.18,1.95l-1.9,0.43l-0.84,0.19l-0.44,0.74l-0.99,1.68l-1.78,-0.77L12,18.85l-0.79,0.34l-1.78,0.77l-0.99,-1.67l-0.44,-0.74l-0.84,-0.19l-1.9,-0.43l0.18,-1.96l0.08,-0.85l-0.56,-0.65l-1.29,-1.47l1.29,-1.48l0.56,-0.65L5.43,9.01L5.25,7.07l1.9,-0.43l0.84,-0.19l0.44,-0.74l0.99,-1.68l1.78,0.77L12,5.14l0.79,-0.34l1.78,-0.77l0.99,1.68l0.44,0.74l0.84,0.19l1.9,0.43l-0.18,1.95l-0.08,0.85l0.56,0.65l1.29,1.47L19.05,13.47z"
|
||||
android:fillColor="#e3e3e3"/>
|
||||
</vector>
|
||||
|
|
@ -0,0 +1,121 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="909.88dp"
|
||||
android:height="546.86dp"
|
||||
android:viewportWidth="909.88"
|
||||
android:viewportHeight="546.86">
|
||||
<path
|
||||
android:pathData="m898.52,135.44h4.69a5.67,5.67 0,0 1,5.67 5.67v84.65a5.67,5.67 0,0 1,-5.67 5.67h-4.69"
|
||||
android:fillColor="#9f9f9e"/>
|
||||
<path
|
||||
android:pathData="M12.7,104.75L886.82,104.75A11.7,11.7 0,0 1,898.52 116.45L898.52,534.16A11.7,11.7 0,0 1,886.82 545.86L12.7,545.86A11.7,11.7 0,0 1,1 534.16L1,116.45A11.7,11.7 0,0 1,12.7 104.75z"
|
||||
android:fillColor="#cbcccb"/>
|
||||
<path
|
||||
android:pathData="m34.47,104.75v113.48a3.67,3.67 0,0 0,3.67 3.67h41a2.35,2.35 0,0 1,2.35 2.35L81.49,545.86L870.95,545.86L870.95,104.75ZM845.99,520.86L106.53,520.86L106.53,213.96a17.06,17.06 0,0 0,-17.06 -17.06h-27.5a2.5,2.5 0,0 1,-2.5 -2.5v-62.15a2.5,2.5 0,0 1,2.5 -2.5h784z"
|
||||
android:fillColor="#9f9f9e"/>
|
||||
<path
|
||||
android:pathData="M845.99,129.75L845.99,520.86L106.53,520.86L106.53,213.96a17,17 0,0 0,-7.2 -13.92v-70.29z"
|
||||
android:fillColor="#cbcccb"/>
|
||||
<path
|
||||
android:pathData="m99.33,129.75v70.29a17,17 0,0 0,-9.86 -3.14h-27.5a2.5,2.5 0,0 1,-2.5 -2.5v-62.15a2.5,2.5 0,0 1,2.5 -2.5z"
|
||||
android:fillColor="#b7b7b7"/>
|
||||
<path
|
||||
android:pathData="M25.45,253.39h13.53v148.4h-13.53z"
|
||||
android:fillColor="#9f9f9e"/>
|
||||
<path
|
||||
android:pathData="m430.64,95.71h71.71a2.55,2.55 0,0 1,2.55 2.55v6.48h-76.8v-6.48a2.55,2.55 0,0 1,2.54 -2.55z"
|
||||
android:fillColor="#b1a368"/>
|
||||
<path
|
||||
android:pathData="m436.27,3.17h60.88a6.2,4.85 0,0 1,6.2 4.85v77.33h-73.28v-77.33a6.2,4.85 0,0 1,6.2 -4.85z"
|
||||
android:strokeWidth="2"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#050606"/>
|
||||
<path
|
||||
android:pathData="M425.88,20.14L506.28,20.14A5.55,5.55 0,0 1,511.83 25.69L511.83,70.55A5.55,5.55 0,0 1,506.28 76.1L425.88,76.1A5.55,5.55 0,0 1,420.33 70.55L420.33,25.69A5.55,5.55 0,0 1,425.88 20.14z"
|
||||
android:strokeWidth="2"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#050606"/>
|
||||
<path
|
||||
android:pathData="m511.8,24.48v47.25a5.52,4.31 0,0 1,-5.55 4.34h-80.37a5.55,4.34 0,0 1,-5.59 -4.34v-47.25a5.55,4.34 0,0 1,5.59 -4.34h80.51a5.52,4.31 0,0 1,5.41 4.34z"
|
||||
android:strokeWidth="3.16706"
|
||||
android:fillColor="#9f9f9e"
|
||||
android:strokeColor="#050606"/>
|
||||
<path
|
||||
android:pathData="M433.29,85.68h65.99v10.03h-65.99z"
|
||||
android:fillColor="#b1a368"/>
|
||||
<path
|
||||
android:pathData="M845.99,129.75L845.99,520.86L106.53,520.86L106.53,213.96a17.06,17.06 0,0 0,-17.06 -17.06h-27.5a2.5,2.5 0,0 1,-2.5 -2.5v-62.15a2.5,2.5 0,0 1,2.5 -2.5h784m25,-25L34.47,104.75v113.48a3.68,3.68 0,0 0,3.67 3.67h41a2.35,2.35 0,0 1,2.35 2.35L81.49,545.86L870.95,545.86L870.95,104.75Z"
|
||||
android:strokeWidth="2"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#050606"/>
|
||||
<path
|
||||
android:pathData="M99.34,200.04L99.34,129.75"
|
||||
android:strokeWidth="2"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#050606"/>
|
||||
<path
|
||||
android:pathData="M25.45,253.39h13.53v148.4h-13.53z"
|
||||
android:strokeWidth="2"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#050606"/>
|
||||
<path
|
||||
android:pathData="m898.52,135.44h4.69a5.67,5.67 0,0 1,5.67 5.67v84.65a5.67,5.67 0,0 1,-5.67 5.67h-4.69"
|
||||
android:strokeWidth="2"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#050606"/>
|
||||
<path
|
||||
android:pathData="m430.64,95.71h71.71a2.55,2.55 0,0 1,2.55 2.55v6.48h-76.8v-6.48a2.55,2.55 0,0 1,2.54 -2.55z"
|
||||
android:strokeWidth="2.04"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#050606"/>
|
||||
<path
|
||||
android:pathData="M433.29,85.68h65.99v10.03h-65.99z"
|
||||
android:strokeWidth="1.99"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#050606"/>
|
||||
<path
|
||||
android:pathData="m78.62,152.33a14,14 0,1 0,14 14,13.95 13.95,0 0,0 -14,-14zM78.62,173.83a7.55,7.55 0,1 1,7.54 -7.55,7.55 7.55,0 0,1 -7.54,7.55z"
|
||||
android:fillColor="#9f9f9e"/>
|
||||
<path
|
||||
android:pathData="M78.62,166.28m-7.55,0a7.55,7.55 0,1 1,15.1 0a7.55,7.55 0,1 1,-15.1 0"
|
||||
android:strokeWidth="2"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#050606"/>
|
||||
<path
|
||||
android:pathData="M78.62,166.28m-13.95,0a13.95,13.95 0,1 1,27.9 0a13.95,13.95 0,1 1,-27.9 0"
|
||||
android:strokeWidth="2"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#050606"/>
|
||||
<path
|
||||
android:pathData="m445.36,440.05c0,11.52 10.38,20.86 23.19,20.86 12.81,0 23.19,-9.34 23.19,-20.86 0,-11.52 -10.38,-20.86 -23.19,-20.86 -12.81,0 -23.19,9.34 -23.19,20.86z"
|
||||
android:strokeWidth="0.458227"
|
||||
android:fillColor="#4d4d4d"/>
|
||||
<path
|
||||
android:pathData="m469.4,538.4c-119.83,0 -217.32,-93.41 -217.32,-208.23 0,-114.82 97.48,-208.23 217.32,-208.23 119.83,0 217.32,93.41 217.32,208.23 0,114.82 -97.48,208.23 -217.32,208.23zM469.4,151.82c-102.64,0 -186.13,80.01 -186.13,178.35 0,98.33 83.5,178.35 186.13,178.35 102.62,0 186.13,-80.02 186.13,-178.35 0,-98.34 -83.51,-178.35 -186.13,-178.35z"
|
||||
android:strokeWidth="0.474832"
|
||||
android:fillColor="#4d4d4d"/>
|
||||
<path
|
||||
android:pathData="m468.56,391.97c-8.54,0 -15.46,-6.23 -15.46,-13.91v-23.51c0,-22.75 19.33,-40.13 36.4,-55.47 12.51,-11.26 25.45,-22.89 25.45,-32.16 0,-23.18 -20.81,-42.04 -46.39,-42.04 -26.01,0 -46.39,18.05 -46.39,41.09 0,7.68 -6.93,13.91 -15.46,13.91 -8.54,0 -15.46,-6.23 -15.46,-13.91 0,-37.99 34.68,-68.9 77.31,-68.9 42.63,0 77.31,31.33 77.31,69.85 0,20.82 -17.55,36.59 -34.51,51.84 -13.45,12.07 -27.34,24.56 -27.34,35.78v23.51c0,7.68 -6.93,13.92 -15.46,13.92z"
|
||||
android:strokeWidth="0.458227"
|
||||
android:fillColor="#4d4d4d"
|
||||
android:strokeColor="#000000"/>
|
||||
<path
|
||||
android:pathData="M12.7,104.75L886.82,104.75A11.7,11.7 0,0 1,898.52 116.45L898.52,534.16A11.7,11.7 0,0 1,886.82 545.86L12.7,545.86A11.7,11.7 0,0 1,1 534.16L1,116.45A11.7,11.7 0,0 1,12.7 104.75z"
|
||||
android:strokeWidth="2"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#050606"/>
|
||||
<path
|
||||
android:pathData="m107.42,363.03 l-0.24,-156.31 -2.99,-3.72 -2.99,-3.72v-34.09,-34.09l150.65,0.05 150.65,0.05 -8.28,3.07c-19.32,7.16 -34.46,14.82 -50.22,25.41 -50.58,33.98 -84.36,88.87 -91.06,147.96 -1.43,12.63 -0.64,44.7 1.39,55.76 7.76,42.44 25.98,77.93 55.68,108.42 17.38,17.85 33.99,30.3 55.43,41.55l11.31,5.93 -134.54,0.02 -134.54,0.02z"
|
||||
android:strokeWidth="0.92"
|
||||
android:fillColor="#ffffff"
|
||||
android:fillAlpha="0"/>
|
||||
<path
|
||||
android:pathData="m107.42,363.03 l-0.24,-156.31 -2.99,-3.72 -2.99,-3.72v-34.09,-34.09l150.65,0.05 150.65,0.05 -8.28,3.07c-19.32,7.16 -34.46,14.82 -50.22,25.41 -50.58,33.98 -84.36,88.87 -91.06,147.96 -1.43,12.63 -0.64,44.7 1.39,55.76 7.76,42.44 25.98,77.93 55.68,108.42 17.38,17.85 33.99,30.3 55.43,41.55l11.31,5.93 -134.54,0.02 -134.54,0.02z"
|
||||
android:strokeWidth="0.92"
|
||||
android:fillColor="#ffffff"
|
||||
android:fillAlpha="0"/>
|
||||
<path
|
||||
android:pathData="m107.42,363.03 l-0.24,-156.31 -2.99,-3.72 -2.99,-3.72v-34.09,-34.09l150.65,0.05 150.65,0.05 -8.28,3.07c-19.32,7.16 -34.46,14.82 -50.22,25.41 -50.58,33.98 -84.36,88.87 -91.06,147.96 -1.43,12.63 -0.64,44.7 1.39,55.76 7.76,42.44 25.98,77.93 55.68,108.42 17.38,17.85 33.99,30.3 55.43,41.55l11.31,5.93 -134.54,0.02 -134.54,0.02z"
|
||||
android:strokeWidth="0.92"
|
||||
android:fillColor="#ffffff"
|
||||
android:fillAlpha="0"/>
|
||||
</vector>
|
||||
|
Before Width: | Height: | Size: 690 B After Width: | Height: | Size: 690 B |
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* 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.resources
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import org.jetbrains.compose.resources.StringResource
|
||||
import org.jetbrains.compose.resources.getString
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
|
||||
/**
|
||||
* A wrapper class for UI text that can be either a dynamic string or a localized string resource. This allows passing
|
||||
* text from domain/data layers to the UI without resolving strings early.
|
||||
*/
|
||||
sealed class UiText {
|
||||
data class DynamicString(val value: String) : UiText()
|
||||
|
||||
class Resource(val res: StringResource, vararg val args: Any) : UiText() {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other == null || this::class != other::class) return false
|
||||
|
||||
other as Resource
|
||||
|
||||
if (res != other.res) return false
|
||||
if (!args.contentEquals(other.args)) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = res.hashCode()
|
||||
result = 31 * result + args.contentHashCode()
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun asString(): String = when (this) {
|
||||
is DynamicString -> value
|
||||
is Resource -> {
|
||||
val resolvedArgs =
|
||||
args.map { arg ->
|
||||
when (arg) {
|
||||
is StringResource -> stringResource(arg)
|
||||
is UiText -> arg.asString()
|
||||
else -> arg
|
||||
}
|
||||
}
|
||||
@Suppress("SpreadOperator")
|
||||
stringResource(res, *resolvedArgs.toTypedArray())
|
||||
}
|
||||
}
|
||||
|
||||
/** Resolves the string in a suspend context. Useful for non-composable code like snackbars. */
|
||||
suspend fun resolve(): String = when (this) {
|
||||
is DynamicString -> value
|
||||
is Resource -> {
|
||||
val resolvedArgs =
|
||||
args.map { arg ->
|
||||
when (arg) {
|
||||
is StringResource -> getString(arg)
|
||||
is UiText -> arg.resolve()
|
||||
else -> arg
|
||||
}
|
||||
}
|
||||
@Suppress("SpreadOperator")
|
||||
getString(res, *resolvedArgs.toTypedArray())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -33,8 +33,8 @@ Most components are designed to be used with the **Compose Multiplatform Resourc
|
|||
|
||||
```kotlin
|
||||
import org.meshtastic.core.ui.component.MeshtasticResourceDialog
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.ok
|
||||
import org.meshtastic.core.resources.Res
|
||||
import org.meshtastic.core.resources.ok
|
||||
|
||||
MeshtasticResourceDialog(
|
||||
title = Res.string.your_title,
|
||||
|
|
@ -59,7 +59,7 @@ graph TB
|
|||
:core:ui -.-> :core:prefs
|
||||
:core:ui -.-> :core:proto
|
||||
:core:ui -.-> :core:service
|
||||
:core:ui -.-> :core:strings
|
||||
:core:ui -.-> :core:resources
|
||||
|
||||
classDef android-application fill:#CAFFBF,stroke:#000,stroke-width:2px,color:#000;
|
||||
classDef android-application-compose fill:#CAFFBF,stroke:#000,stroke-width:2px,color:#000;
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ dependencies {
|
|||
implementation(projects.core.prefs)
|
||||
implementation(projects.core.proto)
|
||||
implementation(projects.core.service)
|
||||
implementation(projects.core.strings)
|
||||
implementation(projects.core.resources)
|
||||
|
||||
implementation(libs.accompanist.permissions)
|
||||
implementation(libs.androidx.activity.compose)
|
||||
|
|
|
|||
|
|
@ -42,9 +42,9 @@ import androidx.compose.ui.text.style.TextDecoration
|
|||
import androidx.compose.ui.unit.dp
|
||||
import org.jetbrains.compose.resources.StringResource
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.cancel
|
||||
import org.meshtastic.core.strings.okay
|
||||
import org.meshtastic.core.resources.Res
|
||||
import org.meshtastic.core.resources.cancel
|
||||
import org.meshtastic.core.resources.okay
|
||||
|
||||
/**
|
||||
* A comprehensive and flexible dialog component for the Meshtastic application.
|
||||
|
|
|
|||
|
|
@ -37,9 +37,9 @@ import androidx.compose.ui.Modifier
|
|||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.clear
|
||||
import org.meshtastic.core.strings.close
|
||||
import org.meshtastic.core.resources.Res
|
||||
import org.meshtastic.core.resources.clear
|
||||
import org.meshtastic.core.resources.close
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ import androidx.compose.ui.Modifier
|
|||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.tooling.preview.PreviewLightDark
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.channel
|
||||
import org.meshtastic.core.resources.Res
|
||||
import org.meshtastic.core.resources.channel
|
||||
import org.meshtastic.core.ui.icon.Channel
|
||||
import org.meshtastic.core.ui.icon.Counter0
|
||||
import org.meshtastic.core.ui.icon.Counter1
|
||||
|
|
|
|||
|
|
@ -30,8 +30,8 @@ import com.google.zxing.common.BitMatrix
|
|||
import org.jetbrains.compose.resources.stringResource
|
||||
import org.meshtastic.core.database.model.Node
|
||||
import org.meshtastic.core.model.util.getSharedContactUrl
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.share_contact
|
||||
import org.meshtastic.core.resources.Res
|
||||
import org.meshtastic.core.resources.share_contact
|
||||
import org.meshtastic.proto.SharedContact
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2025 Meshtastic LLC
|
||||
* 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
|
||||
|
|
@ -14,7 +14,6 @@
|
|||
* 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.ui.component
|
||||
|
||||
import android.content.ClipData
|
||||
|
|
@ -29,8 +28,8 @@ import androidx.compose.ui.platform.ClipEntry
|
|||
import androidx.compose.ui.platform.LocalClipboard
|
||||
import kotlinx.coroutines.launch
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.copy
|
||||
import org.meshtastic.core.resources.Res
|
||||
import org.meshtastic.core.resources.copy
|
||||
|
||||
@Composable
|
||||
fun CopyIconButton(
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ import androidx.compose.ui.Modifier
|
|||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.tooling.preview.PreviewLightDark
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.distance
|
||||
import org.meshtastic.core.resources.Res
|
||||
import org.meshtastic.core.resources.distance
|
||||
import org.meshtastic.core.ui.icon.Distance
|
||||
import org.meshtastic.core.ui.icon.MeshtasticIcons
|
||||
import org.meshtastic.core.ui.theme.AppTheme
|
||||
|
|
|
|||
|
|
@ -47,9 +47,9 @@ import org.jetbrains.compose.resources.stringResource
|
|||
import org.meshtastic.core.model.Channel
|
||||
import org.meshtastic.core.model.util.base64ToByteString
|
||||
import org.meshtastic.core.model.util.encodeToString
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.error
|
||||
import org.meshtastic.core.strings.reset
|
||||
import org.meshtastic.core.resources.Res
|
||||
import org.meshtastic.core.resources.error
|
||||
import org.meshtastic.core.resources.reset
|
||||
|
||||
@Suppress("LongMethod", "CyclomaticComplexMethod", "MagicNumber")
|
||||
@Composable
|
||||
|
|
|
|||
|
|
@ -39,13 +39,13 @@ import androidx.compose.ui.text.input.KeyboardType
|
|||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.add
|
||||
import org.meshtastic.core.strings.delete
|
||||
import org.meshtastic.core.strings.gpio_pin
|
||||
import org.meshtastic.core.strings.ignore_incoming
|
||||
import org.meshtastic.core.strings.name
|
||||
import org.meshtastic.core.strings.type
|
||||
import org.meshtastic.core.resources.Res
|
||||
import org.meshtastic.core.resources.add
|
||||
import org.meshtastic.core.resources.delete
|
||||
import org.meshtastic.core.resources.gpio_pin
|
||||
import org.meshtastic.core.resources.ignore_incoming
|
||||
import org.meshtastic.core.resources.name
|
||||
import org.meshtastic.core.resources.type
|
||||
import org.meshtastic.proto.RemoteHardwarePin
|
||||
import org.meshtastic.proto.RemoteHardwarePinType
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2025 Meshtastic LLC
|
||||
* 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
|
||||
|
|
@ -14,7 +14,6 @@
|
|||
* 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.ui.component
|
||||
|
||||
import androidx.compose.foundation.text.KeyboardActions
|
||||
|
|
@ -35,9 +34,9 @@ import androidx.compose.ui.text.input.PasswordVisualTransformation
|
|||
import androidx.compose.ui.text.input.VisualTransformation
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.hide_password
|
||||
import org.meshtastic.core.strings.show_password
|
||||
import org.meshtastic.core.resources.Res
|
||||
import org.meshtastic.core.resources.hide_password
|
||||
import org.meshtastic.core.resources.show_password
|
||||
|
||||
@Composable
|
||||
fun EditPasswordPreference(
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2025 Meshtastic LLC
|
||||
* 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
|
||||
|
|
@ -14,7 +14,6 @@
|
|||
* 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.ui.component
|
||||
|
||||
import androidx.compose.foundation.layout.Box
|
||||
|
|
@ -44,8 +43,8 @@ import androidx.compose.ui.text.input.VisualTransformation
|
|||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.error
|
||||
import org.meshtastic.core.resources.Res
|
||||
import org.meshtastic.core.resources.error
|
||||
|
||||
@Composable
|
||||
fun SignedIntegerEditTextPreference(
|
||||
|
|
|
|||
|
|
@ -24,9 +24,9 @@ import androidx.compose.ui.tooling.preview.Preview
|
|||
import org.jetbrains.compose.resources.stringResource
|
||||
import org.meshtastic.core.model.util.metersIn
|
||||
import org.meshtastic.core.model.util.toString
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.altitude
|
||||
import org.meshtastic.core.strings.elevation_suffix
|
||||
import org.meshtastic.core.resources.Res
|
||||
import org.meshtastic.core.resources.altitude
|
||||
import org.meshtastic.core.resources.elevation_suffix
|
||||
import org.meshtastic.core.ui.icon.Elevation
|
||||
import org.meshtastic.core.ui.icon.MeshtasticIcons
|
||||
import org.meshtastic.proto.Config.DisplayConfig.DisplayUnits
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ import androidx.compose.ui.Modifier
|
|||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.tooling.preview.PreviewLightDark
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.hops_away
|
||||
import org.meshtastic.core.resources.Res
|
||||
import org.meshtastic.core.resources.hops_away
|
||||
import org.meshtastic.core.ui.icon.Hops
|
||||
import org.meshtastic.core.ui.icon.MeshtasticIcons
|
||||
import org.meshtastic.core.ui.theme.AppTheme
|
||||
|
|
|
|||
|
|
@ -41,22 +41,22 @@ import androidx.core.net.toUri
|
|||
import org.jetbrains.compose.resources.stringResource
|
||||
import org.meshtastic.core.barcode.rememberBarcodeScanner
|
||||
import org.meshtastic.core.nfc.NfcScannerEffect
|
||||
import org.meshtastic.core.strings.Res
|
||||
import org.meshtastic.core.strings.cancel
|
||||
import org.meshtastic.core.strings.import_label
|
||||
import org.meshtastic.core.strings.input_channel_url
|
||||
import org.meshtastic.core.strings.input_shared_contact_url
|
||||
import org.meshtastic.core.strings.nfc_disabled
|
||||
import org.meshtastic.core.strings.okay
|
||||
import org.meshtastic.core.strings.open_settings
|
||||
import org.meshtastic.core.strings.scan_channels_nfc
|
||||
import org.meshtastic.core.strings.scan_channels_qr
|
||||
import org.meshtastic.core.strings.scan_nfc
|
||||
import org.meshtastic.core.strings.scan_nfc_text
|
||||
import org.meshtastic.core.strings.scan_shared_contact_nfc
|
||||
import org.meshtastic.core.strings.scan_shared_contact_qr
|
||||
import org.meshtastic.core.strings.share_channels_qr
|
||||
import org.meshtastic.core.strings.url
|
||||
import org.meshtastic.core.resources.Res
|
||||
import org.meshtastic.core.resources.cancel
|
||||
import org.meshtastic.core.resources.import_label
|
||||
import org.meshtastic.core.resources.input_channel_url
|
||||
import org.meshtastic.core.resources.input_shared_contact_url
|
||||
import org.meshtastic.core.resources.nfc_disabled
|
||||
import org.meshtastic.core.resources.okay
|
||||
import org.meshtastic.core.resources.open_settings
|
||||
import org.meshtastic.core.resources.scan_channels_nfc
|
||||
import org.meshtastic.core.resources.scan_channels_qr
|
||||
import org.meshtastic.core.resources.scan_nfc
|
||||
import org.meshtastic.core.resources.scan_nfc_text
|
||||
import org.meshtastic.core.resources.scan_shared_contact_nfc
|
||||
import org.meshtastic.core.resources.scan_shared_contact_qr
|
||||
import org.meshtastic.core.resources.share_channels_qr
|
||||
import org.meshtastic.core.resources.url
|
||||
import org.meshtastic.core.ui.icon.MeshtasticIcons
|
||||
import org.meshtastic.core.ui.icon.QrCode2
|
||||
import org.meshtastic.core.ui.theme.AppTheme
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue