From e3f4860179e826185b0b571c754c76596189494b Mon Sep 17 00:00:00 2001 From: James Rich <2199651+jamesarich@users.noreply.github.com> Date: Sun, 22 Feb 2026 10:23:34 -0600 Subject: [PATCH 01/18] refactor(messaging): Improve message list performance and fix unread divider bug This commit optimizes the performance of the message list and resolves a UI issue where the "Unread Messages" divider could overlap with a message item. Key changes include: - The logic for finding the unread divider index and navigating to a replied-to message now uses `itemSnapshotList`. This avoids performing searches on the lazy-loaded `PagingData` during composition, leading to better performance and stability. - The unread divider and its corresponding message item are now wrapped in a `Column`. This ensures they are rendered correctly in a single animated block, preventing the visual overlap bug. - Item animation modifiers have been streamlined to reduce redundant code. - `MessageStatusDialog` is now marked as private as it's only used within its own file. Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com> --- .../feature/messaging/MessageListPaged.kt | 92 +++++++++++-------- 1 file changed, 56 insertions(+), 36 deletions(-) diff --git a/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/MessageListPaged.kt b/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/MessageListPaged.kt index c5c50c82de..7ee2710a4b 100644 --- a/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/MessageListPaged.kt +++ b/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/MessageListPaged.kt @@ -18,13 +18,13 @@ package org.meshtastic.feature.messaging import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.LazyItemScope import androidx.compose.foundation.lazy.LazyListState import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.material3.CircularProgressIndicator @@ -192,13 +192,12 @@ private fun MessageListPagedContent( modifier: Modifier = Modifier, quickEmojis: List, ) { - // Calculate unread divider position + // Calculate unread divider position using snapshot to avoid side-effects and improve performance val unreadDividerIndex by remember(state.messages.itemCount, state.firstUnreadMessageUuid) { derivedStateOf { - state.firstUnreadMessageUuid?.let { uuid -> - (0 until state.messages.itemCount).firstOrNull { index -> state.messages[index]?.uuid == uuid } - } + val uuid = state.firstUnreadMessageUuid ?: return@derivedStateOf null + state.messages.itemSnapshotList.items.indexOfFirst { it.uuid == uuid }.takeIf { it != -1 } } } @@ -234,27 +233,49 @@ private fun MessageListPagedContent( } if (message != null) { - renderPagedChatMessageRow( - message = message, - state = state, - nodeMap = nodeMap, - handlers = handlers, - inSelectionMode = inSelectionMode, - coroutineScope = coroutineScope, - haptics = haptics, - listState = listState, - onShowStatusDialog = onShowStatusDialog, - onShowReactions = onShowReactions, - enableAnimations = enableAnimations, - showUserName = !hasSamePrev, - hasSamePrev = hasSamePrev, - hasSameNext = hasSameNext, - quickEmojis = quickEmojis, - ) - - // Show unread divider after the first unread message - if (state.hasUnreadMessages && unreadDividerIndex == index) { - UnreadMessagesDivider(modifier = if (enableAnimations) Modifier.animateItem() else Modifier) + val isFirstUnread = state.hasUnreadMessages && unreadDividerIndex == index + val itemModifier = if (enableAnimations) Modifier.animateItem() else Modifier + + if (isFirstUnread) { + // Wrap in Column to prevent overlapping of divider and message item + // Apply animation to the container Column once + Column(modifier = itemModifier) { + UnreadMessagesDivider() + renderPagedChatMessageRow( + message = message, + state = state, + nodeMap = nodeMap, + handlers = handlers, + inSelectionMode = inSelectionMode, + coroutineScope = coroutineScope, + haptics = haptics, + listState = listState, + onShowStatusDialog = onShowStatusDialog, + onShowReactions = onShowReactions, + showUserName = !hasSamePrev, + hasSamePrev = hasSamePrev, + hasSameNext = hasSameNext, + quickEmojis = quickEmojis, + ) + } + } else { + renderPagedChatMessageRow( + message = message, + state = state, + nodeMap = nodeMap, + handlers = handlers, + inSelectionMode = inSelectionMode, + coroutineScope = coroutineScope, + haptics = haptics, + listState = listState, + onShowStatusDialog = onShowStatusDialog, + onShowReactions = onShowReactions, + modifier = itemModifier, + showUserName = !hasSamePrev, + hasSamePrev = hasSamePrev, + hasSameNext = hasSameNext, + quickEmojis = quickEmojis, + ) } } } @@ -280,7 +301,7 @@ private fun MessageListPagedContent( @Suppress("LongParameterList") @Composable -private fun LazyItemScope.renderPagedChatMessageRow( +private fun renderPagedChatMessageRow( message: Message, state: MessageListPagedState, nodeMap: Map, @@ -291,7 +312,7 @@ private fun LazyItemScope.renderPagedChatMessageRow( listState: LazyListState, onShowStatusDialog: (Message) -> Unit, onShowReactions: (List) -> Unit, - enableAnimations: Boolean, + modifier: Modifier = Modifier, showUserName: Boolean, hasSamePrev: Boolean, hasSameNext: Boolean, @@ -305,7 +326,7 @@ private fun LazyItemScope.renderPagedChatMessageRow( val node = nodeMap[message.node.num] ?: message.node MessageItem( - modifier = if (enableAnimations) Modifier.animateItem() else Modifier, + modifier = modifier, node = node, ourNode = ourNode, message = message, @@ -341,12 +362,11 @@ private fun LazyItemScope.renderPagedChatMessageRow( onNavigateToOriginalMessage = { coroutineScope.launch { // Note: With pagination, we can't guarantee the original message is loaded - // This is a limitation of pagination - we would need to implement - // a search/jump feature to load and scroll to specific messages - val targetIndex = - (0 until state.messages.itemCount).firstOrNull { index -> - state.messages[index]?.packetId == message.replyId - } + // Optimized: Use snapshot to find index to avoid side-effects during search + val targetIndex = state.messages.itemSnapshotList.items.indexOfFirst { + it.packetId == message.replyId + }.takeIf { it != -1 } + if (targetIndex != null) { listState.animateScrollToItem(index = targetIndex) } @@ -503,7 +523,7 @@ internal fun UnreadMessagesDivider(modifier: Modifier = Modifier) { } @Composable -internal fun MessageStatusDialog( +private fun MessageStatusDialog( message: Message, nodes: List, ourNode: Node?, From 7da4b529c51ab4d3937213d872bbd14e0447308c Mon Sep 17 00:00:00 2001 From: James Rich <2199651+jamesarich@users.noreply.github.com> Date: Sun, 22 Feb 2026 10:51:25 -0600 Subject: [PATCH 02/18] feat(messaging): Optimize message list operations with Paging snapshots This commit optimizes the message screen's performance and stability by leveraging `itemSnapshotList` from the Paging 3 library. This avoids triggering unnecessary page loads when performing operations on the currently loaded items. Key optimizations include: - Finding the first unread message without causing new pages to load. - Looking up the original message for a reply from the snapshot. - Copying and selecting messages now operate on the `itemSnapshotList`, preventing accidental fetches of the entire message history. Additionally, `LazyPagingItems` now includes a `contentType` to improve `LazyColumn` performance and efficiency. A minor function rename from `renderPagedChatMessageRow` to `RenderPagedChatMessageRow` has been made to align with composable function naming conventions. Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com> --- .../meshtastic/feature/messaging/Message.kt | 22 +++++------ .../feature/messaging/MessageListPaged.kt | 39 ++++++++++++------- 2 files changed, 33 insertions(+), 28 deletions(-) diff --git a/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/Message.kt b/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/Message.kt index 6d984e14f3..afbc42c032 100644 --- a/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/Message.kt +++ b/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/Message.kt @@ -226,11 +226,12 @@ fun MessageScreen( var hasPerformedInitialScroll by rememberSaveable(contactKey) { mutableStateOf(false) } // Find the index of the first unread message in the paged list + // Optimized: Use snapshot to avoid triggering paging loads during search val firstUnreadIndex by remember(pagedMessages.itemCount, firstUnreadMessageUuid) { derivedStateOf { firstUnreadMessageUuid?.let { uuid -> - (0 until pagedMessages.itemCount).firstOrNull { index -> pagedMessages[index]?.uuid == uuid } + pagedMessages.itemSnapshotList.indexOfFirst { it?.uuid == uuid }.takeIf { it != -1 } } } } @@ -302,14 +303,11 @@ fun MessageScreen( sharedContact?.let { contact -> SharedContactDialog(contact = contact, onDismiss = { sharedContact = null }) } + // Optimized: Use snapshot to find the original message without triggering loads val originalMessage by remember(replyingToPacketId, pagedMessages.itemCount) { derivedStateOf { - replyingToPacketId?.let { id -> - (0 until pagedMessages.itemCount).firstNotNullOfOrNull { index -> - pagedMessages[index]?.takeIf { it.packetId == id } - } - } + replyingToPacketId?.let { id -> pagedMessages.itemSnapshotList.firstOrNull { it?.packetId == id } } } } @@ -322,9 +320,9 @@ fun MessageScreen( onAction = { action -> when (action) { MessageMenuAction.ClipboardCopy -> { + // Optimized: Use snapshot items to avoid triggering loads val copiedText = - (0 until pagedMessages.itemCount) - .mapNotNull { pagedMessages[it] } + pagedMessages.itemSnapshotList.items .filter { it.uuid in selectedMessageIds.value } .joinToString("\n") { it.text } onEvent(MessageScreenEvent.CopyToClipboard(copiedText)) @@ -333,14 +331,12 @@ fun MessageScreen( MessageMenuAction.Delete -> showDeleteDialog = true MessageMenuAction.Dismiss -> selectedMessageIds.value = emptySet() MessageMenuAction.SelectAll -> { - // Note: Select All is disabled with pagination since we don't have - // access to the full message list. This would need to be reworked - // to select all currently loaded items instead. + // Optimized: Select only currently loaded items to avoid massive page trigger selectedMessageIds.value = if (selectedMessageIds.value.size == pagedMessages.itemCount) { emptySet() } else { - (0 until pagedMessages.itemCount).mapNotNull { pagedMessages[it]?.uuid }.toSet() + pagedMessages.itemSnapshotList.items.map { it.uuid }.toSet() } } } @@ -654,7 +650,7 @@ private fun ActionModeTopBar(selectedCount: Int, onAction: (MessageMenuAction) - /** * The default top app bar for the message screen. * - * @param title The title to display (contact or channel name). + * @param title The title to display (contact or name). * @param channelIndex The index of the current channel, if applicable. * @param mismatchKey True if there's a key mismatch for the current PKC. * @param onNavigateBack Callback for the navigation icon. diff --git a/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/MessageListPaged.kt b/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/MessageListPaged.kt index 7ee2710a4b..41a05b79d8 100644 --- a/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/MessageListPaged.kt +++ b/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/MessageListPaged.kt @@ -53,6 +53,7 @@ import androidx.lifecycle.Lifecycle import androidx.lifecycle.compose.LocalLifecycleOwner import androidx.paging.LoadState import androidx.paging.compose.LazyPagingItems +import androidx.paging.compose.itemContentType import androidx.paging.compose.itemKey import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.FlowPreview @@ -193,11 +194,12 @@ private fun MessageListPagedContent( quickEmojis: List, ) { // Calculate unread divider position using snapshot to avoid side-effects and improve performance + // Optimized: Use full snapshot index to correctly match LazyColumn index range val unreadDividerIndex by remember(state.messages.itemCount, state.firstUnreadMessageUuid) { derivedStateOf { val uuid = state.firstUnreadMessageUuid ?: return@derivedStateOf null - state.messages.itemSnapshotList.items.indexOfFirst { it.uuid == uuid }.takeIf { it != -1 } + state.messages.itemSnapshotList.indexOfFirst { it?.uuid == uuid }.takeIf { it != -1 } } } @@ -211,7 +213,11 @@ private fun MessageListPagedContent( reverseLayout = true, contentPadding = PaddingValues(bottom = 24.dp), ) { - items(count = state.messages.itemCount, key = state.messages.itemKey { it.uuid }) { index -> + items( + count = state.messages.itemCount, + key = state.messages.itemKey { it.uuid }, + contentType = state.messages.itemContentType { "message" }, + ) { index -> val message = state.messages[index] val visuallyPrevMessage = if (index < state.messages.itemCount - 1) state.messages[index + 1] else null val visuallyNextMessage = if (index > 0) state.messages[index - 1] else null @@ -241,7 +247,7 @@ private fun MessageListPagedContent( // Apply animation to the container Column once Column(modifier = itemModifier) { UnreadMessagesDivider() - renderPagedChatMessageRow( + RenderPagedChatMessageRow( message = message, state = state, nodeMap = nodeMap, @@ -259,7 +265,7 @@ private fun MessageListPagedContent( ) } } else { - renderPagedChatMessageRow( + RenderPagedChatMessageRow( message = message, state = state, nodeMap = nodeMap, @@ -284,7 +290,7 @@ private fun MessageListPagedContent( state.messages.apply { when { loadState.append is LoadState.Loading -> { - item(key = "append_loading") { + item(key = "append_loading", contentType = "loading") { Box( modifier = Modifier.fillMaxWidth().padding(16.dp), contentAlignment = Alignment.Center, @@ -301,7 +307,7 @@ private fun MessageListPagedContent( @Suppress("LongParameterList") @Composable -private fun renderPagedChatMessageRow( +private fun RenderPagedChatMessageRow( message: Message, state: MessageListPagedState, nodeMap: Map, @@ -363,9 +369,8 @@ private fun renderPagedChatMessageRow( coroutineScope.launch { // Note: With pagination, we can't guarantee the original message is loaded // Optimized: Use snapshot to find index to avoid side-effects during search - val targetIndex = state.messages.itemSnapshotList.items.indexOfFirst { - it.packetId == message.replyId - }.takeIf { it != -1 } + val targetIndex = + state.messages.itemSnapshotList.indexOfFirst { it?.packetId == message.replyId }.takeIf { it != -1 } if (targetIndex != null) { listState.animateScrollToItem(index = targetIndex) @@ -428,19 +433,23 @@ private fun AutoScrollToBottomPaged( } private fun findFirstVisibleUnreadMessage(messages: LazyPagingItems, visibleIndex: Int): Message? { + val snapshot = messages.itemSnapshotList + if (visibleIndex >= snapshot.size) return null val firstVisibleUnreadIndex = - (visibleIndex until messages.itemCount).firstOrNull { i -> - val msg = messages[i] + (visibleIndex until snapshot.size).firstOrNull { i -> + val msg = snapshot[i] msg != null && !msg.read && !msg.fromLocal } - return firstVisibleUnreadIndex?.let { messages[it] } + return firstVisibleUnreadIndex?.let { snapshot[it] } } -private fun findLastUnreadMessageIndex(messages: LazyPagingItems): Int? = - (0 until messages.itemCount).lastOrNull { i -> - val msg = messages[i] +private fun findLastUnreadMessageIndex(messages: LazyPagingItems): Int? { + val snapshot = messages.itemSnapshotList + return (0 until snapshot.size).lastOrNull { i -> + val msg = snapshot[i] msg != null && !msg.read && !msg.fromLocal } +} @OptIn(FlowPreview::class) @Composable From 12009ee4b74fad26b108a0c7ca691bda922da4a5 Mon Sep 17 00:00:00 2001 From: James Rich <2199651+jamesarich@users.noreply.github.com> Date: Sun, 22 Feb 2026 11:04:25 -0600 Subject: [PATCH 03/18] perf(messaging): Optimize MessageList recomposition and performance This commit introduces several performance optimizations to the messaging feature to reduce jank and unnecessary recompositions. - The `MessageListHandlers` and `MessageListPagedState` data classes are now marked as `@Stable` to help the Compose compiler avoid unnecessary recompositions. - The use of `derivedStateOf` has been removed for simple calculations that are dependent on list size changes, such as finding the unread divider index and counting remote messages. - `LazyPagingItems.peek()` is now used to access adjacent items in the list. This prevents the premature fetching of pages and reduces potential performance overhead. Additionally, a minor formatting change was made in `app/build.gradle.kts`. Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com> --- app/build.gradle.kts | 6 ++-- .../feature/messaging/MessageListPaged.kt | 36 +++++++++---------- 2 files changed, 19 insertions(+), 23 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 7503e1f7b0..bb527ad341 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -188,11 +188,9 @@ secrets { androidComponents { onVariants(selector().withBuildType("debug")) { variant -> - variant.flavorName?.let { flavor -> - variant.applicationId = "com.geeksville.mesh.$flavor.debug" - } + variant.flavorName?.let { flavor -> variant.applicationId = "com.geeksville.mesh.$flavor.debug" } } - + onVariants(selector().withBuildType("release")) { variant -> if (variant.flavorName == "google") { val variantNameCapped = variant.name.replaceFirstChar { it.uppercase() } diff --git a/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/MessageListPaged.kt b/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/MessageListPaged.kt index 41a05b79d8..6c330878aa 100644 --- a/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/MessageListPaged.kt +++ b/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/MessageListPaged.kt @@ -35,6 +35,7 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.MutableState +import androidx.compose.runtime.Stable import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf @@ -71,6 +72,7 @@ import org.meshtastic.core.strings.new_messages_below import org.meshtastic.feature.messaging.component.MessageItem import org.meshtastic.feature.messaging.component.ReactionDialog +@Stable internal data class MessageListHandlers( val onUnreadChanged: (Long, Long) -> Unit, val onSendReaction: (String, Int) -> Unit, @@ -80,6 +82,7 @@ internal data class MessageListHandlers( val onReply: (Message?) -> Unit, ) +@Stable internal data class MessageListPagedState( val nodes: List, val ourNode: Node?, @@ -194,13 +197,11 @@ private fun MessageListPagedContent( quickEmojis: List, ) { // Calculate unread divider position using snapshot to avoid side-effects and improve performance - // Optimized: Use full snapshot index to correctly match LazyColumn index range - val unreadDividerIndex by + // Optimized: Avoid derivedStateOf for simple calculations that are bound to list size changes + val unreadDividerIndex = remember(state.messages.itemCount, state.firstUnreadMessageUuid) { - derivedStateOf { - val uuid = state.firstUnreadMessageUuid ?: return@derivedStateOf null - state.messages.itemSnapshotList.indexOfFirst { it?.uuid == uuid }.takeIf { it != -1 } - } + val uuid = state.firstUnreadMessageUuid ?: return@remember null + state.messages.itemSnapshotList.indexOfFirst { it?.uuid == uuid }.takeIf { it != -1 } } // Disable animations during scroll to prevent jank/stutter @@ -219,8 +220,10 @@ private fun MessageListPagedContent( contentType = state.messages.itemContentType { "message" }, ) { index -> val message = state.messages[index] - val visuallyPrevMessage = if (index < state.messages.itemCount - 1) state.messages[index + 1] else null - val visuallyNextMessage = if (index > 0) state.messages[index - 1] else null + // Optimized: Use peek() to prevent premature fetching of adjacent items + val visuallyPrevMessage = + if (index < state.messages.itemCount - 1) state.messages.peek(index + 1) else null + val visuallyNextMessage = if (index > 0) state.messages.peek(index - 1) else null val hasSamePrev = if (message != null && visuallyPrevMessage != null) { @@ -326,9 +329,7 @@ private fun RenderPagedChatMessageRow( ) { val ourNode = state.ourNode ?: return val selected by - remember(message.uuid, state.selectedIds.value) { - derivedStateOf { state.selectedIds.value.contains(message.uuid) } - } + remember(message.uuid, state.selectedIds) { derivedStateOf { state.selectedIds.value.contains(message.uuid) } } val node = nodeMap[message.node.num] ?: message.node MessageItem( @@ -480,9 +481,8 @@ private fun UpdateUnreadCountPaged( // Track remote message count to restart effect when remote messages change // This fixes race condition when sending/receiving messages during debounce period - // Optimized: Use itemSnapshotList instead of iterating through indices - val remoteMessageCount by - remember(messages.itemCount) { derivedStateOf { messages.itemSnapshotList.items.count { !it.fromLocal } } } + // Optimized: Use itemSnapshotList instead of iterating through indices. Avoid unnecessary derivedStateOf + val remoteMessageCount = remember(messages.itemCount) { messages.itemSnapshotList.items.count { !it.fromLocal } } // Mark messages as read after debounce period // Handles both scrolling cases and when all unread messages are visible without scrolling @@ -541,12 +541,10 @@ private fun MessageStatusDialog( onDismiss: () -> Unit, ) { val (title, text) = message.getStatusStringRes() - val relayNodeName by + val relayNodeName = remember(message.relayNode, nodes, ourNode) { - derivedStateOf { - message.relayNode?.let { relayNodeId -> - Packet.getRelayNode(relayNodeId, nodes, ourNode?.num)?.user?.long_name - } + message.relayNode?.let { relayNodeId -> + Packet.getRelayNode(relayNodeId, nodes, ourNode?.num)?.user?.long_name } } DeliveryInfo( From 51faaa71faaa82d0ff46814287ca3d9cf1c75d45 Mon Sep 17 00:00:00 2001 From: James Rich <2199651+jamesarich@users.noreply.github.com> Date: Sun, 22 Feb 2026 11:14:16 -0600 Subject: [PATCH 04/18] refactor(messaging): Replace itemSnapshotList with direct paged list access This commit refactors the messaging feature to remove the usage of `PagingData`'s `itemSnapshotList`. Direct access to the `LazyPagingItems` collection is now used, which simplifies the code and resolves an issue where the snapshot could become stale, leading to incorrect behavior. Key changes include: - Finding the first unread message, the message to reply to, and selected messages for clipboard operations now iterate the `LazyPagingItems` directly. - The "Select All" functionality is now aligned with the currently loaded items in the `LazyPagingItems`. - Several `derivedStateOf` usages have been refined to trigger recalculations only when necessary. - A minor KDoc fix in `MessageTopAppBar` clarifies the `title` parameter. In the `FirmwareReleaseRepository`, logic has been added to explicitly emit `null` if no cached firmware release is found, ensuring the UI receives a clear signal. Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com> --- .../repository/FirmwareReleaseRepository.kt | 8 +++-- .../meshtastic/feature/messaging/Message.kt | 16 ++++----- .../feature/messaging/MessageListPaged.kt | 35 ++++++++++--------- 3 files changed, 31 insertions(+), 28 deletions(-) diff --git a/core/data/src/main/kotlin/org/meshtastic/core/data/repository/FirmwareReleaseRepository.kt b/core/data/src/main/kotlin/org/meshtastic/core/data/repository/FirmwareReleaseRepository.kt index b7c1016ead..67ccdc091c 100644 --- a/core/data/src/main/kotlin/org/meshtastic/core/data/repository/FirmwareReleaseRepository.kt +++ b/core/data/src/main/kotlin/org/meshtastic/core/data/repository/FirmwareReleaseRepository.kt @@ -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. diff --git a/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/Message.kt b/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/Message.kt index afbc42c032..0c54cbf288 100644 --- a/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/Message.kt +++ b/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/Message.kt @@ -226,12 +226,11 @@ fun MessageScreen( var hasPerformedInitialScroll by rememberSaveable(contactKey) { mutableStateOf(false) } // Find the index of the first unread message in the paged list - // Optimized: Use snapshot to avoid triggering paging loads during search val firstUnreadIndex by remember(pagedMessages.itemCount, firstUnreadMessageUuid) { derivedStateOf { firstUnreadMessageUuid?.let { uuid -> - pagedMessages.itemSnapshotList.indexOfFirst { it?.uuid == uuid }.takeIf { it != -1 } + (0 until pagedMessages.itemCount).firstOrNull { index -> pagedMessages[index]?.uuid == uuid } } } } @@ -303,7 +302,6 @@ fun MessageScreen( sharedContact?.let { contact -> SharedContactDialog(contact = contact, onDismiss = { sharedContact = null }) } - // Optimized: Use snapshot to find the original message without triggering loads val originalMessage by remember(replyingToPacketId, pagedMessages.itemCount) { derivedStateOf { @@ -320,9 +318,9 @@ fun MessageScreen( onAction = { action -> when (action) { MessageMenuAction.ClipboardCopy -> { - // Optimized: Use snapshot items to avoid triggering loads val copiedText = - pagedMessages.itemSnapshotList.items + (0 until pagedMessages.itemCount) + .mapNotNull { pagedMessages[it] } .filter { it.uuid in selectedMessageIds.value } .joinToString("\n") { it.text } onEvent(MessageScreenEvent.CopyToClipboard(copiedText)) @@ -331,12 +329,14 @@ fun MessageScreen( MessageMenuAction.Delete -> showDeleteDialog = true MessageMenuAction.Dismiss -> selectedMessageIds.value = emptySet() MessageMenuAction.SelectAll -> { - // Optimized: Select only currently loaded items to avoid massive page trigger + // Note: Select All is disabled with pagination since we don't have + // access to the full message list. This would need to be reworked + // to select all currently loaded items instead. selectedMessageIds.value = if (selectedMessageIds.value.size == pagedMessages.itemCount) { emptySet() } else { - pagedMessages.itemSnapshotList.items.map { it.uuid }.toSet() + (0 until pagedMessages.itemCount).mapNotNull { pagedMessages[it]?.uuid }.toSet() } } } @@ -650,7 +650,7 @@ private fun ActionModeTopBar(selectedCount: Int, onAction: (MessageMenuAction) - /** * The default top app bar for the message screen. * - * @param title The title to display (contact or name). + * @param title The title to display (contact or channel name). * @param channelIndex The index of the current channel, if applicable. * @param mismatchKey True if there's a key mismatch for the current PKC. * @param onNavigateBack Callback for the navigation icon. diff --git a/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/MessageListPaged.kt b/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/MessageListPaged.kt index 6c330878aa..1d2bea345f 100644 --- a/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/MessageListPaged.kt +++ b/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/MessageListPaged.kt @@ -35,7 +35,6 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.MutableState -import androidx.compose.runtime.Stable import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf @@ -72,7 +71,6 @@ import org.meshtastic.core.strings.new_messages_below import org.meshtastic.feature.messaging.component.MessageItem import org.meshtastic.feature.messaging.component.ReactionDialog -@Stable internal data class MessageListHandlers( val onUnreadChanged: (Long, Long) -> Unit, val onSendReaction: (String, Int) -> Unit, @@ -82,7 +80,6 @@ internal data class MessageListHandlers( val onReply: (Message?) -> Unit, ) -@Stable internal data class MessageListPagedState( val nodes: List, val ourNode: Node?, @@ -197,11 +194,13 @@ private fun MessageListPagedContent( quickEmojis: List, ) { // Calculate unread divider position using snapshot to avoid side-effects and improve performance - // Optimized: Avoid derivedStateOf for simple calculations that are bound to list size changes - val unreadDividerIndex = + // Optimized: Use full snapshot index to correctly match LazyColumn index range + val unreadDividerIndex by remember(state.messages.itemCount, state.firstUnreadMessageUuid) { - val uuid = state.firstUnreadMessageUuid ?: return@remember null - state.messages.itemSnapshotList.indexOfFirst { it?.uuid == uuid }.takeIf { it != -1 } + derivedStateOf { + val uuid = state.firstUnreadMessageUuid ?: return@derivedStateOf null + state.messages.itemSnapshotList.indexOfFirst { it?.uuid == uuid }.takeIf { it != -1 } + } } // Disable animations during scroll to prevent jank/stutter @@ -220,10 +219,8 @@ private fun MessageListPagedContent( contentType = state.messages.itemContentType { "message" }, ) { index -> val message = state.messages[index] - // Optimized: Use peek() to prevent premature fetching of adjacent items - val visuallyPrevMessage = - if (index < state.messages.itemCount - 1) state.messages.peek(index + 1) else null - val visuallyNextMessage = if (index > 0) state.messages.peek(index - 1) else null + val visuallyPrevMessage = if (index < state.messages.itemCount - 1) state.messages[index + 1] else null + val visuallyNextMessage = if (index > 0) state.messages[index - 1] else null val hasSamePrev = if (message != null && visuallyPrevMessage != null) { @@ -329,7 +326,8 @@ private fun RenderPagedChatMessageRow( ) { val ourNode = state.ourNode ?: return val selected by - remember(message.uuid, state.selectedIds) { derivedStateOf { state.selectedIds.value.contains(message.uuid) } } + remember(message.uuid, state.selectedIds.value) { + derivedStateOf { state.selectedIds.value.contains(message.uuid) } } val node = nodeMap[message.node.num] ?: message.node MessageItem( @@ -481,8 +479,9 @@ private fun UpdateUnreadCountPaged( // Track remote message count to restart effect when remote messages change // This fixes race condition when sending/receiving messages during debounce period - // Optimized: Use itemSnapshotList instead of iterating through indices. Avoid unnecessary derivedStateOf - val remoteMessageCount = remember(messages.itemCount) { messages.itemSnapshotList.items.count { !it.fromLocal } } + // Optimized: Use itemSnapshotList instead of iterating through indices + val remoteMessageCount by + remember(messages.itemCount) { derivedStateOf { messages.itemSnapshotList.items.count { !it.fromLocal } } } // Mark messages as read after debounce period // Handles both scrolling cases and when all unread messages are visible without scrolling @@ -541,10 +540,12 @@ private fun MessageStatusDialog( onDismiss: () -> Unit, ) { val (title, text) = message.getStatusStringRes() - val relayNodeName = + val relayNodeName by remember(message.relayNode, nodes, ourNode) { - message.relayNode?.let { relayNodeId -> - Packet.getRelayNode(relayNodeId, nodes, ourNode?.num)?.user?.long_name + derivedStateOf { + message.relayNode?.let { relayNodeId -> + Packet.getRelayNode(relayNodeId, nodes, ourNode?.num)?.user?.long_name + } } } DeliveryInfo( From e5bb03dcd1d3064cac27fa4bcfd491e22294dd41 Mon Sep 17 00:00:00 2001 From: James Rich <2199651+jamesarich@users.noreply.github.com> Date: Sun, 22 Feb 2026 11:35:36 -0600 Subject: [PATCH 05/18] refactor(node): Centralize node detail logic with GetNodeDetailsUseCase This commit introduces a `GetNodeDetailsUseCase` to encapsulate and centralize the business logic for fetching and assembling all data required for the node detail screen. This significantly cleans up the `NodeDetailViewModel` and `MetricsViewModel`, removing redundant data-fetching code and improving maintainability. The new use case is responsible for combining flows from multiple repositories (`NodeRepository`, `MeshLogRepository`, `RadioConfigRepository`, etc.) to build a comprehensive `NodeDetailUiState`. This state includes node identity, metrics, configuration, hardware details, and available log types. Key changes: - **`GetNodeDetailsUseCase`**: A new use case that serves as a single source of truth for node detail data. - **`NodeDetailViewModel`**: Refactored to use `GetNodeDetailsUseCase`, drastically simplifying its implementation. State management is now driven directly by the use case output. - **`MetricsViewModel`**: Also refactored to consume `GetNodeDetailsUseCase`, eliminating its own complex data-fetching and state-building logic. It now focuses solely on view-specific concerns like time frame filtering and UI interactions. - **`NodeDetailScreen.kt`**: The `viewModel.start(nodeId)` call is now wrapped in a `LaunchedEffect` to ensure it's executed correctly based on the `nodeId`. Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com> --- .../feature/messaging/MessageListPaged.kt | 3 +- .../feature/node/detail/NodeDetailScreen.kt | 2 +- .../node/detail/NodeDetailViewModel.kt | 189 +-------- .../domain/usecase/GetNodeDetailsUseCase.kt | 239 +++++++++++ .../feature/node/metrics/MetricsViewModel.kt | 373 +++++------------- 5 files changed, 347 insertions(+), 459 deletions(-) create mode 100644 feature/node/src/main/kotlin/org/meshtastic/feature/node/domain/usecase/GetNodeDetailsUseCase.kt diff --git a/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/MessageListPaged.kt b/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/MessageListPaged.kt index 1d2bea345f..41a05b79d8 100644 --- a/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/MessageListPaged.kt +++ b/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/MessageListPaged.kt @@ -327,7 +327,8 @@ private fun RenderPagedChatMessageRow( val ourNode = state.ourNode ?: return val selected by remember(message.uuid, state.selectedIds.value) { - derivedStateOf { state.selectedIds.value.contains(message.uuid) } } + derivedStateOf { state.selectedIds.value.contains(message.uuid) } + } val node = nodeMap[message.node.num] ?: message.node MessageItem( diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/detail/NodeDetailScreen.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/detail/NodeDetailScreen.kt index c0a380342e..875129456a 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/detail/NodeDetailScreen.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/detail/NodeDetailScreen.kt @@ -100,7 +100,7 @@ fun NodeDetailScreen( onNavigate: (Route) -> Unit = {}, onNavigateUp: () -> Unit = {}, ) { - viewModel.start(nodeId) + LaunchedEffect(nodeId) { viewModel.start(nodeId) } val snackbarHostState = remember { SnackbarHostState() } LaunchedEffect(Unit) { diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/detail/NodeDetailViewModel.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/detail/NodeDetailViewModel.kt index f903d8c513..cdafba73fc 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/detail/NodeDetailViewModel.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/detail/NodeDetailViewModel.kt @@ -22,7 +22,6 @@ import androidx.lifecycle.viewModelScope import androidx.navigation.toRoute import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.SharingStarted @@ -31,38 +30,18 @@ import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flowOf -import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch -import org.meshtastic.core.data.repository.DeviceHardwareRepository -import org.meshtastic.core.data.repository.FirmwareReleaseRepository -import org.meshtastic.core.data.repository.MeshLogRepository -import org.meshtastic.core.data.repository.NodeRepository -import org.meshtastic.core.data.repository.RadioConfigRepository -import org.meshtastic.core.database.entity.FirmwareRelease -import org.meshtastic.core.database.entity.MeshLog import org.meshtastic.core.database.model.Node import org.meshtastic.core.model.DataPacket -import org.meshtastic.core.model.MyNodeInfo -import org.meshtastic.core.model.util.hasValidEnvironmentMetrics -import org.meshtastic.core.model.util.isDirectSignal import org.meshtastic.core.navigation.NodesRoutes import org.meshtastic.core.service.ServiceAction import org.meshtastic.core.service.ServiceRepository -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.fallback_node_name -import org.meshtastic.core.strings.getString -import org.meshtastic.core.ui.util.toPosition import org.meshtastic.feature.node.component.NodeMenuAction +import org.meshtastic.feature.node.domain.usecase.GetNodeDetailsUseCase import org.meshtastic.feature.node.metrics.EnvironmentMetricsState import org.meshtastic.feature.node.model.LogsType import org.meshtastic.feature.node.model.MetricsState -import org.meshtastic.proto.Config -import org.meshtastic.proto.DeviceProfile -import org.meshtastic.proto.FirmwareEdition -import org.meshtastic.proto.MeshPacket -import org.meshtastic.proto.PortNum -import org.meshtastic.proto.Telemetry import javax.inject.Inject /** @@ -76,6 +55,7 @@ import javax.inject.Inject * @property lastTracerouteTime Timestamp of the last successful traceroute request. * @property lastRequestNeighborsTime Timestamp of the last successful neighbor info request. */ +@androidx.compose.runtime.Stable data class NodeDetailUiState( val node: Node? = null, val ourNode: Node? = null, @@ -93,17 +73,12 @@ data class NodeDetailUiState( @HiltViewModel class NodeDetailViewModel @Inject -@Suppress("LongParameterList") constructor( savedStateHandle: SavedStateHandle, - private val nodeRepository: NodeRepository, private val nodeManagementActions: NodeManagementActions, private val nodeRequestActions: NodeRequestActions, - private val meshLogRepository: MeshLogRepository, - private val radioConfigRepository: RadioConfigRepository, - private val deviceHardwareRepository: DeviceHardwareRepository, - private val firmwareReleaseRepository: FirmwareReleaseRepository, private val serviceRepository: ServiceRepository, + private val getNodeDetailsUseCase: GetNodeDetailsUseCase, ) : ViewModel() { private val nodeIdFromRoute: Int? = @@ -120,166 +95,10 @@ constructor( activeNodeId .flatMapLatest { nodeId -> if (nodeId == null) return@flatMapLatest flowOf(NodeDetailUiState()) - buildUiStateFlow(nodeId) + getNodeDetailsUseCase(nodeId) } .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), NodeDetailUiState()) - @Suppress("LongMethod", "CyclomaticComplexMethod") - private fun buildUiStateFlow(nodeId: Int): Flow { - val nodeFlow = - nodeRepository.nodeDBbyNum - .map { it[nodeId] ?: Node.createFallback(nodeId, getString(Res.string.fallback_node_name)) } - .distinctUntilChanged() - - // 1. Logs & Metrics Data (fetches telemetry, packets, paxcount, and response history) - val metricsLogsFlow = - combine( - meshLogRepository.getTelemetryFrom(nodeId), - meshLogRepository.getMeshPacketsFrom(nodeId), - meshLogRepository.getMeshPacketsFrom(nodeId, PortNum.POSITION_APP.value), - meshLogRepository.getLogsFrom(nodeId, PortNum.PAXCOUNTER_APP.value), - meshLogRepository.getLogsFrom(nodeId, PortNum.TRACEROUTE_APP.value), - meshLogRepository.getLogsFrom(nodeId, PortNum.NEIGHBORINFO_APP.value), - ) { args: Array> -> - @Suppress("UNCHECKED_CAST") - LogsGroup( - telemetry = args[0] as List, - packets = args[1] as List, - posPackets = args[2] as List, - pax = args[3] as List, - trRes = args[4] as List, - niRes = args[5] as List, - ) - } - - // 2. Identity & Config (local device info and radio profile) - val identityFlow = - combine(nodeRepository.ourNodeInfo, nodeRepository.myNodeInfo, radioConfigRepository.deviceProfileFlow) { - ourNode, - myInfo, - profile, - -> - IdentityGroup(ourNode, myInfo?.toMyNodeInfo(), profile) - } - - // 3. Metadata & Request Timestamps (firmware versions and last request times) - val metadataFlow = - combine( - meshLogRepository.getMyNodeInfo().map { it?.firmware_edition }.distinctUntilChanged(), - firmwareReleaseRepository.stableRelease, - firmwareReleaseRepository.alphaRelease, - nodeRequestActions.lastTracerouteTimes.map { it[nodeId] }, - nodeRequestActions.lastRequestNeighborTimes.map { it[nodeId] }, - ) { args: Array -> - MetadataGroup( - edition = args[0] as? FirmwareEdition, - stable = args[1] as? FirmwareRelease, - alpha = args[2] as? FirmwareRelease, - trTime = args[3] as? Long, - niTime = args[4] as? Long, - ) - } - - // 4. Requests History (tracking traceroute and neighbor info requests sent from this device) - val requestsFlow = - combine( - meshLogRepository.getRequestLogs(nodeId, PortNum.TRACEROUTE_APP), - meshLogRepository.getRequestLogs(nodeId, PortNum.NEIGHBORINFO_APP), - ) { trReqs, niReqs -> - trReqs to niReqs - } - - // Assemble final UI state - return combine(nodeFlow, metricsLogsFlow, identityFlow, metadataFlow, requestsFlow) { - node, - logs, - identity, - metadata, - requests, - -> - val (trReqs, niReqs) = requests - val isLocal = node.num == identity.ourNode?.num - val pioEnv = if (isLocal) identity.myInfo?.pioEnv else null - val hw = deviceHardwareRepository.getDeviceHardwareByModel(node.user.hw_model.value, pioEnv).getOrNull() - - val moduleConfig = identity.profile.module_config - val displayUnits = identity.profile.config?.display?.units ?: Config.DisplayConfig.DisplayUnits.METRIC - - val metricsState = - MetricsState( - node = node, - isLocal = isLocal, - deviceHardware = hw, - reportedTarget = pioEnv, - isManaged = identity.profile.config?.security?.is_managed ?: false, - isFahrenheit = - moduleConfig?.telemetry?.environment_display_fahrenheit == true || - (displayUnits == Config.DisplayConfig.DisplayUnits.IMPERIAL), - displayUnits = displayUnits, - deviceMetrics = logs.telemetry.filter { it.device_metrics != null }, - powerMetrics = logs.telemetry.filter { it.power_metrics != null }, - hostMetrics = logs.telemetry.filter { it.host_metrics != null }, - signalMetrics = logs.packets.filter { it.isDirectSignal() }, - positionLogs = logs.posPackets.mapNotNull { it.toPosition() }, - paxMetrics = logs.pax, - tracerouteRequests = trReqs, - tracerouteResults = logs.trRes, - neighborInfoRequests = niReqs, - neighborInfoResults = logs.niRes, - firmwareEdition = metadata.edition, - latestStableFirmware = metadata.stable ?: FirmwareRelease(), - latestAlphaFirmware = metadata.alpha ?: FirmwareRelease(), - ) - - val environmentState = - EnvironmentMetricsState(environmentMetrics = logs.telemetry.filter { it.hasValidEnvironmentMetrics() }) - - val availableLogs = buildSet { - if (metricsState.hasDeviceMetrics()) add(LogsType.DEVICE) - if (metricsState.hasPositionLogs()) { - add(LogsType.NODE_MAP) - add(LogsType.POSITIONS) - } - if (environmentState.hasEnvironmentMetrics()) add(LogsType.ENVIRONMENT) - if (metricsState.hasSignalMetrics()) add(LogsType.SIGNAL) - if (metricsState.hasPowerMetrics()) add(LogsType.POWER) - if (metricsState.hasTracerouteLogs()) add(LogsType.TRACEROUTE) - if (metricsState.hasNeighborInfoLogs()) add(LogsType.NEIGHBOR_INFO) - if (metricsState.hasHostMetrics()) add(LogsType.HOST) - if (metricsState.hasPaxMetrics()) add(LogsType.PAX) - } - - NodeDetailUiState( - node = node, - ourNode = identity.ourNode, - metricsState = metricsState, - environmentState = environmentState, - availableLogs = availableLogs, - lastTracerouteTime = metadata.trTime, - lastRequestNeighborsTime = metadata.niTime, - ) - } - } - - private data class LogsGroup( - val telemetry: List, - val packets: List, - val posPackets: List, - val pax: List, - val trRes: List, - val niRes: List, - ) - - private data class IdentityGroup(val ourNode: Node?, val myInfo: MyNodeInfo?, val profile: DeviceProfile) - - private data class MetadataGroup( - val edition: FirmwareEdition?, - val stable: FirmwareRelease?, - val alpha: FirmwareRelease?, - val trTime: Long?, - val niTime: Long?, - ) - val effects: SharedFlow = nodeRequestActions.effects fun start(nodeId: Int) { diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/domain/usecase/GetNodeDetailsUseCase.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/domain/usecase/GetNodeDetailsUseCase.kt new file mode 100644 index 0000000000..fe557c2586 --- /dev/null +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/domain/usecase/GetNodeDetailsUseCase.kt @@ -0,0 +1,239 @@ +/* + * 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 . + */ +package org.meshtastic.feature.node.domain.usecase + +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.flatMapLatest +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.onStart +import org.meshtastic.core.data.repository.DeviceHardwareRepository +import org.meshtastic.core.data.repository.FirmwareReleaseRepository +import org.meshtastic.core.data.repository.MeshLogRepository +import org.meshtastic.core.data.repository.NodeRepository +import org.meshtastic.core.data.repository.RadioConfigRepository +import org.meshtastic.core.database.entity.FirmwareRelease +import org.meshtastic.core.database.entity.MeshLog +import org.meshtastic.core.database.model.Node +import org.meshtastic.core.model.MyNodeInfo +import org.meshtastic.core.model.util.hasValidEnvironmentMetrics +import org.meshtastic.core.model.util.isDirectSignal +import org.meshtastic.core.strings.Res +import org.meshtastic.core.strings.fallback_node_name +import org.meshtastic.core.strings.getString +import org.meshtastic.core.ui.util.toPosition +import org.meshtastic.feature.node.detail.NodeDetailUiState +import org.meshtastic.feature.node.detail.NodeRequestActions +import org.meshtastic.feature.node.metrics.EnvironmentMetricsState +import org.meshtastic.feature.node.model.LogsType +import org.meshtastic.feature.node.model.MetricsState +import org.meshtastic.proto.Config +import org.meshtastic.proto.DeviceProfile +import org.meshtastic.proto.FirmwareEdition +import org.meshtastic.proto.MeshPacket +import org.meshtastic.proto.PortNum +import org.meshtastic.proto.Telemetry +import javax.inject.Inject + +class GetNodeDetailsUseCase +@Inject +constructor( + private val nodeRepository: NodeRepository, + private val meshLogRepository: MeshLogRepository, + private val radioConfigRepository: RadioConfigRepository, + private val deviceHardwareRepository: DeviceHardwareRepository, + private val firmwareReleaseRepository: FirmwareReleaseRepository, + private val nodeRequestActions: NodeRequestActions, +) { + + @OptIn(ExperimentalCoroutinesApi::class) + @Suppress("LongMethod", "CyclomaticComplexMethod") + operator fun invoke(nodeId: Int): Flow = + nodeRepository.effectiveLogNodeId(nodeId).flatMapLatest { effectiveNodeId -> + buildFlow(nodeId, effectiveNodeId) + } + + @Suppress("LongMethod", "CyclomaticComplexMethod") + private fun buildFlow(nodeId: Int, effectiveNodeId: Int): Flow { + val nodeFlow = + nodeRepository.nodeDBbyNum + .map { it[nodeId] ?: Node.createFallback(nodeId, getString(Res.string.fallback_node_name)) } + .distinctUntilChanged() + + // 1. Logs & Metrics Data + val metricsLogsFlow = + combine( + meshLogRepository.getTelemetryFrom(effectiveNodeId).onStart { emit(emptyList()) }, + meshLogRepository.getMeshPacketsFrom(effectiveNodeId).onStart { emit(emptyList()) }, + meshLogRepository.getMeshPacketsFrom(effectiveNodeId, PortNum.POSITION_APP.value).onStart { + emit(emptyList()) + }, + meshLogRepository.getLogsFrom(effectiveNodeId, PortNum.PAXCOUNTER_APP.value).onStart { + emit(emptyList()) + }, + meshLogRepository.getLogsFrom(effectiveNodeId, PortNum.TRACEROUTE_APP.value).onStart { + emit(emptyList()) + }, + meshLogRepository.getLogsFrom(effectiveNodeId, PortNum.NEIGHBORINFO_APP.value).onStart { + emit(emptyList()) + }, + ) { args: Array> -> + @Suppress("UNCHECKED_CAST") + LogsGroup( + telemetry = args[0] as List, + packets = args[1] as List, + posPackets = args[2] as List, + pax = args[3] as List, + trRes = args[4] as List, + niRes = args[5] as List, + ) + } + + // 2. Identity & Config + val identityFlow = + combine( + nodeRepository.ourNodeInfo, + nodeRepository.myNodeInfo, + radioConfigRepository.deviceProfileFlow.onStart { emit(DeviceProfile()) }, + ) { ourNode, myInfo, profile -> + IdentityGroup(ourNode, myInfo?.toMyNodeInfo(), profile) + } + + // 3. Metadata & Request Timestamps + val metadataFlow = + combine( + meshLogRepository + .getMyNodeInfo() + .map { it?.firmware_edition } + .distinctUntilChanged() + .onStart { emit(null) }, + firmwareReleaseRepository.stableRelease, + firmwareReleaseRepository.alphaRelease, + nodeRequestActions.lastTracerouteTimes.map { it[nodeId] }, + nodeRequestActions.lastRequestNeighborTimes.map { it[nodeId] }, + ) { args: Array -> + MetadataGroup( + edition = args[0] as? FirmwareEdition, + stable = args[1] as? FirmwareRelease, + alpha = args[2] as? FirmwareRelease, + trTime = args[3] as? Long, + niTime = args[4] as? Long, + ) + } + + // 4. Requests History (we still query request logs by the target nodeId) + val requestsFlow = + combine( + meshLogRepository.getRequestLogs(nodeId, PortNum.TRACEROUTE_APP).onStart { emit(emptyList()) }, + meshLogRepository.getRequestLogs(nodeId, PortNum.NEIGHBORINFO_APP).onStart { emit(emptyList()) }, + ) { trReqs, niReqs -> + trReqs to niReqs + } + + // Assemble final UI state + return combine(nodeFlow, metricsLogsFlow, identityFlow, metadataFlow, requestsFlow) { + node, + logs, + identity, + metadata, + requests, + -> + val (trReqs, niReqs) = requests + val isLocal = node.num == identity.ourNode?.num + val pioEnv = if (isLocal) identity.myInfo?.pioEnv else null + val hw = deviceHardwareRepository.getDeviceHardwareByModel(node.user.hw_model.value, pioEnv).getOrNull() + + val moduleConfig = identity.profile.module_config + val displayUnits = identity.profile.config?.display?.units ?: Config.DisplayConfig.DisplayUnits.METRIC + + val metricsState = + MetricsState( + node = node, + isLocal = isLocal, + deviceHardware = hw, + reportedTarget = pioEnv, + isManaged = identity.profile.config?.security?.is_managed ?: false, + isFahrenheit = + moduleConfig?.telemetry?.environment_display_fahrenheit == true || + (displayUnits == Config.DisplayConfig.DisplayUnits.IMPERIAL), + displayUnits = displayUnits, + deviceMetrics = logs.telemetry.filter { it.device_metrics != null }, + powerMetrics = logs.telemetry.filter { it.power_metrics != null }, + hostMetrics = logs.telemetry.filter { it.host_metrics != null }, + signalMetrics = logs.packets.filter { it.isDirectSignal() }, + positionLogs = logs.posPackets.mapNotNull { it.toPosition() }, + paxMetrics = logs.pax, + tracerouteRequests = trReqs, + tracerouteResults = logs.trRes, + neighborInfoRequests = niReqs, + neighborInfoResults = logs.niRes, + firmwareEdition = metadata.edition, + latestStableFirmware = metadata.stable ?: FirmwareRelease(), + latestAlphaFirmware = metadata.alpha ?: FirmwareRelease(), + ) + + val environmentState = + EnvironmentMetricsState(environmentMetrics = logs.telemetry.filter { it.hasValidEnvironmentMetrics() }) + + val availableLogs = buildSet { + if (metricsState.hasDeviceMetrics()) add(LogsType.DEVICE) + if (metricsState.hasPositionLogs()) { + add(LogsType.NODE_MAP) + add(LogsType.POSITIONS) + } + if (environmentState.hasEnvironmentMetrics()) add(LogsType.ENVIRONMENT) + if (metricsState.hasSignalMetrics()) add(LogsType.SIGNAL) + if (metricsState.hasPowerMetrics()) add(LogsType.POWER) + if (metricsState.hasTracerouteLogs()) add(LogsType.TRACEROUTE) + if (metricsState.hasNeighborInfoLogs()) add(LogsType.NEIGHBOR_INFO) + if (metricsState.hasHostMetrics()) add(LogsType.HOST) + if (metricsState.hasPaxMetrics()) add(LogsType.PAX) + } + + NodeDetailUiState( + node = node, + ourNode = identity.ourNode, + metricsState = metricsState, + environmentState = environmentState, + availableLogs = availableLogs, + lastTracerouteTime = metadata.trTime, + lastRequestNeighborsTime = metadata.niTime, + ) + } + } + + private data class LogsGroup( + val telemetry: List, + val packets: List, + val posPackets: List, + val pax: List, + val trRes: List, + val niRes: List, + ) + + private data class IdentityGroup(val ourNode: Node?, val myInfo: MyNodeInfo?, val profile: DeviceProfile) + + private data class MetadataGroup( + val edition: FirmwareEdition?, + val stable: FirmwareRelease?, + val alpha: FirmwareRelease?, + val trTime: Long?, + val niTime: Long?, + ) +} diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/MetricsViewModel.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/MetricsViewModel.kt index ffd5576940..9db4b3628f 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/MetricsViewModel.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/MetricsViewModel.kt @@ -27,18 +27,17 @@ import androidx.lifecycle.viewModelScope import androidx.navigation.toRoute import co.touchlab.kermit.Logger import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.Job import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharedFlow +import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.asFlow import kotlinx.coroutines.flow.combine -import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.flatMapLatest +import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.map -import kotlinx.coroutines.flow.toList +import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -46,11 +45,8 @@ import org.jetbrains.compose.resources.StringResource import org.meshtastic.core.common.util.nowSeconds import org.meshtastic.core.common.util.toDate import org.meshtastic.core.common.util.toInstant -import org.meshtastic.core.data.repository.DeviceHardwareRepository -import org.meshtastic.core.data.repository.FirmwareReleaseRepository import org.meshtastic.core.data.repository.MeshLogRepository import org.meshtastic.core.data.repository.NodeRepository -import org.meshtastic.core.data.repository.RadioConfigRepository import org.meshtastic.core.data.repository.TracerouteSnapshotRepository import org.meshtastic.core.database.entity.MeshLog import org.meshtastic.core.database.model.Node @@ -58,26 +54,21 @@ import org.meshtastic.core.di.CoroutineDispatchers import org.meshtastic.core.model.TelemetryType import org.meshtastic.core.model.evaluateTracerouteMapAvailability import org.meshtastic.core.model.util.UnitConversions -import org.meshtastic.core.model.util.hasValidEnvironmentMetrics import org.meshtastic.core.navigation.NodesRoutes import org.meshtastic.core.service.ServiceRepository import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.fallback_node_name -import org.meshtastic.core.strings.getString import org.meshtastic.core.strings.okay import org.meshtastic.core.strings.traceroute import org.meshtastic.core.strings.view_on_map import org.meshtastic.core.ui.util.AlertManager import org.meshtastic.core.ui.util.toMessageRes -import org.meshtastic.core.ui.util.toPosition import org.meshtastic.core.ui.viewmodel.stateInWhileSubscribed import org.meshtastic.feature.map.model.TracerouteOverlay import org.meshtastic.feature.node.detail.NodeRequestActions import org.meshtastic.feature.node.detail.NodeRequestEffect +import org.meshtastic.feature.node.domain.usecase.GetNodeDetailsUseCase import org.meshtastic.feature.node.model.MetricsState import org.meshtastic.feature.node.model.TimeFrame -import org.meshtastic.proto.Config -import org.meshtastic.proto.MeshPacket import org.meshtastic.proto.PortNum import org.meshtastic.proto.Telemetry import java.io.BufferedWriter @@ -89,8 +80,6 @@ import java.util.Locale import javax.inject.Inject import org.meshtastic.proto.Paxcount as ProtoPaxcount -private fun MeshPacket.hasValidSignal(): Boolean = rx_time > 0 && (rx_snr != 0f || rx_rssi != 0) - /** * ViewModel responsible for managing and graphing metrics (telemetry, signal strength, paxcount) for a specific node. */ @@ -103,85 +92,38 @@ constructor( private val app: Application, private val dispatchers: CoroutineDispatchers, private val meshLogRepository: MeshLogRepository, - private val radioConfigRepository: RadioConfigRepository, private val serviceRepository: ServiceRepository, private val nodeRepository: NodeRepository, private val tracerouteSnapshotRepository: TracerouteSnapshotRepository, - private val deviceHardwareRepository: DeviceHardwareRepository, - private val firmwareReleaseRepository: FirmwareReleaseRepository, private val nodeRequestActions: NodeRequestActions, private val alertManager: AlertManager, + private val getNodeDetailsUseCase: GetNodeDetailsUseCase, ) : ViewModel() { - private var destNum: Int? = + + private val nodeIdFromRoute: Int? = runCatching { savedStateHandle.toRoute().destNum }.getOrNull() - private var jobs: Job? = null + private val manualNodeId = MutableStateFlow(null) + private val activeNodeId = + combine(MutableStateFlow(nodeIdFromRoute), manualNodeId) { fromRoute, manual -> manual ?: fromRoute } private val tracerouteOverlayCache = MutableStateFlow>(emptyMap()) - fun getUser(nodeNum: Int) = nodeRepository.getUser(nodeNum) - - fun deleteLog(uuid: String) = viewModelScope.launch(dispatchers.io) { meshLogRepository.deleteLog(uuid) } - - /** Returns the map overlay for a specific traceroute request ID. */ - fun getTracerouteOverlay(requestId: Int): TracerouteOverlay? { - val cached = tracerouteOverlayCache.value[requestId] - if (cached != null) return cached - - val overlay = - serviceRepository.tracerouteResponse.value - ?.takeIf { it.requestId == requestId } - ?.let { response -> - TracerouteOverlay( - requestId = response.requestId, - forwardRoute = response.forwardRoute, - returnRoute = response.returnRoute, - ) - } - ?.takeIf { it.hasRoutes } - - if (overlay != null) { - tracerouteOverlayCache.update { it + (requestId to overlay) } - } - - return overlay - } - - fun tracerouteSnapshotPositions(logUuid: String) = tracerouteSnapshotRepository.getSnapshotPositions(logUuid) - - fun clearTracerouteResponse() = serviceRepository.clearTracerouteResponse() - - fun positionedNodeNums(): Set = - nodeRepository.nodeDBbyNum.value.values.filter { it.validPosition != null }.numSet() - - private fun List.numSet(): Set = map { it.num }.toSet() - - init { - viewModelScope.launch { - serviceRepository.tracerouteResponse.filterNotNull().collect { response -> - val overlay = - TracerouteOverlay( - requestId = response.requestId, - forwardRoute = response.forwardRoute, - returnRoute = response.returnRoute, - ) - if (overlay.hasRoutes) { - tracerouteOverlayCache.update { it + (response.requestId to overlay) } - } + val state: StateFlow = + activeNodeId + .flatMapLatest { nodeId -> + if (nodeId == null) return@flatMapLatest flowOf(MetricsState.Empty) + getNodeDetailsUseCase(nodeId).map { it.metricsState } } - } - } - - fun clearPosition() = viewModelScope.launch(dispatchers.io) { - destNum?.let { meshLogRepository.deleteLogs(it, PortNum.POSITION_APP.value) } - } - - private val _state = MutableStateFlow(MetricsState.Empty) - - /** Current aggregated metrics state, including signal history and sensor logs. */ - val state: StateFlow = _state + .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), MetricsState.Empty) - private val environmentState = MutableStateFlow(EnvironmentMetricsState()) + private val environmentState: StateFlow = + activeNodeId + .flatMapLatest { nodeId -> + if (nodeId == null) return@flatMapLatest flowOf(EnvironmentMetricsState()) + getNodeDetailsUseCase(nodeId).map { it.environmentState } + } + .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), EnvironmentMetricsState()) private val _timeFrame = MutableStateFlow(TimeFrame.TWENTY_FOUR_HOURS) @@ -190,8 +132,8 @@ constructor( /** Returns the list of time frames that are actually available based on the oldest data point. */ val availableTimeFrames: StateFlow> = - combine(_state, environmentState) { state, envState -> - val stateOldest = state.oldestTimestampSeconds() + combine(state, environmentState) { currentState, envState -> + val stateOldest = currentState.oldestTimestampSeconds() val envOldest = envState.environmentMetrics.minOfOrNull { (it.time ?: 0).toLong() }?.takeIf { it > 0 } val oldest = listOfNotNull(stateOldest, envOldest).minOrNull() ?: nowSeconds TimeFrame.entries.filter { it.isAvailable(oldest) } @@ -204,10 +146,10 @@ constructor( /** Exposes filtered and unit-converted environment metrics for the UI. */ val filteredEnvironmentMetrics: StateFlow> = - combine(environmentState, _timeFrame, _state) { envState, timeFrame, state -> + combine(environmentState, _timeFrame, state) { envState, timeFrame, currentState -> val threshold = timeFrame.timeThreshold() val data = envState.environmentMetrics.filter { (it.time ?: 0).toLong() >= threshold } - if (state.isFahrenheit) { + if (currentState.isFahrenheit) { data.map { telemetry -> val em = telemetry.environment_metrics ?: return@map telemetry telemetry.copy( @@ -233,9 +175,9 @@ constructor( /** Exposes filtered and decoded pax metrics for the UI. */ val filteredPaxMetrics: StateFlow>> = - combine(_state, _timeFrame) { state, timeFrame -> + combine(state, _timeFrame) { currentState, timeFrame -> val threshold = timeFrame.timeThreshold() - state.paxMetrics + currentState.paxMetrics .filter { (it.received_date / 1000) >= threshold } .mapNotNull { log -> decodePaxFromLog(log)?.let { log to it } } } @@ -244,29 +186,92 @@ constructor( val effects: SharedFlow = nodeRequestActions.effects val lastTraceRouteTime: StateFlow = - nodeRequestActions.lastTracerouteTimes.map { it[destNum] }.stateInWhileSubscribed(null) + combine(nodeRequestActions.lastTracerouteTimes, activeNodeId) { map, id -> id?.let { map[it] } } + .stateInWhileSubscribed(null) val lastRequestNeighborsTime: StateFlow = - nodeRequestActions.lastRequestNeighborTimes.map { it[destNum] }.stateInWhileSubscribed(null) + combine(nodeRequestActions.lastRequestNeighborTimes, activeNodeId) { map, id -> id?.let { map[it] } } + .stateInWhileSubscribed(null) + + fun getUser(nodeNum: Int) = nodeRepository.getUser(nodeNum) + + fun deleteLog(uuid: String) = viewModelScope.launch(dispatchers.io) { meshLogRepository.deleteLog(uuid) } + + fun getTracerouteOverlay(requestId: Int): TracerouteOverlay? { + val cached = tracerouteOverlayCache.value[requestId] + if (cached != null) return cached + + val overlay = + serviceRepository.tracerouteResponse.value + ?.takeIf { it.requestId == requestId } + ?.let { response -> + TracerouteOverlay( + requestId = response.requestId, + forwardRoute = response.forwardRoute, + returnRoute = response.returnRoute, + ) + } + ?.takeIf { it.hasRoutes } + + if (overlay != null) { + tracerouteOverlayCache.update { it + (requestId to overlay) } + } + + return overlay + } + + fun tracerouteSnapshotPositions(logUuid: String) = tracerouteSnapshotRepository.getSnapshotPositions(logUuid) + + fun clearTracerouteResponse() = serviceRepository.clearTracerouteResponse() + + fun positionedNodeNums(): Set = + nodeRepository.nodeDBbyNum.value.values.filter { it.validPosition != null }.numSet() + + private fun List.numSet(): Set = map { it.num }.toSet() + + init { + viewModelScope.launch { + serviceRepository.tracerouteResponse.filterNotNull().collect { response -> + val overlay = + TracerouteOverlay( + requestId = response.requestId, + forwardRoute = response.forwardRoute, + returnRoute = response.returnRoute, + ) + if (overlay.hasRoutes) { + tracerouteOverlayCache.update { it + (response.requestId to overlay) } + } + } + } + Logger.d { "MetricsViewModel created" } + } + + fun clearPosition() = viewModelScope.launch(dispatchers.io) { + (manualNodeId.value ?: nodeIdFromRoute)?.let { + meshLogRepository.deleteLogs(it, PortNum.POSITION_APP.value) + } + } fun requestPosition() { - destNum?.let { nodeRequestActions.requestPosition(viewModelScope, it, state.value.node?.user?.long_name ?: "") } + (manualNodeId.value ?: nodeIdFromRoute)?.let { + nodeRequestActions.requestPosition(viewModelScope, it, state.value.node?.user?.long_name ?: "") + } } fun requestTelemetry(type: TelemetryType) { - destNum?.let { + (manualNodeId.value ?: nodeIdFromRoute)?.let { nodeRequestActions.requestTelemetry(viewModelScope, it, state.value.node?.user?.long_name ?: "", type) } } fun requestTraceroute() { - destNum?.let { + (manualNodeId.value ?: nodeIdFromRoute)?.let { nodeRequestActions.requestTraceroute(viewModelScope, it, state.value.node?.user?.long_name ?: "") } } fun requestNeighborInfo() { - destNum?.let { + (manualNodeId.value ?: nodeIdFromRoute)?.let { nodeRequestActions.requestNeighborInfo(viewModelScope, it, state.value.node?.user?.long_name ?: "") } } @@ -278,7 +283,6 @@ constructor( ) } - /** Shows the detail dialog for a traceroute result, with an option to view on the map. */ fun showTracerouteDetail( annotatedMessage: AnnotatedString, requestId: Int, @@ -318,188 +322,17 @@ constructor( } } - init { - initializeFlows() - } - fun setNodeId(id: Int) { - if (destNum != id) { - destNum = id - initializeFlows() + if (manualNodeId.value != id) { + manualNodeId.value = id } } - @Suppress("LongMethod", "CyclomaticComplexMethod") - private fun initializeFlows() { - jobs?.cancel() - val currentDestNum = destNum - jobs = - viewModelScope.launch { - if (currentDestNum != null) { - val logNodeIdFlow = nodeRepository.effectiveLogNodeId(currentDestNum) - - launch { - combine(nodeRepository.nodeDBbyNum, nodeRepository.myNodeInfo) { nodes, myInfo -> - nodes[currentDestNum] to (nodes.keys.firstOrNull() to myInfo) - } - .distinctUntilChanged() - .collect { (node, localData) -> - val (ourNodeNum, myInfo) = localData - // Create a fallback node if not found in database (for hidden clients, etc.) - val actualNode = - node - ?: Node.createFallback(currentDestNum, getString(Res.string.fallback_node_name)) - val pioEnv = if (currentDestNum == ourNodeNum) myInfo?.pioEnv else null - val hwModel = actualNode.user.hw_model.value - val deviceHardware = - deviceHardwareRepository.getDeviceHardwareByModel(hwModel, target = pioEnv) - - _state.update { state -> - state.copy( - node = actualNode, - isLocal = currentDestNum == ourNodeNum, - deviceHardware = deviceHardware.getOrNull(), - reportedTarget = pioEnv, - ) - } - } - } - - launch { - radioConfigRepository.deviceProfileFlow.collect { profile -> - val moduleConfig = profile.module_config - val displayUnits = profile.config?.display?.units - _state.update { state -> - state.copy( - isManaged = profile.config?.security?.is_managed ?: false, - isFahrenheit = - moduleConfig?.telemetry?.environment_display_fahrenheit == true || - (displayUnits == Config.DisplayConfig.DisplayUnits.IMPERIAL), - displayUnits = displayUnits ?: Config.DisplayConfig.DisplayUnits.METRIC, - ) - } - } - } - - launch { - logNodeIdFlow - .flatMapLatest { meshLogRepository.getTelemetryFrom(it) } - .collect { telemetry -> - val device = mutableListOf() - val power = mutableListOf() - val host = mutableListOf() - val env = mutableListOf() - - for (item in telemetry) { - if (item.device_metrics != null) device.add(item) - if (item.power_metrics != null) power.add(item) - if (item.host_metrics != null) host.add(item) - if (item.hasValidEnvironmentMetrics()) env.add(item) - } - - _state.update { state -> - state.copy(deviceMetrics = device, powerMetrics = power, hostMetrics = host) - } - environmentState.update { it.copy(environmentMetrics = env) } - } - } - - launch { - logNodeIdFlow - .flatMapLatest { meshLogRepository.getMeshPacketsFrom(it) } - .collect { meshPackets -> - _state.update { state -> - state.copy(signalMetrics = meshPackets.filter { it.hasValidSignal() }) - } - } - } - - launch { - combine( - meshLogRepository.getRequestLogs(currentDestNum, PortNum.TRACEROUTE_APP), - logNodeIdFlow.flatMapLatest { - meshLogRepository.getLogsFrom(it, PortNum.TRACEROUTE_APP.value) - }, - ) { request, response -> - _state.update { state -> - state.copy(tracerouteRequests = request, tracerouteResults = response) - } - } - .collect {} - } - - launch { - combine( - meshLogRepository.getRequestLogs(currentDestNum, PortNum.NEIGHBORINFO_APP), - logNodeIdFlow.flatMapLatest { - meshLogRepository.getLogsFrom(it, PortNum.NEIGHBORINFO_APP.value) - }, - ) { request, response -> - _state.update { state -> - state.copy(neighborInfoRequests = request, neighborInfoResults = response) - } - } - .collect {} - } - - launch { - logNodeIdFlow - .flatMapLatest { meshLogRepository.getMeshPacketsFrom(it, PortNum.POSITION_APP.value) } - .collect { packets -> - val distinctPositions = - packets - .mapNotNull { it.toPosition() } - .asFlow() - .distinctUntilChanged { old, new -> - old.time == new.time || - (old.latitude_i == new.latitude_i && old.longitude_i == new.longitude_i) - } - .toList() - _state.update { state -> state.copy(positionLogs = distinctPositions) } - } - } - - launch { - logNodeIdFlow - .flatMapLatest { meshLogRepository.getLogsFrom(it, PortNum.PAXCOUNTER_APP.value) } - .collect { logs -> _state.update { state -> state.copy(paxMetrics = logs) } } - } - - launch { - firmwareReleaseRepository.stableRelease.filterNotNull().collect { latestStable -> - _state.update { state -> state.copy(latestStableFirmware = latestStable) } - } - } - - launch { - firmwareReleaseRepository.alphaRelease.filterNotNull().collect { latestAlpha -> - _state.update { state -> state.copy(latestAlphaFirmware = latestAlpha) } - } - } - - launch { - meshLogRepository - .getMyNodeInfo() - .map { it?.firmware_edition } - .distinctUntilChanged() - .collect { firmwareEdition -> - _state.update { state -> state.copy(firmwareEdition = firmwareEdition) } - } - } - - Logger.d { "MetricsViewModel created" } - } else { - Logger.d { "MetricsViewModel: destNum is null, skipping metrics flows initialization." } - } - } - } - override fun onCleared() { super.onCleared() Logger.d { "MetricsViewModel cleared" } } - /** Write the persisted Position data out to a CSV file in the specified location. */ fun savePositionCSV(uri: Uri) = viewModelScope.launch(dispatchers.main) { val positions = state.value.positionLogs writeToUri(uri) { writer -> @@ -518,7 +351,6 @@ constructor( val speed = position.ground_speed val heading = "%.2f".format((position.ground_track ?: 0) * 1e-5) - // date,time,latitude,longitude,altitude,satsInView,speed,heading writer.appendLine( "$rxDateTime,\"$latitude\",\"$longitude\",\"$altitude\",\"$satsInView\",\"$speed\",\"$heading\"", ) @@ -541,12 +373,10 @@ constructor( @Suppress("MagicNumber", "CyclomaticComplexMethod", "ReturnCount") fun decodePaxFromLog(log: MeshLog): ProtoPaxcount? { - // First, try to parse from the binary fromRadio field (robust, like telemetry) try { val packet = log.fromRadio.packet val decoded = packet?.decoded if (packet != null && decoded != null && decoded.portnum == PortNum.PAXCOUNTER_APP) { - // Requests for paxcount (want_response = true) should not be logged as data points. if (decoded.want_response == true) return null val pax = ProtoPaxcount.ADAPTER.decode(decoded.payload) if ((pax.ble ?: 0) != 0 || (pax.wifi ?: 0) != 0 || (pax.uptime ?: 0) != 0) return pax @@ -554,10 +384,9 @@ constructor( } catch (e: IOException) { Logger.e(e) { "Failed to parse Paxcount from binary data" } } - // Fallback: Attempt to parse Paxcount from raw_message as base64 or hex string. try { val base64 = log.raw_message.trim() - if (base64.matches(Regex("^[A-Za-z0-9+/=\r\n]+$"))) { + if (base64.matches(Regex("^[A-Za-z0-9+/=\\r\\n]+$"))) { val bytes = android.util.Base64.decode(base64, android.util.Base64.DEFAULT) return ProtoPaxcount.ADAPTER.decode(bytes) } else if (base64.matches(Regex("^[0-9a-fA-F]+$")) && base64.length % 2 == 0) { From 10e2d14bb313285ce68d2d8e9029de29986fadd8 Mon Sep 17 00:00:00 2001 From: James Rich <2199651+jamesarich@users.noreply.github.com> Date: Sun, 22 Feb 2026 12:00:10 -0600 Subject: [PATCH 06/18] refact(domain): Extract business logic into use cases This commit refactors the application by extracting business logic from ViewModels into dedicated use case classes. This improves separation of concerns, making the code more modular, testable, and maintainable. The following use cases have been created: - `GetFilteredNodesUseCase`: Encapsulates the logic for filtering and sorting the node list, which was previously in `NodeListViewModel`. - `SendMessageUseCase`: Centralizes the process of sending messages, including handling direct message logic (favoriting nodes or sending contacts) and applying homoglyph transformations. This logic was moved from `MessageViewModel`. - `GetDiscoveredDevicesUseCase`: Consolidates the logic for finding, processing, and matching BLE, USB, and TCP devices with nodes in the database. This simplifies the `ScannerViewModel` by abstracting away the complexities of device discovery and enrichment. The respective ViewModels (`NodeListViewModel`, `MessageViewModel`, and `ScannerViewModel`) have been updated to inject and utilize these new use cases, resulting in cleaner and more focused ViewModel implementations. Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com> --- .../usecase/GetDiscoveredDevicesUseCase.kt | 202 ++++++++++++++++++ .../mesh/ui/connections/ScannerViewModel.kt | 157 ++------------ .../feature/messaging/MessageViewModel.kt | 73 +------ .../domain/usecase/SendMessageUseCase.kt | 103 +++++++++ .../domain/usecase/GetFilteredNodesUseCase.kt | 60 ++++++ .../feature/node/list/NodeListViewModel.kt | 35 +-- 6 files changed, 389 insertions(+), 241 deletions(-) create mode 100644 app/src/main/java/com/geeksville/mesh/domain/usecase/GetDiscoveredDevicesUseCase.kt create mode 100644 feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/domain/usecase/SendMessageUseCase.kt create mode 100644 feature/node/src/main/kotlin/org/meshtastic/feature/node/domain/usecase/GetFilteredNodesUseCase.kt diff --git a/app/src/main/java/com/geeksville/mesh/domain/usecase/GetDiscoveredDevicesUseCase.kt b/app/src/main/java/com/geeksville/mesh/domain/usecase/GetDiscoveredDevicesUseCase.kt new file mode 100644 index 0000000000..7aef2d9ba3 --- /dev/null +++ b/app/src/main/java/com/geeksville/mesh/domain/usecase/GetDiscoveredDevicesUseCase.kt @@ -0,0 +1,202 @@ +/* + * 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 . + */ +package com.geeksville.mesh.domain.usecase + +import android.hardware.usb.UsbManager +import android.net.nsd.NsdServiceInfo +import com.geeksville.mesh.model.DeviceListEntry +import com.geeksville.mesh.model.getMeshtasticShortName +import com.geeksville.mesh.repository.network.NetworkRepository +import com.geeksville.mesh.repository.network.NetworkRepository.Companion.toAddressString +import com.geeksville.mesh.repository.radio.RadioInterfaceService +import com.geeksville.mesh.repository.usb.UsbRepository +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.map +import org.jetbrains.compose.resources.getString +import org.meshtastic.core.ble.BluetoothRepository +import org.meshtastic.core.data.repository.NodeRepository +import org.meshtastic.core.database.DatabaseManager +import org.meshtastic.core.database.model.Node +import org.meshtastic.core.datastore.RecentAddressesDataSource +import org.meshtastic.core.datastore.model.RecentAddress +import org.meshtastic.core.strings.Res +import org.meshtastic.core.strings.meshtastic +import java.util.Locale +import javax.inject.Inject + +data class DiscoveredDevices( + val bleDevices: List, + val usbDevices: List, + val discoveredTcpDevices: List, + val recentTcpDevices: List, +) + +@Suppress("LongParameterList") +class GetDiscoveredDevicesUseCase +@Inject +constructor( + private val bluetoothRepository: BluetoothRepository, + private val networkRepository: NetworkRepository, + private val recentAddressesDataSource: RecentAddressesDataSource, + private val nodeRepository: NodeRepository, + private val databaseManager: DatabaseManager, + private val usbRepository: UsbRepository, + private val radioInterfaceService: RadioInterfaceService, + private val usbManagerLazy: dagger.Lazy, +) { + private val suffixLength = 4 + + @Suppress("LongMethod", "CyclomaticComplexMethod") + fun invoke(showMock: Boolean): Flow { + val nodeDb = nodeRepository.nodeDBbyNum + + val bondedBleFlow = bluetoothRepository.state.map { ble -> ble.bondedDevices.map { DeviceListEntry.Ble(it) } } + + val processedTcpFlow = + combine(networkRepository.resolvedList, recentAddressesDataSource.recentAddresses) { + tcpServices, + recentList, + -> + val recentMap = recentList.associateBy({ it.address }) { it.name } + tcpServices + .map { service -> + val address = "t${service.toAddressString()}" + val txtRecords = service.attributes + val shortNameBytes = txtRecords["shortname"] + val idBytes = txtRecords["id"] + + val shortName = + shortNameBytes?.let { String(it, Charsets.UTF_8) } ?: getString(Res.string.meshtastic) + val deviceId = idBytes?.let { String(it, Charsets.UTF_8) }?.replace("!", "") + var displayName = recentMap[address] ?: shortName + if (deviceId != null && (displayName.split("_").none { it == deviceId })) { + displayName += "_$deviceId" + } + DeviceListEntry.Tcp(displayName, address) + } + .sortedBy { it.name } + } + + val usbDevicesFlow = + usbRepository.serialDevices.map { usb -> + usb.map { (_, d) -> DeviceListEntry.Usb(radioInterfaceService, usbManagerLazy.get(), d) } + } + + return combine( + nodeDb, + bondedBleFlow, + processedTcpFlow, + usbDevicesFlow, + networkRepository.resolvedList, + recentAddressesDataSource.recentAddresses, + ) { args: Array -> + @Suppress("UNCHECKED_CAST", "MagicNumber") + val db = args[0] as Map + + @Suppress("UNCHECKED_CAST", "MagicNumber") + val bondedBle = args[1] as List + + @Suppress("UNCHECKED_CAST", "MagicNumber") + val processedTcp = args[2] as List + + @Suppress("UNCHECKED_CAST", "MagicNumber") + val usbDevices = args[3] as List + + @Suppress("UNCHECKED_CAST", "MagicNumber") + val resolved = args[4] as List + + @Suppress("UNCHECKED_CAST", "MagicNumber") + val recentList = args[5] as List + + val bleForUi = + bondedBle + .map { entry -> + val matchingNode = + if (databaseManager.hasDatabaseFor(entry.fullAddress)) { + db.values.find { node -> + val suffix = entry.peripheral.getMeshtasticShortName()?.lowercase(Locale.ROOT) + suffix != null && node.user.id.lowercase(Locale.ROOT).endsWith(suffix) + } + } else { + null + } + entry.copy(node = matchingNode) + } + .sortedBy { it.name } + + val usbForUi = + (usbDevices + if (showMock) listOf(DeviceListEntry.Mock("Demo Mode")) else emptyList()).map { entry -> + val matchingNode = + if (databaseManager.hasDatabaseFor(entry.fullAddress)) { + db.values.find { node -> + val suffix = entry.name.split("_").lastOrNull()?.lowercase(Locale.ROOT) + suffix != null && + suffix.length >= suffixLength && + node.user.id.lowercase(Locale.ROOT).endsWith(suffix) + } + } else { + null + } + entry.copy(node = matchingNode) + } + + val discoveredTcpForUi = + processedTcp.map { entry -> + val matchingNode = + if (databaseManager.hasDatabaseFor(entry.fullAddress)) { + val resolvedService = resolved.find { "t${it.toAddressString()}" == entry.fullAddress } + val deviceId = resolvedService?.attributes?.get("id")?.let { String(it, Charsets.UTF_8) } + db.values.find { node -> + node.user.id == deviceId || (deviceId != null && node.user.id == "!$deviceId") + } + } else { + null + } + entry.copy(node = matchingNode) + } + + val discoveredTcpAddresses = processedTcp.map { it.fullAddress }.toSet() + val recentTcpForUi = + recentList + .filterNot { discoveredTcpAddresses.contains(it.address) } + .map { DeviceListEntry.Tcp(it.name, it.address) } + .map { entry -> + val matchingNode = + if (databaseManager.hasDatabaseFor(entry.fullAddress)) { + val suffix = entry.name.split("_").lastOrNull()?.lowercase(Locale.ROOT) + db.values.find { node -> + suffix != null && + suffix.length >= suffixLength && + node.user.id.lowercase(Locale.ROOT).endsWith(suffix) + } + } else { + null + } + entry.copy(node = matchingNode) + } + .sortedBy { it.name } + + DiscoveredDevices( + bleDevices = bleForUi, + usbDevices = usbForUi, + discoveredTcpDevices = discoveredTcpForUi, + recentTcpDevices = recentTcpForUi, + ) + } + } +} diff --git a/app/src/main/java/com/geeksville/mesh/ui/connections/ScannerViewModel.kt b/app/src/main/java/com/geeksville/mesh/ui/connections/ScannerViewModel.kt index f694a3bf88..131eb33e8f 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/connections/ScannerViewModel.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/connections/ScannerViewModel.kt @@ -18,16 +18,13 @@ package com.geeksville.mesh.ui.connections import android.app.Application import android.content.Context -import android.hardware.usb.UsbManager import android.os.RemoteException import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import co.touchlab.kermit.Logger import co.touchlab.kermit.Severity +import com.geeksville.mesh.domain.usecase.GetDiscoveredDevicesUseCase import com.geeksville.mesh.model.DeviceListEntry -import com.geeksville.mesh.model.getMeshtasticShortName -import com.geeksville.mesh.repository.network.NetworkRepository -import com.geeksville.mesh.repository.network.NetworkRepository.Companion.toAddressString import com.geeksville.mesh.repository.radio.RadioInterfaceService import com.geeksville.mesh.repository.usb.UsbRepository import com.geeksville.mesh.service.MeshService @@ -36,25 +33,18 @@ import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow -import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch -import org.jetbrains.compose.resources.getString import org.meshtastic.core.ble.BluetoothRepository -import org.meshtastic.core.data.repository.NodeRepository -import org.meshtastic.core.database.DatabaseManager -import org.meshtastic.core.database.model.Node import org.meshtastic.core.datastore.RecentAddressesDataSource import org.meshtastic.core.datastore.model.RecentAddress import org.meshtastic.core.model.util.anonymize import org.meshtastic.core.service.ServiceRepository -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.meshtastic import org.meshtastic.core.ui.viewmodel.stateInWhileSubscribed -import java.util.Locale import javax.inject.Inject @HiltViewModel @@ -66,12 +56,9 @@ constructor( private val serviceRepository: ServiceRepository, private val bluetoothRepository: BluetoothRepository, private val usbRepository: UsbRepository, - private val usbManagerLazy: dagger.Lazy, - private val networkRepository: NetworkRepository, private val radioInterfaceService: RadioInterfaceService, private val recentAddressesDataSource: RecentAddressesDataSource, - private val nodeRepository: NodeRepository, - private val databaseManager: DatabaseManager, + private val getDiscoveredDevicesUseCase: GetDiscoveredDevicesUseCase, ) : ViewModel() { private val context: Context get() = application.applicationContext @@ -81,142 +68,32 @@ constructor( private val _errorText = MutableStateFlow(null) val errorText: StateFlow = _errorText.asStateFlow() - private val nodeDb: StateFlow> = nodeRepository.nodeDBbyNum - - private val bondedBleDevicesFlow: StateFlow> = - bluetoothRepository.state - .map { ble -> ble.bondedDevices.map { DeviceListEntry.Ble(it) } } - .stateIn(viewModelScope, SharingStarted.Lazily, emptyList()) - - // Flow for discovered TCP devices, using recent addresses for potential name enrichment - private val processedDiscoveredTcpDevicesFlow: StateFlow> = - combine(networkRepository.resolvedList, recentAddressesDataSource.recentAddresses) { tcpServices, recentList -> - val recentMap = recentList.associateBy({ it.address }) { it.name } - tcpServices - .map { service -> - val address = "t${service.toAddressString()}" - val txtRecords = service.attributes // Map - val shortNameBytes = txtRecords["shortname"] - val idBytes = txtRecords["id"] - - val shortName = - shortNameBytes?.let { String(it, Charsets.UTF_8) } ?: getString(Res.string.meshtastic) - val deviceId = idBytes?.let { String(it, Charsets.UTF_8) }?.replace("!", "") - var displayName = recentMap[address] ?: shortName - if (deviceId != null && (displayName.split("_").none { it == deviceId })) { - displayName += "_$deviceId" - } - DeviceListEntry.Tcp(displayName, address) - } - .sortedBy { it.name } - } - .stateIn(viewModelScope, SharingStarted.Lazily, emptyList()) + private val discoveredDevicesFlow = + showMockInterface + .flatMapLatest { showMock -> getDiscoveredDevicesUseCase.invoke(showMock) } + .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), null) /** A combined list of bonded BLE devices for the UI. */ val bleDevicesForUi: StateFlow> = - combine(bondedBleDevicesFlow, nodeDb) { bonded, db -> - bonded - .map { entry: DeviceListEntry.Ble -> - val matchingNode = - if (databaseManager.hasDatabaseFor(entry.fullAddress)) { - db.values.find { node -> - val suffix = entry.peripheral.getMeshtasticShortName()?.lowercase(Locale.ROOT) - suffix != null && node.user.id.lowercase(Locale.ROOT).endsWith(suffix) - } - } else { - null - } - entry.copy(node = matchingNode) - } - .sortedBy { it.name } - } - .stateInWhileSubscribed(initialValue = emptyList()) - - private val usbDevicesFlow: StateFlow> = - usbRepository.serialDevices - .map { usb -> usb.map { (_, d) -> DeviceListEntry.Usb(radioInterfaceService, usbManagerLazy.get(), d) } } - .stateIn(viewModelScope, SharingStarted.Lazily, emptyList()) - - val mockDevice = DeviceListEntry.Mock("Demo Mode") + discoveredDevicesFlow + .map { it?.bleDevices ?: emptyList() } + .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), emptyList()) /** UI StateFlow for USB devices. */ val usbDevicesForUi: StateFlow> = - combine(usbDevicesFlow, showMockInterface) { usb, showMock -> - val all: List = usb + if (showMock) listOf(mockDevice) else emptyList() - all.map { entry -> - val matchingNode = - if (databaseManager.hasDatabaseFor(entry.fullAddress)) { - nodeDb.value.values.find { node -> - // Hard to match USB to node without connection, but we can try matching by name if it - // follows Meshtastic pattern - val suffix = entry.name.split("_").lastOrNull()?.lowercase(Locale.ROOT) - suffix != null && - suffix.length >= suffixLength && - node.user.id.lowercase(Locale.ROOT).endsWith(suffix) - } - } else { - null - } - entry.copy(node = matchingNode) - } - } - .stateInWhileSubscribed(initialValue = if (showMockInterface.value) listOf(mockDevice) else emptyList()) - - // Flow for recent TCP devices, filtered to exclude any currently discovered devices - private val filteredRecentTcpDevicesFlow: StateFlow> = - combine(recentAddressesDataSource.recentAddresses, processedDiscoveredTcpDevicesFlow) { - recentList, - discoveredDevices, - -> - val discoveredDeviceAddresses = discoveredDevices.map { it.fullAddress }.toSet() - recentList - .filterNot { recentAddress -> discoveredDeviceAddresses.contains(recentAddress.address) } - .map { recentAddress -> DeviceListEntry.Tcp(recentAddress.name, recentAddress.address) } - .sortedBy { it.name } - } - .stateIn(viewModelScope, SharingStarted.Lazily, emptyList()) - - private val suffixLength = 4 + discoveredDevicesFlow.map { it?.usbDevices ?: emptyList() }.stateInWhileSubscribed(initialValue = emptyList()) /** UI StateFlow for discovered TCP devices. */ val discoveredTcpDevicesForUi: StateFlow> = - combine(processedDiscoveredTcpDevicesFlow, networkRepository.resolvedList, nodeDb) { devices, resolved, db -> - devices.map { entry -> - val matchingNode = - if (databaseManager.hasDatabaseFor(entry.fullAddress)) { - val resolvedService = resolved.find { "t${it.toAddressString()}" == entry.fullAddress } - val deviceId = resolvedService?.attributes?.get("id")?.let { String(it, Charsets.UTF_8) } - db.values.find { node -> - node.user.id == deviceId || (deviceId != null && node.user.id == "!$deviceId") - } - } else { - null - } - entry.copy(node = matchingNode) - } - } - .stateInWhileSubscribed(initialValue = listOf()) + discoveredDevicesFlow + .map { it?.discoveredTcpDevices ?: emptyList() } + .stateInWhileSubscribed(initialValue = emptyList()) /** UI StateFlow for recently connected TCP devices that are not currently discovered. */ val recentTcpDevicesForUi: StateFlow> = - combine(filteredRecentTcpDevicesFlow, nodeDb) { devices, db -> - devices.map { entry -> - val matchingNode = - if (databaseManager.hasDatabaseFor(entry.fullAddress)) { - // For recent TCP, we don't have the TXT records, but maybe the name contains the ID - val suffix = entry.name.split("_").lastOrNull()?.lowercase(Locale.ROOT) - db.values.find { node -> - suffix != null && - suffix.length >= suffixLength && - node.user.id.lowercase(Locale.ROOT).endsWith(suffix) - } - } else { - null - } - entry.copy(node = matchingNode) - } - } - .stateInWhileSubscribed(initialValue = listOf()) + discoveredDevicesFlow + .map { it?.recentTcpDevices ?: emptyList() } + .stateInWhileSubscribed(initialValue = emptyList()) val selectedAddressFlow: StateFlow = radioInterfaceService.currentDeviceAddressFlow diff --git a/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/MessageViewModel.kt b/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/MessageViewModel.kt index 9083dbb579..774faac4ab 100644 --- a/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/MessageViewModel.kt +++ b/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/MessageViewModel.kt @@ -16,13 +16,11 @@ */ package org.meshtastic.feature.messaging -import android.os.RemoteException import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import androidx.paging.PagingData import androidx.paging.cachedIn -import co.touchlab.kermit.Logger import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.Flow @@ -41,7 +39,6 @@ import org.meshtastic.core.data.repository.RadioConfigRepository import org.meshtastic.core.database.entity.ContactSettings import org.meshtastic.core.database.model.Message import org.meshtastic.core.database.model.Node -import org.meshtastic.core.model.Capabilities import org.meshtastic.core.model.DataPacket import org.meshtastic.core.prefs.emoji.CustomEmojiPrefs import org.meshtastic.core.prefs.homoglyph.HomoglyphPrefs @@ -50,9 +47,8 @@ import org.meshtastic.core.service.MeshServiceNotifications import org.meshtastic.core.service.ServiceAction import org.meshtastic.core.service.ServiceRepository import org.meshtastic.core.ui.viewmodel.stateInWhileSubscribed +import org.meshtastic.feature.messaging.domain.usecase.SendMessageUseCase import org.meshtastic.proto.ChannelSet -import org.meshtastic.proto.Config.DeviceConfig.Role -import org.meshtastic.proto.SharedContact import javax.inject.Inject @Suppress("LongParameterList", "TooManyFunctions") @@ -70,6 +66,7 @@ constructor( private val customEmojiPrefs: CustomEmojiPrefs, private val homoglyphEncodingPrefs: HomoglyphPrefs, private val meshServiceNotifications: MeshServiceNotifications, + private val sendMessageUseCase: SendMessageUseCase, ) : ViewModel() { private val _title = MutableStateFlow("") val title: StateFlow = _title.asStateFlow() @@ -194,46 +191,8 @@ constructor( * broadcasting on channel 0. * @param replyId The ID of the message this is a reply to, if any. */ - @Suppress("NestedBlockDepth") fun sendMessage(str: String, contactKey: String = "0${DataPacket.ID_BROADCAST}", replyId: Int? = null) { - // contactKey: unique contact key filter (channel)+(nodeId) - val channel = contactKey[0].digitToIntOrNull() - val dest = if (channel != null) contactKey.substring(1) else contactKey - - // if the destination is a node, we need to ensure it's a - // favorite so it does not get removed from the on-device node database. - if (channel == null) { // no channel specified, so we assume it's a direct message - val fwVersion = ourNodeInfo.value?.metadata?.firmware_version - val destNode = nodeRepository.getNode(dest) - val isClientBase = ourNodeInfo.value?.user?.role == Role.CLIENT_BASE - - val capabilities = Capabilities(fwVersion) - - if (capabilities.canSendVerifiedContacts) { - sendSharedContact(destNode) - } else { - if (!destNode.isFavorite && !isClientBase) { - favoriteNode(destNode) - } - } - } - - // Applying homoglyph encoding to the transmitted string if user has activated the feature - // In most cases the value in "str" parameter will already contain the correct - // transformed string from the text input. This call here added to make sure that - // the feature is effective across all possible message paths (quick-chat, reply, etc.) - val dataPacketText: String = - if (homoglyphEncodingPrefs.homoglyphEncodingEnabled) { - HomoglyphCharacterStringTransformer.optimizeUtf8StringWithHomoglyphs(str) - } else { - str - } - - val p = - DataPacket(dest, channel ?: 0, dataPacketText, replyId).apply { - from = ourNodeInfo.value?.user?.id ?: DataPacket.ID_LOCAL - } - sendDataPacket(p) + viewModelScope.launch { sendMessageUseCase.invoke(str, contactKey, replyId) } } fun sendReaction(emoji: String, replyId: Int, contactKey: String) = @@ -253,30 +212,4 @@ constructor( val unreadCount = packetRepository.getUnreadCount(contact) if (unreadCount == 0) meshServiceNotifications.cancelMessageNotification(contact) } - - private fun favoriteNode(node: Node) = viewModelScope.launch { - try { - serviceRepository.onServiceAction(ServiceAction.Favorite(node)) - } catch (ex: RemoteException) { - Logger.e(ex) { "Favorite node error" } - } - } - - private fun sendSharedContact(node: Node) = viewModelScope.launch { - try { - val contact = - SharedContact(node_num = node.num, user = node.user, manually_verified = node.manuallyVerified) - serviceRepository.onServiceAction(ServiceAction.SendContact(contact = contact)) - } catch (ex: RemoteException) { - Logger.e(ex) { "Send shared contact error" } - } - } - - private fun sendDataPacket(p: DataPacket) { - try { - serviceRepository.meshService?.send(p) - } catch (ex: RemoteException) { - Logger.e { "Send DataPacket error: ${ex.message}" } - } - } } diff --git a/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/domain/usecase/SendMessageUseCase.kt b/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/domain/usecase/SendMessageUseCase.kt new file mode 100644 index 0000000000..1c9863015d --- /dev/null +++ b/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/domain/usecase/SendMessageUseCase.kt @@ -0,0 +1,103 @@ +/* + * 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 . + */ +package org.meshtastic.feature.messaging.domain.usecase + +import co.touchlab.kermit.Logger +import org.meshtastic.core.data.repository.NodeRepository +import org.meshtastic.core.database.model.Node +import org.meshtastic.core.model.Capabilities +import org.meshtastic.core.model.DataPacket +import org.meshtastic.core.prefs.homoglyph.HomoglyphPrefs +import org.meshtastic.core.service.ServiceAction +import org.meshtastic.core.service.ServiceRepository +import org.meshtastic.feature.messaging.HomoglyphCharacterStringTransformer +import org.meshtastic.proto.Config +import org.meshtastic.proto.SharedContact +import javax.inject.Inject + +@Suppress("TooGenericExceptionCaught") +class SendMessageUseCase +@Inject +constructor( + private val nodeRepository: NodeRepository, + private val serviceRepository: ServiceRepository, + private val homoglyphEncodingPrefs: HomoglyphPrefs, +) { + + @Suppress("NestedBlockDepth", "LongMethod", "CyclomaticComplexMethod") + suspend operator fun invoke( + text: String, + contactKey: String = "0${DataPacket.ID_BROADCAST}", + replyId: Int? = null, + ) { + val channel = contactKey[0].digitToIntOrNull() + val dest = if (channel != null) contactKey.substring(1) else contactKey + + val ourNode = nodeRepository.ourNodeInfo.value + val fromId = ourNode?.user?.id ?: DataPacket.ID_LOCAL + + // logic for direct messages + if (channel == null) { + val destNode = nodeRepository.getNode(dest) + val fwVersion = ourNode?.metadata?.firmware_version + val isClientBase = ourNode?.user?.role == Config.DeviceConfig.Role.CLIENT_BASE + val capabilities = Capabilities(fwVersion) + + if (capabilities.canSendVerifiedContacts) { + sendSharedContact(destNode) + } else { + if (!destNode.isFavorite && !isClientBase) { + favoriteNode(destNode) + } + } + } + + // Apply homoglyph encoding + val finalMessageText = + if (homoglyphEncodingPrefs.homoglyphEncodingEnabled) { + HomoglyphCharacterStringTransformer.optimizeUtf8StringWithHomoglyphs(text) + } else { + text + } + + val packet = DataPacket(dest, channel ?: 0, finalMessageText, replyId).apply { from = fromId } + + try { + serviceRepository.meshService?.send(packet) + } catch (ex: Exception) { + Logger.e(ex) { "Failed to send data packet" } + } + } + + private suspend fun favoriteNode(node: Node) { + try { + serviceRepository.onServiceAction(ServiceAction.Favorite(node)) + } catch (ex: Exception) { + Logger.e(ex) { "Favorite node error" } + } + } + + private suspend fun sendSharedContact(node: Node) { + try { + val contact = + SharedContact(node_num = node.num, user = node.user, manually_verified = node.manuallyVerified) + serviceRepository.onServiceAction(ServiceAction.SendContact(contact = contact)) + } catch (ex: Exception) { + Logger.e(ex) { "Send shared contact error" } + } + } +} diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/domain/usecase/GetFilteredNodesUseCase.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/domain/usecase/GetFilteredNodesUseCase.kt new file mode 100644 index 0000000000..1d11bad9b3 --- /dev/null +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/domain/usecase/GetFilteredNodesUseCase.kt @@ -0,0 +1,60 @@ +/* + * 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 . + */ +package org.meshtastic.feature.node.domain.usecase + +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.map +import org.meshtastic.core.data.repository.NodeRepository +import org.meshtastic.core.database.model.Node +import org.meshtastic.core.database.model.NodeSortOption +import org.meshtastic.feature.node.list.NodeFilterState +import org.meshtastic.feature.node.model.isEffectivelyUnmessageable +import org.meshtastic.proto.Config +import javax.inject.Inject + +class GetFilteredNodesUseCase @Inject constructor(private val nodeRepository: NodeRepository) { + @Suppress("CyclomaticComplexMethod", "LongMethod") + operator fun invoke(filter: NodeFilterState, sort: NodeSortOption): Flow> = nodeRepository + .getNodes( + sort = sort, + filter = filter.filterText, + includeUnknown = filter.includeUnknown, + onlyOnline = filter.onlyOnline, + onlyDirect = filter.onlyDirect, + ) + .map { list -> + list + .filter { node -> node.isIgnored == filter.showIgnored } + .filter { node -> + if (filter.excludeInfrastructure) { + val role = node.user.role + + @Suppress("DEPRECATION") + val infrastructureRoles = + listOf( + Config.DeviceConfig.Role.ROUTER, + Config.DeviceConfig.Role.REPEATER, + Config.DeviceConfig.Role.ROUTER_LATE, + Config.DeviceConfig.Role.CLIENT_BASE, + ) + role !in infrastructureRoles && !node.isEffectivelyUnmessageable + } else { + true + } + } + } +} diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/list/NodeListViewModel.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/list/NodeListViewModel.kt index 2b94935451..c90313ae7a 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/list/NodeListViewModel.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/list/NodeListViewModel.kt @@ -29,7 +29,6 @@ import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.flatMapLatest -import kotlinx.coroutines.flow.map import kotlinx.coroutines.launch import org.meshtastic.core.data.repository.NodeRepository import org.meshtastic.core.data.repository.RadioConfigRepository @@ -39,12 +38,13 @@ import org.meshtastic.core.model.util.dispatchMeshtasticUri import org.meshtastic.core.service.ServiceRepository import org.meshtastic.core.ui.viewmodel.stateInWhileSubscribed import org.meshtastic.feature.node.detail.NodeManagementActions -import org.meshtastic.feature.node.model.isEffectivelyUnmessageable +import org.meshtastic.feature.node.domain.usecase.GetFilteredNodesUseCase import org.meshtastic.proto.ChannelSet import org.meshtastic.proto.Config import org.meshtastic.proto.SharedContact import javax.inject.Inject +@Suppress("LongParameterList") @HiltViewModel class NodeListViewModel @Inject @@ -54,6 +54,7 @@ constructor( private val radioConfigRepository: RadioConfigRepository, private val serviceRepository: ServiceRepository, val nodeManagementActions: NodeManagementActions, + private val getFilteredNodesUseCase: GetFilteredNodesUseCase, val nodeFilterPreferences: NodeFilterPreferences, ) : ViewModel() { @@ -116,35 +117,7 @@ constructor( val nodeList: StateFlow> = combine(nodeFilter, nodeSortOption, ::Pair) - .flatMapLatest { (filter, sort) -> - nodeRepository - .getNodes( - sort = sort, - filter = filter.filterText, - includeUnknown = filter.includeUnknown, - onlyOnline = filter.onlyOnline, - onlyDirect = filter.onlyDirect, - ) - .map { list -> - list - .filter { node -> node.isIgnored == filter.showIgnored } - .filter { node -> - if (filter.excludeInfrastructure) { - val role = node.user.role - val infrastructureRoles = - listOf( - Config.DeviceConfig.Role.ROUTER, - Config.DeviceConfig.Role.REPEATER, - Config.DeviceConfig.Role.ROUTER_LATE, - Config.DeviceConfig.Role.CLIENT_BASE, - ) - role !in infrastructureRoles && !node.isEffectivelyUnmessageable - } else { - true - } - } - } - } + .flatMapLatest { (filter, sort) -> getFilteredNodesUseCase.invoke(filter, sort) } .stateInWhileSubscribed(initialValue = emptyList()) val unfilteredNodeList: StateFlow> = From 91c3f8d3131be252afa3ead1264e6b5b160119d4 Mon Sep 17 00:00:00 2001 From: James Rich <2199651+jamesarich@users.noreply.github.com> Date: Sun, 22 Feb 2026 12:32:15 -0600 Subject: [PATCH 07/18] feat(testing): Add unit tests for domain use cases This commit introduces unit tests for several domain use cases across different features, improving code coverage and ensuring the correctness of business logic. - **`SendMessageUseCaseTest`**: Verifies the logic for sending messages. It includes tests for: - Sending broadcast messages. - Automatically favoriting a node when sending a direct message to a device with older firmware. - Sending a shared contact when messaging a device with newer firmware. - Correctly applying homoglyph character transformations when the feature is enabled. - **`GetFilteredNodesUseCaseTest`**: Covers the node filtering logic. Tests ensure that: - Nodes are correctly filtered based on various criteria passed to the repository. - Ignored nodes are properly excluded from the results when requested. - Infrastructure nodes (like `ROUTER` and `REPEATER`) are filtered out when the `excludeInfrastructure` flag is set. - **`GetDiscoveredDevicesUseCaseTest`**: Adds tests for the device discovery mechanism. - Confirms that the "Demo Mode" device is included in the list when the `showMock` flag is true. - Verifies that empty lists are returned when no devices are discovered and the mock flag is false. Additionally, necessary testing dependencies like `mockk` and `kotlinx-coroutines-test` have been added to the `feature:messaging` module's build configuration to support these new tests. Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com> --- .../GetDiscoveredDevicesUseCaseTest.kt | 101 ++++++++++++ feature/messaging/build.gradle.kts | 2 + .../domain/usecase/SendMessageUseCaseTest.kt | 146 ++++++++++++++++++ .../usecase/GetFilteredNodesUseCaseTest.kt | 119 ++++++++++++++ 4 files changed, 368 insertions(+) create mode 100644 app/src/test/java/com/geeksville/mesh/domain/usecase/GetDiscoveredDevicesUseCaseTest.kt create mode 100644 feature/messaging/src/test/kotlin/org/meshtastic/feature/messaging/domain/usecase/SendMessageUseCaseTest.kt create mode 100644 feature/node/src/test/kotlin/org/meshtastic/feature/node/domain/usecase/GetFilteredNodesUseCaseTest.kt diff --git a/app/src/test/java/com/geeksville/mesh/domain/usecase/GetDiscoveredDevicesUseCaseTest.kt b/app/src/test/java/com/geeksville/mesh/domain/usecase/GetDiscoveredDevicesUseCaseTest.kt new file mode 100644 index 0000000000..319db5cf80 --- /dev/null +++ b/app/src/test/java/com/geeksville/mesh/domain/usecase/GetDiscoveredDevicesUseCaseTest.kt @@ -0,0 +1,101 @@ +/* + * 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 . + */ +package com.geeksville.mesh.domain.usecase + +import android.hardware.usb.UsbManager +import com.geeksville.mesh.repository.network.NetworkRepository +import com.geeksville.mesh.repository.radio.RadioInterfaceService +import com.geeksville.mesh.repository.usb.UsbRepository +import io.mockk.every +import io.mockk.mockk +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.test.runTest +import org.junit.Assert.assertEquals +import org.junit.Before +import org.junit.Test +import org.meshtastic.core.ble.BluetoothRepository +import org.meshtastic.core.ble.BluetoothState +import org.meshtastic.core.data.repository.NodeRepository +import org.meshtastic.core.database.DatabaseManager +import org.meshtastic.core.datastore.RecentAddressesDataSource + +class GetDiscoveredDevicesUseCaseTest { + + private lateinit var bluetoothRepository: BluetoothRepository + private lateinit var networkRepository: NetworkRepository + private lateinit var recentAddressesDataSource: RecentAddressesDataSource + private lateinit var nodeRepository: NodeRepository + private lateinit var databaseManager: DatabaseManager + private lateinit var usbRepository: UsbRepository + private lateinit var radioInterfaceService: RadioInterfaceService + private lateinit var usbManagerLazy: dagger.Lazy + private lateinit var useCase: GetDiscoveredDevicesUseCase + + @Before + fun setUp() { + bluetoothRepository = mockk() + networkRepository = mockk() + recentAddressesDataSource = mockk(relaxed = true) + nodeRepository = mockk() + databaseManager = mockk(relaxed = true) + usbRepository = mockk() + radioInterfaceService = mockk() + usbManagerLazy = mockk() + + useCase = + GetDiscoveredDevicesUseCase( + bluetoothRepository = bluetoothRepository, + networkRepository = networkRepository, + recentAddressesDataSource = recentAddressesDataSource, + nodeRepository = nodeRepository, + databaseManager = databaseManager, + usbRepository = usbRepository, + radioInterfaceService = radioInterfaceService, + usbManagerLazy = usbManagerLazy, + ) + + // Default empty flows + every { bluetoothRepository.state } returns MutableStateFlow(BluetoothState()) + every { networkRepository.resolvedList } returns MutableStateFlow(emptyList()) + every { recentAddressesDataSource.recentAddresses } returns MutableStateFlow(emptyList()) + every { nodeRepository.nodeDBbyNum } returns MutableStateFlow(emptyMap()) + every { usbRepository.serialDevices } returns MutableStateFlow(emptyMap()) + } + + @Test + fun `invoke returns discovered devices with mock if enabled`() = runTest { + // Act + val result = useCase.invoke(showMock = true).first() + + // Assert + assertEquals(1, result.usbDevices.size) // The Demo Mode mock device + assertEquals("Demo Mode", result.usbDevices.first().name) + } + + @Test + fun `invoke returns empty lists when no devices are discovered`() = runTest { + // Act + val result = useCase.invoke(showMock = false).first() + + // Assert + assertEquals(0, result.bleDevices.size) + assertEquals(0, result.usbDevices.size) + assertEquals(0, result.discoveredTcpDevices.size) + assertEquals(0, result.recentTcpDevices.size) + } +} diff --git a/feature/messaging/build.gradle.kts b/feature/messaging/build.gradle.kts index 21a483faa0..8cb9833534 100644 --- a/feature/messaging/build.gradle.kts +++ b/feature/messaging/build.gradle.kts @@ -64,4 +64,6 @@ dependencies { androidTestImplementation(libs.androidx.test.ext.junit) testImplementation(libs.junit) + testImplementation(libs.mockk) + testImplementation(libs.kotlinx.coroutines.test) } diff --git a/feature/messaging/src/test/kotlin/org/meshtastic/feature/messaging/domain/usecase/SendMessageUseCaseTest.kt b/feature/messaging/src/test/kotlin/org/meshtastic/feature/messaging/domain/usecase/SendMessageUseCaseTest.kt new file mode 100644 index 0000000000..42adf05a85 --- /dev/null +++ b/feature/messaging/src/test/kotlin/org/meshtastic/feature/messaging/domain/usecase/SendMessageUseCaseTest.kt @@ -0,0 +1,146 @@ +/* + * 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 . + */ +package org.meshtastic.feature.messaging.domain.usecase + +import io.mockk.coVerify +import io.mockk.every +import io.mockk.mockk +import io.mockk.mockkConstructor +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.test.runTest +import org.junit.Before +import org.junit.Test +import org.meshtastic.core.data.repository.NodeRepository +import org.meshtastic.core.database.model.Node +import org.meshtastic.core.model.Capabilities +import org.meshtastic.core.model.DataPacket +import org.meshtastic.core.prefs.homoglyph.HomoglyphPrefs +import org.meshtastic.core.service.ServiceAction +import org.meshtastic.core.service.ServiceRepository +import org.meshtastic.proto.Config +import org.meshtastic.proto.DeviceMetadata + +class SendMessageUseCaseTest { + + private lateinit var nodeRepository: NodeRepository + private lateinit var serviceRepository: ServiceRepository + private lateinit var homoglyphEncodingPrefs: HomoglyphPrefs + private lateinit var useCase: SendMessageUseCase + + @Before + fun setUp() { + nodeRepository = mockk(relaxed = true) + serviceRepository = mockk(relaxed = true) + homoglyphEncodingPrefs = mockk(relaxed = true) + + useCase = + SendMessageUseCase( + nodeRepository = nodeRepository, + serviceRepository = serviceRepository, + homoglyphEncodingPrefs = homoglyphEncodingPrefs, + ) + + mockkConstructor(Capabilities::class) + } + + @Test + fun `invoke with broadcast message simply sends data packet`() = runTest { + // Arrange + val ourNode = mockk(relaxed = true) + every { ourNode.user.id } returns "!1234" + every { nodeRepository.ourNodeInfo } returns MutableStateFlow(ourNode) + every { homoglyphEncodingPrefs.homoglyphEncodingEnabled } returns false + + // Act + useCase("Hello broadcast", "0${DataPacket.ID_BROADCAST}", null) + + // Assert + coVerify(exactly = 0) { serviceRepository.onServiceAction(any()) } + coVerify(exactly = 1) { serviceRepository.meshService?.send(any()) } + } + + @Test + fun `invoke with direct message to older firmware triggers favoriteNode`() = runTest { + // Arrange + val ourNode = mockk(relaxed = true) + val metadata = mockk(relaxed = true) + every { ourNode.user.id } returns "!local" + every { ourNode.user.role } returns Config.DeviceConfig.Role.CLIENT + every { ourNode.metadata } returns metadata + every { metadata.firmware_version } returns "2.0.0" // Older firmware + every { nodeRepository.ourNodeInfo } returns MutableStateFlow(ourNode) + + val destNode = mockk(relaxed = true) + every { destNode.isFavorite } returns false + every { nodeRepository.getNode("!dest") } returns destNode + + every { homoglyphEncodingPrefs.homoglyphEncodingEnabled } returns false + + every { anyConstructed().canSendVerifiedContacts } returns false + + // Act + useCase("Direct message", "!dest", null) + + // Assert + coVerify(exactly = 1) { serviceRepository.onServiceAction(match { it is ServiceAction.Favorite }) } + coVerify(exactly = 1) { serviceRepository.meshService?.send(any()) } + } + + @Test + fun `invoke with direct message to new firmware triggers sendSharedContact`() = runTest { + // Arrange + val ourNode = mockk(relaxed = true) + val metadata = mockk(relaxed = true) + every { ourNode.user.id } returns "!local" + every { ourNode.user.role } returns Config.DeviceConfig.Role.CLIENT + every { ourNode.metadata } returns metadata + every { metadata.firmware_version } returns "2.7.12" // Newer firmware + every { nodeRepository.ourNodeInfo } returns MutableStateFlow(ourNode) + + val destNode = mockk(relaxed = true) + every { nodeRepository.getNode("!dest") } returns destNode + + every { homoglyphEncodingPrefs.homoglyphEncodingEnabled } returns false + + every { anyConstructed().canSendVerifiedContacts } returns true + + // Act + useCase("Direct message", "!dest", null) + + // Assert + coVerify(exactly = 1) { serviceRepository.onServiceAction(match { it is ServiceAction.SendContact }) } + coVerify(exactly = 1) { serviceRepository.meshService?.send(any()) } + } + + @Test + fun `invoke with homoglyph enabled transforms text`() = runTest { + // Arrange + val ourNode = mockk(relaxed = true) + every { nodeRepository.ourNodeInfo } returns MutableStateFlow(ourNode) + every { homoglyphEncodingPrefs.homoglyphEncodingEnabled } returns true + + // Let's use a cyrillic character 'A' (U+0410) that will be mapped to Latin 'A' + val originalText = "\u0410pple" + + // Act + useCase(originalText, "0${DataPacket.ID_BROADCAST}", null) + + // Assert + // We verify that send was called with the transformed text (Latin 'A'pple) + coVerify(exactly = 1) { serviceRepository.meshService?.send(match { it.text?.contains("Apple") == true }) } + } +} diff --git a/feature/node/src/test/kotlin/org/meshtastic/feature/node/domain/usecase/GetFilteredNodesUseCaseTest.kt b/feature/node/src/test/kotlin/org/meshtastic/feature/node/domain/usecase/GetFilteredNodesUseCaseTest.kt new file mode 100644 index 0000000000..1ddfba0f37 --- /dev/null +++ b/feature/node/src/test/kotlin/org/meshtastic/feature/node/domain/usecase/GetFilteredNodesUseCaseTest.kt @@ -0,0 +1,119 @@ +/* + * 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 . + */ +package org.meshtastic.feature.node.domain.usecase + +import io.mockk.every +import io.mockk.mockk +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.test.runTest +import org.junit.Assert.assertEquals +import org.junit.Before +import org.junit.Test +import org.meshtastic.core.data.repository.NodeRepository +import org.meshtastic.core.database.model.Node +import org.meshtastic.core.database.model.NodeSortOption +import org.meshtastic.feature.node.list.NodeFilterState +import org.meshtastic.proto.Config +import org.meshtastic.proto.User + +class GetFilteredNodesUseCaseTest { + + private lateinit var nodeRepository: NodeRepository + private lateinit var useCase: GetFilteredNodesUseCase + + @Before + fun setUp() { + nodeRepository = mockk() + useCase = GetFilteredNodesUseCase(nodeRepository) + } + + private fun createNode( + num: Int, + role: Config.DeviceConfig.Role = Config.DeviceConfig.Role.CLIENT, + ignored: Boolean = false, + name: String = "Node$num", + ): Node { + val user = User(id = "!$num", long_name = name, short_name = "N$num", role = role) + return Node(num = num, user = user, isIgnored = ignored) + } + + @Test + fun `invoke applies repository filters and returns nodes`() = runTest { + // Arrange + val nodes = listOf(createNode(1), createNode(2)) + val filter = NodeFilterState(filterText = "Node", includeUnknown = true) + + every { + nodeRepository.getNodes( + sort = NodeSortOption.LAST_HEARD, + filter = "Node", + includeUnknown = true, + onlyOnline = false, + onlyDirect = false, + ) + } returns flowOf(nodes) + + // Act + val result = useCase(filter, NodeSortOption.LAST_HEARD).first() + + // Assert + assertEquals(2, result.size) + assertEquals(1, result[0].num) + } + + @Test + fun `invoke filters out ignored nodes if showIgnored is false`() = runTest { + // Arrange + val normalNode = createNode(1, ignored = false) + val ignoredNode = createNode(2, ignored = true) + val filter = NodeFilterState(showIgnored = false) + + every { nodeRepository.getNodes(any(), any(), any(), any(), any()) } returns + flowOf(listOf(normalNode, ignoredNode)) + + // Act + val result = useCase(filter, NodeSortOption.LAST_HEARD).first() + + // Assert + assertEquals(1, result.size) + assertEquals(1, result.first().num) + } + + @Test + fun `invoke filters out infrastructure nodes if excludeInfrastructure is true`() = runTest { + // Arrange + val clientNode = createNode(1, role = Config.DeviceConfig.Role.CLIENT) + val routerNode = createNode(2, role = Config.DeviceConfig.Role.ROUTER) + + @Suppress("DEPRECATION") + val repeaterNode = createNode(3, role = Config.DeviceConfig.Role.REPEATER) + val clientBaseNode = createNode(4, role = Config.DeviceConfig.Role.CLIENT_BASE) + val filter = NodeFilterState(excludeInfrastructure = true) + + every { nodeRepository.getNodes(any(), any(), any(), any(), any()) } returns + flowOf(listOf(clientNode, routerNode, repeaterNode, clientBaseNode)) + + // Act + val result = useCase(filter, NodeSortOption.LAST_HEARD).first() + + // Assert + // Should only keep the CLIENT node, others are infrastructure + assertEquals(1, result.size) + assertEquals(1, result.first().num) + } +} From dbafda905c47af9d5097a719277fa69b3ca4d681 Mon Sep 17 00:00:00 2001 From: James Rich <2199651+jamesarich@users.noreply.github.com> Date: Sun, 22 Feb 2026 12:50:45 -0600 Subject: [PATCH 08/18] feat(i18n): Update Crowdin source path for Compose Resources The source path in the `crowdin.yml` configuration has been updated to align with the directory structure of Compose Resources. The path was changed from `/**/src/commonMain/composeResources/values/strings.xml` to `/**/composeResources/values/strings.xml` to correctly locate the source `strings.xml` file for translation. Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com> --- crowdin.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crowdin.yml b/crowdin.yml index ff4020a884..f37d09a27c 100644 --- a/crowdin.yml +++ b/crowdin.yml @@ -1,5 +1,5 @@ files: - - source: /**/src/commonMain/composeResources/values/strings.xml + - source: /**/composeResources/values/strings.xml translation: /%original_path%-%two_letters_code%/strings.xml translate_attributes: 0 content_segmentation: 0 From 9995ea87e581c438d90c374389f061b80c54511e Mon Sep 17 00:00:00 2001 From: James Rich <2199651+jamesarich@users.noreply.github.com> Date: Sun, 22 Feb 2026 13:01:02 -0600 Subject: [PATCH 09/18] chore: migrate core:strings to core:resources --- AGENTS.md | 6 +- CONTRIBUTING.md | 6 +- app/README.md | 2 +- app/build.gradle.kts | 2 +- .../java/com/geeksville/mesh/MainActivity.kt | 4 +- .../usecase/GetDiscoveredDevicesUseCase.kt | 4 +- .../com/geeksville/mesh/model/UIViewModel.kt | 6 +- .../mesh/navigation/NodesNavigation.kt | 20 ++--- .../mesh/service/MeshConnectionManager.kt | 12 +-- .../mesh/service/MeshDataHandler.kt | 12 +-- .../mesh/service/MeshNeighborInfoHandler.kt | 6 +- .../service/MeshServiceNotificationsImpl.kt | 38 ++++---- .../mesh/service/MeshTracerouteHandler.kt | 12 +-- .../main/java/com/geeksville/mesh/ui/Main.kt | 38 ++++---- .../mesh/ui/connections/ConnectionsScreen.kt | 20 ++--- .../ui/connections/components/BLEDevices.kt | 4 +- .../components/ConnectingDeviceInfo.kt | 6 +- .../components/ConnectionsSegmentedBar.kt | 8 +- .../components/CurrentlyConnectedInfo.kt | 6 +- .../connections/components/DeviceListItem.kt | 10 +-- .../connections/components/NetworkDevices.kt | 20 ++--- .../ui/connections/components/UsbDevices.kt | 4 +- .../mesh/ui/contact/AdaptiveContactsScreen.kt | 4 +- .../geeksville/mesh/ui/contact/ContactItem.kt | 8 +- .../geeksville/mesh/ui/contact/Contacts.kt | 42 ++++----- .../mesh/ui/contact/ContactsViewModel.kt | 4 +- .../mesh/ui/node/AdaptiveNodeListScreen.kt | 4 +- .../com/geeksville/mesh/ui/sharing/Channel.kt | 28 +++--- .../com/geeksville/mesh/ui/sharing/Share.kt | 12 +-- .../kotlin/org/meshtastic/buildlogic/Dokka.kt | 2 +- .../kotlin/org/meshtastic/buildlogic/Kover.kt | 2 +- core/barcode/README.md | 2 +- core/barcode/build.gradle.kts | 2 +- .../core/barcode/BarcodeScannerProvider.kt | 4 +- .../core/barcode/BarcodeScannerProvider.kt | 4 +- core/database/README.md | 2 +- core/database/build.gradle.kts | 2 +- .../meshtastic/core/database/model/Message.kt | 54 ++++++------ .../core/database/model/NodeSortOption.kt | 16 ++-- core/{strings => resources}/README.md | 10 +-- core/{strings => resources}/build.gradle.kts | 2 +- .../org/meshtastic/core/strings/ContextExt.kt | 2 +- .../composeResources/values-ar/strings.xml | 0 .../composeResources/values-be/strings.xml | 0 .../composeResources/values-bg/strings.xml | 0 .../composeResources/values-ca/strings.xml | 0 .../composeResources/values-cs/strings.xml | 0 .../composeResources/values-de/strings.xml | 0 .../composeResources/values-el/strings.xml | 0 .../composeResources/values-es/strings.xml | 0 .../composeResources/values-et/strings.xml | 0 .../composeResources/values-fi/strings.xml | 0 .../composeResources/values-fr/strings.xml | 0 .../composeResources/values-ga/strings.xml | 0 .../composeResources/values-gl/strings.xml | 0 .../composeResources/values-he/strings.xml | 0 .../composeResources/values-hr/strings.xml | 0 .../composeResources/values-ht/strings.xml | 0 .../composeResources/values-hu/strings.xml | 0 .../composeResources/values-is/strings.xml | 0 .../composeResources/values-it/strings.xml | 0 .../composeResources/values-ja/strings.xml | 0 .../composeResources/values-ko/strings.xml | 0 .../composeResources/values-lt/strings.xml | 0 .../composeResources/values-nl/strings.xml | 0 .../composeResources/values-no/strings.xml | 0 .../composeResources/values-pl/strings.xml | 0 .../values-pt-rBR/strings.xml | 0 .../composeResources/values-pt/strings.xml | 0 .../composeResources/values-ro/strings.xml | 0 .../composeResources/values-ru/strings.xml | 0 .../composeResources/values-sk/strings.xml | 0 .../composeResources/values-sl/strings.xml | 0 .../composeResources/values-sq/strings.xml | 0 .../composeResources/values-sr/strings.xml | 0 .../composeResources/values-srp/strings.xml | 0 .../composeResources/values-sv/strings.xml | 0 .../composeResources/values-tr/strings.xml | 0 .../composeResources/values-uk/strings.xml | 0 .../values-zh-rCN/strings.xml | 0 .../values-zh-rTW/strings.xml | 0 .../composeResources/values/strings.xml | 0 core/ui/README.md | 6 +- core/ui/build.gradle.kts | 2 +- .../core/ui/component/AlertDialogs.kt | 6 +- .../core/ui/component/BitwisePreference.kt | 6 +- .../core/ui/component/ChannelInfo.kt | 4 +- .../core/ui/component/ContactSharing.kt | 4 +- .../core/ui/component/CopyIconButton.kt | 4 +- .../core/ui/component/DistanceInfo.kt | 4 +- .../core/ui/component/EditBase64Preference.kt | 6 +- .../core/ui/component/EditListPreference.kt | 14 +-- .../ui/component/EditPasswordPreference.kt | 6 +- .../core/ui/component/EditTextPreference.kt | 4 +- .../core/ui/component/ElevationInfo.kt | 6 +- .../meshtastic/core/ui/component/HopsInfo.kt | 4 +- .../meshtastic/core/ui/component/ImportFab.kt | 32 +++---- .../core/ui/component/IndoorAirQuality.kt | 8 +- .../core/ui/component/LastHeardInfo.kt | 4 +- .../core/ui/component/LoraSignalIndicator.kt | 18 ++-- .../core/ui/component/MainAppBar.kt | 6 +- .../core/ui/component/MaterialBatteryInfo.kt | 4 +- .../component/MaterialBluetoothSignalInfo.kt | 4 +- .../core/ui/component/NodeKeyStatusIcon.kt | 26 +++--- .../component/PositionPrecisionPreference.kt | 6 +- .../meshtastic/core/ui/component/QrDialog.kt | 10 +-- .../core/ui/component/SatelliteCountInfo.kt | 4 +- .../core/ui/component/SecurityIcon.kt | 32 +++---- .../core/ui/component/SignalInfo.kt | 4 +- .../core/ui/component/TelemetryInfo.kt | 26 +++--- .../core/ui/component/TransportIcon.kt | 10 +-- .../core/ui/qr/ScannedQrCodeDialog.kt | 16 ++-- .../core/ui/share/SharedContactDialog.kt | 12 +-- .../org/meshtastic/core/ui/util/FormatAgo.kt | 8 +- .../core/ui/util/ModelExtensions.kt | 26 +++--- .../core/ui/util/ProtoExtensions.kt | 4 +- feature/firmware/README.md | 2 +- feature/firmware/build.gradle.kts | 2 +- .../feature/firmware/FirmwareDfuService.kt | 6 +- .../feature/firmware/FirmwareUpdateScreen.kt | 88 +++++++++---------- .../firmware/FirmwareUpdateViewModel.kt | 44 +++++----- .../feature/firmware/NordicDfuHandler.kt | 10 +-- .../feature/firmware/UsbUpdateHandler.kt | 10 +-- .../firmware/ota/Esp32OtaUpdateHandler.kt | 22 ++--- feature/intro/README.md | 2 +- feature/intro/build.gradle.kts | 2 +- .../feature/intro/AnalyticsIntro.kt | 14 +-- .../feature/intro/AppIntroductionScreen.kt | 6 +- .../feature/intro/BluetoothScreen.kt | 20 ++--- .../feature/intro/CriticalAlertsScreen.kt | 10 +-- .../feature/intro/LocationScreen.kt | 28 +++--- .../feature/intro/NotificationsScreen.kt | 24 ++--- .../feature/intro/PermissionScreenLayout.kt | 4 +- .../meshtastic/feature/intro/WelcomeScreen.kt | 20 ++--- feature/map/README.md | 2 +- feature/map/build.gradle.kts | 2 +- .../org/meshtastic/feature/map/MapView.kt | 64 +++++++------- .../feature/map/component/CacheLayout.kt | 10 +-- .../feature/map/component/DownloadButton.kt | 4 +- .../map/component/EditWaypointDialog.kt | 24 ++--- .../feature/map/component/MapButton.kt | 4 +- .../org/meshtastic/feature/map/MapView.kt | 20 ++--- .../map/component/ClusterItemsListDialog.kt | 6 +- .../map/component/CustomMapLayersSheet.kt | 16 ++-- .../CustomTileProviderManagerSheet.kt | 30 +++---- .../map/component/EditWaypointDialog.kt | 24 ++--- .../map/component/MapControlsOverlay.kt | 12 +-- .../map/component/MapFilterDropdown.kt | 10 +-- .../feature/map/component/MapTypeDropdown.kt | 14 +-- .../feature/map/component/WaypointMarkers.kt | 4 +- .../feature/map/BaseMapViewModel.kt | 12 +-- .../org/meshtastic/feature/map/MapScreen.kt | 4 +- feature/messaging/README.md | 2 +- feature/messaging/build.gradle.kts | 2 +- .../feature/messaging/DeliveryInfoDialog.kt | 8 +- .../meshtastic/feature/messaging/Message.kt | 52 +++++------ .../feature/messaging/MessageListPaged.kt | 4 +- .../meshtastic/feature/messaging/QuickChat.kt | 24 ++--- .../messaging/component/MessageActions.kt | 8 +- .../component/MessageActionsBottomSheet.kt | 12 +-- .../messaging/component/MessageItem.kt | 10 +-- .../feature/messaging/component/Reaction.kt | 16 ++-- feature/node/README.md | 2 +- feature/node/build.gradle.kts | 2 +- feature/node/component/DeviceActions.kt | 18 ++-- .../node/component/AdministrationSection.kt | 18 ++-- .../node/component/CompassBottomSheet.kt | 28 +++--- .../feature/node/component/DeviceActions.kt | 16 ++-- .../node/component/DeviceDetailsSection.kt | 10 +-- .../feature/node/component/DistanceInfo.kt | 4 +- .../feature/node/component/ElevationInfo.kt | 6 +- .../node/component/EnvironmentMetrics.kt | 34 +++---- .../component/FirmwareReleaseSheetContent.kt | 8 +- .../feature/node/component/HopsInfo.kt | 4 +- .../feature/node/component/InfoCard.kt | 4 +- .../feature/node/component/LastHeardInfo.kt | 4 +- .../node/component/LinkedCoordinatesItem.kt | 8 +- .../node/component/NodeDetailComponents.kt | 4 +- .../node/component/NodeDetailsSection.kt | 40 ++++----- .../node/component/NodeFilterTextField.kt | 24 ++--- .../feature/node/component/NodeItem.kt | 16 ++-- .../feature/node/component/NodeStatusIcons.kt | 18 ++-- .../feature/node/component/NotesSection.kt | 8 +- .../feature/node/component/PositionSection.kt | 8 +- .../feature/node/component/PowerMetrics.kt | 8 +- .../node/component/SatelliteCountInfo.kt | 4 +- .../component/TelemetricActionsSection.kt | 12 +-- .../feature/node/component/TelemetryInfo.kt | 22 ++--- .../feature/node/detail/NodeDetailScreen.kt | 8 +- .../node/detail/NodeManagementActions.kt | 26 +++--- .../feature/node/detail/NodeRequestActions.kt | 26 +++--- .../domain/usecase/GetNodeDetailsUseCase.kt | 6 +- .../feature/node/list/NodeListScreen.kt | 22 ++--- .../feature/node/metrics/BaseMetricChart.kt | 6 +- .../feature/node/metrics/CommonCharts.kt | 12 +-- .../feature/node/metrics/DeviceMetrics.kt | 20 ++--- .../feature/node/metrics/EnvironmentCharts.kt | 18 ++-- .../node/metrics/EnvironmentMetrics.kt | 30 +++---- .../feature/node/metrics/HostMetricsLog.kt | 14 +-- .../feature/node/metrics/MetricsViewModel.kt | 8 +- .../feature/node/metrics/NeighborInfoLog.kt | 8 +- .../feature/node/metrics/PaxMetrics.kt | 16 ++-- .../feature/node/metrics/PositionLog.kt | 22 ++--- .../feature/node/metrics/PowerMetrics.kt | 16 ++-- .../feature/node/metrics/SignalMetrics.kt | 14 +-- .../feature/node/metrics/TracerouteLog.kt | 24 ++--- .../node/metrics/TracerouteMapScreen.kt | 10 +-- .../meshtastic/feature/node/model/LogsType.kt | 22 ++--- .../feature/node/model/TimeFrame.kt | 14 +-- .../node/metrics/BaseMetricScreenTest.kt | 4 +- feature/settings/README.md | 2 +- feature/settings/build.gradle.kts | 2 +- .../settings/debugging/DebugFiltersTest.kt | 8 +- .../settings/debugging/DebugSearchTest.kt | 10 +-- .../component/EditDeviceProfileDialogTest.kt | 8 +- .../component/MapReportingPreferenceTest.kt | 10 +-- .../feature/settings/AboutScreen.kt | 4 +- .../feature/settings/SettingsScreen.kt | 54 ++++++------ .../feature/settings/debugging/Debug.kt | 32 +++---- .../settings/debugging/DebugFilters.kt | 20 ++--- .../feature/settings/debugging/DebugSearch.kt | 12 +-- .../settings/debugging/DebugViewModel.kt | 6 +- .../settings/filter/FilterSettingsScreen.kt | 24 ++--- .../settings/navigation/ConfigRoute.kt | 22 ++--- .../settings/navigation/ModuleRoute.kt | 30 +++---- .../settings/radio/CleanNodeDatabaseScreen.kt | 14 +-- .../radio/CleanNodeDatabaseViewModel.kt | 8 +- .../feature/settings/radio/RadioConfig.kt | 36 ++++---- .../settings/radio/RadioConfigViewModel.kt | 4 +- .../radio/channel/ChannelConfigScreen.kt | 14 +-- .../radio/channel/component/ChannelCard.kt | 4 +- .../channel/component/ChannelConfigHeader.kt | 8 +- .../radio/channel/component/ChannelLegend.kt | 34 +++---- .../channel/component/EditChannelDialog.kt | 14 +-- .../AmbientLightingConfigItemList.kt | 16 ++-- .../radio/component/AudioConfigItemList.kt | 20 ++--- .../component/BluetoothConfigItemList.kt | 12 +-- .../component/CannedMessageConfigItemList.kt | 30 +++---- .../DetectionSensorConfigItemList.kt | 22 ++--- .../radio/component/DeviceConfigItemList.kt | 88 +++++++++---------- .../radio/component/DisplayConfigItemList.kt | 50 +++++------ .../component/EditDeviceProfileDialog.kt | 18 ++-- .../ExternalNotificationConfigItemList.kt | 48 +++++----- .../radio/component/LoRaConfigItemList.kt | 48 +++++----- .../radio/component/MQTTConfigItemList.kt | 28 +++--- .../radio/component/MapReportingPreference.kt | 16 ++-- .../component/NeighborInfoConfigItemList.kt | 14 +-- .../radio/component/NetworkConfigItemList.kt | 58 ++++++------ .../component/PacketResponseStateDialog.kt | 8 +- .../component/PaxcounterConfigItemList.kt | 14 +-- .../radio/component/PositionConfigItemList.kt | 50 +++++------ .../radio/component/PowerConfigItemList.kt | 24 ++--- .../radio/component/RadioConfigScreenList.kt | 6 +- .../component/RangeTestConfigItemList.kt | 12 +-- .../component/RemoteHardwareConfigItemList.kt | 12 +-- .../radio/component/SecurityConfigItemList.kt | 46 +++++----- .../radio/component/SerialConfigItemList.kt | 18 ++-- .../component/ShutdownConfirmationDialog.kt | 10 +-- .../component/StatusMessageConfigItemList.kt | 10 +-- .../component/StoreForwardConfigItemList.kt | 18 ++-- .../component/TelemetryConfigItemList.kt | 30 +++---- .../radio/component/UserConfigItemList.kt | 22 ++--- .../settings/radio/component/WarningDialog.kt | 6 +- .../settings/util/FixedUpdateIntervals.kt | 12 +-- .../feature/settings/util/LanguageUtils.kt | 12 +-- .../feature/settings/HomoglyphSettingTest.kt | 6 +- settings.gradle.kts | 2 +- 267 files changed, 1672 insertions(+), 1672 deletions(-) rename core/{strings => resources}/README.md (78%) rename core/{strings => resources}/build.gradle.kts (94%) rename core/{strings => resources}/src/androidMain/kotlin/org/meshtastic/core/strings/ContextExt.kt (97%) rename core/{strings => resources}/src/commonMain/composeResources/values-ar/strings.xml (100%) rename core/{strings => resources}/src/commonMain/composeResources/values-be/strings.xml (100%) rename core/{strings => resources}/src/commonMain/composeResources/values-bg/strings.xml (100%) rename core/{strings => resources}/src/commonMain/composeResources/values-ca/strings.xml (100%) rename core/{strings => resources}/src/commonMain/composeResources/values-cs/strings.xml (100%) rename core/{strings => resources}/src/commonMain/composeResources/values-de/strings.xml (100%) rename core/{strings => resources}/src/commonMain/composeResources/values-el/strings.xml (100%) rename core/{strings => resources}/src/commonMain/composeResources/values-es/strings.xml (100%) rename core/{strings => resources}/src/commonMain/composeResources/values-et/strings.xml (100%) rename core/{strings => resources}/src/commonMain/composeResources/values-fi/strings.xml (100%) rename core/{strings => resources}/src/commonMain/composeResources/values-fr/strings.xml (100%) rename core/{strings => resources}/src/commonMain/composeResources/values-ga/strings.xml (100%) rename core/{strings => resources}/src/commonMain/composeResources/values-gl/strings.xml (100%) rename core/{strings => resources}/src/commonMain/composeResources/values-he/strings.xml (100%) rename core/{strings => resources}/src/commonMain/composeResources/values-hr/strings.xml (100%) rename core/{strings => resources}/src/commonMain/composeResources/values-ht/strings.xml (100%) rename core/{strings => resources}/src/commonMain/composeResources/values-hu/strings.xml (100%) rename core/{strings => resources}/src/commonMain/composeResources/values-is/strings.xml (100%) rename core/{strings => resources}/src/commonMain/composeResources/values-it/strings.xml (100%) rename core/{strings => resources}/src/commonMain/composeResources/values-ja/strings.xml (100%) rename core/{strings => resources}/src/commonMain/composeResources/values-ko/strings.xml (100%) rename core/{strings => resources}/src/commonMain/composeResources/values-lt/strings.xml (100%) rename core/{strings => resources}/src/commonMain/composeResources/values-nl/strings.xml (100%) rename core/{strings => resources}/src/commonMain/composeResources/values-no/strings.xml (100%) rename core/{strings => resources}/src/commonMain/composeResources/values-pl/strings.xml (100%) rename core/{strings => resources}/src/commonMain/composeResources/values-pt-rBR/strings.xml (100%) rename core/{strings => resources}/src/commonMain/composeResources/values-pt/strings.xml (100%) rename core/{strings => resources}/src/commonMain/composeResources/values-ro/strings.xml (100%) rename core/{strings => resources}/src/commonMain/composeResources/values-ru/strings.xml (100%) rename core/{strings => resources}/src/commonMain/composeResources/values-sk/strings.xml (100%) rename core/{strings => resources}/src/commonMain/composeResources/values-sl/strings.xml (100%) rename core/{strings => resources}/src/commonMain/composeResources/values-sq/strings.xml (100%) rename core/{strings => resources}/src/commonMain/composeResources/values-sr/strings.xml (100%) rename core/{strings => resources}/src/commonMain/composeResources/values-srp/strings.xml (100%) rename core/{strings => resources}/src/commonMain/composeResources/values-sv/strings.xml (100%) rename core/{strings => resources}/src/commonMain/composeResources/values-tr/strings.xml (100%) rename core/{strings => resources}/src/commonMain/composeResources/values-uk/strings.xml (100%) rename core/{strings => resources}/src/commonMain/composeResources/values-zh-rCN/strings.xml (100%) rename core/{strings => resources}/src/commonMain/composeResources/values-zh-rTW/strings.xml (100%) rename core/{strings => resources}/src/commonMain/composeResources/values/strings.xml (100%) diff --git a/AGENTS.md b/AGENTS.md index ae128ca37f..2d1705a95c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -37,8 +37,8 @@ This file serves as a comprehensive guide for AI agents and developers working o - **Usage:** ```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)) ``` @@ -118,7 +118,7 @@ This file serves as a comprehensive guide for AI agents and developers working o ## 7. Troubleshooting -- **Missing Strings:** If `Res.string.xyz` is unresolved, ensure you have imported `org.meshtastic.core.strings.Res` and the specific string property, and that you have run a build to generate the resources. +- **Missing Strings:** If `Res.string.xyz` is unresolved, ensure you have imported `org.meshtastic.core.resources.Res` and the specific string property, and that you have run a build to generate the resources. - **Build Errors:** Check `gradle/libs.versions.toml` for version conflicts. Use `build-logic` conventions to ensure plugins are applied correctly. --- diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b47041cebb..be72c6fae0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -19,14 +19,14 @@ Thank you for your interest in contributing to Meshtastic-Android! We welcome co - Write clear, descriptive variable and function names. - Add comments where necessary, especially for complex logic. - Keep methods and classes focused and concise. -- **Strings:** Use localised strings via the **Compose Multiplatform Resource** library in `:core:strings`. +- **Strings:** Use localised strings via the **Compose Multiplatform Resource** library in `:core:resources`. - Do **not** use the legacy `app/src/main/res/values/strings.xml`. - **Definition:** Add strings to `core/strings/src/commonMain/composeResources/values/strings.xml`. - **Usage:** ```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)) ``` diff --git a/app/README.md b/app/README.md index 6dd8c1ca7b..d61f3a4183 100644 --- a/app/README.md +++ b/app/README.md @@ -39,7 +39,7 @@ graph TB :app -.-> :core:prefs :app -.-> :core:proto :app -.-> :core:service - :app -.-> :core:strings + :app -.-> :core:resources :app -.-> :core:ui :app -.-> :core:barcode :app -.-> :feature:intro diff --git a/app/build.gradle.kts b/app/build.gradle.kts index bb527ad341..1743e37bce 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -224,7 +224,7 @@ dependencies { implementation(projects.core.prefs) implementation(projects.core.proto) implementation(projects.core.service) - implementation(projects.core.strings) + implementation(projects.core.resources) implementation(projects.core.ui) implementation(projects.core.barcode) implementation(projects.feature.intro) diff --git a/app/src/main/java/com/geeksville/mesh/MainActivity.kt b/app/src/main/java/com/geeksville/mesh/MainActivity.kt index ef82258384..3b5dffc1e3 100644 --- a/app/src/main/java/com/geeksville/mesh/MainActivity.kt +++ b/app/src/main/java/com/geeksville/mesh/MainActivity.kt @@ -50,8 +50,8 @@ import no.nordicsemi.kotlin.ble.core.android.AndroidEnvironment import no.nordicsemi.kotlin.ble.environment.android.compose.LocalEnvironmentOwner import org.meshtastic.core.model.util.dispatchMeshtasticUri import org.meshtastic.core.navigation.DEEP_LINK_BASE_URI -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.channel_invalid +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.channel_invalid import org.meshtastic.core.ui.theme.AppTheme import org.meshtastic.core.ui.theme.MODE_DYNAMIC import org.meshtastic.core.ui.util.showToast diff --git a/app/src/main/java/com/geeksville/mesh/domain/usecase/GetDiscoveredDevicesUseCase.kt b/app/src/main/java/com/geeksville/mesh/domain/usecase/GetDiscoveredDevicesUseCase.kt index 7aef2d9ba3..a6759dae6c 100644 --- a/app/src/main/java/com/geeksville/mesh/domain/usecase/GetDiscoveredDevicesUseCase.kt +++ b/app/src/main/java/com/geeksville/mesh/domain/usecase/GetDiscoveredDevicesUseCase.kt @@ -34,8 +34,8 @@ import org.meshtastic.core.database.DatabaseManager import org.meshtastic.core.database.model.Node import org.meshtastic.core.datastore.RecentAddressesDataSource import org.meshtastic.core.datastore.model.RecentAddress -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.meshtastic +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.meshtastic import java.util.Locale import javax.inject.Inject diff --git a/app/src/main/java/com/geeksville/mesh/model/UIViewModel.kt b/app/src/main/java/com/geeksville/mesh/model/UIViewModel.kt index 87e0519325..fa8fec8f8e 100644 --- a/app/src/main/java/com/geeksville/mesh/model/UIViewModel.kt +++ b/app/src/main/java/com/geeksville/mesh/model/UIViewModel.kt @@ -57,9 +57,9 @@ import org.meshtastic.core.service.IMeshService import org.meshtastic.core.service.MeshServiceNotifications import org.meshtastic.core.service.ServiceRepository import org.meshtastic.core.service.TracerouteResponse -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.client_notification -import org.meshtastic.core.strings.compromised_keys +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.client_notification +import org.meshtastic.core.resources.compromised_keys import org.meshtastic.core.ui.component.ScrollToTopEvent import org.meshtastic.core.ui.util.AlertManager import org.meshtastic.core.ui.util.ComposableContent diff --git a/app/src/main/java/com/geeksville/mesh/navigation/NodesNavigation.kt b/app/src/main/java/com/geeksville/mesh/navigation/NodesNavigation.kt index 0a8e50f344..d9fded5b43 100644 --- a/app/src/main/java/com/geeksville/mesh/navigation/NodesNavigation.kt +++ b/app/src/main/java/com/geeksville/mesh/navigation/NodesNavigation.kt @@ -46,16 +46,16 @@ import org.meshtastic.core.navigation.DEEP_LINK_BASE_URI import org.meshtastic.core.navigation.NodeDetailRoutes import org.meshtastic.core.navigation.NodesRoutes import org.meshtastic.core.navigation.Route -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.device -import org.meshtastic.core.strings.environment -import org.meshtastic.core.strings.host -import org.meshtastic.core.strings.neighbor_info -import org.meshtastic.core.strings.pax -import org.meshtastic.core.strings.position_log -import org.meshtastic.core.strings.power -import org.meshtastic.core.strings.signal -import org.meshtastic.core.strings.traceroute +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.device +import org.meshtastic.core.resources.environment +import org.meshtastic.core.resources.host +import org.meshtastic.core.resources.neighbor_info +import org.meshtastic.core.resources.pax +import org.meshtastic.core.resources.position_log +import org.meshtastic.core.resources.power +import org.meshtastic.core.resources.signal +import org.meshtastic.core.resources.traceroute import org.meshtastic.core.ui.component.ScrollToTopEvent import org.meshtastic.feature.map.node.NodeMapScreen import org.meshtastic.feature.map.node.NodeMapViewModel diff --git a/app/src/main/java/com/geeksville/mesh/service/MeshConnectionManager.kt b/app/src/main/java/com/geeksville/mesh/service/MeshConnectionManager.kt index 4512b7a7d2..e25febf4ad 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshConnectionManager.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshConnectionManager.kt @@ -38,12 +38,12 @@ import org.meshtastic.core.data.repository.RadioConfigRepository import org.meshtastic.core.prefs.ui.UiPrefs import org.meshtastic.core.service.ConnectionState import org.meshtastic.core.service.MeshServiceNotifications -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.connected_count -import org.meshtastic.core.strings.connecting -import org.meshtastic.core.strings.device_sleeping -import org.meshtastic.core.strings.disconnected -import org.meshtastic.core.strings.getString +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.connected_count +import org.meshtastic.core.resources.connecting +import org.meshtastic.core.resources.device_sleeping +import org.meshtastic.core.resources.disconnected +import org.meshtastic.core.resources.getString import org.meshtastic.proto.AdminMessage import org.meshtastic.proto.Config import org.meshtastic.proto.Telemetry diff --git a/app/src/main/java/com/geeksville/mesh/service/MeshDataHandler.kt b/app/src/main/java/com/geeksville/mesh/service/MeshDataHandler.kt index bc880d4111..c036241f72 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshDataHandler.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshDataHandler.kt @@ -46,12 +46,12 @@ import org.meshtastic.core.prefs.mesh.MeshPrefs import org.meshtastic.core.service.MeshServiceNotifications import org.meshtastic.core.service.ServiceRepository import org.meshtastic.core.service.filter.MessageFilterService -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.critical_alert -import org.meshtastic.core.strings.error_duty_cycle -import org.meshtastic.core.strings.getString -import org.meshtastic.core.strings.unknown_username -import org.meshtastic.core.strings.waypoint_received +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.critical_alert +import org.meshtastic.core.resources.error_duty_cycle +import org.meshtastic.core.resources.getString +import org.meshtastic.core.resources.unknown_username +import org.meshtastic.core.resources.waypoint_received import org.meshtastic.proto.AdminMessage import org.meshtastic.proto.MeshPacket import org.meshtastic.proto.Paxcount diff --git a/app/src/main/java/com/geeksville/mesh/service/MeshNeighborInfoHandler.kt b/app/src/main/java/com/geeksville/mesh/service/MeshNeighborInfoHandler.kt index 37694ada0e..333a1a1c85 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshNeighborInfoHandler.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshNeighborInfoHandler.kt @@ -22,9 +22,9 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob import org.meshtastic.core.common.util.nowMillis import org.meshtastic.core.service.ServiceRepository -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.getString -import org.meshtastic.core.strings.unknown_username +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.getString +import org.meshtastic.core.resources.unknown_username import org.meshtastic.proto.MeshPacket import org.meshtastic.proto.NeighborInfo import java.util.Locale diff --git a/app/src/main/java/com/geeksville/mesh/service/MeshServiceNotificationsImpl.kt b/app/src/main/java/com/geeksville/mesh/service/MeshServiceNotificationsImpl.kt index 62fe766e11..b76eccd03f 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshServiceNotificationsImpl.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshServiceNotificationsImpl.kt @@ -55,25 +55,25 @@ import org.meshtastic.core.model.util.formatUptime import org.meshtastic.core.navigation.DEEP_LINK_BASE_URI import org.meshtastic.core.service.MeshServiceNotifications import org.meshtastic.core.service.SERVICE_NOTIFY_ID -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.client_notification -import org.meshtastic.core.strings.getString -import org.meshtastic.core.strings.low_battery_message -import org.meshtastic.core.strings.low_battery_title -import org.meshtastic.core.strings.mark_as_read -import org.meshtastic.core.strings.meshtastic_alerts_notifications -import org.meshtastic.core.strings.meshtastic_app_name -import org.meshtastic.core.strings.meshtastic_broadcast_notifications -import org.meshtastic.core.strings.meshtastic_low_battery_notifications -import org.meshtastic.core.strings.meshtastic_low_battery_temporary_remote_notifications -import org.meshtastic.core.strings.meshtastic_messages_notifications -import org.meshtastic.core.strings.meshtastic_new_nodes_notifications -import org.meshtastic.core.strings.meshtastic_service_notifications -import org.meshtastic.core.strings.meshtastic_waypoints_notifications -import org.meshtastic.core.strings.new_node_seen -import org.meshtastic.core.strings.no_local_stats -import org.meshtastic.core.strings.reply -import org.meshtastic.core.strings.you +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.client_notification +import org.meshtastic.core.resources.getString +import org.meshtastic.core.resources.low_battery_message +import org.meshtastic.core.resources.low_battery_title +import org.meshtastic.core.resources.mark_as_read +import org.meshtastic.core.resources.meshtastic_alerts_notifications +import org.meshtastic.core.resources.meshtastic_app_name +import org.meshtastic.core.resources.meshtastic_broadcast_notifications +import org.meshtastic.core.resources.meshtastic_low_battery_notifications +import org.meshtastic.core.resources.meshtastic_low_battery_temporary_remote_notifications +import org.meshtastic.core.resources.meshtastic_messages_notifications +import org.meshtastic.core.resources.meshtastic_new_nodes_notifications +import org.meshtastic.core.resources.meshtastic_service_notifications +import org.meshtastic.core.resources.meshtastic_waypoints_notifications +import org.meshtastic.core.resources.new_node_seen +import org.meshtastic.core.resources.no_local_stats +import org.meshtastic.core.resources.reply +import org.meshtastic.core.resources.you import org.meshtastic.proto.ClientNotification import org.meshtastic.proto.DeviceMetrics import org.meshtastic.proto.LocalStats diff --git a/app/src/main/java/com/geeksville/mesh/service/MeshTracerouteHandler.kt b/app/src/main/java/com/geeksville/mesh/service/MeshTracerouteHandler.kt index d03c3042a0..daaf84984e 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshTracerouteHandler.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshTracerouteHandler.kt @@ -28,12 +28,12 @@ import org.meshtastic.core.model.fullRouteDiscovery import org.meshtastic.core.model.getFullTracerouteResponse import org.meshtastic.core.service.ServiceRepository import org.meshtastic.core.service.TracerouteResponse -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.getString -import org.meshtastic.core.strings.traceroute_duration -import org.meshtastic.core.strings.traceroute_route_back_to_us -import org.meshtastic.core.strings.traceroute_route_towards_dest -import org.meshtastic.core.strings.unknown_username +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.getString +import org.meshtastic.core.resources.traceroute_duration +import org.meshtastic.core.resources.traceroute_route_back_to_us +import org.meshtastic.core.resources.traceroute_route_towards_dest +import org.meshtastic.core.resources.unknown_username import org.meshtastic.proto.MeshPacket import java.util.Locale import javax.inject.Inject 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 170926b7cc..00d41a18d8 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/Main.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/Main.kt @@ -107,25 +107,25 @@ import org.meshtastic.core.navigation.NodesRoutes import org.meshtastic.core.navigation.Route import org.meshtastic.core.navigation.SettingsRoutes import org.meshtastic.core.service.ConnectionState -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.app_too_old -import org.meshtastic.core.strings.bottom_nav_settings -import org.meshtastic.core.strings.connected -import org.meshtastic.core.strings.connecting -import org.meshtastic.core.strings.connections -import org.meshtastic.core.strings.conversations -import org.meshtastic.core.strings.device_sleeping -import org.meshtastic.core.strings.disconnected -import org.meshtastic.core.strings.firmware_old -import org.meshtastic.core.strings.firmware_too_old -import org.meshtastic.core.strings.map -import org.meshtastic.core.strings.must_update -import org.meshtastic.core.strings.nodes -import org.meshtastic.core.strings.okay -import org.meshtastic.core.strings.should_update -import org.meshtastic.core.strings.should_update_firmware -import org.meshtastic.core.strings.traceroute -import org.meshtastic.core.strings.view_on_map +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.app_too_old +import org.meshtastic.core.resources.bottom_nav_settings +import org.meshtastic.core.resources.connected +import org.meshtastic.core.resources.connecting +import org.meshtastic.core.resources.connections +import org.meshtastic.core.resources.conversations +import org.meshtastic.core.resources.device_sleeping +import org.meshtastic.core.resources.disconnected +import org.meshtastic.core.resources.firmware_old +import org.meshtastic.core.resources.firmware_too_old +import org.meshtastic.core.resources.map +import org.meshtastic.core.resources.must_update +import org.meshtastic.core.resources.nodes +import org.meshtastic.core.resources.okay +import org.meshtastic.core.resources.should_update +import org.meshtastic.core.resources.should_update_firmware +import org.meshtastic.core.resources.traceroute +import org.meshtastic.core.resources.view_on_map import org.meshtastic.core.ui.component.MeshtasticDialog import org.meshtastic.core.ui.component.ScrollToTopEvent import org.meshtastic.core.ui.icon.Conversations diff --git a/app/src/main/java/com/geeksville/mesh/ui/connections/ConnectionsScreen.kt b/app/src/main/java/com/geeksville/mesh/ui/connections/ConnectionsScreen.kt index 6b2873d5b4..2c009810d3 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/connections/ConnectionsScreen.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/connections/ConnectionsScreen.kt @@ -65,16 +65,16 @@ import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.navigation.Route import org.meshtastic.core.navigation.SettingsRoutes import org.meshtastic.core.service.ConnectionState -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.connected -import org.meshtastic.core.strings.connected_device -import org.meshtastic.core.strings.connected_sleeping -import org.meshtastic.core.strings.connecting -import org.meshtastic.core.strings.connections -import org.meshtastic.core.strings.must_set_region -import org.meshtastic.core.strings.no_device_selected -import org.meshtastic.core.strings.not_connected -import org.meshtastic.core.strings.set_your_region +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.connected +import org.meshtastic.core.resources.connected_device +import org.meshtastic.core.resources.connected_sleeping +import org.meshtastic.core.resources.connecting +import org.meshtastic.core.resources.connections +import org.meshtastic.core.resources.must_set_region +import org.meshtastic.core.resources.no_device_selected +import org.meshtastic.core.resources.not_connected +import org.meshtastic.core.resources.set_your_region import org.meshtastic.core.ui.component.ListItem import org.meshtastic.core.ui.component.MainAppBar import org.meshtastic.core.ui.component.TitledCard diff --git a/app/src/main/java/com/geeksville/mesh/ui/connections/components/BLEDevices.kt b/app/src/main/java/com/geeksville/mesh/ui/connections/components/BLEDevices.kt index 8747eca701..fd338b72d3 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/connections/components/BLEDevices.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/connections/components/BLEDevices.kt @@ -38,8 +38,8 @@ import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.ble.MeshtasticBleConstants.BLE_NAME_PATTERN import org.meshtastic.core.ble.MeshtasticBleConstants.SERVICE_UUID import org.meshtastic.core.service.ConnectionState -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.bluetooth_available_devices +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.bluetooth_available_devices /** * Composable that displays a list of Bluetooth Low Energy (BLE) devices and allows scanning. It handles Bluetooth diff --git a/app/src/main/java/com/geeksville/mesh/ui/connections/components/ConnectingDeviceInfo.kt b/app/src/main/java/com/geeksville/mesh/ui/connections/components/ConnectingDeviceInfo.kt index f26aa2e05f..86341f2ce3 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/connections/components/ConnectingDeviceInfo.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/connections/components/ConnectingDeviceInfo.kt @@ -35,9 +35,9 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp import org.jetbrains.compose.resources.stringResource -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.connecting -import org.meshtastic.core.strings.disconnect +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.connecting +import org.meshtastic.core.resources.disconnect import org.meshtastic.core.ui.theme.StatusColors.StatusRed @OptIn(ExperimentalMaterial3ExpressiveApi::class) diff --git a/app/src/main/java/com/geeksville/mesh/ui/connections/components/ConnectionsSegmentedBar.kt b/app/src/main/java/com/geeksville/mesh/ui/connections/components/ConnectionsSegmentedBar.kt index 1b5ed2de5c..15b30c17b2 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/connections/components/ConnectionsSegmentedBar.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/connections/components/ConnectionsSegmentedBar.kt @@ -34,10 +34,10 @@ import androidx.compose.ui.tooling.preview.Preview import com.geeksville.mesh.ui.connections.DeviceType import org.jetbrains.compose.resources.StringResource import org.jetbrains.compose.resources.stringResource -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.bluetooth -import org.meshtastic.core.strings.network -import org.meshtastic.core.strings.serial +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.bluetooth +import org.meshtastic.core.resources.network +import org.meshtastic.core.resources.serial import org.meshtastic.core.ui.theme.AppTheme @Suppress("LambdaParameterEventTrailing") diff --git a/app/src/main/java/com/geeksville/mesh/ui/connections/components/CurrentlyConnectedInfo.kt b/app/src/main/java/com/geeksville/mesh/ui/connections/components/CurrentlyConnectedInfo.kt index f95fe05ba4..e4b7115808 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/connections/components/CurrentlyConnectedInfo.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/connections/components/CurrentlyConnectedInfo.kt @@ -48,9 +48,9 @@ import no.nordicsemi.kotlin.ble.client.exception.OperationFailedException import no.nordicsemi.kotlin.ble.client.exception.PeripheralNotConnectedException import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.database.model.Node -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.disconnect -import org.meshtastic.core.strings.firmware_version +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.disconnect +import org.meshtastic.core.resources.firmware_version import org.meshtastic.core.ui.component.MaterialBatteryInfo import org.meshtastic.core.ui.component.NodeChip import org.meshtastic.core.ui.theme.AppTheme diff --git a/app/src/main/java/com/geeksville/mesh/ui/connections/components/DeviceListItem.kt b/app/src/main/java/com/geeksville/mesh/ui/connections/components/DeviceListItem.kt index 92b0e762d7..4f1b563fb0 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/connections/components/DeviceListItem.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/connections/components/DeviceListItem.kt @@ -57,11 +57,11 @@ import kotlinx.coroutines.delay import no.nordicsemi.android.common.ui.view.RssiIcon import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.service.ConnectionState -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.add -import org.meshtastic.core.strings.bluetooth -import org.meshtastic.core.strings.network -import org.meshtastic.core.strings.serial +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.add +import org.meshtastic.core.resources.bluetooth +import org.meshtastic.core.resources.network +import org.meshtastic.core.resources.serial import org.meshtastic.core.ui.component.NodeChip private const val RSSI_UPDATE_RATE_MS = 2000L diff --git a/app/src/main/java/com/geeksville/mesh/ui/connections/components/NetworkDevices.kt b/app/src/main/java/com/geeksville/mesh/ui/connections/components/NetworkDevices.kt index 499c1cd952..62f837f366 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/connections/components/NetworkDevices.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/connections/components/NetworkDevices.kt @@ -54,16 +54,16 @@ import com.geeksville.mesh.ui.connections.isValidAddress import kotlinx.coroutines.launch import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.service.ConnectionState -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.add_network_device -import org.meshtastic.core.strings.address -import org.meshtastic.core.strings.cancel -import org.meshtastic.core.strings.confirm_forget_connection -import org.meshtastic.core.strings.discovered_network_devices -import org.meshtastic.core.strings.forget_connection -import org.meshtastic.core.strings.ip_port -import org.meshtastic.core.strings.no_network_devices -import org.meshtastic.core.strings.recent_network_devices +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.add_network_device +import org.meshtastic.core.resources.address +import org.meshtastic.core.resources.cancel +import org.meshtastic.core.resources.confirm_forget_connection +import org.meshtastic.core.resources.discovered_network_devices +import org.meshtastic.core.resources.forget_connection +import org.meshtastic.core.resources.ip_port +import org.meshtastic.core.resources.no_network_devices +import org.meshtastic.core.resources.recent_network_devices import org.meshtastic.core.ui.component.MeshtasticResourceDialog import org.meshtastic.core.ui.theme.AppTheme diff --git a/app/src/main/java/com/geeksville/mesh/ui/connections/components/UsbDevices.kt b/app/src/main/java/com/geeksville/mesh/ui/connections/components/UsbDevices.kt index abcea444e5..c5e9f0f498 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/connections/components/UsbDevices.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/connections/components/UsbDevices.kt @@ -28,8 +28,8 @@ import com.geeksville.mesh.model.DeviceListEntry import com.geeksville.mesh.ui.connections.ScannerViewModel import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.service.ConnectionState -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.no_usb_devices +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.no_usb_devices @Composable fun UsbDevices( diff --git a/app/src/main/java/com/geeksville/mesh/ui/contact/AdaptiveContactsScreen.kt b/app/src/main/java/com/geeksville/mesh/ui/contact/AdaptiveContactsScreen.kt index 281cb9cedc..243b1f292f 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/contact/AdaptiveContactsScreen.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/contact/AdaptiveContactsScreen.kt @@ -49,8 +49,8 @@ import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.navigation.ChannelsRoutes import org.meshtastic.core.navigation.ContactsRoutes import org.meshtastic.core.navigation.NodesRoutes -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.conversations +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.conversations import org.meshtastic.core.ui.component.ScrollToTopEvent import org.meshtastic.core.ui.icon.Conversations import org.meshtastic.core.ui.icon.MeshtasticIcons diff --git a/app/src/main/java/com/geeksville/mesh/ui/contact/ContactItem.kt b/app/src/main/java/com/geeksville/mesh/ui/contact/ContactItem.kt index 7f3735817e..fdb970abe8 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/contact/ContactItem.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/contact/ContactItem.kt @@ -53,10 +53,10 @@ import androidx.compose.ui.tooling.preview.PreviewLightDark import androidx.compose.ui.unit.dp import com.geeksville.mesh.model.Contact import org.jetbrains.compose.resources.stringResource -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.sample_message -import org.meshtastic.core.strings.some_username -import org.meshtastic.core.strings.unknown_username +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.sample_message +import org.meshtastic.core.resources.some_username +import org.meshtastic.core.resources.unknown_username import org.meshtastic.core.ui.component.SecurityIcon import org.meshtastic.core.ui.theme.AppTheme import org.meshtastic.proto.ChannelSet diff --git a/app/src/main/java/com/geeksville/mesh/ui/contact/Contacts.kt b/app/src/main/java/com/geeksville/mesh/ui/contact/Contacts.kt index cdd1703594..6346bc8cef 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/contact/Contacts.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/contact/Contacts.kt @@ -70,27 +70,27 @@ import org.meshtastic.core.database.entity.ContactSettings import org.meshtastic.core.model.util.TimeConstants import org.meshtastic.core.model.util.formatMuteRemainingTime import org.meshtastic.core.model.util.getChannel -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.are_you_sure -import org.meshtastic.core.strings.cancel -import org.meshtastic.core.strings.channel_invalid -import org.meshtastic.core.strings.close_selection -import org.meshtastic.core.strings.conversations -import org.meshtastic.core.strings.currently -import org.meshtastic.core.strings.delete -import org.meshtastic.core.strings.delete_messages -import org.meshtastic.core.strings.delete_selection -import org.meshtastic.core.strings.mute_1_week -import org.meshtastic.core.strings.mute_8_hours -import org.meshtastic.core.strings.mute_always -import org.meshtastic.core.strings.mute_notifications -import org.meshtastic.core.strings.mute_status_always -import org.meshtastic.core.strings.mute_status_muted_for_days -import org.meshtastic.core.strings.mute_status_muted_for_hours -import org.meshtastic.core.strings.mute_status_unmuted -import org.meshtastic.core.strings.okay -import org.meshtastic.core.strings.select_all -import org.meshtastic.core.strings.unmute +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.are_you_sure +import org.meshtastic.core.resources.cancel +import org.meshtastic.core.resources.channel_invalid +import org.meshtastic.core.resources.close_selection +import org.meshtastic.core.resources.conversations +import org.meshtastic.core.resources.currently +import org.meshtastic.core.resources.delete +import org.meshtastic.core.resources.delete_messages +import org.meshtastic.core.resources.delete_selection +import org.meshtastic.core.resources.mute_1_week +import org.meshtastic.core.resources.mute_8_hours +import org.meshtastic.core.resources.mute_always +import org.meshtastic.core.resources.mute_notifications +import org.meshtastic.core.resources.mute_status_always +import org.meshtastic.core.resources.mute_status_muted_for_days +import org.meshtastic.core.resources.mute_status_muted_for_hours +import org.meshtastic.core.resources.mute_status_unmuted +import org.meshtastic.core.resources.okay +import org.meshtastic.core.resources.select_all +import org.meshtastic.core.resources.unmute import org.meshtastic.core.ui.component.MainAppBar import org.meshtastic.core.ui.component.MeshtasticDialog import org.meshtastic.core.ui.component.MeshtasticImportFAB diff --git a/app/src/main/java/com/geeksville/mesh/ui/contact/ContactsViewModel.kt b/app/src/main/java/com/geeksville/mesh/ui/contact/ContactsViewModel.kt index 6b219e8956..977c4af50b 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/contact/ContactsViewModel.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/contact/ContactsViewModel.kt @@ -40,8 +40,8 @@ import org.meshtastic.core.model.DataPacket import org.meshtastic.core.model.util.getChannel import org.meshtastic.core.model.util.getShortDate import org.meshtastic.core.service.ServiceRepository -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.channel_name +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.channel_name import org.meshtastic.core.ui.viewmodel.stateInWhileSubscribed import org.meshtastic.proto.ChannelSet import javax.inject.Inject diff --git a/app/src/main/java/com/geeksville/mesh/ui/node/AdaptiveNodeListScreen.kt b/app/src/main/java/com/geeksville/mesh/ui/node/AdaptiveNodeListScreen.kt index d9ef36b87c..fdef5b4bdd 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/node/AdaptiveNodeListScreen.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/node/AdaptiveNodeListScreen.kt @@ -48,8 +48,8 @@ import kotlinx.coroutines.launch import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.navigation.ChannelsRoutes import org.meshtastic.core.navigation.NodesRoutes -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.nodes +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.nodes import org.meshtastic.core.ui.component.ScrollToTopEvent import org.meshtastic.core.ui.icon.MeshtasticIcons import org.meshtastic.core.ui.icon.Nodes diff --git a/app/src/main/java/com/geeksville/mesh/ui/sharing/Channel.kt b/app/src/main/java/com/geeksville/mesh/ui/sharing/Channel.kt index 454e839283..c2ee346249 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/sharing/Channel.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/sharing/Channel.kt @@ -73,20 +73,20 @@ import org.meshtastic.core.model.util.getChannelUrl import org.meshtastic.core.model.util.qrCode import org.meshtastic.core.navigation.Route import org.meshtastic.core.service.ConnectionState -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.add -import org.meshtastic.core.strings.apply -import org.meshtastic.core.strings.are_you_sure_change_default -import org.meshtastic.core.strings.cancel -import org.meshtastic.core.strings.cant_change_no_radio -import org.meshtastic.core.strings.edit -import org.meshtastic.core.strings.generate_qr_code -import org.meshtastic.core.strings.modem_preset -import org.meshtastic.core.strings.navigate_into_label -import org.meshtastic.core.strings.replace -import org.meshtastic.core.strings.reset -import org.meshtastic.core.strings.reset_to_defaults -import org.meshtastic.core.strings.share_channels_qr +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.add +import org.meshtastic.core.resources.apply +import org.meshtastic.core.resources.are_you_sure_change_default +import org.meshtastic.core.resources.cancel +import org.meshtastic.core.resources.cant_change_no_radio +import org.meshtastic.core.resources.edit +import org.meshtastic.core.resources.generate_qr_code +import org.meshtastic.core.resources.modem_preset +import org.meshtastic.core.resources.navigate_into_label +import org.meshtastic.core.resources.replace +import org.meshtastic.core.resources.reset +import org.meshtastic.core.resources.reset_to_defaults +import org.meshtastic.core.resources.share_channels_qr import org.meshtastic.core.ui.component.AdaptiveTwoPane import org.meshtastic.core.ui.component.ChannelSelection import org.meshtastic.core.ui.component.MainAppBar diff --git a/app/src/main/java/com/geeksville/mesh/ui/sharing/Share.kt b/app/src/main/java/com/geeksville/mesh/ui/sharing/Share.kt index 688b19c35b..8b9dfc6f85 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/sharing/Share.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/sharing/Share.kt @@ -43,12 +43,12 @@ import com.geeksville.mesh.model.Contact import com.geeksville.mesh.ui.contact.ContactItem import com.geeksville.mesh.ui.contact.ContactsViewModel import org.jetbrains.compose.resources.stringResource -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.sample_message -import org.meshtastic.core.strings.share -import org.meshtastic.core.strings.share_to -import org.meshtastic.core.strings.some_username -import org.meshtastic.core.strings.unknown_username +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.sample_message +import org.meshtastic.core.resources.share +import org.meshtastic.core.resources.share_to +import org.meshtastic.core.resources.some_username +import org.meshtastic.core.resources.unknown_username import org.meshtastic.core.ui.component.MainAppBar import org.meshtastic.core.ui.theme.AppTheme diff --git a/build-logic/convention/src/main/kotlin/org/meshtastic/buildlogic/Dokka.kt b/build-logic/convention/src/main/kotlin/org/meshtastic/buildlogic/Dokka.kt index be41ad5d48..e3bb46435d 100644 --- a/build-logic/convention/src/main/kotlin/org/meshtastic/buildlogic/Dokka.kt +++ b/build-logic/convention/src/main/kotlin/org/meshtastic/buildlogic/Dokka.kt @@ -33,7 +33,7 @@ fun Project.configureDokka() { suppress.set(true) } perPackageOption { - matchingRegex.set("org.meshtastic.core.strings.*") + matchingRegex.set("org.meshtastic.core.resources.*") suppress.set(true) } diff --git a/build-logic/convention/src/main/kotlin/org/meshtastic/buildlogic/Kover.kt b/build-logic/convention/src/main/kotlin/org/meshtastic/buildlogic/Kover.kt index 23a0e95429..b4c4deedde 100644 --- a/build-logic/convention/src/main/kotlin/org/meshtastic/buildlogic/Kover.kt +++ b/build-logic/convention/src/main/kotlin/org/meshtastic/buildlogic/Kover.kt @@ -57,7 +57,7 @@ fun Project.configureKover() { // Suppress generated code packages("hilt_aggregated_deps") - packages("org.meshtastic.core.strings") + packages("org.meshtastic.core.resources") } } } diff --git a/core/barcode/README.md b/core/barcode/README.md index 4bb25c4c19..053e5655e4 100644 --- a/core/barcode/README.md +++ b/core/barcode/README.md @@ -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; diff --git a/core/barcode/build.gradle.kts b/core/barcode/build.gradle.kts index 46ece16e7a..f5978105ca 100644 --- a/core/barcode/build.gradle.kts +++ b/core/barcode/build.gradle.kts @@ -29,7 +29,7 @@ configure { } dependencies { - implementation(project(":core:strings")) + implementation(project(":core:resources")) implementation(libs.androidx.activity.compose) implementation(libs.androidx.compose.material3) diff --git a/core/barcode/src/fdroid/kotlin/org/meshtastic/core/barcode/BarcodeScannerProvider.kt b/core/barcode/src/fdroid/kotlin/org/meshtastic/core/barcode/BarcodeScannerProvider.kt index 6761e997a1..5d12b6f13d 100644 --- a/core/barcode/src/fdroid/kotlin/org/meshtastic/core/barcode/BarcodeScannerProvider.kt +++ b/core/barcode/src/fdroid/kotlin/org/meshtastic/core/barcode/BarcodeScannerProvider.kt @@ -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 diff --git a/core/barcode/src/google/kotlin/org/meshtastic/core/barcode/BarcodeScannerProvider.kt b/core/barcode/src/google/kotlin/org/meshtastic/core/barcode/BarcodeScannerProvider.kt index beb0484bbd..c9ff070bd1 100644 --- a/core/barcode/src/google/kotlin/org/meshtastic/core/barcode/BarcodeScannerProvider.kt +++ b/core/barcode/src/google/kotlin/org/meshtastic/core/barcode/BarcodeScannerProvider.kt @@ -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 diff --git a/core/database/README.md b/core/database/README.md index 3447954ec7..dd56166f1f 100644 --- a/core/database/README.md +++ b/core/database/README.md @@ -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; diff --git a/core/database/build.gradle.kts b/core/database/build.gradle.kts index e1f9521b51..5c5ed5dcb7 100644 --- a/core/database/build.gradle.kts +++ b/core/database/build.gradle.kts @@ -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) diff --git a/core/database/src/main/kotlin/org/meshtastic/core/database/model/Message.kt b/core/database/src/main/kotlin/org/meshtastic/core/database/model/Message.kt index 459e0f815f..3205c05298 100644 --- a/core/database/src/main/kotlin/org/meshtastic/core/database/model/Message.kt +++ b/core/database/src/main/kotlin/org/meshtastic/core/database/model/Message.kt @@ -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 diff --git a/core/database/src/main/kotlin/org/meshtastic/core/database/model/NodeSortOption.kt b/core/database/src/main/kotlin/org/meshtastic/core/database/model/NodeSortOption.kt index d186341efa..753562776f 100644 --- a/core/database/src/main/kotlin/org/meshtastic/core/database/model/NodeSortOption.kt +++ b/core/database/src/main/kotlin/org/meshtastic/core/database/model/NodeSortOption.kt @@ -18,14 +18,14 @@ 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), diff --git a/core/strings/README.md b/core/resources/README.md similarity index 78% rename from core/strings/README.md rename to core/resources/README.md index a0a0ac015c..8c24dda541 100644 --- a/core/strings/README.md +++ b/core/resources/README.md @@ -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)) ```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; diff --git a/core/strings/build.gradle.kts b/core/resources/build.gradle.kts similarity index 94% rename from core/strings/build.gradle.kts rename to core/resources/build.gradle.kts index 4f7c8998a6..347c9d69a0 100644 --- a/core/strings/build.gradle.kts +++ b/core/resources/build.gradle.kts @@ -29,5 +29,5 @@ kotlin { compose.resources { publicResClass = true - packageOfResClass = "org.meshtastic.core.strings" + packageOfResClass = "org.meshtastic.core.resources" } diff --git a/core/strings/src/androidMain/kotlin/org/meshtastic/core/strings/ContextExt.kt b/core/resources/src/androidMain/kotlin/org/meshtastic/core/strings/ContextExt.kt similarity index 97% rename from core/strings/src/androidMain/kotlin/org/meshtastic/core/strings/ContextExt.kt rename to core/resources/src/androidMain/kotlin/org/meshtastic/core/strings/ContextExt.kt index 42e68fd896..5ebc912504 100644 --- a/core/strings/src/androidMain/kotlin/org/meshtastic/core/strings/ContextExt.kt +++ b/core/resources/src/androidMain/kotlin/org/meshtastic/core/strings/ContextExt.kt @@ -14,7 +14,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package org.meshtastic.core.strings +package org.meshtastic.core.resources import kotlinx.coroutines.runBlocking import org.jetbrains.compose.resources.StringResource diff --git a/core/strings/src/commonMain/composeResources/values-ar/strings.xml b/core/resources/src/commonMain/composeResources/values-ar/strings.xml similarity index 100% rename from core/strings/src/commonMain/composeResources/values-ar/strings.xml rename to core/resources/src/commonMain/composeResources/values-ar/strings.xml diff --git a/core/strings/src/commonMain/composeResources/values-be/strings.xml b/core/resources/src/commonMain/composeResources/values-be/strings.xml similarity index 100% rename from core/strings/src/commonMain/composeResources/values-be/strings.xml rename to core/resources/src/commonMain/composeResources/values-be/strings.xml diff --git a/core/strings/src/commonMain/composeResources/values-bg/strings.xml b/core/resources/src/commonMain/composeResources/values-bg/strings.xml similarity index 100% rename from core/strings/src/commonMain/composeResources/values-bg/strings.xml rename to core/resources/src/commonMain/composeResources/values-bg/strings.xml diff --git a/core/strings/src/commonMain/composeResources/values-ca/strings.xml b/core/resources/src/commonMain/composeResources/values-ca/strings.xml similarity index 100% rename from core/strings/src/commonMain/composeResources/values-ca/strings.xml rename to core/resources/src/commonMain/composeResources/values-ca/strings.xml diff --git a/core/strings/src/commonMain/composeResources/values-cs/strings.xml b/core/resources/src/commonMain/composeResources/values-cs/strings.xml similarity index 100% rename from core/strings/src/commonMain/composeResources/values-cs/strings.xml rename to core/resources/src/commonMain/composeResources/values-cs/strings.xml diff --git a/core/strings/src/commonMain/composeResources/values-de/strings.xml b/core/resources/src/commonMain/composeResources/values-de/strings.xml similarity index 100% rename from core/strings/src/commonMain/composeResources/values-de/strings.xml rename to core/resources/src/commonMain/composeResources/values-de/strings.xml diff --git a/core/strings/src/commonMain/composeResources/values-el/strings.xml b/core/resources/src/commonMain/composeResources/values-el/strings.xml similarity index 100% rename from core/strings/src/commonMain/composeResources/values-el/strings.xml rename to core/resources/src/commonMain/composeResources/values-el/strings.xml diff --git a/core/strings/src/commonMain/composeResources/values-es/strings.xml b/core/resources/src/commonMain/composeResources/values-es/strings.xml similarity index 100% rename from core/strings/src/commonMain/composeResources/values-es/strings.xml rename to core/resources/src/commonMain/composeResources/values-es/strings.xml diff --git a/core/strings/src/commonMain/composeResources/values-et/strings.xml b/core/resources/src/commonMain/composeResources/values-et/strings.xml similarity index 100% rename from core/strings/src/commonMain/composeResources/values-et/strings.xml rename to core/resources/src/commonMain/composeResources/values-et/strings.xml diff --git a/core/strings/src/commonMain/composeResources/values-fi/strings.xml b/core/resources/src/commonMain/composeResources/values-fi/strings.xml similarity index 100% rename from core/strings/src/commonMain/composeResources/values-fi/strings.xml rename to core/resources/src/commonMain/composeResources/values-fi/strings.xml diff --git a/core/strings/src/commonMain/composeResources/values-fr/strings.xml b/core/resources/src/commonMain/composeResources/values-fr/strings.xml similarity index 100% rename from core/strings/src/commonMain/composeResources/values-fr/strings.xml rename to core/resources/src/commonMain/composeResources/values-fr/strings.xml diff --git a/core/strings/src/commonMain/composeResources/values-ga/strings.xml b/core/resources/src/commonMain/composeResources/values-ga/strings.xml similarity index 100% rename from core/strings/src/commonMain/composeResources/values-ga/strings.xml rename to core/resources/src/commonMain/composeResources/values-ga/strings.xml diff --git a/core/strings/src/commonMain/composeResources/values-gl/strings.xml b/core/resources/src/commonMain/composeResources/values-gl/strings.xml similarity index 100% rename from core/strings/src/commonMain/composeResources/values-gl/strings.xml rename to core/resources/src/commonMain/composeResources/values-gl/strings.xml diff --git a/core/strings/src/commonMain/composeResources/values-he/strings.xml b/core/resources/src/commonMain/composeResources/values-he/strings.xml similarity index 100% rename from core/strings/src/commonMain/composeResources/values-he/strings.xml rename to core/resources/src/commonMain/composeResources/values-he/strings.xml diff --git a/core/strings/src/commonMain/composeResources/values-hr/strings.xml b/core/resources/src/commonMain/composeResources/values-hr/strings.xml similarity index 100% rename from core/strings/src/commonMain/composeResources/values-hr/strings.xml rename to core/resources/src/commonMain/composeResources/values-hr/strings.xml diff --git a/core/strings/src/commonMain/composeResources/values-ht/strings.xml b/core/resources/src/commonMain/composeResources/values-ht/strings.xml similarity index 100% rename from core/strings/src/commonMain/composeResources/values-ht/strings.xml rename to core/resources/src/commonMain/composeResources/values-ht/strings.xml diff --git a/core/strings/src/commonMain/composeResources/values-hu/strings.xml b/core/resources/src/commonMain/composeResources/values-hu/strings.xml similarity index 100% rename from core/strings/src/commonMain/composeResources/values-hu/strings.xml rename to core/resources/src/commonMain/composeResources/values-hu/strings.xml diff --git a/core/strings/src/commonMain/composeResources/values-is/strings.xml b/core/resources/src/commonMain/composeResources/values-is/strings.xml similarity index 100% rename from core/strings/src/commonMain/composeResources/values-is/strings.xml rename to core/resources/src/commonMain/composeResources/values-is/strings.xml diff --git a/core/strings/src/commonMain/composeResources/values-it/strings.xml b/core/resources/src/commonMain/composeResources/values-it/strings.xml similarity index 100% rename from core/strings/src/commonMain/composeResources/values-it/strings.xml rename to core/resources/src/commonMain/composeResources/values-it/strings.xml diff --git a/core/strings/src/commonMain/composeResources/values-ja/strings.xml b/core/resources/src/commonMain/composeResources/values-ja/strings.xml similarity index 100% rename from core/strings/src/commonMain/composeResources/values-ja/strings.xml rename to core/resources/src/commonMain/composeResources/values-ja/strings.xml diff --git a/core/strings/src/commonMain/composeResources/values-ko/strings.xml b/core/resources/src/commonMain/composeResources/values-ko/strings.xml similarity index 100% rename from core/strings/src/commonMain/composeResources/values-ko/strings.xml rename to core/resources/src/commonMain/composeResources/values-ko/strings.xml diff --git a/core/strings/src/commonMain/composeResources/values-lt/strings.xml b/core/resources/src/commonMain/composeResources/values-lt/strings.xml similarity index 100% rename from core/strings/src/commonMain/composeResources/values-lt/strings.xml rename to core/resources/src/commonMain/composeResources/values-lt/strings.xml diff --git a/core/strings/src/commonMain/composeResources/values-nl/strings.xml b/core/resources/src/commonMain/composeResources/values-nl/strings.xml similarity index 100% rename from core/strings/src/commonMain/composeResources/values-nl/strings.xml rename to core/resources/src/commonMain/composeResources/values-nl/strings.xml diff --git a/core/strings/src/commonMain/composeResources/values-no/strings.xml b/core/resources/src/commonMain/composeResources/values-no/strings.xml similarity index 100% rename from core/strings/src/commonMain/composeResources/values-no/strings.xml rename to core/resources/src/commonMain/composeResources/values-no/strings.xml diff --git a/core/strings/src/commonMain/composeResources/values-pl/strings.xml b/core/resources/src/commonMain/composeResources/values-pl/strings.xml similarity index 100% rename from core/strings/src/commonMain/composeResources/values-pl/strings.xml rename to core/resources/src/commonMain/composeResources/values-pl/strings.xml diff --git a/core/strings/src/commonMain/composeResources/values-pt-rBR/strings.xml b/core/resources/src/commonMain/composeResources/values-pt-rBR/strings.xml similarity index 100% rename from core/strings/src/commonMain/composeResources/values-pt-rBR/strings.xml rename to core/resources/src/commonMain/composeResources/values-pt-rBR/strings.xml diff --git a/core/strings/src/commonMain/composeResources/values-pt/strings.xml b/core/resources/src/commonMain/composeResources/values-pt/strings.xml similarity index 100% rename from core/strings/src/commonMain/composeResources/values-pt/strings.xml rename to core/resources/src/commonMain/composeResources/values-pt/strings.xml diff --git a/core/strings/src/commonMain/composeResources/values-ro/strings.xml b/core/resources/src/commonMain/composeResources/values-ro/strings.xml similarity index 100% rename from core/strings/src/commonMain/composeResources/values-ro/strings.xml rename to core/resources/src/commonMain/composeResources/values-ro/strings.xml diff --git a/core/strings/src/commonMain/composeResources/values-ru/strings.xml b/core/resources/src/commonMain/composeResources/values-ru/strings.xml similarity index 100% rename from core/strings/src/commonMain/composeResources/values-ru/strings.xml rename to core/resources/src/commonMain/composeResources/values-ru/strings.xml diff --git a/core/strings/src/commonMain/composeResources/values-sk/strings.xml b/core/resources/src/commonMain/composeResources/values-sk/strings.xml similarity index 100% rename from core/strings/src/commonMain/composeResources/values-sk/strings.xml rename to core/resources/src/commonMain/composeResources/values-sk/strings.xml diff --git a/core/strings/src/commonMain/composeResources/values-sl/strings.xml b/core/resources/src/commonMain/composeResources/values-sl/strings.xml similarity index 100% rename from core/strings/src/commonMain/composeResources/values-sl/strings.xml rename to core/resources/src/commonMain/composeResources/values-sl/strings.xml diff --git a/core/strings/src/commonMain/composeResources/values-sq/strings.xml b/core/resources/src/commonMain/composeResources/values-sq/strings.xml similarity index 100% rename from core/strings/src/commonMain/composeResources/values-sq/strings.xml rename to core/resources/src/commonMain/composeResources/values-sq/strings.xml diff --git a/core/strings/src/commonMain/composeResources/values-sr/strings.xml b/core/resources/src/commonMain/composeResources/values-sr/strings.xml similarity index 100% rename from core/strings/src/commonMain/composeResources/values-sr/strings.xml rename to core/resources/src/commonMain/composeResources/values-sr/strings.xml diff --git a/core/strings/src/commonMain/composeResources/values-srp/strings.xml b/core/resources/src/commonMain/composeResources/values-srp/strings.xml similarity index 100% rename from core/strings/src/commonMain/composeResources/values-srp/strings.xml rename to core/resources/src/commonMain/composeResources/values-srp/strings.xml diff --git a/core/strings/src/commonMain/composeResources/values-sv/strings.xml b/core/resources/src/commonMain/composeResources/values-sv/strings.xml similarity index 100% rename from core/strings/src/commonMain/composeResources/values-sv/strings.xml rename to core/resources/src/commonMain/composeResources/values-sv/strings.xml diff --git a/core/strings/src/commonMain/composeResources/values-tr/strings.xml b/core/resources/src/commonMain/composeResources/values-tr/strings.xml similarity index 100% rename from core/strings/src/commonMain/composeResources/values-tr/strings.xml rename to core/resources/src/commonMain/composeResources/values-tr/strings.xml diff --git a/core/strings/src/commonMain/composeResources/values-uk/strings.xml b/core/resources/src/commonMain/composeResources/values-uk/strings.xml similarity index 100% rename from core/strings/src/commonMain/composeResources/values-uk/strings.xml rename to core/resources/src/commonMain/composeResources/values-uk/strings.xml diff --git a/core/strings/src/commonMain/composeResources/values-zh-rCN/strings.xml b/core/resources/src/commonMain/composeResources/values-zh-rCN/strings.xml similarity index 100% rename from core/strings/src/commonMain/composeResources/values-zh-rCN/strings.xml rename to core/resources/src/commonMain/composeResources/values-zh-rCN/strings.xml diff --git a/core/strings/src/commonMain/composeResources/values-zh-rTW/strings.xml b/core/resources/src/commonMain/composeResources/values-zh-rTW/strings.xml similarity index 100% rename from core/strings/src/commonMain/composeResources/values-zh-rTW/strings.xml rename to core/resources/src/commonMain/composeResources/values-zh-rTW/strings.xml diff --git a/core/strings/src/commonMain/composeResources/values/strings.xml b/core/resources/src/commonMain/composeResources/values/strings.xml similarity index 100% rename from core/strings/src/commonMain/composeResources/values/strings.xml rename to core/resources/src/commonMain/composeResources/values/strings.xml diff --git a/core/ui/README.md b/core/ui/README.md index 3be5c4e192..61bad4bda3 100644 --- a/core/ui/README.md +++ b/core/ui/README.md @@ -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; diff --git a/core/ui/build.gradle.kts b/core/ui/build.gradle.kts index 9441d291ab..1dfdc27b8f 100644 --- a/core/ui/build.gradle.kts +++ b/core/ui/build.gradle.kts @@ -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) diff --git a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/AlertDialogs.kt b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/AlertDialogs.kt index 7e983126cb..a06a9e6079 100644 --- a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/AlertDialogs.kt +++ b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/AlertDialogs.kt @@ -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. diff --git a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/BitwisePreference.kt b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/BitwisePreference.kt index 547340a6ea..558af087bc 100644 --- a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/BitwisePreference.kt +++ b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/BitwisePreference.kt @@ -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 diff --git a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/ChannelInfo.kt b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/ChannelInfo.kt index 3e01ec5580..150c88d51c 100644 --- a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/ChannelInfo.kt +++ b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/ChannelInfo.kt @@ -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 diff --git a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/ContactSharing.kt b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/ContactSharing.kt index d4ca9f16d6..98036bab96 100644 --- a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/ContactSharing.kt +++ b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/ContactSharing.kt @@ -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 /** diff --git a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/CopyIconButton.kt b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/CopyIconButton.kt index b8168904d7..f1d8d8d138 100644 --- a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/CopyIconButton.kt +++ b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/CopyIconButton.kt @@ -29,8 +29,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( diff --git a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/DistanceInfo.kt b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/DistanceInfo.kt index 3ced8c7cc5..992f98c2c3 100644 --- a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/DistanceInfo.kt +++ b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/DistanceInfo.kt @@ -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 diff --git a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/EditBase64Preference.kt b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/EditBase64Preference.kt index f5e6391e0c..26d2277a6f 100644 --- a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/EditBase64Preference.kt +++ b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/EditBase64Preference.kt @@ -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 diff --git a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/EditListPreference.kt b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/EditListPreference.kt index feda280178..29f6baca06 100644 --- a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/EditListPreference.kt +++ b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/EditListPreference.kt @@ -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 diff --git a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/EditPasswordPreference.kt b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/EditPasswordPreference.kt index da78d7f516..d0cb54241c 100644 --- a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/EditPasswordPreference.kt +++ b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/EditPasswordPreference.kt @@ -35,9 +35,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( diff --git a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/EditTextPreference.kt b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/EditTextPreference.kt index 3e366d062d..5eeda6aefb 100644 --- a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/EditTextPreference.kt +++ b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/EditTextPreference.kt @@ -44,8 +44,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( diff --git a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/ElevationInfo.kt b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/ElevationInfo.kt index 176cd6c7dd..9bf3e702cc 100644 --- a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/ElevationInfo.kt +++ b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/ElevationInfo.kt @@ -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 diff --git a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/HopsInfo.kt b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/HopsInfo.kt index 270ef1255e..42b569094f 100644 --- a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/HopsInfo.kt +++ b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/HopsInfo.kt @@ -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 diff --git a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/ImportFab.kt b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/ImportFab.kt index 609e649caf..e4852111c7 100644 --- a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/ImportFab.kt +++ b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/ImportFab.kt @@ -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 diff --git a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/IndoorAirQuality.kt b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/IndoorAirQuality.kt index 630f348a00..deb6cd03ea 100644 --- a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/IndoorAirQuality.kt +++ b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/IndoorAirQuality.kt @@ -50,10 +50,10 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import org.jetbrains.compose.resources.stringResource -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.air_quality_icon -import org.meshtastic.core.strings.close -import org.meshtastic.core.strings.indoor_air_quality_iaq +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.air_quality_icon +import org.meshtastic.core.resources.close +import org.meshtastic.core.resources.indoor_air_quality_iaq import org.meshtastic.core.ui.icon.MeshtasticIcons import org.meshtastic.core.ui.icon.ThumbUp import org.meshtastic.core.ui.icon.Warning diff --git a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/LastHeardInfo.kt b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/LastHeardInfo.kt index ada97a8ad7..dbd9163f1a 100644 --- a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/LastHeardInfo.kt +++ b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/LastHeardInfo.kt @@ -25,8 +25,8 @@ import androidx.compose.ui.res.vectorResource import androidx.compose.ui.tooling.preview.PreviewLightDark import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.common.util.nowSeconds -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.node_sort_last_heard +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.node_sort_last_heard import org.meshtastic.core.ui.R import org.meshtastic.core.ui.theme.AppTheme import org.meshtastic.core.ui.util.formatAgo diff --git a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/LoraSignalIndicator.kt b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/LoraSignalIndicator.kt index b96eb81de8..a818208a70 100644 --- a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/LoraSignalIndicator.kt +++ b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/LoraSignalIndicator.kt @@ -45,15 +45,15 @@ import androidx.compose.ui.graphics.vector.ImageVector 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.bad -import org.meshtastic.core.strings.fair -import org.meshtastic.core.strings.good -import org.meshtastic.core.strings.none_quality -import org.meshtastic.core.strings.rssi -import org.meshtastic.core.strings.signal -import org.meshtastic.core.strings.signal_quality -import org.meshtastic.core.strings.snr +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.bad +import org.meshtastic.core.resources.fair +import org.meshtastic.core.resources.good +import org.meshtastic.core.resources.none_quality +import org.meshtastic.core.resources.rssi +import org.meshtastic.core.resources.signal +import org.meshtastic.core.resources.signal_quality +import org.meshtastic.core.resources.snr import org.meshtastic.core.ui.theme.StatusColors.StatusGreen import org.meshtastic.core.ui.theme.StatusColors.StatusOrange import org.meshtastic.core.ui.theme.StatusColors.StatusRed diff --git a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/MainAppBar.kt b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/MainAppBar.kt index 741ad0fa30..ecc0f34678 100644 --- a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/MainAppBar.kt +++ b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/MainAppBar.kt @@ -40,9 +40,9 @@ import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.database.model.Node -import org.meshtastic.core.strings.R -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.navigate_back +import org.meshtastic.core.resources.R +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.navigate_back import org.meshtastic.core.ui.component.preview.BooleanProvider import org.meshtastic.core.ui.component.preview.previewNode import org.meshtastic.core.ui.theme.AppTheme diff --git a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/MaterialBatteryInfo.kt b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/MaterialBatteryInfo.kt index df8cc989fa..4a4cc5ee82 100644 --- a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/MaterialBatteryInfo.kt +++ b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/MaterialBatteryInfo.kt @@ -39,8 +39,8 @@ import androidx.compose.ui.tooling.preview.PreviewParameterProvider import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import org.jetbrains.compose.resources.stringResource -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.unknown +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.unknown import org.meshtastic.core.ui.icon.BatteryEmpty import org.meshtastic.core.ui.icon.BatteryUnknown import org.meshtastic.core.ui.icon.MeshtasticIcons diff --git a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/MaterialBluetoothSignalInfo.kt b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/MaterialBluetoothSignalInfo.kt index c0dbe7c097..444bad7333 100644 --- a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/MaterialBluetoothSignalInfo.kt +++ b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/MaterialBluetoothSignalInfo.kt @@ -40,8 +40,8 @@ import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.tooling.preview.PreviewParameterProvider import androidx.compose.ui.unit.dp import org.jetbrains.compose.resources.stringResource -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.dbm_value +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.dbm_value import org.meshtastic.core.ui.icon.MeshtasticIcons import org.meshtastic.core.ui.icon.SignalCellular0Bar import org.meshtastic.core.ui.icon.SignalCellular1Bar diff --git a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/NodeKeyStatusIcon.kt b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/NodeKeyStatusIcon.kt index 07d2566490..bd7fc8e0df 100644 --- a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/NodeKeyStatusIcon.kt +++ b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/NodeKeyStatusIcon.kt @@ -55,19 +55,19 @@ import okio.ByteString import org.jetbrains.compose.resources.StringResource import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.model.Channel -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.config_security_public_key -import org.meshtastic.core.strings.encryption_error -import org.meshtastic.core.strings.encryption_error_text -import org.meshtastic.core.strings.encryption_pkc -import org.meshtastic.core.strings.encryption_pkc_text -import org.meshtastic.core.strings.encryption_psk -import org.meshtastic.core.strings.encryption_psk_text -import org.meshtastic.core.strings.error -import org.meshtastic.core.strings.security_icon_help_dismiss -import org.meshtastic.core.strings.security_icon_help_show_all -import org.meshtastic.core.strings.security_icon_help_show_less -import org.meshtastic.core.strings.show_all_key_title +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.config_security_public_key +import org.meshtastic.core.resources.encryption_error +import org.meshtastic.core.resources.encryption_error_text +import org.meshtastic.core.resources.encryption_pkc +import org.meshtastic.core.resources.encryption_pkc_text +import org.meshtastic.core.resources.encryption_psk +import org.meshtastic.core.resources.encryption_psk_text +import org.meshtastic.core.resources.error +import org.meshtastic.core.resources.security_icon_help_dismiss +import org.meshtastic.core.resources.security_icon_help_show_all +import org.meshtastic.core.resources.security_icon_help_show_less +import org.meshtastic.core.resources.show_all_key_title import org.meshtastic.core.ui.icon.KeyOff import org.meshtastic.core.ui.icon.Lock import org.meshtastic.core.ui.icon.LockOpen diff --git a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/PositionPrecisionPreference.kt b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/PositionPrecisionPreference.kt index 1b4c0a6963..fdc849b300 100644 --- a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/PositionPrecisionPreference.kt +++ b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/PositionPrecisionPreference.kt @@ -33,9 +33,9 @@ import androidx.compose.ui.unit.dp import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.model.util.DistanceUnit import org.meshtastic.core.model.util.toDistanceString -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.position_enabled -import org.meshtastic.core.strings.precise_location +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.position_enabled +import org.meshtastic.core.resources.precise_location import kotlin.math.pow import kotlin.math.roundToInt diff --git a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/QrDialog.kt b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/QrDialog.kt index 3c97b9092b..dc41418198 100644 --- a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/QrDialog.kt +++ b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/QrDialog.kt @@ -48,11 +48,11 @@ import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp 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.strings.okay -import org.meshtastic.core.strings.qr_code -import org.meshtastic.core.strings.url +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.copy +import org.meshtastic.core.resources.okay +import org.meshtastic.core.resources.qr_code +import org.meshtastic.core.resources.url import org.meshtastic.core.ui.util.findActivity private const val QR_IMAGE_SIZE = 320 diff --git a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/SatelliteCountInfo.kt b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/SatelliteCountInfo.kt index 2474c500f2..782b61fa3d 100644 --- a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/SatelliteCountInfo.kt +++ b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/SatelliteCountInfo.kt @@ -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.sats +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.sats import org.meshtastic.core.ui.icon.MeshtasticIcons import org.meshtastic.core.ui.icon.Satellites import org.meshtastic.core.ui.theme.AppTheme diff --git a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/SecurityIcon.kt b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/SecurityIcon.kt index e5f16a870f..b54ffa6ce3 100644 --- a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/SecurityIcon.kt +++ b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/SecurityIcon.kt @@ -57,22 +57,22 @@ import org.jetbrains.compose.resources.StringResource import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.model.Channel import org.meshtastic.core.model.util.getChannel -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.security_icon_badge_warning_description -import org.meshtastic.core.strings.security_icon_description -import org.meshtastic.core.strings.security_icon_help_dismiss -import org.meshtastic.core.strings.security_icon_help_green_lock -import org.meshtastic.core.strings.security_icon_help_red_open_lock -import org.meshtastic.core.strings.security_icon_help_show_all -import org.meshtastic.core.strings.security_icon_help_show_less -import org.meshtastic.core.strings.security_icon_help_title -import org.meshtastic.core.strings.security_icon_help_title_all -import org.meshtastic.core.strings.security_icon_help_warning_precise_mqtt -import org.meshtastic.core.strings.security_icon_help_yellow_open_lock -import org.meshtastic.core.strings.security_icon_insecure_no_precise -import org.meshtastic.core.strings.security_icon_insecure_precise_only -import org.meshtastic.core.strings.security_icon_secure -import org.meshtastic.core.strings.security_icon_warning_precise_mqtt +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.security_icon_badge_warning_description +import org.meshtastic.core.resources.security_icon_description +import org.meshtastic.core.resources.security_icon_help_dismiss +import org.meshtastic.core.resources.security_icon_help_green_lock +import org.meshtastic.core.resources.security_icon_help_red_open_lock +import org.meshtastic.core.resources.security_icon_help_show_all +import org.meshtastic.core.resources.security_icon_help_show_less +import org.meshtastic.core.resources.security_icon_help_title +import org.meshtastic.core.resources.security_icon_help_title_all +import org.meshtastic.core.resources.security_icon_help_warning_precise_mqtt +import org.meshtastic.core.resources.security_icon_help_yellow_open_lock +import org.meshtastic.core.resources.security_icon_insecure_no_precise +import org.meshtastic.core.resources.security_icon_insecure_precise_only +import org.meshtastic.core.resources.security_icon_secure +import org.meshtastic.core.resources.security_icon_warning_precise_mqtt import org.meshtastic.core.ui.icon.Lock import org.meshtastic.core.ui.icon.LockOpen import org.meshtastic.core.ui.icon.MeshtasticIcons diff --git a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/SignalInfo.kt b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/SignalInfo.kt index b698f5b10d..50878e6f8d 100644 --- a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/SignalInfo.kt +++ b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/SignalInfo.kt @@ -34,8 +34,8 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.database.model.Node -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.signal_quality +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.signal_quality import org.meshtastic.core.ui.component.preview.NodePreviewParameterProvider import org.meshtastic.core.ui.theme.AppTheme diff --git a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/TelemetryInfo.kt b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/TelemetryInfo.kt index 051689af6b..84cb45a690 100644 --- a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/TelemetryInfo.kt +++ b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/TelemetryInfo.kt @@ -39,19 +39,19 @@ import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import org.jetbrains.compose.resources.stringResource -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.baro_pressure -import org.meshtastic.core.strings.env_metrics_log -import org.meshtastic.core.strings.humidity -import org.meshtastic.core.strings.iaq -import org.meshtastic.core.strings.node_id -import org.meshtastic.core.strings.pax -import org.meshtastic.core.strings.pax_metrics_log -import org.meshtastic.core.strings.role -import org.meshtastic.core.strings.soil_moisture -import org.meshtastic.core.strings.soil_temperature -import org.meshtastic.core.strings.temperature -import org.meshtastic.core.strings.uptime +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.baro_pressure +import org.meshtastic.core.resources.env_metrics_log +import org.meshtastic.core.resources.humidity +import org.meshtastic.core.resources.iaq +import org.meshtastic.core.resources.node_id +import org.meshtastic.core.resources.pax +import org.meshtastic.core.resources.pax_metrics_log +import org.meshtastic.core.resources.role +import org.meshtastic.core.resources.soil_moisture +import org.meshtastic.core.resources.soil_temperature +import org.meshtastic.core.resources.temperature +import org.meshtastic.core.resources.uptime import org.meshtastic.core.ui.icon.AirQuality import org.meshtastic.core.ui.icon.ArrowCircleUp import org.meshtastic.core.ui.icon.HardwareModel diff --git a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/TransportIcon.kt b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/TransportIcon.kt index 387b44213a..538eaf9965 100644 --- a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/TransportIcon.kt +++ b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/TransportIcon.kt @@ -20,11 +20,11 @@ import androidx.compose.material3.Icon import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.internal -import org.meshtastic.core.strings.via_api -import org.meshtastic.core.strings.via_mqtt -import org.meshtastic.core.strings.via_udp +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.internal +import org.meshtastic.core.resources.via_api +import org.meshtastic.core.resources.via_mqtt +import org.meshtastic.core.resources.via_udp import org.meshtastic.core.ui.icon.Api import org.meshtastic.core.ui.icon.Cloud import org.meshtastic.core.ui.icon.Device diff --git a/core/ui/src/main/kotlin/org/meshtastic/core/ui/qr/ScannedQrCodeDialog.kt b/core/ui/src/main/kotlin/org/meshtastic/core/ui/qr/ScannedQrCodeDialog.kt index 819b26acb9..33e721a3ef 100644 --- a/core/ui/src/main/kotlin/org/meshtastic/core/ui/qr/ScannedQrCodeDialog.kt +++ b/core/ui/src/main/kotlin/org/meshtastic/core/ui/qr/ScannedQrCodeDialog.kt @@ -51,14 +51,14 @@ import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.model.Channel -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.accept -import org.meshtastic.core.strings.add -import org.meshtastic.core.strings.add_channels_description -import org.meshtastic.core.strings.cancel -import org.meshtastic.core.strings.new_channel_rcvd -import org.meshtastic.core.strings.replace -import org.meshtastic.core.strings.replace_channels_and_settings_description +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.accept +import org.meshtastic.core.resources.add +import org.meshtastic.core.resources.add_channels_description +import org.meshtastic.core.resources.cancel +import org.meshtastic.core.resources.new_channel_rcvd +import org.meshtastic.core.resources.replace +import org.meshtastic.core.resources.replace_channels_and_settings_description import org.meshtastic.core.ui.component.ChannelSelection import org.meshtastic.proto.ChannelSet diff --git a/core/ui/src/main/kotlin/org/meshtastic/core/ui/share/SharedContactDialog.kt b/core/ui/src/main/kotlin/org/meshtastic/core/ui/share/SharedContactDialog.kt index b017a88d94..50588f547d 100644 --- a/core/ui/src/main/kotlin/org/meshtastic/core/ui/share/SharedContactDialog.kt +++ b/core/ui/src/main/kotlin/org/meshtastic/core/ui/share/SharedContactDialog.kt @@ -27,12 +27,12 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.model.util.compareUsers import org.meshtastic.core.model.util.userFieldsToString -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.cancel -import org.meshtastic.core.strings.import_known_shared_contact_text -import org.meshtastic.core.strings.import_label -import org.meshtastic.core.strings.import_shared_contact -import org.meshtastic.core.strings.public_key_changed +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.cancel +import org.meshtastic.core.resources.import_known_shared_contact_text +import org.meshtastic.core.resources.import_label +import org.meshtastic.core.resources.import_shared_contact +import org.meshtastic.core.resources.public_key_changed import org.meshtastic.core.ui.component.MeshtasticDialog import org.meshtastic.proto.SharedContact import org.meshtastic.proto.User diff --git a/core/ui/src/main/kotlin/org/meshtastic/core/ui/util/FormatAgo.kt b/core/ui/src/main/kotlin/org/meshtastic/core/ui/util/FormatAgo.kt index 6626a8b163..068f60ae46 100644 --- a/core/ui/src/main/kotlin/org/meshtastic/core/ui/util/FormatAgo.kt +++ b/core/ui/src/main/kotlin/org/meshtastic/core/ui/util/FormatAgo.kt @@ -18,10 +18,10 @@ package org.meshtastic.core.ui.util import android.text.format.DateUtils import org.meshtastic.core.common.util.nowMillis -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.getString -import org.meshtastic.core.strings.now -import org.meshtastic.core.strings.unknown +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.getString +import org.meshtastic.core.resources.now +import org.meshtastic.core.resources.unknown import kotlin.time.Duration.Companion.milliseconds import kotlin.time.Duration.Companion.minutes import kotlin.time.Duration.Companion.seconds diff --git a/core/ui/src/main/kotlin/org/meshtastic/core/ui/util/ModelExtensions.kt b/core/ui/src/main/kotlin/org/meshtastic/core/ui/util/ModelExtensions.kt index e521088836..767f0cbdf9 100644 --- a/core/ui/src/main/kotlin/org/meshtastic/core/ui/util/ModelExtensions.kt +++ b/core/ui/src/main/kotlin/org/meshtastic/core/ui/util/ModelExtensions.kt @@ -19,19 +19,19 @@ package org.meshtastic.core.ui.util import org.jetbrains.compose.resources.StringResource import org.meshtastic.core.model.ChannelOption import org.meshtastic.core.model.TracerouteMapAvailability -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.label_long_fast -import org.meshtastic.core.strings.label_long_moderate -import org.meshtastic.core.strings.label_long_slow -import org.meshtastic.core.strings.label_long_turbo -import org.meshtastic.core.strings.label_medium_fast -import org.meshtastic.core.strings.label_medium_slow -import org.meshtastic.core.strings.label_short_fast -import org.meshtastic.core.strings.label_short_slow -import org.meshtastic.core.strings.label_short_turbo -import org.meshtastic.core.strings.label_very_long_slow -import org.meshtastic.core.strings.traceroute_endpoint_missing -import org.meshtastic.core.strings.traceroute_map_no_data +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.label_long_fast +import org.meshtastic.core.resources.label_long_moderate +import org.meshtastic.core.resources.label_long_slow +import org.meshtastic.core.resources.label_long_turbo +import org.meshtastic.core.resources.label_medium_fast +import org.meshtastic.core.resources.label_medium_slow +import org.meshtastic.core.resources.label_short_fast +import org.meshtastic.core.resources.label_short_slow +import org.meshtastic.core.resources.label_short_turbo +import org.meshtastic.core.resources.label_very_long_slow +import org.meshtastic.core.resources.traceroute_endpoint_missing +import org.meshtastic.core.resources.traceroute_map_no_data val ChannelOption.labelRes: StringResource get() = diff --git a/core/ui/src/main/kotlin/org/meshtastic/core/ui/util/ProtoExtensions.kt b/core/ui/src/main/kotlin/org/meshtastic/core/ui/util/ProtoExtensions.kt index d2df8ad830..9eca1ba874 100644 --- a/core/ui/src/main/kotlin/org/meshtastic/core/ui/util/ProtoExtensions.kt +++ b/core/ui/src/main/kotlin/org/meshtastic/core/ui/util/ProtoExtensions.kt @@ -21,8 +21,8 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.platform.LocalContext import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.common.util.nowMillis -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.unknown_age +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.unknown_age import org.meshtastic.proto.Channel import org.meshtastic.proto.ChannelSettings import org.meshtastic.proto.MeshPacket diff --git a/feature/firmware/README.md b/feature/firmware/README.md index 88c943a309..19fcfa41ad 100644 --- a/feature/firmware/README.md +++ b/feature/firmware/README.md @@ -16,7 +16,7 @@ graph TB :feature:firmware -.-> :core:prefs :feature:firmware -.-> :core:proto :feature:firmware -.-> :core:service - :feature:firmware -.-> :core:strings + :feature:firmware -.-> :core:resources :feature:firmware -.-> :core:ui classDef android-application fill:#CAFFBF,stroke:#000,stroke-width:2px,color:#000; diff --git a/feature/firmware/build.gradle.kts b/feature/firmware/build.gradle.kts index b4c682d76f..db489e53c5 100644 --- a/feature/firmware/build.gradle.kts +++ b/feature/firmware/build.gradle.kts @@ -36,7 +36,7 @@ dependencies { implementation(projects.core.prefs) implementation(projects.core.proto) implementation(projects.core.service) - implementation(projects.core.strings) + implementation(projects.core.resources) implementation(projects.core.ui) implementation(libs.accompanist.permissions) diff --git a/feature/firmware/src/main/kotlin/org/meshtastic/feature/firmware/FirmwareDfuService.kt b/feature/firmware/src/main/kotlin/org/meshtastic/feature/firmware/FirmwareDfuService.kt index c376fa64a0..da1dc18fe6 100644 --- a/feature/firmware/src/main/kotlin/org/meshtastic/feature/firmware/FirmwareDfuService.kt +++ b/feature/firmware/src/main/kotlin/org/meshtastic/feature/firmware/FirmwareDfuService.kt @@ -24,9 +24,9 @@ import kotlinx.coroutines.runBlocking import no.nordicsemi.android.dfu.DfuBaseService import org.jetbrains.compose.resources.getString import org.meshtastic.core.model.BuildConfig -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.firmware_update_channel_description -import org.meshtastic.core.strings.firmware_update_channel_name +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.firmware_update_channel_description +import org.meshtastic.core.resources.firmware_update_channel_name class FirmwareDfuService : DfuBaseService() { override fun onCreate() { diff --git a/feature/firmware/src/main/kotlin/org/meshtastic/feature/firmware/FirmwareUpdateScreen.kt b/feature/firmware/src/main/kotlin/org/meshtastic/feature/firmware/FirmwareUpdateScreen.kt index 579eda1ccc..4a91d998c5 100644 --- a/feature/firmware/src/main/kotlin/org/meshtastic/feature/firmware/FirmwareUpdateScreen.kt +++ b/feature/firmware/src/main/kotlin/org/meshtastic/feature/firmware/FirmwareUpdateScreen.kt @@ -91,50 +91,50 @@ import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.database.entity.FirmwareRelease import org.meshtastic.core.database.entity.FirmwareReleaseType import org.meshtastic.core.model.DeviceHardware -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.back -import org.meshtastic.core.strings.cancel -import org.meshtastic.core.strings.chirpy -import org.meshtastic.core.strings.dont_show_again_for_device -import org.meshtastic.core.strings.firmware_update_almost_there -import org.meshtastic.core.strings.firmware_update_alpha -import org.meshtastic.core.strings.firmware_update_checking -import org.meshtastic.core.strings.firmware_update_currently_installed -import org.meshtastic.core.strings.firmware_update_device -import org.meshtastic.core.strings.firmware_update_disclaimer_chirpy_says -import org.meshtastic.core.strings.firmware_update_disclaimer_text -import org.meshtastic.core.strings.firmware_update_disclaimer_title -import org.meshtastic.core.strings.firmware_update_disconnect_warning -import org.meshtastic.core.strings.firmware_update_do_not_close -import org.meshtastic.core.strings.firmware_update_done -import org.meshtastic.core.strings.firmware_update_error -import org.meshtastic.core.strings.firmware_update_hang_tight -import org.meshtastic.core.strings.firmware_update_keep_device_close -import org.meshtastic.core.strings.firmware_update_latest -import org.meshtastic.core.strings.firmware_update_local_file -import org.meshtastic.core.strings.firmware_update_method_detail -import org.meshtastic.core.strings.firmware_update_rak4631_bootloader_hint -import org.meshtastic.core.strings.firmware_update_release_notes -import org.meshtastic.core.strings.firmware_update_retry -import org.meshtastic.core.strings.firmware_update_save_dfu_file -import org.meshtastic.core.strings.firmware_update_select_file -import org.meshtastic.core.strings.firmware_update_source_local -import org.meshtastic.core.strings.firmware_update_stable -import org.meshtastic.core.strings.firmware_update_success -import org.meshtastic.core.strings.firmware_update_taking_a_while -import org.meshtastic.core.strings.firmware_update_target -import org.meshtastic.core.strings.firmware_update_title -import org.meshtastic.core.strings.firmware_update_unknown_release -import org.meshtastic.core.strings.firmware_update_usb_bootloader_warning -import org.meshtastic.core.strings.firmware_update_usb_instruction_text -import org.meshtastic.core.strings.firmware_update_usb_instruction_title -import org.meshtastic.core.strings.firmware_update_verification_failed -import org.meshtastic.core.strings.firmware_update_verifying -import org.meshtastic.core.strings.firmware_update_waiting_reconnect -import org.meshtastic.core.strings.i_know_what_i_m_doing -import org.meshtastic.core.strings.learn_more -import org.meshtastic.core.strings.okay -import org.meshtastic.core.strings.save +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.back +import org.meshtastic.core.resources.cancel +import org.meshtastic.core.resources.chirpy +import org.meshtastic.core.resources.dont_show_again_for_device +import org.meshtastic.core.resources.firmware_update_almost_there +import org.meshtastic.core.resources.firmware_update_alpha +import org.meshtastic.core.resources.firmware_update_checking +import org.meshtastic.core.resources.firmware_update_currently_installed +import org.meshtastic.core.resources.firmware_update_device +import org.meshtastic.core.resources.firmware_update_disclaimer_chirpy_says +import org.meshtastic.core.resources.firmware_update_disclaimer_text +import org.meshtastic.core.resources.firmware_update_disclaimer_title +import org.meshtastic.core.resources.firmware_update_disconnect_warning +import org.meshtastic.core.resources.firmware_update_do_not_close +import org.meshtastic.core.resources.firmware_update_done +import org.meshtastic.core.resources.firmware_update_error +import org.meshtastic.core.resources.firmware_update_hang_tight +import org.meshtastic.core.resources.firmware_update_keep_device_close +import org.meshtastic.core.resources.firmware_update_latest +import org.meshtastic.core.resources.firmware_update_local_file +import org.meshtastic.core.resources.firmware_update_method_detail +import org.meshtastic.core.resources.firmware_update_rak4631_bootloader_hint +import org.meshtastic.core.resources.firmware_update_release_notes +import org.meshtastic.core.resources.firmware_update_retry +import org.meshtastic.core.resources.firmware_update_save_dfu_file +import org.meshtastic.core.resources.firmware_update_select_file +import org.meshtastic.core.resources.firmware_update_source_local +import org.meshtastic.core.resources.firmware_update_stable +import org.meshtastic.core.resources.firmware_update_success +import org.meshtastic.core.resources.firmware_update_taking_a_while +import org.meshtastic.core.resources.firmware_update_target +import org.meshtastic.core.resources.firmware_update_title +import org.meshtastic.core.resources.firmware_update_unknown_release +import org.meshtastic.core.resources.firmware_update_usb_bootloader_warning +import org.meshtastic.core.resources.firmware_update_usb_instruction_text +import org.meshtastic.core.resources.firmware_update_usb_instruction_title +import org.meshtastic.core.resources.firmware_update_verification_failed +import org.meshtastic.core.resources.firmware_update_verifying +import org.meshtastic.core.resources.firmware_update_waiting_reconnect +import org.meshtastic.core.resources.i_know_what_i_m_doing +import org.meshtastic.core.resources.learn_more +import org.meshtastic.core.resources.okay +import org.meshtastic.core.resources.save import org.meshtastic.core.ui.component.MeshtasticDialog import org.meshtastic.core.ui.icon.Bluetooth import org.meshtastic.core.ui.icon.CheckCircle diff --git a/feature/firmware/src/main/kotlin/org/meshtastic/feature/firmware/FirmwareUpdateViewModel.kt b/feature/firmware/src/main/kotlin/org/meshtastic/feature/firmware/FirmwareUpdateViewModel.kt index fc25cd754e..35185ce48e 100644 --- a/feature/firmware/src/main/kotlin/org/meshtastic/feature/firmware/FirmwareUpdateViewModel.kt +++ b/feature/firmware/src/main/kotlin/org/meshtastic/feature/firmware/FirmwareUpdateViewModel.kt @@ -51,28 +51,28 @@ import org.meshtastic.core.prefs.radio.isSerial import org.meshtastic.core.prefs.radio.isTcp import org.meshtastic.core.service.ConnectionState import org.meshtastic.core.service.ServiceRepository -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.firmware_update_battery_low -import org.meshtastic.core.strings.firmware_update_copying -import org.meshtastic.core.strings.firmware_update_dfu_aborted -import org.meshtastic.core.strings.firmware_update_dfu_error -import org.meshtastic.core.strings.firmware_update_disconnecting -import org.meshtastic.core.strings.firmware_update_enabling_dfu -import org.meshtastic.core.strings.firmware_update_extracting -import org.meshtastic.core.strings.firmware_update_failed -import org.meshtastic.core.strings.firmware_update_flashing -import org.meshtastic.core.strings.firmware_update_local_failed -import org.meshtastic.core.strings.firmware_update_method_ble -import org.meshtastic.core.strings.firmware_update_method_usb -import org.meshtastic.core.strings.firmware_update_method_wifi -import org.meshtastic.core.strings.firmware_update_no_device -import org.meshtastic.core.strings.firmware_update_node_info_missing -import org.meshtastic.core.strings.firmware_update_starting_dfu -import org.meshtastic.core.strings.firmware_update_unknown_error -import org.meshtastic.core.strings.firmware_update_unknown_hardware -import org.meshtastic.core.strings.firmware_update_updating -import org.meshtastic.core.strings.firmware_update_validating -import org.meshtastic.core.strings.unknown +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.firmware_update_battery_low +import org.meshtastic.core.resources.firmware_update_copying +import org.meshtastic.core.resources.firmware_update_dfu_aborted +import org.meshtastic.core.resources.firmware_update_dfu_error +import org.meshtastic.core.resources.firmware_update_disconnecting +import org.meshtastic.core.resources.firmware_update_enabling_dfu +import org.meshtastic.core.resources.firmware_update_extracting +import org.meshtastic.core.resources.firmware_update_failed +import org.meshtastic.core.resources.firmware_update_flashing +import org.meshtastic.core.resources.firmware_update_local_failed +import org.meshtastic.core.resources.firmware_update_method_ble +import org.meshtastic.core.resources.firmware_update_method_usb +import org.meshtastic.core.resources.firmware_update_method_wifi +import org.meshtastic.core.resources.firmware_update_no_device +import org.meshtastic.core.resources.firmware_update_node_info_missing +import org.meshtastic.core.resources.firmware_update_starting_dfu +import org.meshtastic.core.resources.firmware_update_unknown_error +import org.meshtastic.core.resources.firmware_update_unknown_hardware +import org.meshtastic.core.resources.firmware_update_updating +import org.meshtastic.core.resources.firmware_update_validating +import org.meshtastic.core.resources.unknown import java.io.File import javax.inject.Inject diff --git a/feature/firmware/src/main/kotlin/org/meshtastic/feature/firmware/NordicDfuHandler.kt b/feature/firmware/src/main/kotlin/org/meshtastic/feature/firmware/NordicDfuHandler.kt index 0d753ddad7..310a450e70 100644 --- a/feature/firmware/src/main/kotlin/org/meshtastic/feature/firmware/NordicDfuHandler.kt +++ b/feature/firmware/src/main/kotlin/org/meshtastic/feature/firmware/NordicDfuHandler.kt @@ -34,11 +34,11 @@ import org.jetbrains.compose.resources.getString import org.meshtastic.core.database.entity.FirmwareRelease import org.meshtastic.core.model.DeviceHardware import org.meshtastic.core.service.ServiceRepository -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.firmware_update_downloading_percent -import org.meshtastic.core.strings.firmware_update_nordic_failed -import org.meshtastic.core.strings.firmware_update_not_found_in_release -import org.meshtastic.core.strings.firmware_update_starting_service +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.firmware_update_downloading_percent +import org.meshtastic.core.resources.firmware_update_nordic_failed +import org.meshtastic.core.resources.firmware_update_not_found_in_release +import org.meshtastic.core.resources.firmware_update_starting_service import java.io.File import javax.inject.Inject diff --git a/feature/firmware/src/main/kotlin/org/meshtastic/feature/firmware/UsbUpdateHandler.kt b/feature/firmware/src/main/kotlin/org/meshtastic/feature/firmware/UsbUpdateHandler.kt index 3fdd2245f4..e251b60bdd 100644 --- a/feature/firmware/src/main/kotlin/org/meshtastic/feature/firmware/UsbUpdateHandler.kt +++ b/feature/firmware/src/main/kotlin/org/meshtastic/feature/firmware/UsbUpdateHandler.kt @@ -24,11 +24,11 @@ import org.jetbrains.compose.resources.getString import org.meshtastic.core.database.entity.FirmwareRelease import org.meshtastic.core.model.DeviceHardware import org.meshtastic.core.service.ServiceRepository -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.firmware_update_downloading_percent -import org.meshtastic.core.strings.firmware_update_rebooting -import org.meshtastic.core.strings.firmware_update_retrieval_failed -import org.meshtastic.core.strings.firmware_update_usb_failed +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.firmware_update_downloading_percent +import org.meshtastic.core.resources.firmware_update_rebooting +import org.meshtastic.core.resources.firmware_update_retrieval_failed +import org.meshtastic.core.resources.firmware_update_usb_failed import java.io.File import javax.inject.Inject diff --git a/feature/firmware/src/main/kotlin/org/meshtastic/feature/firmware/ota/Esp32OtaUpdateHandler.kt b/feature/firmware/src/main/kotlin/org/meshtastic/feature/firmware/ota/Esp32OtaUpdateHandler.kt index 25bb0818d1..3bddb2b53f 100644 --- a/feature/firmware/src/main/kotlin/org/meshtastic/feature/firmware/ota/Esp32OtaUpdateHandler.kt +++ b/feature/firmware/src/main/kotlin/org/meshtastic/feature/firmware/ota/Esp32OtaUpdateHandler.kt @@ -30,17 +30,17 @@ import org.meshtastic.core.common.util.nowMillis import org.meshtastic.core.database.entity.FirmwareRelease import org.meshtastic.core.model.DeviceHardware import org.meshtastic.core.service.ServiceRepository -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.firmware_update_connecting_attempt -import org.meshtastic.core.strings.firmware_update_downloading_percent -import org.meshtastic.core.strings.firmware_update_erasing -import org.meshtastic.core.strings.firmware_update_hash_rejected -import org.meshtastic.core.strings.firmware_update_loading -import org.meshtastic.core.strings.firmware_update_ota_failed -import org.meshtastic.core.strings.firmware_update_retrieval_failed -import org.meshtastic.core.strings.firmware_update_starting_ota -import org.meshtastic.core.strings.firmware_update_uploading -import org.meshtastic.core.strings.firmware_update_waiting_reboot +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.firmware_update_connecting_attempt +import org.meshtastic.core.resources.firmware_update_downloading_percent +import org.meshtastic.core.resources.firmware_update_erasing +import org.meshtastic.core.resources.firmware_update_hash_rejected +import org.meshtastic.core.resources.firmware_update_loading +import org.meshtastic.core.resources.firmware_update_ota_failed +import org.meshtastic.core.resources.firmware_update_retrieval_failed +import org.meshtastic.core.resources.firmware_update_starting_ota +import org.meshtastic.core.resources.firmware_update_uploading +import org.meshtastic.core.resources.firmware_update_waiting_reboot import org.meshtastic.feature.firmware.FirmwareRetriever import org.meshtastic.feature.firmware.FirmwareUpdateHandler import org.meshtastic.feature.firmware.FirmwareUpdateState diff --git a/feature/intro/README.md b/feature/intro/README.md index 53993b747d..d399c878ba 100644 --- a/feature/intro/README.md +++ b/feature/intro/README.md @@ -20,7 +20,7 @@ Dedicated screens for explaining and requesting specific permissions: ```mermaid graph TB :feature:intro[intro]:::android-feature - :feature:intro -.-> :core:strings + :feature:intro -.-> :core:resources :feature:intro -.-> :core:ui classDef android-application fill:#CAFFBF,stroke:#000,stroke-width:2px,color:#000; diff --git a/feature/intro/build.gradle.kts b/feature/intro/build.gradle.kts index 6d058a2cca..21aa1b2dbb 100644 --- a/feature/intro/build.gradle.kts +++ b/feature/intro/build.gradle.kts @@ -27,7 +27,7 @@ plugins { configure { namespace = "org.meshtastic.feature.intro" } dependencies { - implementation(projects.core.strings) + implementation(projects.core.resources) implementation(projects.core.ui) implementation(libs.androidx.compose.material.iconsExtended) diff --git a/feature/intro/src/google/kotlin/org/meshtastic/feature/intro/AnalyticsIntro.kt b/feature/intro/src/google/kotlin/org/meshtastic/feature/intro/AnalyticsIntro.kt index 97072122d0..459ca9d826 100644 --- a/feature/intro/src/google/kotlin/org/meshtastic/feature/intro/AnalyticsIntro.kt +++ b/feature/intro/src/google/kotlin/org/meshtastic/feature/intro/AnalyticsIntro.kt @@ -29,13 +29,13 @@ import androidx.compose.ui.text.style.TextAlign 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.analytics_notice -import org.meshtastic.core.strings.analytics_platforms -import org.meshtastic.core.strings.datadog_link -import org.meshtastic.core.strings.firebase_link -import org.meshtastic.core.strings.for_more_information_see_our_privacy_policy -import org.meshtastic.core.strings.privacy_url +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.analytics_notice +import org.meshtastic.core.resources.analytics_platforms +import org.meshtastic.core.resources.datadog_link +import org.meshtastic.core.resources.firebase_link +import org.meshtastic.core.resources.for_more_information_see_our_privacy_policy +import org.meshtastic.core.resources.privacy_url import org.meshtastic.core.ui.component.AutoLinkText @Composable diff --git a/feature/intro/src/main/kotlin/org/meshtastic/feature/intro/AppIntroductionScreen.kt b/feature/intro/src/main/kotlin/org/meshtastic/feature/intro/AppIntroductionScreen.kt index 7f2270bebb..275dd84b42 100644 --- a/feature/intro/src/main/kotlin/org/meshtastic/feature/intro/AppIntroductionScreen.kt +++ b/feature/intro/src/main/kotlin/org/meshtastic/feature/intro/AppIntroductionScreen.kt @@ -33,9 +33,9 @@ import kotlinx.serialization.Serializable import no.nordicsemi.android.common.permissions.ble.RequireBluetooth import no.nordicsemi.android.common.permissions.ble.RequireLocation import no.nordicsemi.android.common.permissions.notification.RequestNotificationPermission -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.permission_denied -import org.meshtastic.core.strings.permission_granted +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.permission_denied +import org.meshtastic.core.resources.permission_granted import org.meshtastic.core.ui.util.showToast /** diff --git a/feature/intro/src/main/kotlin/org/meshtastic/feature/intro/BluetoothScreen.kt b/feature/intro/src/main/kotlin/org/meshtastic/feature/intro/BluetoothScreen.kt index f6e1c60ac8..849c8ce119 100644 --- a/feature/intro/src/main/kotlin/org/meshtastic/feature/intro/BluetoothScreen.kt +++ b/feature/intro/src/main/kotlin/org/meshtastic/feature/intro/BluetoothScreen.kt @@ -25,16 +25,16 @@ import androidx.compose.material.icons.outlined.SettingsInputAntenna import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.platform.LocalContext -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.bluetooth_feature_config -import org.meshtastic.core.strings.bluetooth_feature_config_description -import org.meshtastic.core.strings.bluetooth_feature_discovery -import org.meshtastic.core.strings.bluetooth_feature_discovery_description -import org.meshtastic.core.strings.bluetooth_permission -import org.meshtastic.core.strings.configure_bluetooth_permissions -import org.meshtastic.core.strings.next -import org.meshtastic.core.strings.permission_missing_31 -import org.meshtastic.core.strings.settings +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.bluetooth_feature_config +import org.meshtastic.core.resources.bluetooth_feature_config_description +import org.meshtastic.core.resources.bluetooth_feature_discovery +import org.meshtastic.core.resources.bluetooth_feature_discovery_description +import org.meshtastic.core.resources.bluetooth_permission +import org.meshtastic.core.resources.configure_bluetooth_permissions +import org.meshtastic.core.resources.next +import org.meshtastic.core.resources.permission_missing_31 +import org.meshtastic.core.resources.settings /** * Screen for configuring Bluetooth permissions during the app introduction. It explains why Bluetooth permissions are diff --git a/feature/intro/src/main/kotlin/org/meshtastic/feature/intro/CriticalAlertsScreen.kt b/feature/intro/src/main/kotlin/org/meshtastic/feature/intro/CriticalAlertsScreen.kt index 79b2a3ce8c..0daa3fbfa0 100644 --- a/feature/intro/src/main/kotlin/org/meshtastic/feature/intro/CriticalAlertsScreen.kt +++ b/feature/intro/src/main/kotlin/org/meshtastic/feature/intro/CriticalAlertsScreen.kt @@ -34,11 +34,11 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import org.jetbrains.compose.resources.stringResource -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.configure_critical_alerts -import org.meshtastic.core.strings.critical_alerts -import org.meshtastic.core.strings.critical_alerts_dnd_request_text -import org.meshtastic.core.strings.skip +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.configure_critical_alerts +import org.meshtastic.core.resources.critical_alerts +import org.meshtastic.core.resources.critical_alerts_dnd_request_text +import org.meshtastic.core.resources.skip /** * Screen for explaining and guiding the user to configure critical alert settings. This screen is part of the app diff --git a/feature/intro/src/main/kotlin/org/meshtastic/feature/intro/LocationScreen.kt b/feature/intro/src/main/kotlin/org/meshtastic/feature/intro/LocationScreen.kt index f7185d3e29..9ebd027bdf 100644 --- a/feature/intro/src/main/kotlin/org/meshtastic/feature/intro/LocationScreen.kt +++ b/feature/intro/src/main/kotlin/org/meshtastic/feature/intro/LocationScreen.kt @@ -26,20 +26,20 @@ import androidx.compose.material.icons.outlined.Router import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.platform.LocalContext -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.configure_location_permissions -import org.meshtastic.core.strings.distance_filters -import org.meshtastic.core.strings.distance_filters_description -import org.meshtastic.core.strings.distance_measurements -import org.meshtastic.core.strings.distance_measurements_description -import org.meshtastic.core.strings.mesh_map_location -import org.meshtastic.core.strings.mesh_map_location_description -import org.meshtastic.core.strings.next -import org.meshtastic.core.strings.phone_location -import org.meshtastic.core.strings.phone_location_description -import org.meshtastic.core.strings.settings -import org.meshtastic.core.strings.share_location -import org.meshtastic.core.strings.share_location_description +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.configure_location_permissions +import org.meshtastic.core.resources.distance_filters +import org.meshtastic.core.resources.distance_filters_description +import org.meshtastic.core.resources.distance_measurements +import org.meshtastic.core.resources.distance_measurements_description +import org.meshtastic.core.resources.mesh_map_location +import org.meshtastic.core.resources.mesh_map_location_description +import org.meshtastic.core.resources.next +import org.meshtastic.core.resources.phone_location +import org.meshtastic.core.resources.phone_location_description +import org.meshtastic.core.resources.settings +import org.meshtastic.core.resources.share_location +import org.meshtastic.core.resources.share_location_description /** * Screen for configuring location permissions during the app introduction. It explains why location permissions are diff --git a/feature/intro/src/main/kotlin/org/meshtastic/feature/intro/NotificationsScreen.kt b/feature/intro/src/main/kotlin/org/meshtastic/feature/intro/NotificationsScreen.kt index 2c8ae60fd1..41a45f4e1a 100644 --- a/feature/intro/src/main/kotlin/org/meshtastic/feature/intro/NotificationsScreen.kt +++ b/feature/intro/src/main/kotlin/org/meshtastic/feature/intro/NotificationsScreen.kt @@ -26,18 +26,18 @@ import androidx.compose.material.icons.outlined.SpeakerPhone import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.platform.LocalContext -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.app_notifications -import org.meshtastic.core.strings.configure_notification_permissions -import org.meshtastic.core.strings.incoming_messages -import org.meshtastic.core.strings.low_battery -import org.meshtastic.core.strings.new_nodes -import org.meshtastic.core.strings.next -import org.meshtastic.core.strings.notification_permissions_description -import org.meshtastic.core.strings.notifications_for_channel_and_direct_messages -import org.meshtastic.core.strings.notifications_for_low_battery_alerts -import org.meshtastic.core.strings.notifications_for_newly_discovered_nodes -import org.meshtastic.core.strings.settings +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.app_notifications +import org.meshtastic.core.resources.configure_notification_permissions +import org.meshtastic.core.resources.incoming_messages +import org.meshtastic.core.resources.low_battery +import org.meshtastic.core.resources.new_nodes +import org.meshtastic.core.resources.next +import org.meshtastic.core.resources.notification_permissions_description +import org.meshtastic.core.resources.notifications_for_channel_and_direct_messages +import org.meshtastic.core.resources.notifications_for_low_battery_alerts +import org.meshtastic.core.resources.notifications_for_newly_discovered_nodes +import org.meshtastic.core.resources.settings /** * Screen for configuring notification permissions during the app introduction. It explains why notification permissions diff --git a/feature/intro/src/main/kotlin/org/meshtastic/feature/intro/PermissionScreenLayout.kt b/feature/intro/src/main/kotlin/org/meshtastic/feature/intro/PermissionScreenLayout.kt index f80456c035..889f746716 100644 --- a/feature/intro/src/main/kotlin/org/meshtastic/feature/intro/PermissionScreenLayout.kt +++ b/feature/intro/src/main/kotlin/org/meshtastic/feature/intro/PermissionScreenLayout.kt @@ -43,8 +43,8 @@ import androidx.compose.ui.text.style.TextAlign 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.skip +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.skip /** * A generic layout for screens within the app introduction flow. It typically presents a headline, a descriptive text diff --git a/feature/intro/src/main/kotlin/org/meshtastic/feature/intro/WelcomeScreen.kt b/feature/intro/src/main/kotlin/org/meshtastic/feature/intro/WelcomeScreen.kt index fac0417fb8..1c115958fb 100644 --- a/feature/intro/src/main/kotlin/org/meshtastic/feature/intro/WelcomeScreen.kt +++ b/feature/intro/src/main/kotlin/org/meshtastic/feature/intro/WelcomeScreen.kt @@ -40,16 +40,16 @@ import androidx.compose.ui.text.style.TextAlign 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.communicate_off_the_grid -import org.meshtastic.core.strings.create_your_own_networks -import org.meshtastic.core.strings.easily_set_up_private_mesh_networks -import org.meshtastic.core.strings.get_started -import org.meshtastic.core.strings.intro_welcome -import org.meshtastic.core.strings.meshtastic -import org.meshtastic.core.strings.share_your_location_in_real_time -import org.meshtastic.core.strings.stay_connected_anywhere -import org.meshtastic.core.strings.track_and_share_locations +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.communicate_off_the_grid +import org.meshtastic.core.resources.create_your_own_networks +import org.meshtastic.core.resources.easily_set_up_private_mesh_networks +import org.meshtastic.core.resources.get_started +import org.meshtastic.core.resources.intro_welcome +import org.meshtastic.core.resources.meshtastic +import org.meshtastic.core.resources.share_your_location_in_real_time +import org.meshtastic.core.resources.stay_connected_anywhere +import org.meshtastic.core.resources.track_and_share_locations /** * The initial welcome screen for the app introduction flow. It displays a brief overview of the app's key features. diff --git a/feature/map/README.md b/feature/map/README.md index e43177b23e..bb70f56c25 100644 --- a/feature/map/README.md +++ b/feature/map/README.md @@ -36,7 +36,7 @@ graph TB :feature:map -.-> :core:prefs :feature:map -.-> :core:proto :feature:map -.-> :core:service - :feature:map -.-> :core:strings + :feature:map -.-> :core:resources :feature:map -.-> :core:ui classDef android-application fill:#CAFFBF,stroke:#000,stroke-width:2px,color:#000; diff --git a/feature/map/build.gradle.kts b/feature/map/build.gradle.kts index 49d40cc51a..5395120776 100644 --- a/feature/map/build.gradle.kts +++ b/feature/map/build.gradle.kts @@ -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(projects.core.ui) implementation(libs.accompanist.permissions) diff --git a/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/MapView.kt b/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/MapView.kt index f72b132bae..923f829119 100644 --- a/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/MapView.kt +++ b/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/MapView.kt @@ -89,38 +89,38 @@ import org.meshtastic.core.common.util.nowMillis import org.meshtastic.core.database.entity.Packet import org.meshtastic.core.database.model.Node import org.meshtastic.core.model.DataPacket -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.calculating -import org.meshtastic.core.strings.cancel -import org.meshtastic.core.strings.clear -import org.meshtastic.core.strings.close -import org.meshtastic.core.strings.delete_for_everyone -import org.meshtastic.core.strings.delete_for_me -import org.meshtastic.core.strings.expires -import org.meshtastic.core.strings.getString -import org.meshtastic.core.strings.location_disabled -import org.meshtastic.core.strings.map_cache_info -import org.meshtastic.core.strings.map_cache_manager -import org.meshtastic.core.strings.map_cache_size -import org.meshtastic.core.strings.map_cache_tiles -import org.meshtastic.core.strings.map_clear_tiles -import org.meshtastic.core.strings.map_download_complete -import org.meshtastic.core.strings.map_download_errors -import org.meshtastic.core.strings.map_download_region -import org.meshtastic.core.strings.map_filter -import org.meshtastic.core.strings.map_node_popup_details -import org.meshtastic.core.strings.map_offline_manager -import org.meshtastic.core.strings.map_purge_fail -import org.meshtastic.core.strings.map_purge_success -import org.meshtastic.core.strings.map_style_selection -import org.meshtastic.core.strings.map_subDescription -import org.meshtastic.core.strings.map_tile_source -import org.meshtastic.core.strings.only_favorites -import org.meshtastic.core.strings.show_precision_circle -import org.meshtastic.core.strings.show_waypoints -import org.meshtastic.core.strings.toggle_my_position -import org.meshtastic.core.strings.waypoint_delete -import org.meshtastic.core.strings.you +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.calculating +import org.meshtastic.core.resources.cancel +import org.meshtastic.core.resources.clear +import org.meshtastic.core.resources.close +import org.meshtastic.core.resources.delete_for_everyone +import org.meshtastic.core.resources.delete_for_me +import org.meshtastic.core.resources.expires +import org.meshtastic.core.resources.getString +import org.meshtastic.core.resources.location_disabled +import org.meshtastic.core.resources.map_cache_info +import org.meshtastic.core.resources.map_cache_manager +import org.meshtastic.core.resources.map_cache_size +import org.meshtastic.core.resources.map_cache_tiles +import org.meshtastic.core.resources.map_clear_tiles +import org.meshtastic.core.resources.map_download_complete +import org.meshtastic.core.resources.map_download_errors +import org.meshtastic.core.resources.map_download_region +import org.meshtastic.core.resources.map_filter +import org.meshtastic.core.resources.map_node_popup_details +import org.meshtastic.core.resources.map_offline_manager +import org.meshtastic.core.resources.map_purge_fail +import org.meshtastic.core.resources.map_purge_success +import org.meshtastic.core.resources.map_style_selection +import org.meshtastic.core.resources.map_subDescription +import org.meshtastic.core.resources.map_tile_source +import org.meshtastic.core.resources.only_favorites +import org.meshtastic.core.resources.show_precision_circle +import org.meshtastic.core.resources.show_waypoints +import org.meshtastic.core.resources.toggle_my_position +import org.meshtastic.core.resources.waypoint_delete +import org.meshtastic.core.resources.you import org.meshtastic.core.ui.component.BasicListItem import org.meshtastic.core.ui.component.ListItem import org.meshtastic.core.ui.theme.TracerouteColors diff --git a/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/component/CacheLayout.kt b/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/component/CacheLayout.kt index 0e2a7a5394..dcdd24c291 100644 --- a/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/component/CacheLayout.kt +++ b/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/component/CacheLayout.kt @@ -36,11 +36,11 @@ import androidx.compose.ui.text.style.TextAlign 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.cancel -import org.meshtastic.core.strings.map_select_download_region -import org.meshtastic.core.strings.map_start_download -import org.meshtastic.core.strings.map_tile_download_estimate +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.cancel +import org.meshtastic.core.resources.map_select_download_region +import org.meshtastic.core.resources.map_start_download +import org.meshtastic.core.resources.map_tile_download_estimate @OptIn(ExperimentalLayoutApi::class) @Composable diff --git a/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/component/DownloadButton.kt b/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/component/DownloadButton.kt index ea7ae21026..6716262411 100644 --- a/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/component/DownloadButton.kt +++ b/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/component/DownloadButton.kt @@ -30,8 +30,8 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.draw.scale import org.jetbrains.compose.resources.stringResource -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.map_download_region +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.map_download_region @Composable fun DownloadButton(enabled: Boolean, onClick: () -> Unit) { diff --git a/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/component/EditWaypointDialog.kt b/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/component/EditWaypointDialog.kt index c2572f1155..0dc57bd4cc 100644 --- a/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/component/EditWaypointDialog.kt +++ b/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/component/EditWaypointDialog.kt @@ -70,18 +70,18 @@ import org.meshtastic.core.common.util.nowInstant import org.meshtastic.core.common.util.nowSeconds import org.meshtastic.core.common.util.systemTimeZone import org.meshtastic.core.common.util.toDate -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.cancel -import org.meshtastic.core.strings.date -import org.meshtastic.core.strings.delete -import org.meshtastic.core.strings.description -import org.meshtastic.core.strings.expires -import org.meshtastic.core.strings.locked -import org.meshtastic.core.strings.name -import org.meshtastic.core.strings.send -import org.meshtastic.core.strings.time -import org.meshtastic.core.strings.waypoint_edit -import org.meshtastic.core.strings.waypoint_new +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.cancel +import org.meshtastic.core.resources.date +import org.meshtastic.core.resources.delete +import org.meshtastic.core.resources.description +import org.meshtastic.core.resources.expires +import org.meshtastic.core.resources.locked +import org.meshtastic.core.resources.name +import org.meshtastic.core.resources.send +import org.meshtastic.core.resources.time +import org.meshtastic.core.resources.waypoint_edit +import org.meshtastic.core.resources.waypoint_new import org.meshtastic.core.ui.component.EditTextPreference import org.meshtastic.core.ui.emoji.EmojiPickerDialog import org.meshtastic.core.ui.theme.AppTheme diff --git a/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/component/MapButton.kt b/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/component/MapButton.kt index 5ced0960df..6b30c8ac87 100644 --- a/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/component/MapButton.kt +++ b/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/component/MapButton.kt @@ -29,8 +29,8 @@ import androidx.compose.ui.tooling.preview.PreviewLightDark 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.map_style_selection +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.map_style_selection import org.meshtastic.core.ui.theme.AppTheme @Composable diff --git a/feature/map/src/google/kotlin/org/meshtastic/feature/map/MapView.kt b/feature/map/src/google/kotlin/org/meshtastic/feature/map/MapView.kt index c15ec03d2d..03081c3abc 100644 --- a/feature/map/src/google/kotlin/org/meshtastic/feature/map/MapView.kt +++ b/feature/map/src/google/kotlin/org/meshtastic/feature/map/MapView.kt @@ -97,16 +97,16 @@ import org.meshtastic.core.model.util.metersIn import org.meshtastic.core.model.util.mpsToKmph import org.meshtastic.core.model.util.mpsToMph import org.meshtastic.core.model.util.toString -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.alt -import org.meshtastic.core.strings.heading -import org.meshtastic.core.strings.latitude -import org.meshtastic.core.strings.longitude -import org.meshtastic.core.strings.position -import org.meshtastic.core.strings.sats -import org.meshtastic.core.strings.speed -import org.meshtastic.core.strings.timestamp -import org.meshtastic.core.strings.track_point +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.alt +import org.meshtastic.core.resources.heading +import org.meshtastic.core.resources.latitude +import org.meshtastic.core.resources.longitude +import org.meshtastic.core.resources.position +import org.meshtastic.core.resources.sats +import org.meshtastic.core.resources.speed +import org.meshtastic.core.resources.timestamp +import org.meshtastic.core.resources.track_point import org.meshtastic.core.ui.component.NodeChip import org.meshtastic.core.ui.theme.TracerouteColors import org.meshtastic.core.ui.util.formatAgo diff --git a/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/ClusterItemsListDialog.kt b/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/ClusterItemsListDialog.kt index aea1f1114d..b005cc460a 100644 --- a/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/ClusterItemsListDialog.kt +++ b/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/ClusterItemsListDialog.kt @@ -31,9 +31,9 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import org.jetbrains.compose.resources.stringResource -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.nodes_at_this_location -import org.meshtastic.core.strings.okay +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.nodes_at_this_location +import org.meshtastic.core.resources.okay import org.meshtastic.core.ui.component.NodeChip import org.meshtastic.feature.map.model.NodeClusterItem diff --git a/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/CustomMapLayersSheet.kt b/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/CustomMapLayersSheet.kt index 637a1e6536..30686eddb9 100644 --- a/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/CustomMapLayersSheet.kt +++ b/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/CustomMapLayersSheet.kt @@ -39,14 +39,14 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import org.jetbrains.compose.resources.stringResource -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.add_layer -import org.meshtastic.core.strings.hide_layer -import org.meshtastic.core.strings.manage_map_layers -import org.meshtastic.core.strings.map_layer_formats -import org.meshtastic.core.strings.no_map_layers_loaded -import org.meshtastic.core.strings.remove_layer -import org.meshtastic.core.strings.show_layer +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.add_layer +import org.meshtastic.core.resources.hide_layer +import org.meshtastic.core.resources.manage_map_layers +import org.meshtastic.core.resources.map_layer_formats +import org.meshtastic.core.resources.no_map_layers_loaded +import org.meshtastic.core.resources.remove_layer +import org.meshtastic.core.resources.show_layer import org.meshtastic.feature.map.MapLayerItem @Suppress("LongMethod") diff --git a/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/CustomTileProviderManagerSheet.kt b/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/CustomTileProviderManagerSheet.kt index 15172cd143..c34eb86c52 100644 --- a/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/CustomTileProviderManagerSheet.kt +++ b/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/CustomTileProviderManagerSheet.kt @@ -49,21 +49,21 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import kotlinx.coroutines.flow.collectLatest import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.data.model.CustomTileProviderConfig -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.add_custom_tile_source -import org.meshtastic.core.strings.cancel -import org.meshtastic.core.strings.delete_custom_tile_source -import org.meshtastic.core.strings.edit_custom_tile_source -import org.meshtastic.core.strings.manage_custom_tile_sources -import org.meshtastic.core.strings.name -import org.meshtastic.core.strings.name_cannot_be_empty -import org.meshtastic.core.strings.no_custom_tile_sources_found -import org.meshtastic.core.strings.provider_name_exists -import org.meshtastic.core.strings.save -import org.meshtastic.core.strings.url_cannot_be_empty -import org.meshtastic.core.strings.url_must_contain_placeholders -import org.meshtastic.core.strings.url_template -import org.meshtastic.core.strings.url_template_hint +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.add_custom_tile_source +import org.meshtastic.core.resources.cancel +import org.meshtastic.core.resources.delete_custom_tile_source +import org.meshtastic.core.resources.edit_custom_tile_source +import org.meshtastic.core.resources.manage_custom_tile_sources +import org.meshtastic.core.resources.name +import org.meshtastic.core.resources.name_cannot_be_empty +import org.meshtastic.core.resources.no_custom_tile_sources_found +import org.meshtastic.core.resources.provider_name_exists +import org.meshtastic.core.resources.save +import org.meshtastic.core.resources.url_cannot_be_empty +import org.meshtastic.core.resources.url_must_contain_placeholders +import org.meshtastic.core.resources.url_template +import org.meshtastic.core.resources.url_template_hint import org.meshtastic.core.ui.component.MeshtasticDialog import org.meshtastic.core.ui.util.showToast import org.meshtastic.feature.map.MapViewModel diff --git a/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/EditWaypointDialog.kt b/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/EditWaypointDialog.kt index c6b03ed097..8e423dea66 100644 --- a/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/EditWaypointDialog.kt +++ b/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/EditWaypointDialog.kt @@ -71,18 +71,18 @@ import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.common.util.nowInstant import org.meshtastic.core.common.util.systemTimeZone import org.meshtastic.core.common.util.toDate -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.cancel -import org.meshtastic.core.strings.date -import org.meshtastic.core.strings.delete -import org.meshtastic.core.strings.description -import org.meshtastic.core.strings.expires -import org.meshtastic.core.strings.locked -import org.meshtastic.core.strings.name -import org.meshtastic.core.strings.send -import org.meshtastic.core.strings.time -import org.meshtastic.core.strings.waypoint_edit -import org.meshtastic.core.strings.waypoint_new +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.cancel +import org.meshtastic.core.resources.date +import org.meshtastic.core.resources.delete +import org.meshtastic.core.resources.description +import org.meshtastic.core.resources.expires +import org.meshtastic.core.resources.locked +import org.meshtastic.core.resources.name +import org.meshtastic.core.resources.send +import org.meshtastic.core.resources.time +import org.meshtastic.core.resources.waypoint_edit +import org.meshtastic.core.resources.waypoint_new import org.meshtastic.core.ui.emoji.EmojiPickerDialog import org.meshtastic.proto.Waypoint import kotlin.time.Duration.Companion.hours diff --git a/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/MapControlsOverlay.kt b/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/MapControlsOverlay.kt index cd6ed7ca8c..c2bccf97d4 100644 --- a/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/MapControlsOverlay.kt +++ b/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/MapControlsOverlay.kt @@ -32,12 +32,12 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.draw.rotate import org.jetbrains.compose.resources.stringResource -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.manage_map_layers -import org.meshtastic.core.strings.map_filter -import org.meshtastic.core.strings.map_tile_source -import org.meshtastic.core.strings.orient_north -import org.meshtastic.core.strings.toggle_my_position +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.manage_map_layers +import org.meshtastic.core.resources.map_filter +import org.meshtastic.core.resources.map_tile_source +import org.meshtastic.core.resources.orient_north +import org.meshtastic.core.resources.toggle_my_position import org.meshtastic.core.ui.theme.StatusColors.StatusRed import org.meshtastic.feature.map.MapViewModel diff --git a/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/MapFilterDropdown.kt b/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/MapFilterDropdown.kt index c9bcbbca45..f6f84e154b 100644 --- a/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/MapFilterDropdown.kt +++ b/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/MapFilterDropdown.kt @@ -40,11 +40,11 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import org.jetbrains.compose.resources.stringResource -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.last_heard_filter_label -import org.meshtastic.core.strings.only_favorites -import org.meshtastic.core.strings.show_precision_circle -import org.meshtastic.core.strings.show_waypoints +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.last_heard_filter_label +import org.meshtastic.core.resources.only_favorites +import org.meshtastic.core.resources.show_precision_circle +import org.meshtastic.core.resources.show_waypoints import org.meshtastic.feature.map.LastHeardFilter import org.meshtastic.feature.map.MapViewModel import kotlin.math.roundToInt diff --git a/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/MapTypeDropdown.kt b/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/MapTypeDropdown.kt index 6a6fc74804..f4b3a98f55 100644 --- a/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/MapTypeDropdown.kt +++ b/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/MapTypeDropdown.kt @@ -29,13 +29,13 @@ import androidx.compose.runtime.getValue import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.google.maps.android.compose.MapType import org.jetbrains.compose.resources.stringResource -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.manage_custom_tile_sources -import org.meshtastic.core.strings.map_type_hybrid -import org.meshtastic.core.strings.map_type_normal -import org.meshtastic.core.strings.map_type_satellite -import org.meshtastic.core.strings.map_type_terrain -import org.meshtastic.core.strings.selected_map_type +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.manage_custom_tile_sources +import org.meshtastic.core.resources.map_type_hybrid +import org.meshtastic.core.resources.map_type_normal +import org.meshtastic.core.resources.map_type_satellite +import org.meshtastic.core.resources.map_type_terrain +import org.meshtastic.core.resources.selected_map_type import org.meshtastic.feature.map.MapViewModel @Suppress("LongMethod") diff --git a/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/WaypointMarkers.kt b/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/WaypointMarkers.kt index 1776a40394..7072a6ae22 100644 --- a/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/WaypointMarkers.kt +++ b/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/WaypointMarkers.kt @@ -25,8 +25,8 @@ import com.google.android.gms.maps.model.LatLng import com.google.maps.android.compose.Marker import com.google.maps.android.compose.rememberUpdatedMarkerState import kotlinx.coroutines.launch -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.locked +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.locked import org.meshtastic.core.ui.util.showToast import org.meshtastic.feature.map.BaseMapViewModel import org.meshtastic.proto.Waypoint diff --git a/feature/map/src/main/kotlin/org/meshtastic/feature/map/BaseMapViewModel.kt b/feature/map/src/main/kotlin/org/meshtastic/feature/map/BaseMapViewModel.kt index 70af2c7790..e3384e03aa 100644 --- a/feature/map/src/main/kotlin/org/meshtastic/feature/map/BaseMapViewModel.kt +++ b/feature/map/src/main/kotlin/org/meshtastic/feature/map/BaseMapViewModel.kt @@ -37,12 +37,12 @@ import org.meshtastic.core.model.DataPacket import org.meshtastic.core.model.util.TimeConstants import org.meshtastic.core.prefs.map.MapPrefs import org.meshtastic.core.service.ServiceRepository -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.any -import org.meshtastic.core.strings.eight_hours -import org.meshtastic.core.strings.one_day -import org.meshtastic.core.strings.one_hour -import org.meshtastic.core.strings.two_days +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.any +import org.meshtastic.core.resources.eight_hours +import org.meshtastic.core.resources.one_day +import org.meshtastic.core.resources.one_hour +import org.meshtastic.core.resources.two_days import org.meshtastic.core.ui.viewmodel.stateInWhileSubscribed import org.meshtastic.feature.map.model.TracerouteOverlay import org.meshtastic.proto.Position diff --git a/feature/map/src/main/kotlin/org/meshtastic/feature/map/MapScreen.kt b/feature/map/src/main/kotlin/org/meshtastic/feature/map/MapScreen.kt index 7a31fbea26..9af91022fc 100644 --- a/feature/map/src/main/kotlin/org/meshtastic/feature/map/MapScreen.kt +++ b/feature/map/src/main/kotlin/org/meshtastic/feature/map/MapScreen.kt @@ -26,8 +26,8 @@ import androidx.compose.ui.Modifier import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import org.jetbrains.compose.resources.stringResource -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.map +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.map import org.meshtastic.core.ui.component.MainAppBar @Composable diff --git a/feature/messaging/README.md b/feature/messaging/README.md index 33582b1768..2fc1649144 100644 --- a/feature/messaging/README.md +++ b/feature/messaging/README.md @@ -32,7 +32,7 @@ graph TB :feature:messaging -.-> :core:prefs :feature:messaging -.-> :core:proto :feature:messaging -.-> :core:service - :feature:messaging -.-> :core:strings + :feature:messaging -.-> :core:resources :feature:messaging -.-> :core:ui classDef android-application fill:#CAFFBF,stroke:#000,stroke-width:2px,color:#000; diff --git a/feature/messaging/build.gradle.kts b/feature/messaging/build.gradle.kts index 8cb9833534..5f787f3b4d 100644 --- a/feature/messaging/build.gradle.kts +++ b/feature/messaging/build.gradle.kts @@ -48,7 +48,7 @@ dependencies { implementation(projects.core.prefs) implementation(projects.core.proto) implementation(projects.core.service) - implementation(projects.core.strings) + implementation(projects.core.resources) implementation(projects.core.ui) implementation(libs.androidx.compose.material.iconsExtended) diff --git a/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/DeliveryInfoDialog.kt b/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/DeliveryInfoDialog.kt index 65d73f6c72..f02ac9218c 100644 --- a/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/DeliveryInfoDialog.kt +++ b/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/DeliveryInfoDialog.kt @@ -29,10 +29,10 @@ import androidx.compose.ui.unit.dp import org.jetbrains.compose.resources.StringResource import org.jetbrains.compose.resources.pluralStringResource import org.jetbrains.compose.resources.stringResource -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.close -import org.meshtastic.core.strings.relays -import org.meshtastic.core.strings.resend +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.close +import org.meshtastic.core.resources.relays +import org.meshtastic.core.resources.resend import org.meshtastic.core.ui.component.MeshtasticDialog @Suppress("UnusedParameter") diff --git a/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/Message.kt b/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/Message.kt index 0c54cbf288..2c2835c753 100644 --- a/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/Message.kt +++ b/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/Message.kt @@ -105,32 +105,32 @@ import org.meshtastic.core.database.model.Message import org.meshtastic.core.database.model.Node import org.meshtastic.core.model.DataPacket import org.meshtastic.core.model.util.getChannel -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.alert_bell_text -import org.meshtastic.core.strings.cancel_reply -import org.meshtastic.core.strings.clear_selection -import org.meshtastic.core.strings.copy -import org.meshtastic.core.strings.delete -import org.meshtastic.core.strings.delete_messages -import org.meshtastic.core.strings.delete_messages_title -import org.meshtastic.core.strings.filter_disable_for_contact -import org.meshtastic.core.strings.filter_enable_for_contact -import org.meshtastic.core.strings.filter_hide_count -import org.meshtastic.core.strings.filter_show_count -import org.meshtastic.core.strings.message_input_label -import org.meshtastic.core.strings.navigate_back -import org.meshtastic.core.strings.overflow_menu -import org.meshtastic.core.strings.quick_chat -import org.meshtastic.core.strings.quick_chat_hide -import org.meshtastic.core.strings.quick_chat_show -import org.meshtastic.core.strings.reply -import org.meshtastic.core.strings.replying_to -import org.meshtastic.core.strings.scroll_to_bottom -import org.meshtastic.core.strings.select_all -import org.meshtastic.core.strings.send -import org.meshtastic.core.strings.type_a_message -import org.meshtastic.core.strings.unknown -import org.meshtastic.core.strings.unknown_channel +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.alert_bell_text +import org.meshtastic.core.resources.cancel_reply +import org.meshtastic.core.resources.clear_selection +import org.meshtastic.core.resources.copy +import org.meshtastic.core.resources.delete +import org.meshtastic.core.resources.delete_messages +import org.meshtastic.core.resources.delete_messages_title +import org.meshtastic.core.resources.filter_disable_for_contact +import org.meshtastic.core.resources.filter_enable_for_contact +import org.meshtastic.core.resources.filter_hide_count +import org.meshtastic.core.resources.filter_show_count +import org.meshtastic.core.resources.message_input_label +import org.meshtastic.core.resources.navigate_back +import org.meshtastic.core.resources.overflow_menu +import org.meshtastic.core.resources.quick_chat +import org.meshtastic.core.resources.quick_chat_hide +import org.meshtastic.core.resources.quick_chat_show +import org.meshtastic.core.resources.reply +import org.meshtastic.core.resources.replying_to +import org.meshtastic.core.resources.scroll_to_bottom +import org.meshtastic.core.resources.select_all +import org.meshtastic.core.resources.send +import org.meshtastic.core.resources.type_a_message +import org.meshtastic.core.resources.unknown +import org.meshtastic.core.resources.unknown_channel import org.meshtastic.core.ui.component.MeshtasticTextDialog import org.meshtastic.core.ui.component.NodeKeyStatusIcon import org.meshtastic.core.ui.component.SecurityIcon diff --git a/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/MessageListPaged.kt b/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/MessageListPaged.kt index 41a05b79d8..25be104303 100644 --- a/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/MessageListPaged.kt +++ b/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/MessageListPaged.kt @@ -66,8 +66,8 @@ import org.meshtastic.core.database.entity.Reaction import org.meshtastic.core.database.model.Message import org.meshtastic.core.database.model.Node import org.meshtastic.core.model.MessageStatus -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.new_messages_below +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.new_messages_below import org.meshtastic.feature.messaging.component.MessageItem import org.meshtastic.feature.messaging.component.ReactionDialog diff --git a/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/QuickChat.kt b/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/QuickChat.kt index 260066e433..f63a8a1013 100644 --- a/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/QuickChat.kt +++ b/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/QuickChat.kt @@ -65,18 +65,18 @@ import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.database.entity.QuickChatAction -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.add -import org.meshtastic.core.strings.cancel -import org.meshtastic.core.strings.delete -import org.meshtastic.core.strings.message -import org.meshtastic.core.strings.name -import org.meshtastic.core.strings.quick_chat -import org.meshtastic.core.strings.quick_chat_append -import org.meshtastic.core.strings.quick_chat_edit -import org.meshtastic.core.strings.quick_chat_instant -import org.meshtastic.core.strings.quick_chat_new -import org.meshtastic.core.strings.save +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.add +import org.meshtastic.core.resources.cancel +import org.meshtastic.core.resources.delete +import org.meshtastic.core.resources.message +import org.meshtastic.core.resources.name +import org.meshtastic.core.resources.quick_chat +import org.meshtastic.core.resources.quick_chat_append +import org.meshtastic.core.resources.quick_chat_edit +import org.meshtastic.core.resources.quick_chat_instant +import org.meshtastic.core.resources.quick_chat_new +import org.meshtastic.core.resources.save import org.meshtastic.core.ui.component.MainAppBar import org.meshtastic.core.ui.component.MeshtasticDialog import org.meshtastic.core.ui.component.dragContainer diff --git a/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/component/MessageActions.kt b/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/component/MessageActions.kt index 1d68d69f31..3ef1e3ccb0 100644 --- a/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/component/MessageActions.kt +++ b/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/component/MessageActions.kt @@ -42,10 +42,10 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.model.MessageStatus -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.message_delivery_status -import org.meshtastic.core.strings.react -import org.meshtastic.core.strings.reply +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.message_delivery_status +import org.meshtastic.core.resources.react +import org.meshtastic.core.resources.reply import org.meshtastic.core.ui.emoji.EmojiPickerDialog @Composable diff --git a/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/component/MessageActionsBottomSheet.kt b/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/component/MessageActionsBottomSheet.kt index 0762fea99e..f95c64b45f 100644 --- a/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/component/MessageActionsBottomSheet.kt +++ b/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/component/MessageActionsBottomSheet.kt @@ -47,12 +47,12 @@ import androidx.compose.ui.unit.sp import org.jetbrains.compose.resources.StringResource import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.model.MessageStatus -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.copy -import org.meshtastic.core.strings.delete -import org.meshtastic.core.strings.message_delivery_status -import org.meshtastic.core.strings.reply -import org.meshtastic.core.strings.select +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.copy +import org.meshtastic.core.resources.delete +import org.meshtastic.core.resources.message_delivery_status +import org.meshtastic.core.resources.reply +import org.meshtastic.core.resources.select @Composable fun MessageActionsContent( diff --git a/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/component/MessageItem.kt b/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/component/MessageItem.kt index cf3d150f5f..79f7c8ba68 100644 --- a/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/component/MessageItem.kt +++ b/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/component/MessageItem.kt @@ -66,11 +66,11 @@ import org.meshtastic.core.database.entity.Reaction import org.meshtastic.core.database.model.Message import org.meshtastic.core.database.model.Node import org.meshtastic.core.model.MessageStatus -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.filter_message_label -import org.meshtastic.core.strings.message_delivery_status -import org.meshtastic.core.strings.reply -import org.meshtastic.core.strings.sample_message +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.filter_message_label +import org.meshtastic.core.resources.message_delivery_status +import org.meshtastic.core.resources.reply +import org.meshtastic.core.resources.sample_message import org.meshtastic.core.ui.component.AutoLinkText import org.meshtastic.core.ui.component.NodeChip import org.meshtastic.core.ui.component.Rssi diff --git a/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/component/Reaction.kt b/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/component/Reaction.kt index 06b80bed8d..0011e1e5c1 100644 --- a/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/component/Reaction.kt +++ b/feature/messaging/src/main/kotlin/org/meshtastic/feature/messaging/component/Reaction.kt @@ -64,14 +64,14 @@ import org.meshtastic.core.database.model.getStringResFrom import org.meshtastic.core.model.DataPacket import org.meshtastic.core.model.MessageStatus import org.meshtastic.core.model.util.getShortDateTime -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.react -import org.meshtastic.core.strings.you +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.react +import org.meshtastic.core.resources.you import org.meshtastic.core.ui.component.BottomSheetDialog import org.meshtastic.core.ui.component.Rssi import org.meshtastic.core.ui.component.Snr diff --git a/feature/node/README.md b/feature/node/README.md index 787d59de9e..1d2ba4c2fd 100644 --- a/feature/node/README.md +++ b/feature/node/README.md @@ -31,7 +31,7 @@ graph TB :feature:node -.-> :core:model :feature:node -.-> :core:proto :feature:node -.-> :core:service - :feature:node -.-> :core:strings + :feature:node -.-> :core:resources :feature:node -.-> :core:ui :feature:node -.-> :core:navigation :feature:node -.-> :feature:map diff --git a/feature/node/build.gradle.kts b/feature/node/build.gradle.kts index 01d92ddd37..de857e9d97 100644 --- a/feature/node/build.gradle.kts +++ b/feature/node/build.gradle.kts @@ -40,7 +40,7 @@ dependencies { implementation(projects.core.model) implementation(projects.core.proto) implementation(projects.core.service) - implementation(projects.core.strings) + implementation(projects.core.resources) implementation(projects.core.ui) implementation(projects.core.navigation) implementation(projects.feature.map) diff --git a/feature/node/component/DeviceActions.kt b/feature/node/component/DeviceActions.kt index 4607cd4aa9..39bb324c89 100644 --- a/feature/node/component/DeviceActions.kt +++ b/feature/node/component/DeviceActions.kt @@ -56,15 +56,15 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.database.model.Node -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.actions -import org.meshtastic.core.strings.direct_message -import org.meshtastic.core.strings.favorite -import org.meshtastic.core.strings.ignore -import org.meshtastic.core.strings.mute_always -import org.meshtastic.core.strings.remove -import org.meshtastic.core.strings.share_contact -import org.meshtastic.core.strings.unmute +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.actions +import org.meshtastic.core.resources.direct_message +import org.meshtastic.core.resources.favorite +import org.meshtastic.core.resources.ignore +import org.meshtastic.core.resources.mute_always +import org.meshtastic.core.resources.remove +import org.meshtastic.core.resources.share_contact +import org.meshtastic.core.resources.unmute import org.meshtastic.core.ui.component.ListItem import org.meshtastic.core.ui.component.SwitchListItem import org.meshtastic.feature.node.model.NodeDetailAction diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/AdministrationSection.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/AdministrationSection.kt index 21ca38a602..bb756fbe78 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/AdministrationSection.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/AdministrationSection.kt @@ -33,15 +33,15 @@ import org.meshtastic.core.database.model.Node import org.meshtastic.core.model.DeviceVersion import org.meshtastic.core.navigation.SettingsRoutes import org.meshtastic.core.service.ServiceAction -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.administration -import org.meshtastic.core.strings.firmware -import org.meshtastic.core.strings.firmware_edition -import org.meshtastic.core.strings.installed_firmware_version -import org.meshtastic.core.strings.latest_alpha_firmware -import org.meshtastic.core.strings.latest_stable_firmware -import org.meshtastic.core.strings.remote_admin -import org.meshtastic.core.strings.request_metadata +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.administration +import org.meshtastic.core.resources.firmware +import org.meshtastic.core.resources.firmware_edition +import org.meshtastic.core.resources.installed_firmware_version +import org.meshtastic.core.resources.latest_alpha_firmware +import org.meshtastic.core.resources.latest_stable_firmware +import org.meshtastic.core.resources.remote_admin +import org.meshtastic.core.resources.request_metadata import org.meshtastic.core.ui.component.ListItem import org.meshtastic.core.ui.theme.StatusColors.StatusGreen import org.meshtastic.core.ui.theme.StatusColors.StatusOrange diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/CompassBottomSheet.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/CompassBottomSheet.kt index 407e02830b..7f8b995736 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/CompassBottomSheet.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/CompassBottomSheet.kt @@ -56,20 +56,20 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import org.jetbrains.compose.resources.stringResource -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.compass_bearing -import org.meshtastic.core.strings.compass_bearing_na -import org.meshtastic.core.strings.compass_distance -import org.meshtastic.core.strings.compass_location_disabled -import org.meshtastic.core.strings.compass_no_location_fix -import org.meshtastic.core.strings.compass_no_location_permission -import org.meshtastic.core.strings.compass_no_magnetometer -import org.meshtastic.core.strings.compass_title -import org.meshtastic.core.strings.compass_uncertainty -import org.meshtastic.core.strings.compass_uncertainty_unknown -import org.meshtastic.core.strings.elevation_suffix -import org.meshtastic.core.strings.exchange_position -import org.meshtastic.core.strings.last_position_update +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.compass_bearing +import org.meshtastic.core.resources.compass_bearing_na +import org.meshtastic.core.resources.compass_distance +import org.meshtastic.core.resources.compass_location_disabled +import org.meshtastic.core.resources.compass_no_location_fix +import org.meshtastic.core.resources.compass_no_location_permission +import org.meshtastic.core.resources.compass_no_magnetometer +import org.meshtastic.core.resources.compass_title +import org.meshtastic.core.resources.compass_uncertainty +import org.meshtastic.core.resources.compass_uncertainty_unknown +import org.meshtastic.core.resources.elevation_suffix +import org.meshtastic.core.resources.exchange_position +import org.meshtastic.core.resources.last_position_update import org.meshtastic.core.ui.theme.AppTheme import org.meshtastic.feature.node.compass.CompassUiState import org.meshtastic.feature.node.compass.CompassWarning diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/DeviceActions.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/DeviceActions.kt index 504d8a6b3e..b96ad7927d 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/DeviceActions.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/DeviceActions.kt @@ -47,14 +47,14 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.database.model.Node -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.actions -import org.meshtastic.core.strings.direct_message -import org.meshtastic.core.strings.favorite -import org.meshtastic.core.strings.ignore -import org.meshtastic.core.strings.mute_notifications -import org.meshtastic.core.strings.remove -import org.meshtastic.core.strings.share_contact +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.actions +import org.meshtastic.core.resources.direct_message +import org.meshtastic.core.resources.favorite +import org.meshtastic.core.resources.ignore +import org.meshtastic.core.resources.mute_notifications +import org.meshtastic.core.resources.remove +import org.meshtastic.core.resources.share_contact import org.meshtastic.core.ui.component.ListItem import org.meshtastic.core.ui.component.SwitchListItem import org.meshtastic.feature.node.model.LogsType diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/DeviceDetailsSection.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/DeviceDetailsSection.kt index c60023f058..e4720f2f1f 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/DeviceDetailsSection.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/DeviceDetailsSection.kt @@ -46,11 +46,11 @@ import coil3.compose.AsyncImage import coil3.request.ImageRequest import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.model.DeviceHardware -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.device -import org.meshtastic.core.strings.hardware -import org.meshtastic.core.strings.supported -import org.meshtastic.core.strings.supported_by_community +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.device +import org.meshtastic.core.resources.hardware +import org.meshtastic.core.resources.supported +import org.meshtastic.core.resources.supported_by_community import org.meshtastic.core.ui.component.ListItem import org.meshtastic.core.ui.theme.StatusColors.StatusGreen import org.meshtastic.core.ui.theme.StatusColors.StatusRed diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/DistanceInfo.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/DistanceInfo.kt index 4d13c59bf6..c65b9a4902 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/DistanceInfo.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/DistanceInfo.kt @@ -24,8 +24,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.theme.AppTheme @Composable diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/ElevationInfo.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/ElevationInfo.kt index 6a81858ef9..dca3b143f9 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/ElevationInfo.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/ElevationInfo.kt @@ -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 diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/EnvironmentMetrics.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/EnvironmentMetrics.kt index 84978557db..c8157ebdcb 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/EnvironmentMetrics.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/EnvironmentMetrics.kt @@ -40,23 +40,23 @@ import org.meshtastic.core.model.util.UnitConversions import org.meshtastic.core.model.util.UnitConversions.toTempString import org.meshtastic.core.model.util.toSmallDistanceString import org.meshtastic.core.model.util.toSpeedString -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.current -import org.meshtastic.core.strings.dew_point -import org.meshtastic.core.strings.distance -import org.meshtastic.core.strings.gas_resistance -import org.meshtastic.core.strings.humidity -import org.meshtastic.core.strings.iaq -import org.meshtastic.core.strings.lux -import org.meshtastic.core.strings.pressure -import org.meshtastic.core.strings.radiation -import org.meshtastic.core.strings.soil_moisture -import org.meshtastic.core.strings.soil_temperature -import org.meshtastic.core.strings.temperature -import org.meshtastic.core.strings.uv_lux -import org.meshtastic.core.strings.voltage -import org.meshtastic.core.strings.weight -import org.meshtastic.core.strings.wind +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.current +import org.meshtastic.core.resources.dew_point +import org.meshtastic.core.resources.distance +import org.meshtastic.core.resources.gas_resistance +import org.meshtastic.core.resources.humidity +import org.meshtastic.core.resources.iaq +import org.meshtastic.core.resources.lux +import org.meshtastic.core.resources.pressure +import org.meshtastic.core.resources.radiation +import org.meshtastic.core.resources.soil_moisture +import org.meshtastic.core.resources.soil_temperature +import org.meshtastic.core.resources.temperature +import org.meshtastic.core.resources.uv_lux +import org.meshtastic.core.resources.voltage +import org.meshtastic.core.resources.weight +import org.meshtastic.core.resources.wind import org.meshtastic.feature.node.model.DrawableMetricInfo import org.meshtastic.feature.node.model.VectorMetricInfo import org.meshtastic.proto.Config diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/FirmwareReleaseSheetContent.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/FirmwareReleaseSheetContent.kt index d5d55abf33..7a6e0e6a08 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/FirmwareReleaseSheetContent.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/FirmwareReleaseSheetContent.kt @@ -45,10 +45,10 @@ import com.mikepenz.markdown.m3.Markdown import kotlinx.coroutines.launch import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.database.entity.FirmwareRelease -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.download -import org.meshtastic.core.strings.error_no_app_to_handle_link -import org.meshtastic.core.strings.view_release +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.download +import org.meshtastic.core.resources.error_no_app_to_handle_link +import org.meshtastic.core.resources.view_release import org.meshtastic.core.ui.util.showToast @Composable diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/HopsInfo.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/HopsInfo.kt index 2226621ef6..c888bbca1b 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/HopsInfo.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/HopsInfo.kt @@ -24,8 +24,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.theme.AppTheme @Composable diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/InfoCard.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/InfoCard.kt index 864f210bc8..70681012e3 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/InfoCard.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/InfoCard.kt @@ -49,8 +49,8 @@ import androidx.compose.ui.semantics.semantics import androidx.compose.ui.unit.dp 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 import org.meshtastic.core.ui.util.thenIf @OptIn(ExperimentalMaterial3ExpressiveApi::class, ExperimentalFoundationApi::class) diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/LastHeardInfo.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/LastHeardInfo.kt index 9015284fbe..50aefe6510 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/LastHeardInfo.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/LastHeardInfo.kt @@ -25,8 +25,8 @@ import androidx.compose.ui.res.vectorResource import androidx.compose.ui.tooling.preview.PreviewLightDark import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.common.util.nowSeconds -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.node_sort_last_heard +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.node_sort_last_heard import org.meshtastic.core.ui.R import org.meshtastic.core.ui.theme.AppTheme import org.meshtastic.core.ui.util.formatAgo diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/LinkedCoordinatesItem.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/LinkedCoordinatesItem.kt index b42643955c..1098f03bbb 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/LinkedCoordinatesItem.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/LinkedCoordinatesItem.kt @@ -44,10 +44,10 @@ import org.meshtastic.core.database.model.Node import org.meshtastic.core.model.util.GPSFormat 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.copy -import org.meshtastic.core.strings.elevation_suffix -import org.meshtastic.core.strings.last_position_update +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.copy +import org.meshtastic.core.resources.elevation_suffix +import org.meshtastic.core.resources.last_position_update import org.meshtastic.core.ui.component.BasicListItem import org.meshtastic.core.ui.component.icon import org.meshtastic.core.ui.theme.AppTheme diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/NodeDetailComponents.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/NodeDetailComponents.kt index 7d3c931660..bc5b660524 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/NodeDetailComponents.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/NodeDetailComponents.kt @@ -53,8 +53,8 @@ import androidx.compose.ui.unit.dp import kotlinx.coroutines.launch import org.jetbrains.compose.resources.StringResource 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 internal fun SectionCard( diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/NodeDetailsSection.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/NodeDetailsSection.kt index e84892134c..1ccd6c2780 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/NodeDetailsSection.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/NodeDetailsSection.kt @@ -58,26 +58,26 @@ import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.database.model.Node import org.meshtastic.core.model.DataPacket import org.meshtastic.core.model.util.formatUptime -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.copy -import org.meshtastic.core.strings.details -import org.meshtastic.core.strings.encryption_error -import org.meshtastic.core.strings.encryption_error_text -import org.meshtastic.core.strings.error -import org.meshtastic.core.strings.hops_away -import org.meshtastic.core.strings.node_id -import org.meshtastic.core.strings.node_number -import org.meshtastic.core.strings.node_sort_last_heard -import org.meshtastic.core.strings.public_key -import org.meshtastic.core.strings.role -import org.meshtastic.core.strings.rssi -import org.meshtastic.core.strings.short_name -import org.meshtastic.core.strings.snr -import org.meshtastic.core.strings.status_message -import org.meshtastic.core.strings.supported -import org.meshtastic.core.strings.uptime -import org.meshtastic.core.strings.user_id -import org.meshtastic.core.strings.via_mqtt +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.copy +import org.meshtastic.core.resources.details +import org.meshtastic.core.resources.encryption_error +import org.meshtastic.core.resources.encryption_error_text +import org.meshtastic.core.resources.error +import org.meshtastic.core.resources.hops_away +import org.meshtastic.core.resources.node_id +import org.meshtastic.core.resources.node_number +import org.meshtastic.core.resources.node_sort_last_heard +import org.meshtastic.core.resources.public_key +import org.meshtastic.core.resources.role +import org.meshtastic.core.resources.rssi +import org.meshtastic.core.resources.short_name +import org.meshtastic.core.resources.snr +import org.meshtastic.core.resources.status_message +import org.meshtastic.core.resources.supported +import org.meshtastic.core.resources.uptime +import org.meshtastic.core.resources.user_id +import org.meshtastic.core.resources.via_mqtt import org.meshtastic.core.ui.component.preview.NodePreviewParameterProvider import org.meshtastic.core.ui.icon.ArrowCircleUp import org.meshtastic.core.ui.icon.ChannelUtilization diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/NodeFilterTextField.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/NodeFilterTextField.kt index 1aa8a1bbb3..fa431c8988 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/NodeFilterTextField.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/NodeFilterTextField.kt @@ -61,18 +61,18 @@ import androidx.compose.ui.tooling.preview.PreviewLightDark import androidx.compose.ui.unit.dp import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.database.model.NodeSortOption -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.desc_node_filter_clear -import org.meshtastic.core.strings.node_filter_exclude_infrastructure -import org.meshtastic.core.strings.node_filter_ignored -import org.meshtastic.core.strings.node_filter_include_unknown -import org.meshtastic.core.strings.node_filter_only_direct -import org.meshtastic.core.strings.node_filter_only_online -import org.meshtastic.core.strings.node_filter_placeholder -import org.meshtastic.core.strings.node_filter_show_ignored -import org.meshtastic.core.strings.node_filter_title -import org.meshtastic.core.strings.node_sort_button -import org.meshtastic.core.strings.node_sort_title +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.desc_node_filter_clear +import org.meshtastic.core.resources.node_filter_exclude_infrastructure +import org.meshtastic.core.resources.node_filter_ignored +import org.meshtastic.core.resources.node_filter_include_unknown +import org.meshtastic.core.resources.node_filter_only_direct +import org.meshtastic.core.resources.node_filter_only_online +import org.meshtastic.core.resources.node_filter_placeholder +import org.meshtastic.core.resources.node_filter_show_ignored +import org.meshtastic.core.resources.node_filter_title +import org.meshtastic.core.resources.node_sort_button +import org.meshtastic.core.resources.node_sort_title import org.meshtastic.core.ui.theme.AppTheme @Suppress("LongParameterList") diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/NodeItem.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/NodeItem.kt index 31f5bddc1f..182df61a01 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/NodeItem.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/NodeItem.kt @@ -56,14 +56,14 @@ import org.meshtastic.core.database.model.isUnmessageableRole import org.meshtastic.core.model.util.UnitConversions.celsiusToFahrenheit import org.meshtastic.core.model.util.toDistanceString import org.meshtastic.core.service.ConnectionState -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.air_utilization -import org.meshtastic.core.strings.channel_utilization -import org.meshtastic.core.strings.current -import org.meshtastic.core.strings.elevation_suffix -import org.meshtastic.core.strings.signal_quality -import org.meshtastic.core.strings.unknown_username -import org.meshtastic.core.strings.voltage +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.air_utilization +import org.meshtastic.core.resources.channel_utilization +import org.meshtastic.core.resources.current +import org.meshtastic.core.resources.elevation_suffix +import org.meshtastic.core.resources.signal_quality +import org.meshtastic.core.resources.unknown_username +import org.meshtastic.core.resources.voltage import org.meshtastic.core.ui.component.AirQualityInfo import org.meshtastic.core.ui.component.ChannelInfo import org.meshtastic.core.ui.component.DistanceInfo diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/NodeStatusIcons.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/NodeStatusIcons.kt index cd55596560..1520c9caad 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/NodeStatusIcons.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/NodeStatusIcons.kt @@ -38,15 +38,15 @@ import androidx.compose.ui.unit.dp import org.jetbrains.compose.resources.StringResource import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.service.ConnectionState -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.connected -import org.meshtastic.core.strings.connecting -import org.meshtastic.core.strings.device_sleeping -import org.meshtastic.core.strings.disconnected -import org.meshtastic.core.strings.favorite -import org.meshtastic.core.strings.mute_always -import org.meshtastic.core.strings.unmessageable -import org.meshtastic.core.strings.unmonitored_or_infrastructure +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.connected +import org.meshtastic.core.resources.connecting +import org.meshtastic.core.resources.device_sleeping +import org.meshtastic.core.resources.disconnected +import org.meshtastic.core.resources.favorite +import org.meshtastic.core.resources.mute_always +import org.meshtastic.core.resources.unmessageable +import org.meshtastic.core.resources.unmonitored_or_infrastructure import org.meshtastic.core.ui.icon.CloudDone import org.meshtastic.core.ui.icon.CloudOffTwoTone import org.meshtastic.core.ui.icon.CloudSync diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/NotesSection.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/NotesSection.kt index 5c28218b1e..257ed0566b 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/NotesSection.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/NotesSection.kt @@ -44,10 +44,10 @@ import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.unit.dp import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.database.model.Node -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.add_a_note -import org.meshtastic.core.strings.notes -import org.meshtastic.core.strings.save +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.add_a_note +import org.meshtastic.core.resources.notes +import org.meshtastic.core.resources.save @Composable fun NotesSection(node: Node, onSaveNotes: (Int, String) -> Unit, modifier: Modifier = Modifier) { diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/PositionSection.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/PositionSection.kt index 0a09214ee2..f4fe60fcc8 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/PositionSection.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/PositionSection.kt @@ -48,10 +48,10 @@ import androidx.compose.ui.unit.dp import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.database.model.Node import org.meshtastic.core.model.util.toDistanceString -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.exchange_position -import org.meshtastic.core.strings.open_compass -import org.meshtastic.core.strings.position +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.exchange_position +import org.meshtastic.core.resources.open_compass +import org.meshtastic.core.resources.position import org.meshtastic.feature.node.model.LogsType import org.meshtastic.feature.node.model.MetricsState import org.meshtastic.feature.node.model.NodeDetailAction diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/PowerMetrics.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/PowerMetrics.kt index 2f7b9553fa..6927a7861c 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/PowerMetrics.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/PowerMetrics.kt @@ -27,10 +27,10 @@ import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.database.model.Node -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.channel_1 -import org.meshtastic.core.strings.channel_2 -import org.meshtastic.core.strings.channel_3 +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.channel_1 +import org.meshtastic.core.resources.channel_2 +import org.meshtastic.core.resources.channel_3 import org.meshtastic.feature.node.model.VectorMetricInfo /** diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/SatelliteCountInfo.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/SatelliteCountInfo.kt index da1be0f44d..f11749d983 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/SatelliteCountInfo.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/SatelliteCountInfo.kt @@ -24,8 +24,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.sats +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.sats import org.meshtastic.core.ui.theme.AppTheme @Composable diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/TelemetricActionsSection.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/TelemetricActionsSection.kt index d67141e6e2..0cee70ea87 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/TelemetricActionsSection.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/TelemetricActionsSection.kt @@ -49,12 +49,12 @@ import org.jetbrains.compose.resources.StringResource import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.database.model.Node import org.meshtastic.core.model.TelemetryType -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.logs -import org.meshtastic.core.strings.request_air_quality_metrics -import org.meshtastic.core.strings.request_telemetry -import org.meshtastic.core.strings.telemetry -import org.meshtastic.core.strings.userinfo +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.logs +import org.meshtastic.core.resources.request_air_quality_metrics +import org.meshtastic.core.resources.request_telemetry +import org.meshtastic.core.resources.telemetry +import org.meshtastic.core.resources.userinfo import org.meshtastic.core.ui.icon.AirQuality import org.meshtastic.core.ui.icon.LineAxis import org.meshtastic.core.ui.icon.MeshtasticIcons diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/TelemetryInfo.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/TelemetryInfo.kt index 6fa47e7e1c..12acecf9d6 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/TelemetryInfo.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/TelemetryInfo.kt @@ -33,17 +33,17 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import org.jetbrains.compose.resources.stringResource -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.env_metrics_log -import org.meshtastic.core.strings.humidity -import org.meshtastic.core.strings.iaq -import org.meshtastic.core.strings.node_id -import org.meshtastic.core.strings.pax -import org.meshtastic.core.strings.pax_metrics_log -import org.meshtastic.core.strings.role -import org.meshtastic.core.strings.soil_moisture -import org.meshtastic.core.strings.soil_temperature -import org.meshtastic.core.strings.temperature +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.env_metrics_log +import org.meshtastic.core.resources.humidity +import org.meshtastic.core.resources.iaq +import org.meshtastic.core.resources.node_id +import org.meshtastic.core.resources.pax +import org.meshtastic.core.resources.pax_metrics_log +import org.meshtastic.core.resources.role +import org.meshtastic.core.resources.soil_moisture +import org.meshtastic.core.resources.soil_temperature +import org.meshtastic.core.resources.temperature @Composable fun TemperatureInfo( diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/detail/NodeDetailScreen.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/detail/NodeDetailScreen.kt index 875129456a..77cc1cf1ce 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/detail/NodeDetailScreen.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/detail/NodeDetailScreen.kt @@ -61,10 +61,10 @@ import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.database.entity.FirmwareRelease import org.meshtastic.core.database.model.Node import org.meshtastic.core.navigation.Route -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.details -import org.meshtastic.core.strings.getString -import org.meshtastic.core.strings.loading +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.details +import org.meshtastic.core.resources.getString +import org.meshtastic.core.resources.loading import org.meshtastic.core.ui.component.MainAppBar import org.meshtastic.core.ui.component.SharedContactDialog import org.meshtastic.core.ui.component.preview.NodePreviewParameterProvider diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/detail/NodeManagementActions.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/detail/NodeManagementActions.kt index 854fedf41e..0d50a525a6 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/detail/NodeManagementActions.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/detail/NodeManagementActions.kt @@ -26,19 +26,19 @@ import org.meshtastic.core.data.repository.NodeRepository import org.meshtastic.core.database.model.Node import org.meshtastic.core.service.ServiceAction import org.meshtastic.core.service.ServiceRepository -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.favorite -import org.meshtastic.core.strings.favorite_add -import org.meshtastic.core.strings.favorite_remove -import org.meshtastic.core.strings.ignore -import org.meshtastic.core.strings.ignore_add -import org.meshtastic.core.strings.ignore_remove -import org.meshtastic.core.strings.mute_add -import org.meshtastic.core.strings.mute_notifications -import org.meshtastic.core.strings.mute_remove -import org.meshtastic.core.strings.remove -import org.meshtastic.core.strings.remove_node_text -import org.meshtastic.core.strings.unmute +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.favorite +import org.meshtastic.core.resources.favorite_add +import org.meshtastic.core.resources.favorite_remove +import org.meshtastic.core.resources.ignore +import org.meshtastic.core.resources.ignore_add +import org.meshtastic.core.resources.ignore_remove +import org.meshtastic.core.resources.mute_add +import org.meshtastic.core.resources.mute_notifications +import org.meshtastic.core.resources.mute_remove +import org.meshtastic.core.resources.remove +import org.meshtastic.core.resources.remove_node_text +import org.meshtastic.core.resources.unmute import org.meshtastic.core.ui.util.AlertManager import javax.inject.Inject import javax.inject.Singleton diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/detail/NodeRequestActions.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/detail/NodeRequestActions.kt index eeefac9fe6..300023bf06 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/detail/NodeRequestActions.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/detail/NodeRequestActions.kt @@ -32,19 +32,19 @@ import org.meshtastic.core.common.util.nowMillis import org.meshtastic.core.model.Position import org.meshtastic.core.model.TelemetryType import org.meshtastic.core.service.ServiceRepository -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.neighbor_info -import org.meshtastic.core.strings.position -import org.meshtastic.core.strings.request_air_quality_metrics -import org.meshtastic.core.strings.request_device_metrics -import org.meshtastic.core.strings.request_environment_metrics -import org.meshtastic.core.strings.request_host_metrics -import org.meshtastic.core.strings.request_pax_metrics -import org.meshtastic.core.strings.request_power_metrics -import org.meshtastic.core.strings.requesting_from -import org.meshtastic.core.strings.signal_quality -import org.meshtastic.core.strings.traceroute -import org.meshtastic.core.strings.user_info +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.neighbor_info +import org.meshtastic.core.resources.position +import org.meshtastic.core.resources.request_air_quality_metrics +import org.meshtastic.core.resources.request_device_metrics +import org.meshtastic.core.resources.request_environment_metrics +import org.meshtastic.core.resources.request_host_metrics +import org.meshtastic.core.resources.request_pax_metrics +import org.meshtastic.core.resources.request_power_metrics +import org.meshtastic.core.resources.requesting_from +import org.meshtastic.core.resources.signal_quality +import org.meshtastic.core.resources.traceroute +import org.meshtastic.core.resources.user_info import javax.inject.Inject import javax.inject.Singleton diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/domain/usecase/GetNodeDetailsUseCase.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/domain/usecase/GetNodeDetailsUseCase.kt index fe557c2586..229a8539aa 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/domain/usecase/GetNodeDetailsUseCase.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/domain/usecase/GetNodeDetailsUseCase.kt @@ -34,9 +34,9 @@ import org.meshtastic.core.database.model.Node import org.meshtastic.core.model.MyNodeInfo import org.meshtastic.core.model.util.hasValidEnvironmentMetrics import org.meshtastic.core.model.util.isDirectSignal -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.fallback_node_name -import org.meshtastic.core.strings.getString +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.fallback_node_name +import org.meshtastic.core.resources.getString import org.meshtastic.core.ui.util.toPosition import org.meshtastic.feature.node.detail.NodeDetailUiState import org.meshtastic.feature.node.detail.NodeRequestActions diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/list/NodeListScreen.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/list/NodeListScreen.kt index 156394d757..f4e9341352 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/list/NodeListScreen.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/list/NodeListScreen.kt @@ -69,17 +69,17 @@ import kotlinx.coroutines.launch import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.database.model.Node import org.meshtastic.core.service.ConnectionState -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.add_favorite -import org.meshtastic.core.strings.channel_invalid -import org.meshtastic.core.strings.ignore -import org.meshtastic.core.strings.mute_always -import org.meshtastic.core.strings.node_count_template -import org.meshtastic.core.strings.nodes -import org.meshtastic.core.strings.remove -import org.meshtastic.core.strings.remove_favorite -import org.meshtastic.core.strings.remove_ignored -import org.meshtastic.core.strings.unmute +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.add_favorite +import org.meshtastic.core.resources.channel_invalid +import org.meshtastic.core.resources.ignore +import org.meshtastic.core.resources.mute_always +import org.meshtastic.core.resources.node_count_template +import org.meshtastic.core.resources.nodes +import org.meshtastic.core.resources.remove +import org.meshtastic.core.resources.remove_favorite +import org.meshtastic.core.resources.remove_ignored +import org.meshtastic.core.resources.unmute import org.meshtastic.core.ui.component.MainAppBar import org.meshtastic.core.ui.component.MeshtasticImportFAB import org.meshtastic.core.ui.component.ScrollToTopEvent diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/BaseMetricChart.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/BaseMetricChart.kt index 275a0a1eb6..ffc8b698ac 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/BaseMetricChart.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/BaseMetricChart.kt @@ -59,9 +59,9 @@ import kotlinx.coroutines.launch import org.jetbrains.compose.resources.StringResource import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.model.TelemetryType -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.info -import org.meshtastic.core.strings.logs +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.info +import org.meshtastic.core.resources.logs import org.meshtastic.core.ui.component.MainAppBar import org.meshtastic.core.ui.icon.MeshtasticIcons import org.meshtastic.core.ui.icon.Refresh diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/CommonCharts.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/CommonCharts.kt index de263751d8..ee1419b029 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/CommonCharts.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/CommonCharts.kt @@ -63,12 +63,12 @@ import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.common.util.toDate import org.meshtastic.core.common.util.toInstant import org.meshtastic.core.model.util.TimeConstants -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.close -import org.meshtastic.core.strings.delete -import org.meshtastic.core.strings.info -import org.meshtastic.core.strings.rssi -import org.meshtastic.core.strings.snr +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.close +import org.meshtastic.core.resources.delete +import org.meshtastic.core.resources.info +import org.meshtastic.core.resources.rssi +import org.meshtastic.core.resources.snr import org.meshtastic.core.ui.icon.Delete import org.meshtastic.core.ui.icon.MeshtasticIcons import java.text.DateFormat diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/DeviceMetrics.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/DeviceMetrics.kt index 87a6c7ba8d..721808e6b0 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/DeviceMetrics.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/DeviceMetrics.kt @@ -66,16 +66,16 @@ import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.common.util.nowSeconds import org.meshtastic.core.model.TelemetryType import org.meshtastic.core.model.util.formatUptime -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.air_util_definition -import org.meshtastic.core.strings.air_utilization -import org.meshtastic.core.strings.battery -import org.meshtastic.core.strings.ch_util_definition -import org.meshtastic.core.strings.channel_utilization -import org.meshtastic.core.strings.device_metrics_log -import org.meshtastic.core.strings.getString -import org.meshtastic.core.strings.uptime -import org.meshtastic.core.strings.voltage +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.air_util_definition +import org.meshtastic.core.resources.air_utilization +import org.meshtastic.core.resources.battery +import org.meshtastic.core.resources.ch_util_definition +import org.meshtastic.core.resources.channel_utilization +import org.meshtastic.core.resources.device_metrics_log +import org.meshtastic.core.resources.getString +import org.meshtastic.core.resources.uptime +import org.meshtastic.core.resources.voltage import org.meshtastic.core.ui.component.MaterialBatteryInfo import org.meshtastic.core.ui.theme.AppTheme import org.meshtastic.core.ui.theme.GraphColors.Cyan diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/EnvironmentCharts.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/EnvironmentCharts.kt index 60a034bfe6..d7ccf869c1 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/EnvironmentCharts.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/EnvironmentCharts.kt @@ -33,15 +33,15 @@ import com.patrykandpatrick.vico.compose.cartesian.data.lineSeries import com.patrykandpatrick.vico.compose.cartesian.layer.LineCartesianLayer import com.patrykandpatrick.vico.compose.cartesian.layer.rememberLineCartesianLayer import org.jetbrains.compose.resources.stringResource -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.baro_pressure -import org.meshtastic.core.strings.humidity -import org.meshtastic.core.strings.iaq -import org.meshtastic.core.strings.lux -import org.meshtastic.core.strings.soil_moisture -import org.meshtastic.core.strings.soil_temperature -import org.meshtastic.core.strings.temperature -import org.meshtastic.core.strings.uv_lux +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.baro_pressure +import org.meshtastic.core.resources.humidity +import org.meshtastic.core.resources.iaq +import org.meshtastic.core.resources.lux +import org.meshtastic.core.resources.soil_moisture +import org.meshtastic.core.resources.soil_temperature +import org.meshtastic.core.resources.temperature +import org.meshtastic.core.resources.uv_lux import org.meshtastic.proto.Telemetry @Suppress("MagicNumber") diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/EnvironmentMetrics.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/EnvironmentMetrics.kt index daa2e30abd..ecdd8268b9 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/EnvironmentMetrics.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/EnvironmentMetrics.kt @@ -51,21 +51,21 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.common.util.nowSeconds import org.meshtastic.core.model.TelemetryType -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.current -import org.meshtastic.core.strings.env_metrics_log -import org.meshtastic.core.strings.gas_resistance -import org.meshtastic.core.strings.getString -import org.meshtastic.core.strings.humidity -import org.meshtastic.core.strings.iaq -import org.meshtastic.core.strings.iaq_definition -import org.meshtastic.core.strings.lux -import org.meshtastic.core.strings.radiation -import org.meshtastic.core.strings.soil_moisture -import org.meshtastic.core.strings.soil_temperature -import org.meshtastic.core.strings.temperature -import org.meshtastic.core.strings.uv_lux -import org.meshtastic.core.strings.voltage +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.current +import org.meshtastic.core.resources.env_metrics_log +import org.meshtastic.core.resources.gas_resistance +import org.meshtastic.core.resources.getString +import org.meshtastic.core.resources.humidity +import org.meshtastic.core.resources.iaq +import org.meshtastic.core.resources.iaq_definition +import org.meshtastic.core.resources.lux +import org.meshtastic.core.resources.radiation +import org.meshtastic.core.resources.soil_moisture +import org.meshtastic.core.resources.soil_temperature +import org.meshtastic.core.resources.temperature +import org.meshtastic.core.resources.uv_lux +import org.meshtastic.core.resources.voltage import org.meshtastic.core.ui.component.IaqDisplayMode import org.meshtastic.core.ui.component.IndoorAirQuality import org.meshtastic.feature.node.detail.NodeRequestEffect diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/HostMetricsLog.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/HostMetricsLog.kt index 6bd7df2e61..d4b76e0640 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/HostMetricsLog.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/HostMetricsLog.kt @@ -59,13 +59,13 @@ import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.common.util.nowSeconds import org.meshtastic.core.model.TelemetryType import org.meshtastic.core.model.util.formatUptime -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.disk_free_indexed -import org.meshtastic.core.strings.free_memory -import org.meshtastic.core.strings.getString -import org.meshtastic.core.strings.load_indexed -import org.meshtastic.core.strings.uptime -import org.meshtastic.core.strings.user_string +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.disk_free_indexed +import org.meshtastic.core.resources.free_memory +import org.meshtastic.core.resources.getString +import org.meshtastic.core.resources.load_indexed +import org.meshtastic.core.resources.uptime +import org.meshtastic.core.resources.user_string import org.meshtastic.core.ui.component.MainAppBar import org.meshtastic.core.ui.icon.DataArray import org.meshtastic.core.ui.icon.MeshtasticIcons diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/MetricsViewModel.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/MetricsViewModel.kt index 9db4b3628f..700c35505b 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/MetricsViewModel.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/MetricsViewModel.kt @@ -56,10 +56,10 @@ import org.meshtastic.core.model.evaluateTracerouteMapAvailability import org.meshtastic.core.model.util.UnitConversions import org.meshtastic.core.navigation.NodesRoutes import org.meshtastic.core.service.ServiceRepository -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.okay -import org.meshtastic.core.strings.traceroute -import org.meshtastic.core.strings.view_on_map +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.okay +import org.meshtastic.core.resources.traceroute +import org.meshtastic.core.resources.view_on_map import org.meshtastic.core.ui.util.AlertManager import org.meshtastic.core.ui.util.toMessageRes import org.meshtastic.core.ui.viewmodel.stateInWhileSubscribed diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/NeighborInfoLog.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/NeighborInfoLog.kt index ba8eddf859..ac45d3e206 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/NeighborInfoLog.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/NeighborInfoLog.kt @@ -45,10 +45,10 @@ import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.model.getNeighborInfoResponse -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.getString -import org.meshtastic.core.strings.neighbor_info -import org.meshtastic.core.strings.routing_error_no_response +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.getString +import org.meshtastic.core.resources.neighbor_info +import org.meshtastic.core.resources.routing_error_no_response import org.meshtastic.core.ui.component.MainAppBar import org.meshtastic.core.ui.icon.Groups import org.meshtastic.core.ui.icon.MeshtasticIcons diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/PaxMetrics.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/PaxMetrics.kt index e8ec78445d..037214424b 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/PaxMetrics.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/PaxMetrics.kt @@ -59,14 +59,14 @@ import org.meshtastic.core.common.util.toInstant import org.meshtastic.core.database.entity.MeshLog import org.meshtastic.core.model.TelemetryType import org.meshtastic.core.model.util.formatUptime -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.ble_devices -import org.meshtastic.core.strings.getString -import org.meshtastic.core.strings.no_pax_metrics_logs -import org.meshtastic.core.strings.pax -import org.meshtastic.core.strings.pax_metrics_log -import org.meshtastic.core.strings.uptime -import org.meshtastic.core.strings.wifi_devices +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.ble_devices +import org.meshtastic.core.resources.getString +import org.meshtastic.core.resources.no_pax_metrics_logs +import org.meshtastic.core.resources.pax +import org.meshtastic.core.resources.pax_metrics_log +import org.meshtastic.core.resources.uptime +import org.meshtastic.core.resources.wifi_devices import org.meshtastic.core.ui.component.IconInfo import org.meshtastic.core.ui.icon.MeshtasticIcons import org.meshtastic.core.ui.icon.Paxcount diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/PositionLog.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/PositionLog.kt index 9cada14159..0a9879ee67 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/PositionLog.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/PositionLog.kt @@ -65,17 +65,17 @@ import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.common.util.nowSeconds 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.alt -import org.meshtastic.core.strings.clear -import org.meshtastic.core.strings.getString -import org.meshtastic.core.strings.heading -import org.meshtastic.core.strings.latitude -import org.meshtastic.core.strings.longitude -import org.meshtastic.core.strings.sats -import org.meshtastic.core.strings.save -import org.meshtastic.core.strings.speed -import org.meshtastic.core.strings.timestamp +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.alt +import org.meshtastic.core.resources.clear +import org.meshtastic.core.resources.getString +import org.meshtastic.core.resources.heading +import org.meshtastic.core.resources.latitude +import org.meshtastic.core.resources.longitude +import org.meshtastic.core.resources.sats +import org.meshtastic.core.resources.save +import org.meshtastic.core.resources.speed +import org.meshtastic.core.resources.timestamp import org.meshtastic.core.ui.component.MainAppBar import org.meshtastic.core.ui.icon.Delete import org.meshtastic.core.ui.icon.MeshtasticIcons diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/PowerMetrics.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/PowerMetrics.kt index 7906cc3b8c..93dfba8304 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/PowerMetrics.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/PowerMetrics.kt @@ -64,14 +64,14 @@ import com.patrykandpatrick.vico.compose.cartesian.layer.rememberLineCartesianLa import org.jetbrains.compose.resources.StringResource import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.model.TelemetryType -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.channel_1 -import org.meshtastic.core.strings.channel_2 -import org.meshtastic.core.strings.channel_3 -import org.meshtastic.core.strings.current -import org.meshtastic.core.strings.getString -import org.meshtastic.core.strings.power_metrics_log -import org.meshtastic.core.strings.voltage +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.channel_1 +import org.meshtastic.core.resources.channel_2 +import org.meshtastic.core.resources.channel_3 +import org.meshtastic.core.resources.current +import org.meshtastic.core.resources.getString +import org.meshtastic.core.resources.power_metrics_log +import org.meshtastic.core.resources.voltage import org.meshtastic.core.ui.theme.GraphColors.Gold import org.meshtastic.core.ui.theme.GraphColors.InfantryBlue import org.meshtastic.feature.node.detail.NodeRequestEffect diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/SignalMetrics.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/SignalMetrics.kt index 2a6eea13b3..c2e90197cb 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/SignalMetrics.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/SignalMetrics.kt @@ -58,13 +58,13 @@ import com.patrykandpatrick.vico.compose.cartesian.data.lineSeries import com.patrykandpatrick.vico.compose.cartesian.layer.LineCartesianLayer import com.patrykandpatrick.vico.compose.cartesian.layer.rememberLineCartesianLayer import org.meshtastic.core.model.TelemetryType -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.getString -import org.meshtastic.core.strings.rssi -import org.meshtastic.core.strings.rssi_definition -import org.meshtastic.core.strings.signal_quality -import org.meshtastic.core.strings.snr -import org.meshtastic.core.strings.snr_definition +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.getString +import org.meshtastic.core.resources.rssi +import org.meshtastic.core.resources.rssi_definition +import org.meshtastic.core.resources.signal_quality +import org.meshtastic.core.resources.snr +import org.meshtastic.core.resources.snr_definition import org.meshtastic.core.ui.component.LoraSignalIndicator import org.meshtastic.core.ui.theme.GraphColors.Blue import org.meshtastic.core.ui.theme.GraphColors.Green diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/TracerouteLog.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/TracerouteLog.kt index 81da6af260..5d7494c6e6 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/TracerouteLog.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/TracerouteLog.kt @@ -52,18 +52,18 @@ import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.common.util.nowMillis import org.meshtastic.core.model.fullRouteDiscovery import org.meshtastic.core.model.getTracerouteResponse -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.getString -import org.meshtastic.core.strings.routing_error_no_response -import org.meshtastic.core.strings.traceroute -import org.meshtastic.core.strings.traceroute_diff -import org.meshtastic.core.strings.traceroute_direct -import org.meshtastic.core.strings.traceroute_duration -import org.meshtastic.core.strings.traceroute_hops -import org.meshtastic.core.strings.traceroute_log -import org.meshtastic.core.strings.traceroute_route_back_to_us -import org.meshtastic.core.strings.traceroute_route_towards_dest -import org.meshtastic.core.strings.traceroute_time_and_text +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.getString +import org.meshtastic.core.resources.routing_error_no_response +import org.meshtastic.core.resources.traceroute +import org.meshtastic.core.resources.traceroute_diff +import org.meshtastic.core.resources.traceroute_direct +import org.meshtastic.core.resources.traceroute_duration +import org.meshtastic.core.resources.traceroute_hops +import org.meshtastic.core.resources.traceroute_log +import org.meshtastic.core.resources.traceroute_route_back_to_us +import org.meshtastic.core.resources.traceroute_route_towards_dest +import org.meshtastic.core.resources.traceroute_time_and_text import org.meshtastic.core.ui.component.MainAppBar import org.meshtastic.core.ui.icon.Group import org.meshtastic.core.ui.icon.MeshtasticIcons diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/TracerouteMapScreen.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/TracerouteMapScreen.kt index 792b478acc..c42d570354 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/TracerouteMapScreen.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/TracerouteMapScreen.kt @@ -43,11 +43,11 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import kotlinx.coroutines.flow.flowOf import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.model.fullRouteDiscovery -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.traceroute -import org.meshtastic.core.strings.traceroute_outgoing_route -import org.meshtastic.core.strings.traceroute_return_route -import org.meshtastic.core.strings.traceroute_showing_nodes +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.traceroute +import org.meshtastic.core.resources.traceroute_outgoing_route +import org.meshtastic.core.resources.traceroute_return_route +import org.meshtastic.core.resources.traceroute_showing_nodes import org.meshtastic.core.ui.component.MainAppBar import org.meshtastic.core.ui.icon.MeshtasticIcons import org.meshtastic.core.ui.icon.Route diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/model/LogsType.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/model/LogsType.kt index 502eac84da..930a7b826a 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/model/LogsType.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/model/LogsType.kt @@ -29,17 +29,17 @@ import androidx.compose.ui.graphics.vector.ImageVector import org.jetbrains.compose.resources.StringResource import org.meshtastic.core.navigation.NodeDetailRoutes import org.meshtastic.core.navigation.Route -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.device_metrics_log -import org.meshtastic.core.strings.env_metrics_log -import org.meshtastic.core.strings.host_metrics_log -import org.meshtastic.core.strings.neighbor_info -import org.meshtastic.core.strings.node_map -import org.meshtastic.core.strings.pax_metrics_log -import org.meshtastic.core.strings.position_log -import org.meshtastic.core.strings.power_metrics_log -import org.meshtastic.core.strings.signal_quality -import org.meshtastic.core.strings.traceroute_log +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.device_metrics_log +import org.meshtastic.core.resources.env_metrics_log +import org.meshtastic.core.resources.host_metrics_log +import org.meshtastic.core.resources.neighbor_info +import org.meshtastic.core.resources.node_map +import org.meshtastic.core.resources.pax_metrics_log +import org.meshtastic.core.resources.position_log +import org.meshtastic.core.resources.power_metrics_log +import org.meshtastic.core.resources.signal_quality +import org.meshtastic.core.resources.traceroute_log import org.meshtastic.core.ui.icon.MeshtasticIcons import org.meshtastic.core.ui.icon.Paxcount import org.meshtastic.core.ui.icon.Route diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/model/TimeFrame.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/model/TimeFrame.kt index e26881b4c4..b775574f01 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/model/TimeFrame.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/model/TimeFrame.kt @@ -18,13 +18,13 @@ package org.meshtastic.feature.node.model import org.jetbrains.compose.resources.StringResource import org.meshtastic.core.common.util.nowSeconds -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.all_time -import org.meshtastic.core.strings.one_hour_short -import org.meshtastic.core.strings.one_month -import org.meshtastic.core.strings.one_week -import org.meshtastic.core.strings.twenty_four_hours -import org.meshtastic.core.strings.two_weeks +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.all_time +import org.meshtastic.core.resources.one_hour_short +import org.meshtastic.core.resources.one_month +import org.meshtastic.core.resources.one_week +import org.meshtastic.core.resources.twenty_four_hours +import org.meshtastic.core.resources.two_weeks @Suppress("MagicNumber") enum class TimeFrame(val strRes: StringResource, val seconds: Long) { diff --git a/feature/node/src/test/kotlin/org/meshtastic/feature/node/metrics/BaseMetricScreenTest.kt b/feature/node/src/test/kotlin/org/meshtastic/feature/node/metrics/BaseMetricScreenTest.kt index e663355808..6166892777 100644 --- a/feature/node/src/test/kotlin/org/meshtastic/feature/node/metrics/BaseMetricScreenTest.kt +++ b/feature/node/src/test/kotlin/org/meshtastic/feature/node/metrics/BaseMetricScreenTest.kt @@ -27,8 +27,8 @@ import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.meshtastic.core.model.TelemetryType -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.device_metrics_log +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.device_metrics_log import org.meshtastic.core.ui.theme.AppTheme import org.robolectric.RobolectricTestRunner import org.robolectric.annotation.Config diff --git a/feature/settings/README.md b/feature/settings/README.md index e2d69c8049..78074fb4d0 100644 --- a/feature/settings/README.md +++ b/feature/settings/README.md @@ -35,7 +35,7 @@ graph TB :feature:settings -.-> :core:prefs :feature:settings -.-> :core:proto :feature:settings -.-> :core:service - :feature:settings -.-> :core:strings + :feature:settings -.-> :core:resources :feature:settings -.-> :core:ui :feature:settings -.-> :core:barcode diff --git a/feature/settings/build.gradle.kts b/feature/settings/build.gradle.kts index 6ad18ff41a..9a7de65a8b 100644 --- a/feature/settings/build.gradle.kts +++ b/feature/settings/build.gradle.kts @@ -39,7 +39,7 @@ dependencies { implementation(projects.core.prefs) implementation(projects.core.proto) implementation(projects.core.service) - implementation(projects.core.strings) + implementation(projects.core.resources) implementation(projects.core.ui) implementation(projects.core.barcode) diff --git a/feature/settings/src/androidTest/kotlin/org/meshtastic/feature/settings/debugging/DebugFiltersTest.kt b/feature/settings/src/androidTest/kotlin/org/meshtastic/feature/settings/debugging/DebugFiltersTest.kt index 124726e0cf..5b31f7012f 100644 --- a/feature/settings/src/androidTest/kotlin/org/meshtastic/feature/settings/debugging/DebugFiltersTest.kt +++ b/feature/settings/src/androidTest/kotlin/org/meshtastic/feature/settings/debugging/DebugFiltersTest.kt @@ -35,10 +35,10 @@ import androidx.test.platform.app.InstrumentationRegistry import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.debug_active_filters -import org.meshtastic.core.strings.debug_filters -import org.meshtastic.core.strings.getString +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.debug_active_filters +import org.meshtastic.core.resources.debug_filters +import org.meshtastic.core.resources.getString import org.meshtastic.feature.settings.debugging.DebugViewModel.UiMeshLog @RunWith(AndroidJUnit4::class) diff --git a/feature/settings/src/androidTest/kotlin/org/meshtastic/feature/settings/debugging/DebugSearchTest.kt b/feature/settings/src/androidTest/kotlin/org/meshtastic/feature/settings/debugging/DebugSearchTest.kt index 87f54cb27e..ed1e6a7f5d 100644 --- a/feature/settings/src/androidTest/kotlin/org/meshtastic/feature/settings/debugging/DebugSearchTest.kt +++ b/feature/settings/src/androidTest/kotlin/org/meshtastic/feature/settings/debugging/DebugSearchTest.kt @@ -34,11 +34,11 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.debug_active_filters -import org.meshtastic.core.strings.debug_default_search -import org.meshtastic.core.strings.debug_filters -import org.meshtastic.core.strings.getString +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.debug_active_filters +import org.meshtastic.core.resources.debug_default_search +import org.meshtastic.core.resources.debug_filters +import org.meshtastic.core.resources.getString import org.meshtastic.feature.settings.debugging.DebugViewModel.UiMeshLog import org.meshtastic.feature.settings.debugging.LogSearchManager.SearchMatch import org.meshtastic.feature.settings.debugging.LogSearchManager.SearchState diff --git a/feature/settings/src/androidTest/kotlin/org/meshtastic/feature/settings/radio/component/EditDeviceProfileDialogTest.kt b/feature/settings/src/androidTest/kotlin/org/meshtastic/feature/settings/radio/component/EditDeviceProfileDialogTest.kt index a0449cca48..1f390e44e2 100644 --- a/feature/settings/src/androidTest/kotlin/org/meshtastic/feature/settings/radio/component/EditDeviceProfileDialogTest.kt +++ b/feature/settings/src/androidTest/kotlin/org/meshtastic/feature/settings/radio/component/EditDeviceProfileDialogTest.kt @@ -25,10 +25,10 @@ import org.junit.Assert import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.cancel -import org.meshtastic.core.strings.getString -import org.meshtastic.core.strings.save +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.cancel +import org.meshtastic.core.resources.getString +import org.meshtastic.core.resources.save import org.meshtastic.proto.DeviceProfile import org.meshtastic.proto.Position diff --git a/feature/settings/src/androidTest/kotlin/org/meshtastic/feature/settings/radio/component/MapReportingPreferenceTest.kt b/feature/settings/src/androidTest/kotlin/org/meshtastic/feature/settings/radio/component/MapReportingPreferenceTest.kt index b25bc354df..9eb31a6e7e 100644 --- a/feature/settings/src/androidTest/kotlin/org/meshtastic/feature/settings/radio/component/MapReportingPreferenceTest.kt +++ b/feature/settings/src/androidTest/kotlin/org/meshtastic/feature/settings/radio/component/MapReportingPreferenceTest.kt @@ -28,11 +28,11 @@ import org.junit.Assert import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.getString -import org.meshtastic.core.strings.i_agree -import org.meshtastic.core.strings.map_reporting -import org.meshtastic.core.strings.map_reporting_summary +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.getString +import org.meshtastic.core.resources.i_agree +import org.meshtastic.core.resources.map_reporting +import org.meshtastic.core.resources.map_reporting_summary @RunWith(AndroidJUnit4::class) class MapReportingPreferenceTest { diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/AboutScreen.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/AboutScreen.kt index 2b790c00db..0f872cb910 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/AboutScreen.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/AboutScreen.kt @@ -30,8 +30,8 @@ import com.mikepenz.aboutlibraries.Libs import com.mikepenz.aboutlibraries.ui.compose.m3.LibrariesContainer import com.mikepenz.aboutlibraries.util.withContext import org.jetbrains.compose.resources.stringResource -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.acknowledgements +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.acknowledgements import org.meshtastic.core.ui.component.MainAppBar @Composable diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/SettingsScreen.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/SettingsScreen.kt index 2829346ef5..1887edbb34 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/SettingsScreen.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/SettingsScreen.kt @@ -74,33 +74,33 @@ import org.meshtastic.core.common.util.toInstant import org.meshtastic.core.database.DatabaseConstants import org.meshtastic.core.navigation.Route import org.meshtastic.core.navigation.SettingsRoutes -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.acknowledgements -import org.meshtastic.core.strings.analytics_okay -import org.meshtastic.core.strings.app_settings -import org.meshtastic.core.strings.app_version -import org.meshtastic.core.strings.bottom_nav_settings -import org.meshtastic.core.strings.choose_theme -import org.meshtastic.core.strings.device_db_cache_limit -import org.meshtastic.core.strings.device_db_cache_limit_summary -import org.meshtastic.core.strings.dynamic -import org.meshtastic.core.strings.export_configuration -import org.meshtastic.core.strings.export_data_csv -import org.meshtastic.core.strings.import_configuration -import org.meshtastic.core.strings.intro_show -import org.meshtastic.core.strings.location_disabled -import org.meshtastic.core.strings.modules_already_unlocked -import org.meshtastic.core.strings.modules_unlocked -import org.meshtastic.core.strings.preferences_language -import org.meshtastic.core.strings.provide_location_to_mesh -import org.meshtastic.core.strings.remotely_administrating -import org.meshtastic.core.strings.save_rangetest -import org.meshtastic.core.strings.system_settings -import org.meshtastic.core.strings.theme -import org.meshtastic.core.strings.theme_dark -import org.meshtastic.core.strings.theme_light -import org.meshtastic.core.strings.theme_system -import org.meshtastic.core.strings.use_homoglyph_characters_encoding +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.acknowledgements +import org.meshtastic.core.resources.analytics_okay +import org.meshtastic.core.resources.app_settings +import org.meshtastic.core.resources.app_version +import org.meshtastic.core.resources.bottom_nav_settings +import org.meshtastic.core.resources.choose_theme +import org.meshtastic.core.resources.device_db_cache_limit +import org.meshtastic.core.resources.device_db_cache_limit_summary +import org.meshtastic.core.resources.dynamic +import org.meshtastic.core.resources.export_configuration +import org.meshtastic.core.resources.export_data_csv +import org.meshtastic.core.resources.import_configuration +import org.meshtastic.core.resources.intro_show +import org.meshtastic.core.resources.location_disabled +import org.meshtastic.core.resources.modules_already_unlocked +import org.meshtastic.core.resources.modules_unlocked +import org.meshtastic.core.resources.preferences_language +import org.meshtastic.core.resources.provide_location_to_mesh +import org.meshtastic.core.resources.remotely_administrating +import org.meshtastic.core.resources.save_rangetest +import org.meshtastic.core.resources.system_settings +import org.meshtastic.core.resources.theme +import org.meshtastic.core.resources.theme_dark +import org.meshtastic.core.resources.theme_light +import org.meshtastic.core.resources.theme_system +import org.meshtastic.core.resources.use_homoglyph_characters_encoding import org.meshtastic.core.ui.component.DropDownPreference import org.meshtastic.core.ui.component.ListItem import org.meshtastic.core.ui.component.MainAppBar diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/debugging/Debug.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/debugging/Debug.kt index 49fab4e0f9..7a62781694 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/debugging/Debug.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/debugging/Debug.kt @@ -86,22 +86,22 @@ import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.common.util.nowMillis import org.meshtastic.core.common.util.toDate import org.meshtastic.core.common.util.toInstant -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.debug_clear -import org.meshtastic.core.strings.debug_decoded_payload -import org.meshtastic.core.strings.debug_default_search -import org.meshtastic.core.strings.debug_export_failed -import org.meshtastic.core.strings.debug_export_success -import org.meshtastic.core.strings.debug_filters -import org.meshtastic.core.strings.debug_logs_export -import org.meshtastic.core.strings.debug_panel -import org.meshtastic.core.strings.debug_store_logs_summary -import org.meshtastic.core.strings.debug_store_logs_title -import org.meshtastic.core.strings.log_retention_days -import org.meshtastic.core.strings.log_retention_days_quantity -import org.meshtastic.core.strings.log_retention_days_summary -import org.meshtastic.core.strings.log_retention_hours -import org.meshtastic.core.strings.log_retention_never +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.debug_clear +import org.meshtastic.core.resources.debug_decoded_payload +import org.meshtastic.core.resources.debug_default_search +import org.meshtastic.core.resources.debug_export_failed +import org.meshtastic.core.resources.debug_export_success +import org.meshtastic.core.resources.debug_filters +import org.meshtastic.core.resources.debug_logs_export +import org.meshtastic.core.resources.debug_panel +import org.meshtastic.core.resources.debug_store_logs_summary +import org.meshtastic.core.resources.debug_store_logs_title +import org.meshtastic.core.resources.log_retention_days +import org.meshtastic.core.resources.log_retention_days_quantity +import org.meshtastic.core.resources.log_retention_days_summary +import org.meshtastic.core.resources.log_retention_hours +import org.meshtastic.core.resources.log_retention_never import org.meshtastic.core.ui.component.CopyIconButton import org.meshtastic.core.ui.component.DropDownPreference import org.meshtastic.core.ui.component.MainAppBar diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/debugging/DebugFilters.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/debugging/DebugFilters.kt index 8a393f67ff..9a9addff34 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/debugging/DebugFilters.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/debugging/DebugFilters.kt @@ -56,16 +56,16 @@ import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.unit.DpOffset import androidx.compose.ui.unit.dp import org.jetbrains.compose.resources.stringResource -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.debug_active_filters -import org.meshtastic.core.strings.debug_filter_add -import org.meshtastic.core.strings.debug_filter_add_custom -import org.meshtastic.core.strings.debug_filter_clear -import org.meshtastic.core.strings.debug_filter_included -import org.meshtastic.core.strings.debug_filter_preset_title -import org.meshtastic.core.strings.debug_filters -import org.meshtastic.core.strings.match_all -import org.meshtastic.core.strings.match_any +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.debug_active_filters +import org.meshtastic.core.resources.debug_filter_add +import org.meshtastic.core.resources.debug_filter_add_custom +import org.meshtastic.core.resources.debug_filter_clear +import org.meshtastic.core.resources.debug_filter_included +import org.meshtastic.core.resources.debug_filter_preset_title +import org.meshtastic.core.resources.debug_filters +import org.meshtastic.core.resources.match_all +import org.meshtastic.core.resources.match_any import org.meshtastic.feature.settings.debugging.DebugViewModel.UiMeshLog @Composable diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/debugging/DebugSearch.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/debugging/DebugSearch.kt index 82c70982eb..f1db9005bf 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/debugging/DebugSearch.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/debugging/DebugSearch.kt @@ -52,12 +52,12 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import org.jetbrains.compose.resources.stringResource -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.debug_default_search -import org.meshtastic.core.strings.debug_logs_export -import org.meshtastic.core.strings.debug_search_clear -import org.meshtastic.core.strings.debug_search_next -import org.meshtastic.core.strings.debug_search_prev +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.debug_default_search +import org.meshtastic.core.resources.debug_logs_export +import org.meshtastic.core.resources.debug_search_clear +import org.meshtastic.core.resources.debug_search_next +import org.meshtastic.core.resources.debug_search_prev import org.meshtastic.core.ui.theme.AppTheme import org.meshtastic.feature.settings.debugging.DebugViewModel.UiMeshLog import org.meshtastic.feature.settings.debugging.LogSearchManager.SearchMatch diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/debugging/DebugViewModel.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/debugging/DebugViewModel.kt index 06b0b19513..161134b163 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/debugging/DebugViewModel.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/debugging/DebugViewModel.kt @@ -44,9 +44,9 @@ import org.meshtastic.core.model.getTracerouteResponse import org.meshtastic.core.model.util.decodeOrNull import org.meshtastic.core.model.util.toReadableString import org.meshtastic.core.prefs.meshlog.MeshLogPrefs -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.debug_clear -import org.meshtastic.core.strings.debug_clear_logs_confirm +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.debug_clear +import org.meshtastic.core.resources.debug_clear_logs_confirm import org.meshtastic.core.ui.util.AlertManager import org.meshtastic.core.ui.viewmodel.stateInWhileSubscribed import org.meshtastic.proto.AdminMessage diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/filter/FilterSettingsScreen.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/filter/FilterSettingsScreen.kt index e8e953cf69..9a2c1f0eef 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/filter/FilterSettingsScreen.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/filter/FilterSettingsScreen.kt @@ -48,18 +48,18 @@ import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.unit.dp import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel 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.filter_add_placeholder -import org.meshtastic.core.strings.filter_enable -import org.meshtastic.core.strings.filter_enable_summary -import org.meshtastic.core.strings.filter_no_words -import org.meshtastic.core.strings.filter_regex_pattern -import org.meshtastic.core.strings.filter_settings -import org.meshtastic.core.strings.filter_whole_word -import org.meshtastic.core.strings.filter_words -import org.meshtastic.core.strings.filter_words_summary +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.add +import org.meshtastic.core.resources.delete +import org.meshtastic.core.resources.filter_add_placeholder +import org.meshtastic.core.resources.filter_enable +import org.meshtastic.core.resources.filter_enable_summary +import org.meshtastic.core.resources.filter_no_words +import org.meshtastic.core.resources.filter_regex_pattern +import org.meshtastic.core.resources.filter_settings +import org.meshtastic.core.resources.filter_whole_word +import org.meshtastic.core.resources.filter_words +import org.meshtastic.core.resources.filter_words_summary import org.meshtastic.core.ui.component.MainAppBar @Composable diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/navigation/ConfigRoute.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/navigation/ConfigRoute.kt index 1ad0a5bfef..1821fd6c3e 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/navigation/ConfigRoute.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/navigation/ConfigRoute.kt @@ -31,17 +31,17 @@ import androidx.compose.ui.graphics.vector.ImageVector import org.jetbrains.compose.resources.StringResource import org.meshtastic.core.navigation.Route import org.meshtastic.core.navigation.SettingsRoutes -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.bluetooth -import org.meshtastic.core.strings.channels -import org.meshtastic.core.strings.device -import org.meshtastic.core.strings.display -import org.meshtastic.core.strings.lora -import org.meshtastic.core.strings.network -import org.meshtastic.core.strings.position -import org.meshtastic.core.strings.power -import org.meshtastic.core.strings.security -import org.meshtastic.core.strings.user +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.bluetooth +import org.meshtastic.core.resources.channels +import org.meshtastic.core.resources.device +import org.meshtastic.core.resources.display +import org.meshtastic.core.resources.lora +import org.meshtastic.core.resources.network +import org.meshtastic.core.resources.position +import org.meshtastic.core.resources.power +import org.meshtastic.core.resources.security +import org.meshtastic.core.resources.user import org.meshtastic.proto.AdminMessage import org.meshtastic.proto.DeviceMetadata diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/navigation/ModuleRoute.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/navigation/ModuleRoute.kt index 6c7b2bedb1..cb96d573bc 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/navigation/ModuleRoute.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/navigation/ModuleRoute.kt @@ -35,21 +35,21 @@ import org.jetbrains.compose.resources.StringResource import org.meshtastic.core.model.Capabilities import org.meshtastic.core.navigation.Route import org.meshtastic.core.navigation.SettingsRoutes -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.ambient_lighting -import org.meshtastic.core.strings.audio -import org.meshtastic.core.strings.canned_message -import org.meshtastic.core.strings.detection_sensor -import org.meshtastic.core.strings.external_notification -import org.meshtastic.core.strings.mqtt -import org.meshtastic.core.strings.neighbor_info -import org.meshtastic.core.strings.paxcounter -import org.meshtastic.core.strings.range_test -import org.meshtastic.core.strings.remote_hardware -import org.meshtastic.core.strings.serial -import org.meshtastic.core.strings.status_message -import org.meshtastic.core.strings.store_forward -import org.meshtastic.core.strings.telemetry +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.ambient_lighting +import org.meshtastic.core.resources.audio +import org.meshtastic.core.resources.canned_message +import org.meshtastic.core.resources.detection_sensor +import org.meshtastic.core.resources.external_notification +import org.meshtastic.core.resources.mqtt +import org.meshtastic.core.resources.neighbor_info +import org.meshtastic.core.resources.paxcounter +import org.meshtastic.core.resources.range_test +import org.meshtastic.core.resources.remote_hardware +import org.meshtastic.core.resources.serial +import org.meshtastic.core.resources.status_message +import org.meshtastic.core.resources.store_forward +import org.meshtastic.core.resources.telemetry import org.meshtastic.proto.AdminMessage import org.meshtastic.proto.DeviceMetadata diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/CleanNodeDatabaseScreen.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/CleanNodeDatabaseScreen.kt index 7ca93ad0fc..06c5a853ba 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/CleanNodeDatabaseScreen.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/CleanNodeDatabaseScreen.kt @@ -41,13 +41,13 @@ import androidx.compose.ui.unit.dp import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.database.entity.NodeEntity -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.clean_node_database_description -import org.meshtastic.core.strings.clean_node_database_title -import org.meshtastic.core.strings.clean_nodes_older_than -import org.meshtastic.core.strings.clean_now -import org.meshtastic.core.strings.clean_unknown_nodes -import org.meshtastic.core.strings.nodes_queued_for_deletion +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.clean_node_database_description +import org.meshtastic.core.resources.clean_node_database_title +import org.meshtastic.core.resources.clean_nodes_older_than +import org.meshtastic.core.resources.clean_now +import org.meshtastic.core.resources.clean_unknown_nodes +import org.meshtastic.core.resources.nodes_queued_for_deletion import org.meshtastic.core.ui.component.NodeChip /** diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/CleanNodeDatabaseViewModel.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/CleanNodeDatabaseViewModel.kt index d516543305..cfed889682 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/CleanNodeDatabaseViewModel.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/CleanNodeDatabaseViewModel.kt @@ -27,10 +27,10 @@ import org.meshtastic.core.common.util.nowSeconds import org.meshtastic.core.data.repository.NodeRepository import org.meshtastic.core.database.entity.NodeEntity import org.meshtastic.core.service.ServiceRepository -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.are_you_sure -import org.meshtastic.core.strings.clean_node_database_confirmation -import org.meshtastic.core.strings.clean_now +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.are_you_sure +import org.meshtastic.core.resources.clean_node_database_confirmation +import org.meshtastic.core.resources.clean_now import org.meshtastic.core.ui.util.AlertManager import javax.inject.Inject import kotlin.time.Duration.Companion.days diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/RadioConfig.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/RadioConfig.kt index 679abc664c..e220b5c827 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/RadioConfig.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/RadioConfig.kt @@ -54,24 +54,24 @@ import org.meshtastic.core.database.model.Node import org.meshtastic.core.navigation.FirmwareRoutes import org.meshtastic.core.navigation.Route import org.meshtastic.core.navigation.SettingsRoutes -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.administration -import org.meshtastic.core.strings.advanced_title -import org.meshtastic.core.strings.backup_restore -import org.meshtastic.core.strings.clean_node_database_title -import org.meshtastic.core.strings.debug_panel -import org.meshtastic.core.strings.device_configuration -import org.meshtastic.core.strings.export_configuration -import org.meshtastic.core.strings.factory_reset -import org.meshtastic.core.strings.firmware_update_title -import org.meshtastic.core.strings.import_configuration -import org.meshtastic.core.strings.message_device_managed -import org.meshtastic.core.strings.module_settings -import org.meshtastic.core.strings.nodedb_reset -import org.meshtastic.core.strings.preserve_favorites -import org.meshtastic.core.strings.radio_configuration -import org.meshtastic.core.strings.reboot -import org.meshtastic.core.strings.shutdown +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.administration +import org.meshtastic.core.resources.advanced_title +import org.meshtastic.core.resources.backup_restore +import org.meshtastic.core.resources.clean_node_database_title +import org.meshtastic.core.resources.debug_panel +import org.meshtastic.core.resources.device_configuration +import org.meshtastic.core.resources.export_configuration +import org.meshtastic.core.resources.factory_reset +import org.meshtastic.core.resources.firmware_update_title +import org.meshtastic.core.resources.import_configuration +import org.meshtastic.core.resources.message_device_managed +import org.meshtastic.core.resources.module_settings +import org.meshtastic.core.resources.nodedb_reset +import org.meshtastic.core.resources.preserve_favorites +import org.meshtastic.core.resources.radio_configuration +import org.meshtastic.core.resources.reboot +import org.meshtastic.core.resources.shutdown import org.meshtastic.core.ui.component.ListItem import org.meshtastic.core.ui.component.TitledCard import org.meshtastic.core.ui.theme.AppTheme diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/RadioConfigViewModel.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/RadioConfigViewModel.kt index cf12c81236..67503ddf1f 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/RadioConfigViewModel.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/RadioConfigViewModel.kt @@ -61,8 +61,8 @@ import org.meshtastic.core.prefs.map.MapConsentPrefs import org.meshtastic.core.service.ConnectionState import org.meshtastic.core.service.IMeshService import org.meshtastic.core.service.ServiceRepository -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.cant_shutdown +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.cant_shutdown import org.meshtastic.core.ui.util.getChannelList import org.meshtastic.feature.settings.navigation.ConfigRoute import org.meshtastic.feature.settings.navigation.ModuleRoute diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/channel/ChannelConfigScreen.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/channel/ChannelConfigScreen.kt index 71931f30c8..5915c54aa7 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/channel/ChannelConfigScreen.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/channel/ChannelConfigScreen.kt @@ -54,13 +54,13 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.model.Capabilities import org.meshtastic.core.model.Channel -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.add -import org.meshtastic.core.strings.cancel -import org.meshtastic.core.strings.channel_name -import org.meshtastic.core.strings.channels -import org.meshtastic.core.strings.press_and_drag -import org.meshtastic.core.strings.send +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.add +import org.meshtastic.core.resources.cancel +import org.meshtastic.core.resources.channel_name +import org.meshtastic.core.resources.channels +import org.meshtastic.core.resources.press_and_drag +import org.meshtastic.core.resources.send import org.meshtastic.core.ui.component.MainAppBar import org.meshtastic.core.ui.component.PreferenceFooter import org.meshtastic.core.ui.component.dragContainer diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/channel/component/ChannelCard.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/channel/component/ChannelCard.kt index e89c37df9b..81252fee2a 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/channel/component/ChannelCard.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/channel/component/ChannelCard.kt @@ -29,8 +29,8 @@ import androidx.compose.ui.Modifier 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.delete +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.delete import org.meshtastic.core.ui.component.ChannelItem import org.meshtastic.core.ui.component.SecurityIcon import org.meshtastic.core.ui.theme.AppTheme diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/channel/component/ChannelConfigHeader.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/channel/component/ChannelConfigHeader.kt index 9e7fd028e2..c4a49c2641 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/channel/component/ChannelConfigHeader.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/channel/component/ChannelConfigHeader.kt @@ -28,10 +28,10 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.sp import org.jetbrains.compose.resources.stringResource -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.channels -import org.meshtastic.core.strings.freq -import org.meshtastic.core.strings.slot +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.channels +import org.meshtastic.core.resources.freq +import org.meshtastic.core.resources.slot import org.meshtastic.core.ui.component.PreferenceCategory import org.meshtastic.core.ui.theme.AppTheme diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/channel/component/ChannelLegend.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/channel/component/ChannelLegend.kt index f88675dd1f..0759ac214c 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/channel/component/ChannelLegend.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/channel/component/ChannelLegend.kt @@ -42,23 +42,23 @@ import androidx.compose.ui.unit.dp import org.jetbrains.compose.resources.StringResource import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.model.Capabilities -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.channel_features -import org.meshtastic.core.strings.downlink_enabled -import org.meshtastic.core.strings.downlink_feature_description -import org.meshtastic.core.strings.icon_meanings -import org.meshtastic.core.strings.info -import org.meshtastic.core.strings.location_sharing -import org.meshtastic.core.strings.manual_position_request -import org.meshtastic.core.strings.periodic_position_broadcast -import org.meshtastic.core.strings.primary -import org.meshtastic.core.strings.primary_channel_feature -import org.meshtastic.core.strings.secondary -import org.meshtastic.core.strings.secondary_channel_position_feature -import org.meshtastic.core.strings.secondary_no_telemetry -import org.meshtastic.core.strings.security_icon_help_dismiss -import org.meshtastic.core.strings.uplink_enabled -import org.meshtastic.core.strings.uplink_feature_description +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.channel_features +import org.meshtastic.core.resources.downlink_enabled +import org.meshtastic.core.resources.downlink_feature_description +import org.meshtastic.core.resources.icon_meanings +import org.meshtastic.core.resources.info +import org.meshtastic.core.resources.location_sharing +import org.meshtastic.core.resources.manual_position_request +import org.meshtastic.core.resources.periodic_position_broadcast +import org.meshtastic.core.resources.primary +import org.meshtastic.core.resources.primary_channel_feature +import org.meshtastic.core.resources.secondary +import org.meshtastic.core.resources.secondary_channel_position_feature +import org.meshtastic.core.resources.secondary_no_telemetry +import org.meshtastic.core.resources.security_icon_help_dismiss +import org.meshtastic.core.resources.uplink_enabled +import org.meshtastic.core.resources.uplink_feature_description import org.meshtastic.core.ui.component.MeshtasticDialog @Composable diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/channel/component/EditChannelDialog.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/channel/component/EditChannelDialog.kt index 4674342fcf..835fa95570 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/channel/component/EditChannelDialog.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/channel/component/EditChannelDialog.kt @@ -34,13 +34,13 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.model.Channel -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.cancel -import org.meshtastic.core.strings.channel_name -import org.meshtastic.core.strings.default_ -import org.meshtastic.core.strings.downlink_enabled -import org.meshtastic.core.strings.save -import org.meshtastic.core.strings.uplink_enabled +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.cancel +import org.meshtastic.core.resources.channel_name +import org.meshtastic.core.resources.default_ +import org.meshtastic.core.resources.downlink_enabled +import org.meshtastic.core.resources.save +import org.meshtastic.core.resources.uplink_enabled import org.meshtastic.core.ui.component.EditBase64Preference import org.meshtastic.core.ui.component.EditTextPreference import org.meshtastic.core.ui.component.MeshtasticDialog diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/AmbientLightingConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/AmbientLightingConfigItemList.kt index e29c41fa4f..fe6efefe9d 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/AmbientLightingConfigItemList.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/AmbientLightingConfigItemList.kt @@ -25,14 +25,14 @@ import androidx.compose.ui.platform.LocalFocusManager import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import org.jetbrains.compose.resources.stringResource -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.ambient_lighting -import org.meshtastic.core.strings.ambient_lighting_config -import org.meshtastic.core.strings.blue -import org.meshtastic.core.strings.current -import org.meshtastic.core.strings.green -import org.meshtastic.core.strings.led_state -import org.meshtastic.core.strings.red +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.ambient_lighting +import org.meshtastic.core.resources.ambient_lighting_config +import org.meshtastic.core.resources.blue +import org.meshtastic.core.resources.current +import org.meshtastic.core.resources.green +import org.meshtastic.core.resources.led_state +import org.meshtastic.core.resources.red import org.meshtastic.core.ui.component.EditTextPreference import org.meshtastic.core.ui.component.SwitchPreference import org.meshtastic.core.ui.component.TitledCard diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/AudioConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/AudioConfigItemList.kt index 6e868478ea..9b009352b0 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/AudioConfigItemList.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/AudioConfigItemList.kt @@ -25,16 +25,16 @@ import androidx.compose.ui.platform.LocalFocusManager import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import org.jetbrains.compose.resources.stringResource -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.audio -import org.meshtastic.core.strings.audio_config -import org.meshtastic.core.strings.codec2_sample_rate -import org.meshtastic.core.strings.codec_2_enabled -import org.meshtastic.core.strings.i2s_clock -import org.meshtastic.core.strings.i2s_data_in -import org.meshtastic.core.strings.i2s_data_out -import org.meshtastic.core.strings.i2s_word_select -import org.meshtastic.core.strings.ptt_pin +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.audio +import org.meshtastic.core.resources.audio_config +import org.meshtastic.core.resources.codec2_sample_rate +import org.meshtastic.core.resources.codec_2_enabled +import org.meshtastic.core.resources.i2s_clock +import org.meshtastic.core.resources.i2s_data_in +import org.meshtastic.core.resources.i2s_data_out +import org.meshtastic.core.resources.i2s_word_select +import org.meshtastic.core.resources.ptt_pin import org.meshtastic.core.ui.component.DropDownPreference import org.meshtastic.core.ui.component.EditTextPreference import org.meshtastic.core.ui.component.SwitchPreference diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/BluetoothConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/BluetoothConfigItemList.kt index d9d5ecc5a6..f05efd1f82 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/BluetoothConfigItemList.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/BluetoothConfigItemList.kt @@ -25,12 +25,12 @@ import androidx.compose.ui.platform.LocalFocusManager import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import org.jetbrains.compose.resources.stringResource -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.bluetooth -import org.meshtastic.core.strings.bluetooth_config -import org.meshtastic.core.strings.bluetooth_enabled -import org.meshtastic.core.strings.fixed_pin -import org.meshtastic.core.strings.pairing_mode +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.bluetooth +import org.meshtastic.core.resources.bluetooth_config +import org.meshtastic.core.resources.bluetooth_enabled +import org.meshtastic.core.resources.fixed_pin +import org.meshtastic.core.resources.pairing_mode import org.meshtastic.core.ui.component.DropDownPreference import org.meshtastic.core.ui.component.EditTextPreference import org.meshtastic.core.ui.component.SwitchPreference diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/CannedMessageConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/CannedMessageConfigItemList.kt index bacc82b763..e96e00f0ae 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/CannedMessageConfigItemList.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/CannedMessageConfigItemList.kt @@ -31,21 +31,21 @@ import androidx.compose.ui.text.input.KeyboardType import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import org.jetbrains.compose.resources.stringResource -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.allow_input_source -import org.meshtastic.core.strings.canned_message -import org.meshtastic.core.strings.canned_message_config -import org.meshtastic.core.strings.canned_message_enabled -import org.meshtastic.core.strings.generate_input_event_on_ccw -import org.meshtastic.core.strings.generate_input_event_on_cw -import org.meshtastic.core.strings.generate_input_event_on_press -import org.meshtastic.core.strings.gpio_pin_for_rotary_encoder_a_port -import org.meshtastic.core.strings.gpio_pin_for_rotary_encoder_b_port -import org.meshtastic.core.strings.gpio_pin_for_rotary_encoder_press_port -import org.meshtastic.core.strings.messages -import org.meshtastic.core.strings.rotary_encoder_1_enabled -import org.meshtastic.core.strings.send_bell -import org.meshtastic.core.strings.up_down_select_input_enabled +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.allow_input_source +import org.meshtastic.core.resources.canned_message +import org.meshtastic.core.resources.canned_message_config +import org.meshtastic.core.resources.canned_message_enabled +import org.meshtastic.core.resources.generate_input_event_on_ccw +import org.meshtastic.core.resources.generate_input_event_on_cw +import org.meshtastic.core.resources.generate_input_event_on_press +import org.meshtastic.core.resources.gpio_pin_for_rotary_encoder_a_port +import org.meshtastic.core.resources.gpio_pin_for_rotary_encoder_b_port +import org.meshtastic.core.resources.gpio_pin_for_rotary_encoder_press_port +import org.meshtastic.core.resources.messages +import org.meshtastic.core.resources.rotary_encoder_1_enabled +import org.meshtastic.core.resources.send_bell +import org.meshtastic.core.resources.up_down_select_input_enabled import org.meshtastic.core.ui.component.DropDownPreference import org.meshtastic.core.ui.component.EditTextPreference import org.meshtastic.core.ui.component.SwitchPreference diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/DetectionSensorConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/DetectionSensorConfigItemList.kt index 89ec48a205..e6c8d9a172 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/DetectionSensorConfigItemList.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/DetectionSensorConfigItemList.kt @@ -29,17 +29,17 @@ import androidx.compose.ui.text.input.KeyboardType import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import org.jetbrains.compose.resources.stringResource -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.detection_sensor -import org.meshtastic.core.strings.detection_sensor_config -import org.meshtastic.core.strings.detection_sensor_enabled -import org.meshtastic.core.strings.detection_trigger_type -import org.meshtastic.core.strings.friendly_name -import org.meshtastic.core.strings.gpio_pin_to_monitor -import org.meshtastic.core.strings.minimum_broadcast_seconds -import org.meshtastic.core.strings.send_bell_with_alert_message -import org.meshtastic.core.strings.state_broadcast_seconds -import org.meshtastic.core.strings.use_input_pullup_mode +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.detection_sensor +import org.meshtastic.core.resources.detection_sensor_config +import org.meshtastic.core.resources.detection_sensor_enabled +import org.meshtastic.core.resources.detection_trigger_type +import org.meshtastic.core.resources.friendly_name +import org.meshtastic.core.resources.gpio_pin_to_monitor +import org.meshtastic.core.resources.minimum_broadcast_seconds +import org.meshtastic.core.resources.send_bell_with_alert_message +import org.meshtastic.core.resources.state_broadcast_seconds +import org.meshtastic.core.resources.use_input_pullup_mode import org.meshtastic.core.ui.component.DropDownPreference import org.meshtastic.core.ui.component.EditTextPreference import org.meshtastic.core.ui.component.SwitchPreference diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/DeviceConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/DeviceConfigItemList.kt index 9ec687e9cd..d2151165f7 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/DeviceConfigItemList.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/DeviceConfigItemList.kt @@ -64,50 +64,50 @@ import no.nordicsemi.android.common.core.registerReceiver import org.jetbrains.compose.resources.StringResource import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.model.util.toPosixString -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.accept -import org.meshtastic.core.strings.are_you_sure -import org.meshtastic.core.strings.button_gpio -import org.meshtastic.core.strings.buzzer_gpio -import org.meshtastic.core.strings.cancel -import org.meshtastic.core.strings.config_device_doubleTapAsButtonPress_summary -import org.meshtastic.core.strings.config_device_ledHeartbeatEnabled_summary -import org.meshtastic.core.strings.config_device_tripleClickAsAdHocPing_summary -import org.meshtastic.core.strings.config_device_tzdef_summary -import org.meshtastic.core.strings.config_device_use_phone_tz -import org.meshtastic.core.strings.device -import org.meshtastic.core.strings.double_tap_as_button_press -import org.meshtastic.core.strings.gpio -import org.meshtastic.core.strings.hardware -import org.meshtastic.core.strings.i_know_what_i_m_doing -import org.meshtastic.core.strings.led_heartbeat -import org.meshtastic.core.strings.nodeinfo_broadcast_interval -import org.meshtastic.core.strings.options -import org.meshtastic.core.strings.rebroadcast_mode -import org.meshtastic.core.strings.rebroadcast_mode_all_desc -import org.meshtastic.core.strings.rebroadcast_mode_all_skip_decoding_desc -import org.meshtastic.core.strings.rebroadcast_mode_core_portnums_only_desc -import org.meshtastic.core.strings.rebroadcast_mode_known_only_desc -import org.meshtastic.core.strings.rebroadcast_mode_local_only_desc -import org.meshtastic.core.strings.rebroadcast_mode_none_desc -import org.meshtastic.core.strings.role -import org.meshtastic.core.strings.role_client_base_desc -import org.meshtastic.core.strings.role_client_desc -import org.meshtastic.core.strings.role_client_hidden_desc -import org.meshtastic.core.strings.role_client_mute_desc -import org.meshtastic.core.strings.role_lost_and_found_desc -import org.meshtastic.core.strings.role_repeater_desc -import org.meshtastic.core.strings.role_router_client_desc -import org.meshtastic.core.strings.role_router_desc -import org.meshtastic.core.strings.role_router_late_desc -import org.meshtastic.core.strings.role_sensor_desc -import org.meshtastic.core.strings.role_tak_desc -import org.meshtastic.core.strings.role_tak_tracker_desc -import org.meshtastic.core.strings.role_tracker_desc -import org.meshtastic.core.strings.router_role_confirmation_text -import org.meshtastic.core.strings.time_zone -import org.meshtastic.core.strings.triple_click_adhoc_ping -import org.meshtastic.core.strings.unrecognized +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.accept +import org.meshtastic.core.resources.are_you_sure +import org.meshtastic.core.resources.button_gpio +import org.meshtastic.core.resources.buzzer_gpio +import org.meshtastic.core.resources.cancel +import org.meshtastic.core.resources.config_device_doubleTapAsButtonPress_summary +import org.meshtastic.core.resources.config_device_ledHeartbeatEnabled_summary +import org.meshtastic.core.resources.config_device_tripleClickAsAdHocPing_summary +import org.meshtastic.core.resources.config_device_tzdef_summary +import org.meshtastic.core.resources.config_device_use_phone_tz +import org.meshtastic.core.resources.device +import org.meshtastic.core.resources.double_tap_as_button_press +import org.meshtastic.core.resources.gpio +import org.meshtastic.core.resources.hardware +import org.meshtastic.core.resources.i_know_what_i_m_doing +import org.meshtastic.core.resources.led_heartbeat +import org.meshtastic.core.resources.nodeinfo_broadcast_interval +import org.meshtastic.core.resources.options +import org.meshtastic.core.resources.rebroadcast_mode +import org.meshtastic.core.resources.rebroadcast_mode_all_desc +import org.meshtastic.core.resources.rebroadcast_mode_all_skip_decoding_desc +import org.meshtastic.core.resources.rebroadcast_mode_core_portnums_only_desc +import org.meshtastic.core.resources.rebroadcast_mode_known_only_desc +import org.meshtastic.core.resources.rebroadcast_mode_local_only_desc +import org.meshtastic.core.resources.rebroadcast_mode_none_desc +import org.meshtastic.core.resources.role +import org.meshtastic.core.resources.role_client_base_desc +import org.meshtastic.core.resources.role_client_desc +import org.meshtastic.core.resources.role_client_hidden_desc +import org.meshtastic.core.resources.role_client_mute_desc +import org.meshtastic.core.resources.role_lost_and_found_desc +import org.meshtastic.core.resources.role_repeater_desc +import org.meshtastic.core.resources.role_router_client_desc +import org.meshtastic.core.resources.role_router_desc +import org.meshtastic.core.resources.role_router_late_desc +import org.meshtastic.core.resources.role_sensor_desc +import org.meshtastic.core.resources.role_tak_desc +import org.meshtastic.core.resources.role_tak_tracker_desc +import org.meshtastic.core.resources.role_tracker_desc +import org.meshtastic.core.resources.router_role_confirmation_text +import org.meshtastic.core.resources.time_zone +import org.meshtastic.core.resources.triple_click_adhoc_ping +import org.meshtastic.core.resources.unrecognized import org.meshtastic.core.ui.component.DropDownPreference import org.meshtastic.core.ui.component.EditTextPreference import org.meshtastic.core.ui.component.InsetDivider diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/DisplayConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/DisplayConfigItemList.kt index ea5b8e8b76..a7f05cb6b9 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/DisplayConfigItemList.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/DisplayConfigItemList.kt @@ -24,31 +24,31 @@ import androidx.compose.runtime.remember import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import org.jetbrains.compose.resources.stringResource -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.advanced -import org.meshtastic.core.strings.always_point_north -import org.meshtastic.core.strings.bold_heading -import org.meshtastic.core.strings.carousel_interval -import org.meshtastic.core.strings.compass_orientation -import org.meshtastic.core.strings.config_display_auto_screen_carousel_secs_summary -import org.meshtastic.core.strings.config_display_compass_north_top_summary -import org.meshtastic.core.strings.config_display_displaymode_summary -import org.meshtastic.core.strings.config_display_flip_screen_summary -import org.meshtastic.core.strings.config_display_heading_bold_summary -import org.meshtastic.core.strings.config_display_oled_summary -import org.meshtastic.core.strings.config_display_screen_on_secs_summary -import org.meshtastic.core.strings.config_display_units_summary -import org.meshtastic.core.strings.config_display_wake_on_tap_or_motion_summary -import org.meshtastic.core.strings.display -import org.meshtastic.core.strings.display_config -import org.meshtastic.core.strings.display_mode -import org.meshtastic.core.strings.display_time_in_12h_format -import org.meshtastic.core.strings.display_units -import org.meshtastic.core.strings.flip_screen -import org.meshtastic.core.strings.oled_type -import org.meshtastic.core.strings.screen_on_for -import org.meshtastic.core.strings.use_12h_format -import org.meshtastic.core.strings.wake_on_tap_or_motion +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.advanced +import org.meshtastic.core.resources.always_point_north +import org.meshtastic.core.resources.bold_heading +import org.meshtastic.core.resources.carousel_interval +import org.meshtastic.core.resources.compass_orientation +import org.meshtastic.core.resources.config_display_auto_screen_carousel_secs_summary +import org.meshtastic.core.resources.config_display_compass_north_top_summary +import org.meshtastic.core.resources.config_display_displaymode_summary +import org.meshtastic.core.resources.config_display_flip_screen_summary +import org.meshtastic.core.resources.config_display_heading_bold_summary +import org.meshtastic.core.resources.config_display_oled_summary +import org.meshtastic.core.resources.config_display_screen_on_secs_summary +import org.meshtastic.core.resources.config_display_units_summary +import org.meshtastic.core.resources.config_display_wake_on_tap_or_motion_summary +import org.meshtastic.core.resources.display +import org.meshtastic.core.resources.display_config +import org.meshtastic.core.resources.display_mode +import org.meshtastic.core.resources.display_time_in_12h_format +import org.meshtastic.core.resources.display_units +import org.meshtastic.core.resources.flip_screen +import org.meshtastic.core.resources.oled_type +import org.meshtastic.core.resources.screen_on_for +import org.meshtastic.core.resources.use_12h_format +import org.meshtastic.core.resources.wake_on_tap_or_motion import org.meshtastic.core.ui.component.DropDownPreference import org.meshtastic.core.ui.component.SwitchPreference import org.meshtastic.core.ui.component.TitledCard diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/EditDeviceProfileDialog.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/EditDeviceProfileDialog.kt index 3346d725c7..1e4abcd116 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/EditDeviceProfileDialog.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/EditDeviceProfileDialog.kt @@ -28,15 +28,15 @@ import androidx.compose.ui.tooling.preview.Preview 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.channel_url -import org.meshtastic.core.strings.fixed_position -import org.meshtastic.core.strings.long_name -import org.meshtastic.core.strings.module_settings -import org.meshtastic.core.strings.radio_configuration -import org.meshtastic.core.strings.save -import org.meshtastic.core.strings.short_name +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.cancel +import org.meshtastic.core.resources.channel_url +import org.meshtastic.core.resources.fixed_position +import org.meshtastic.core.resources.long_name +import org.meshtastic.core.resources.module_settings +import org.meshtastic.core.resources.radio_configuration +import org.meshtastic.core.resources.save +import org.meshtastic.core.resources.short_name import org.meshtastic.core.ui.component.MeshtasticDialog import org.meshtastic.core.ui.component.SwitchPreference import org.meshtastic.proto.DeviceProfile diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/ExternalNotificationConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/ExternalNotificationConfigItemList.kt index da63704d5b..00800c844e 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/ExternalNotificationConfigItemList.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/ExternalNotificationConfigItemList.kt @@ -45,30 +45,30 @@ import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import co.touchlab.kermit.Logger import org.jetbrains.compose.resources.stringResource -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.advanced -import org.meshtastic.core.strings.alert_bell_buzzer -import org.meshtastic.core.strings.alert_bell_led -import org.meshtastic.core.strings.alert_bell_vibra -import org.meshtastic.core.strings.alert_message_buzzer -import org.meshtastic.core.strings.alert_message_led -import org.meshtastic.core.strings.alert_message_vibra -import org.meshtastic.core.strings.external_notification -import org.meshtastic.core.strings.external_notification_config -import org.meshtastic.core.strings.external_notification_enabled -import org.meshtastic.core.strings.import_label -import org.meshtastic.core.strings.nag_timeout_seconds -import org.meshtastic.core.strings.notifications_on_alert_bell_receipt -import org.meshtastic.core.strings.notifications_on_message_receipt -import org.meshtastic.core.strings.output_buzzer_gpio -import org.meshtastic.core.strings.output_duration_milliseconds -import org.meshtastic.core.strings.output_led_active_high -import org.meshtastic.core.strings.output_led_gpio -import org.meshtastic.core.strings.output_vibra_gpio -import org.meshtastic.core.strings.play -import org.meshtastic.core.strings.ringtone -import org.meshtastic.core.strings.use_i2s_as_buzzer -import org.meshtastic.core.strings.use_pwm_buzzer +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.advanced +import org.meshtastic.core.resources.alert_bell_buzzer +import org.meshtastic.core.resources.alert_bell_led +import org.meshtastic.core.resources.alert_bell_vibra +import org.meshtastic.core.resources.alert_message_buzzer +import org.meshtastic.core.resources.alert_message_led +import org.meshtastic.core.resources.alert_message_vibra +import org.meshtastic.core.resources.external_notification +import org.meshtastic.core.resources.external_notification_config +import org.meshtastic.core.resources.external_notification_enabled +import org.meshtastic.core.resources.import_label +import org.meshtastic.core.resources.nag_timeout_seconds +import org.meshtastic.core.resources.notifications_on_alert_bell_receipt +import org.meshtastic.core.resources.notifications_on_message_receipt +import org.meshtastic.core.resources.output_buzzer_gpio +import org.meshtastic.core.resources.output_duration_milliseconds +import org.meshtastic.core.resources.output_led_active_high +import org.meshtastic.core.resources.output_led_gpio +import org.meshtastic.core.resources.output_vibra_gpio +import org.meshtastic.core.resources.play +import org.meshtastic.core.resources.ringtone +import org.meshtastic.core.resources.use_i2s_as_buzzer +import org.meshtastic.core.resources.use_pwm_buzzer import org.meshtastic.core.ui.component.DropDownPreference import org.meshtastic.core.ui.component.EditTextPreference import org.meshtastic.core.ui.component.SwitchPreference diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/LoRaConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/LoRaConfigItemList.kt index d7d77b566e..e4f91ece61 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/LoRaConfigItemList.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/LoRaConfigItemList.kt @@ -31,30 +31,30 @@ import org.meshtastic.core.model.Channel import org.meshtastic.core.model.ChannelOption import org.meshtastic.core.model.RegionInfo import org.meshtastic.core.model.numChannels -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.advanced -import org.meshtastic.core.strings.bandwidth -import org.meshtastic.core.strings.coding_rate -import org.meshtastic.core.strings.config_lora_frequency_slot_summary -import org.meshtastic.core.strings.config_lora_hop_limit_summary -import org.meshtastic.core.strings.config_lora_modem_preset_summary -import org.meshtastic.core.strings.config_lora_region_summary -import org.meshtastic.core.strings.frequency_slot -import org.meshtastic.core.strings.hop_limit -import org.meshtastic.core.strings.ignore_mqtt -import org.meshtastic.core.strings.lora -import org.meshtastic.core.strings.modem_preset -import org.meshtastic.core.strings.ok_to_mqtt -import org.meshtastic.core.strings.options -import org.meshtastic.core.strings.override_duty_cycle -import org.meshtastic.core.strings.override_frequency_mhz -import org.meshtastic.core.strings.pa_fan_disabled -import org.meshtastic.core.strings.region_frequency_plan -import org.meshtastic.core.strings.spread_factor -import org.meshtastic.core.strings.sx126x_rx_boosted_gain -import org.meshtastic.core.strings.tx_enabled -import org.meshtastic.core.strings.tx_power_dbm -import org.meshtastic.core.strings.use_modem_preset +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.advanced +import org.meshtastic.core.resources.bandwidth +import org.meshtastic.core.resources.coding_rate +import org.meshtastic.core.resources.config_lora_frequency_slot_summary +import org.meshtastic.core.resources.config_lora_hop_limit_summary +import org.meshtastic.core.resources.config_lora_modem_preset_summary +import org.meshtastic.core.resources.config_lora_region_summary +import org.meshtastic.core.resources.frequency_slot +import org.meshtastic.core.resources.hop_limit +import org.meshtastic.core.resources.ignore_mqtt +import org.meshtastic.core.resources.lora +import org.meshtastic.core.resources.modem_preset +import org.meshtastic.core.resources.ok_to_mqtt +import org.meshtastic.core.resources.options +import org.meshtastic.core.resources.override_duty_cycle +import org.meshtastic.core.resources.override_frequency_mhz +import org.meshtastic.core.resources.pa_fan_disabled +import org.meshtastic.core.resources.region_frequency_plan +import org.meshtastic.core.resources.spread_factor +import org.meshtastic.core.resources.sx126x_rx_boosted_gain +import org.meshtastic.core.resources.tx_enabled +import org.meshtastic.core.resources.tx_power_dbm +import org.meshtastic.core.resources.use_modem_preset import org.meshtastic.core.ui.component.DropDownPreference import org.meshtastic.core.ui.component.EditTextPreference import org.meshtastic.core.ui.component.SignedIntegerEditTextPreference diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/MQTTConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/MQTTConfigItemList.kt index e043cdaa91..4451e9f67a 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/MQTTConfigItemList.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/MQTTConfigItemList.kt @@ -30,20 +30,20 @@ import androidx.compose.ui.text.input.KeyboardType import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import org.jetbrains.compose.resources.stringResource -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.address -import org.meshtastic.core.strings.default_mqtt_address -import org.meshtastic.core.strings.encryption_enabled -import org.meshtastic.core.strings.json_output_enabled -import org.meshtastic.core.strings.map_reporting -import org.meshtastic.core.strings.mqtt -import org.meshtastic.core.strings.mqtt_config -import org.meshtastic.core.strings.mqtt_enabled -import org.meshtastic.core.strings.password -import org.meshtastic.core.strings.proxy_to_client_enabled -import org.meshtastic.core.strings.root_topic -import org.meshtastic.core.strings.tls_enabled -import org.meshtastic.core.strings.username +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.address +import org.meshtastic.core.resources.default_mqtt_address +import org.meshtastic.core.resources.encryption_enabled +import org.meshtastic.core.resources.json_output_enabled +import org.meshtastic.core.resources.map_reporting +import org.meshtastic.core.resources.mqtt +import org.meshtastic.core.resources.mqtt_config +import org.meshtastic.core.resources.mqtt_enabled +import org.meshtastic.core.resources.password +import org.meshtastic.core.resources.proxy_to_client_enabled +import org.meshtastic.core.resources.root_topic +import org.meshtastic.core.resources.tls_enabled +import org.meshtastic.core.resources.username import org.meshtastic.core.ui.component.EditPasswordPreference import org.meshtastic.core.ui.component.EditTextPreference import org.meshtastic.core.ui.component.SwitchPreference diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/MapReportingPreference.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/MapReportingPreference.kt index ac1e3a9846..e6530647cb 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/MapReportingPreference.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/MapReportingPreference.kt @@ -40,14 +40,14 @@ import androidx.compose.ui.unit.dp import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.model.util.DistanceUnit import org.meshtastic.core.model.util.toDistanceString -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.i_agree -import org.meshtastic.core.strings.i_agree_to_share_my_location -import org.meshtastic.core.strings.map_reporting -import org.meshtastic.core.strings.map_reporting_consent_header -import org.meshtastic.core.strings.map_reporting_consent_text -import org.meshtastic.core.strings.map_reporting_interval_seconds -import org.meshtastic.core.strings.map_reporting_summary +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.i_agree +import org.meshtastic.core.resources.i_agree_to_share_my_location +import org.meshtastic.core.resources.map_reporting +import org.meshtastic.core.resources.map_reporting_consent_header +import org.meshtastic.core.resources.map_reporting_consent_text +import org.meshtastic.core.resources.map_reporting_interval_seconds +import org.meshtastic.core.resources.map_reporting_summary import org.meshtastic.core.ui.component.DropDownPreference import org.meshtastic.core.ui.component.SwitchPreference import org.meshtastic.core.ui.component.precisionBitsToMeters diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/NeighborInfoConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/NeighborInfoConfigItemList.kt index 8a18f8eeae..4a2944195c 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/NeighborInfoConfigItemList.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/NeighborInfoConfigItemList.kt @@ -25,13 +25,13 @@ import androidx.compose.ui.platform.LocalFocusManager import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import org.jetbrains.compose.resources.stringResource -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.config_device_transmitOverLora_summary -import org.meshtastic.core.strings.neighbor_info -import org.meshtastic.core.strings.neighbor_info_config -import org.meshtastic.core.strings.neighbor_info_enabled -import org.meshtastic.core.strings.transmit_over_lora -import org.meshtastic.core.strings.update_interval_seconds +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.config_device_transmitOverLora_summary +import org.meshtastic.core.resources.neighbor_info +import org.meshtastic.core.resources.neighbor_info_config +import org.meshtastic.core.resources.neighbor_info_enabled +import org.meshtastic.core.resources.transmit_over_lora +import org.meshtastic.core.resources.update_interval_seconds import org.meshtastic.core.ui.component.EditTextPreference import org.meshtastic.core.ui.component.SwitchPreference import org.meshtastic.core.ui.component.TitledCard diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/NetworkConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/NetworkConfigItemList.kt index bb7da7e168..4e30a5f3de 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/NetworkConfigItemList.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/NetworkConfigItemList.kt @@ -44,35 +44,35 @@ import org.meshtastic.core.barcode.extractWifiCredentials import org.meshtastic.core.barcode.rememberBarcodeScanner import org.meshtastic.core.model.util.handleMeshtasticUri import org.meshtastic.core.nfc.NfcScannerEffect -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.advanced -import org.meshtastic.core.strings.cancel -import org.meshtastic.core.strings.config_network_eth_enabled_summary -import org.meshtastic.core.strings.config_network_udp_enabled_summary -import org.meshtastic.core.strings.config_network_wifi_enabled_summary -import org.meshtastic.core.strings.connection_status -import org.meshtastic.core.strings.error -import org.meshtastic.core.strings.ethernet_config -import org.meshtastic.core.strings.ethernet_enabled -import org.meshtastic.core.strings.ethernet_ip -import org.meshtastic.core.strings.gateway -import org.meshtastic.core.strings.ip -import org.meshtastic.core.strings.ipv4_mode -import org.meshtastic.core.strings.network -import org.meshtastic.core.strings.nfc_disabled -import org.meshtastic.core.strings.ntp_server -import org.meshtastic.core.strings.open_settings -import org.meshtastic.core.strings.password -import org.meshtastic.core.strings.rsyslog_server -import org.meshtastic.core.strings.scan_nfc -import org.meshtastic.core.strings.ssid -import org.meshtastic.core.strings.subnet -import org.meshtastic.core.strings.udp_enabled -import org.meshtastic.core.strings.wifi_config -import org.meshtastic.core.strings.wifi_enabled -import org.meshtastic.core.strings.wifi_ip -import org.meshtastic.core.strings.wifi_qr_code_error -import org.meshtastic.core.strings.wifi_qr_code_scan +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.advanced +import org.meshtastic.core.resources.cancel +import org.meshtastic.core.resources.config_network_eth_enabled_summary +import org.meshtastic.core.resources.config_network_udp_enabled_summary +import org.meshtastic.core.resources.config_network_wifi_enabled_summary +import org.meshtastic.core.resources.connection_status +import org.meshtastic.core.resources.error +import org.meshtastic.core.resources.ethernet_config +import org.meshtastic.core.resources.ethernet_enabled +import org.meshtastic.core.resources.ethernet_ip +import org.meshtastic.core.resources.gateway +import org.meshtastic.core.resources.ip +import org.meshtastic.core.resources.ipv4_mode +import org.meshtastic.core.resources.network +import org.meshtastic.core.resources.nfc_disabled +import org.meshtastic.core.resources.ntp_server +import org.meshtastic.core.resources.open_settings +import org.meshtastic.core.resources.password +import org.meshtastic.core.resources.rsyslog_server +import org.meshtastic.core.resources.scan_nfc +import org.meshtastic.core.resources.ssid +import org.meshtastic.core.resources.subnet +import org.meshtastic.core.resources.udp_enabled +import org.meshtastic.core.resources.wifi_config +import org.meshtastic.core.resources.wifi_enabled +import org.meshtastic.core.resources.wifi_ip +import org.meshtastic.core.resources.wifi_qr_code_error +import org.meshtastic.core.resources.wifi_qr_code_scan import org.meshtastic.core.ui.component.DropDownPreference import org.meshtastic.core.ui.component.EditIPv4Preference import org.meshtastic.core.ui.component.EditPasswordPreference diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/PacketResponseStateDialog.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/PacketResponseStateDialog.kt index 9b664650a9..366f8669c1 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/PacketResponseStateDialog.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/PacketResponseStateDialog.kt @@ -33,10 +33,10 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import kotlinx.coroutines.delay import org.jetbrains.compose.resources.stringResource -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.close -import org.meshtastic.core.strings.delivery_confirmed -import org.meshtastic.core.strings.error +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.close +import org.meshtastic.core.resources.delivery_confirmed +import org.meshtastic.core.resources.error import org.meshtastic.core.ui.component.MeshtasticDialog import org.meshtastic.feature.settings.radio.ResponseState diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/PaxcounterConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/PaxcounterConfigItemList.kt index c32a54eb37..b268bbecef 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/PaxcounterConfigItemList.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/PaxcounterConfigItemList.kt @@ -26,13 +26,13 @@ import androidx.compose.ui.platform.LocalFocusManager import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import org.jetbrains.compose.resources.stringResource -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.ble_rssi_threshold_defaults_to_80 -import org.meshtastic.core.strings.paxcounter -import org.meshtastic.core.strings.paxcounter_config -import org.meshtastic.core.strings.paxcounter_enabled -import org.meshtastic.core.strings.update_interval_seconds -import org.meshtastic.core.strings.wifi_rssi_threshold_defaults_to_80 +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.ble_rssi_threshold_defaults_to_80 +import org.meshtastic.core.resources.paxcounter +import org.meshtastic.core.resources.paxcounter_config +import org.meshtastic.core.resources.paxcounter_enabled +import org.meshtastic.core.resources.update_interval_seconds +import org.meshtastic.core.resources.wifi_rssi_threshold_defaults_to_80 import org.meshtastic.core.ui.component.DropDownPreference import org.meshtastic.core.ui.component.SignedIntegerEditTextPreference import org.meshtastic.core.ui.component.SwitchPreference diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/PositionConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/PositionConfigItemList.kt index 41dfe39448..7b33f74ac2 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/PositionConfigItemList.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/PositionConfigItemList.kt @@ -40,31 +40,31 @@ import kotlinx.coroutines.launch import no.nordicsemi.android.common.permissions.ble.RequireLocation import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.model.Position -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.advanced_device_gps -import org.meshtastic.core.strings.altitude -import org.meshtastic.core.strings.broadcast_interval -import org.meshtastic.core.strings.config_position_broadcast_secs_summary -import org.meshtastic.core.strings.config_position_broadcast_smart_minimum_distance_summary -import org.meshtastic.core.strings.config_position_broadcast_smart_minimum_interval_secs_summary -import org.meshtastic.core.strings.config_position_flags_summary -import org.meshtastic.core.strings.config_position_gps_update_interval_summary -import org.meshtastic.core.strings.device_gps -import org.meshtastic.core.strings.fixed_position -import org.meshtastic.core.strings.gps_en_gpio -import org.meshtastic.core.strings.gps_mode -import org.meshtastic.core.strings.gps_receive_gpio -import org.meshtastic.core.strings.gps_transmit_gpio -import org.meshtastic.core.strings.latitude -import org.meshtastic.core.strings.longitude -import org.meshtastic.core.strings.minimum_distance -import org.meshtastic.core.strings.minimum_interval -import org.meshtastic.core.strings.position -import org.meshtastic.core.strings.position_config_set_fixed_from_phone -import org.meshtastic.core.strings.position_flags -import org.meshtastic.core.strings.position_packet -import org.meshtastic.core.strings.smart_position -import org.meshtastic.core.strings.update_interval +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.advanced_device_gps +import org.meshtastic.core.resources.altitude +import org.meshtastic.core.resources.broadcast_interval +import org.meshtastic.core.resources.config_position_broadcast_secs_summary +import org.meshtastic.core.resources.config_position_broadcast_smart_minimum_distance_summary +import org.meshtastic.core.resources.config_position_broadcast_smart_minimum_interval_secs_summary +import org.meshtastic.core.resources.config_position_flags_summary +import org.meshtastic.core.resources.config_position_gps_update_interval_summary +import org.meshtastic.core.resources.device_gps +import org.meshtastic.core.resources.fixed_position +import org.meshtastic.core.resources.gps_en_gpio +import org.meshtastic.core.resources.gps_mode +import org.meshtastic.core.resources.gps_receive_gpio +import org.meshtastic.core.resources.gps_transmit_gpio +import org.meshtastic.core.resources.latitude +import org.meshtastic.core.resources.longitude +import org.meshtastic.core.resources.minimum_distance +import org.meshtastic.core.resources.minimum_interval +import org.meshtastic.core.resources.position +import org.meshtastic.core.resources.position_config_set_fixed_from_phone +import org.meshtastic.core.resources.position_flags +import org.meshtastic.core.resources.position_packet +import org.meshtastic.core.resources.smart_position +import org.meshtastic.core.resources.update_interval import org.meshtastic.core.ui.component.BitwisePreference import org.meshtastic.core.ui.component.DropDownPreference import org.meshtastic.core.ui.component.EditTextPreference diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/PowerConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/PowerConfigItemList.kt index 1321dc885f..6b6b349c1f 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/PowerConfigItemList.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/PowerConfigItemList.kt @@ -26,18 +26,18 @@ import androidx.compose.ui.platform.LocalFocusManager import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import org.jetbrains.compose.resources.stringResource -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.adc_multiplier_override -import org.meshtastic.core.strings.adc_multiplier_override_ratio -import org.meshtastic.core.strings.battery_ina_2xx_i2c_address -import org.meshtastic.core.strings.config_power_is_power_saving_summary -import org.meshtastic.core.strings.enable_power_saving_mode -import org.meshtastic.core.strings.minimum_wake_time_seconds -import org.meshtastic.core.strings.power -import org.meshtastic.core.strings.power_config -import org.meshtastic.core.strings.shutdown_on_power_loss -import org.meshtastic.core.strings.super_deep_sleep_duration_seconds -import org.meshtastic.core.strings.wait_for_bluetooth_duration_seconds +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.adc_multiplier_override +import org.meshtastic.core.resources.adc_multiplier_override_ratio +import org.meshtastic.core.resources.battery_ina_2xx_i2c_address +import org.meshtastic.core.resources.config_power_is_power_saving_summary +import org.meshtastic.core.resources.enable_power_saving_mode +import org.meshtastic.core.resources.minimum_wake_time_seconds +import org.meshtastic.core.resources.power +import org.meshtastic.core.resources.power_config +import org.meshtastic.core.resources.shutdown_on_power_loss +import org.meshtastic.core.resources.super_deep_sleep_duration_seconds +import org.meshtastic.core.resources.wait_for_bluetooth_duration_seconds import org.meshtastic.core.ui.component.DropDownPreference import org.meshtastic.core.ui.component.EditTextPreference import org.meshtastic.core.ui.component.SwitchPreference diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/RadioConfigScreenList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/RadioConfigScreenList.kt index 0a855a2414..71b5ffb411 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/RadioConfigScreenList.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/RadioConfigScreenList.kt @@ -34,9 +34,9 @@ import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.unit.dp import com.squareup.wire.Message import org.jetbrains.compose.resources.stringResource -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.discard_changes -import org.meshtastic.core.strings.save_changes +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.discard_changes +import org.meshtastic.core.resources.save_changes import org.meshtastic.core.ui.component.MainAppBar import org.meshtastic.core.ui.component.PreferenceFooter import org.meshtastic.feature.settings.radio.ResponseState diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/RangeTestConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/RangeTestConfigItemList.kt index 66061c4046..ea78843d07 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/RangeTestConfigItemList.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/RangeTestConfigItemList.kt @@ -24,12 +24,12 @@ import androidx.compose.runtime.remember import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import org.jetbrains.compose.resources.stringResource -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.range_test -import org.meshtastic.core.strings.range_test_config -import org.meshtastic.core.strings.range_test_enabled -import org.meshtastic.core.strings.save_csv_in_storage_esp32_only -import org.meshtastic.core.strings.sender_message_interval_seconds +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.range_test +import org.meshtastic.core.resources.range_test_config +import org.meshtastic.core.resources.range_test_enabled +import org.meshtastic.core.resources.save_csv_in_storage_esp32_only +import org.meshtastic.core.resources.sender_message_interval_seconds import org.meshtastic.core.ui.component.DropDownPreference import org.meshtastic.core.ui.component.SwitchPreference import org.meshtastic.core.ui.component.TitledCard diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/RemoteHardwareConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/RemoteHardwareConfigItemList.kt index d13f4e2eed..1fba75ddb1 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/RemoteHardwareConfigItemList.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/RemoteHardwareConfigItemList.kt @@ -25,12 +25,12 @@ import androidx.compose.ui.platform.LocalFocusManager import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import org.jetbrains.compose.resources.stringResource -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.allow_undefined_pin_access -import org.meshtastic.core.strings.available_pins -import org.meshtastic.core.strings.remote_hardware -import org.meshtastic.core.strings.remote_hardware_config -import org.meshtastic.core.strings.remote_hardware_enabled +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.allow_undefined_pin_access +import org.meshtastic.core.resources.available_pins +import org.meshtastic.core.resources.remote_hardware +import org.meshtastic.core.resources.remote_hardware_config +import org.meshtastic.core.resources.remote_hardware_enabled import org.meshtastic.core.ui.component.EditListPreference import org.meshtastic.core.ui.component.SwitchPreference import org.meshtastic.core.ui.component.TitledCard diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/SecurityConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/SecurityConfigItemList.kt index ee78eac503..5610483937 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/SecurityConfigItemList.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/SecurityConfigItemList.kt @@ -42,29 +42,29 @@ import okio.ByteString.Companion.toByteString import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.common.util.nowMillis import org.meshtastic.core.model.util.encodeToString -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.admin_key -import org.meshtastic.core.strings.admin_keys -import org.meshtastic.core.strings.administration -import org.meshtastic.core.strings.config_security_admin_key -import org.meshtastic.core.strings.config_security_debug_log_api_enabled -import org.meshtastic.core.strings.config_security_is_managed -import org.meshtastic.core.strings.config_security_private_key -import org.meshtastic.core.strings.config_security_public_key -import org.meshtastic.core.strings.config_security_serial_enabled -import org.meshtastic.core.strings.debug_log_api_enabled -import org.meshtastic.core.strings.direct_message_key -import org.meshtastic.core.strings.export_keys -import org.meshtastic.core.strings.export_keys_confirmation -import org.meshtastic.core.strings.legacy_admin_channel -import org.meshtastic.core.strings.logs -import org.meshtastic.core.strings.managed_mode -import org.meshtastic.core.strings.private_key -import org.meshtastic.core.strings.public_key -import org.meshtastic.core.strings.regenerate_keys_confirmation -import org.meshtastic.core.strings.regenerate_private_key -import org.meshtastic.core.strings.security -import org.meshtastic.core.strings.serial_console +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.admin_key +import org.meshtastic.core.resources.admin_keys +import org.meshtastic.core.resources.administration +import org.meshtastic.core.resources.config_security_admin_key +import org.meshtastic.core.resources.config_security_debug_log_api_enabled +import org.meshtastic.core.resources.config_security_is_managed +import org.meshtastic.core.resources.config_security_private_key +import org.meshtastic.core.resources.config_security_public_key +import org.meshtastic.core.resources.config_security_serial_enabled +import org.meshtastic.core.resources.debug_log_api_enabled +import org.meshtastic.core.resources.direct_message_key +import org.meshtastic.core.resources.export_keys +import org.meshtastic.core.resources.export_keys_confirmation +import org.meshtastic.core.resources.legacy_admin_channel +import org.meshtastic.core.resources.logs +import org.meshtastic.core.resources.managed_mode +import org.meshtastic.core.resources.private_key +import org.meshtastic.core.resources.public_key +import org.meshtastic.core.resources.regenerate_keys_confirmation +import org.meshtastic.core.resources.regenerate_private_key +import org.meshtastic.core.resources.security +import org.meshtastic.core.resources.serial_console import org.meshtastic.core.ui.component.CopyIconButton import org.meshtastic.core.ui.component.EditBase64Preference import org.meshtastic.core.ui.component.EditListPreference diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/SerialConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/SerialConfigItemList.kt index cdd08e93cc..779030aad4 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/SerialConfigItemList.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/SerialConfigItemList.kt @@ -25,15 +25,15 @@ import androidx.compose.ui.platform.LocalFocusManager import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import org.jetbrains.compose.resources.stringResource -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.echo_enabled -import org.meshtastic.core.strings.override_console_serial_port -import org.meshtastic.core.strings.serial -import org.meshtastic.core.strings.serial_baud_rate -import org.meshtastic.core.strings.serial_config -import org.meshtastic.core.strings.serial_enabled -import org.meshtastic.core.strings.serial_mode -import org.meshtastic.core.strings.timeout +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.echo_enabled +import org.meshtastic.core.resources.override_console_serial_port +import org.meshtastic.core.resources.serial +import org.meshtastic.core.resources.serial_baud_rate +import org.meshtastic.core.resources.serial_config +import org.meshtastic.core.resources.serial_enabled +import org.meshtastic.core.resources.serial_mode +import org.meshtastic.core.resources.timeout import org.meshtastic.core.ui.component.DropDownPreference import org.meshtastic.core.ui.component.EditTextPreference import org.meshtastic.core.ui.component.SwitchPreference diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/ShutdownConfirmationDialog.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/ShutdownConfirmationDialog.kt index 53b831ccf2..2176b32be1 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/ShutdownConfirmationDialog.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/ShutdownConfirmationDialog.kt @@ -34,11 +34,11 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.database.model.Node -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.cancel -import org.meshtastic.core.strings.send -import org.meshtastic.core.strings.shutdown_node_name -import org.meshtastic.core.strings.shutdown_warning +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.cancel +import org.meshtastic.core.resources.send +import org.meshtastic.core.resources.shutdown_node_name +import org.meshtastic.core.resources.shutdown_warning import org.meshtastic.core.ui.component.MeshtasticDialog import org.meshtastic.core.ui.theme.AppTheme import org.meshtastic.proto.User diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/StatusMessageConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/StatusMessageConfigItemList.kt index 57a4ca4cfb..de0e0b4cc9 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/StatusMessageConfigItemList.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/StatusMessageConfigItemList.kt @@ -32,11 +32,11 @@ import androidx.compose.ui.text.input.KeyboardType import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import org.jetbrains.compose.resources.stringResource -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.clear -import org.meshtastic.core.strings.node_status_summary -import org.meshtastic.core.strings.status_message -import org.meshtastic.core.strings.status_message_config +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.clear +import org.meshtastic.core.resources.node_status_summary +import org.meshtastic.core.resources.status_message +import org.meshtastic.core.resources.status_message_config import org.meshtastic.core.ui.component.EditTextPreference import org.meshtastic.core.ui.component.TitledCard import org.meshtastic.feature.settings.radio.RadioConfigViewModel diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/StoreForwardConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/StoreForwardConfigItemList.kt index 76719a80c8..11a75d37e3 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/StoreForwardConfigItemList.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/StoreForwardConfigItemList.kt @@ -25,15 +25,15 @@ import androidx.compose.ui.platform.LocalFocusManager import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import org.jetbrains.compose.resources.stringResource -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.heartbeat -import org.meshtastic.core.strings.history_return_max -import org.meshtastic.core.strings.history_return_window -import org.meshtastic.core.strings.number_of_records -import org.meshtastic.core.strings.server -import org.meshtastic.core.strings.store_forward -import org.meshtastic.core.strings.store_forward_config -import org.meshtastic.core.strings.store_forward_enabled +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.heartbeat +import org.meshtastic.core.resources.history_return_max +import org.meshtastic.core.resources.history_return_window +import org.meshtastic.core.resources.number_of_records +import org.meshtastic.core.resources.server +import org.meshtastic.core.resources.store_forward +import org.meshtastic.core.resources.store_forward_config +import org.meshtastic.core.resources.store_forward_enabled import org.meshtastic.core.ui.component.EditTextPreference import org.meshtastic.core.ui.component.SwitchPreference import org.meshtastic.core.ui.component.TitledCard diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/TelemetryConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/TelemetryConfigItemList.kt index 0c2655b1a5..2921adccd0 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/TelemetryConfigItemList.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/TelemetryConfigItemList.kt @@ -25,21 +25,21 @@ import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.model.Capabilities -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.air_quality_metrics_module_enabled -import org.meshtastic.core.strings.air_quality_metrics_update_interval_seconds -import org.meshtastic.core.strings.device_metrics_update_interval_seconds -import org.meshtastic.core.strings.device_telemetry_enabled -import org.meshtastic.core.strings.device_telemetry_enabled_summary -import org.meshtastic.core.strings.environment_metrics_module_enabled -import org.meshtastic.core.strings.environment_metrics_on_screen_enabled -import org.meshtastic.core.strings.environment_metrics_update_interval_seconds -import org.meshtastic.core.strings.environment_metrics_use_fahrenheit -import org.meshtastic.core.strings.power_metrics_module_enabled -import org.meshtastic.core.strings.power_metrics_on_screen_enabled -import org.meshtastic.core.strings.power_metrics_update_interval_seconds -import org.meshtastic.core.strings.telemetry -import org.meshtastic.core.strings.telemetry_config +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.air_quality_metrics_module_enabled +import org.meshtastic.core.resources.air_quality_metrics_update_interval_seconds +import org.meshtastic.core.resources.device_metrics_update_interval_seconds +import org.meshtastic.core.resources.device_telemetry_enabled +import org.meshtastic.core.resources.device_telemetry_enabled_summary +import org.meshtastic.core.resources.environment_metrics_module_enabled +import org.meshtastic.core.resources.environment_metrics_on_screen_enabled +import org.meshtastic.core.resources.environment_metrics_update_interval_seconds +import org.meshtastic.core.resources.environment_metrics_use_fahrenheit +import org.meshtastic.core.resources.power_metrics_module_enabled +import org.meshtastic.core.resources.power_metrics_on_screen_enabled +import org.meshtastic.core.resources.power_metrics_update_interval_seconds +import org.meshtastic.core.resources.telemetry +import org.meshtastic.core.resources.telemetry_config import org.meshtastic.core.ui.component.DropDownPreference import org.meshtastic.core.ui.component.SwitchPreference import org.meshtastic.core.ui.component.TitledCard diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/UserConfigItemList.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/UserConfigItemList.kt index 7a72712311..2a7c673e2d 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/UserConfigItemList.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/UserConfigItemList.kt @@ -31,17 +31,17 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.database.model.isUnmessageableRole import org.meshtastic.core.model.Capabilities -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.hardware_model -import org.meshtastic.core.strings.licensed_amateur_radio -import org.meshtastic.core.strings.licensed_amateur_radio_text -import org.meshtastic.core.strings.long_name -import org.meshtastic.core.strings.node_id -import org.meshtastic.core.strings.short_name -import org.meshtastic.core.strings.unmessageable -import org.meshtastic.core.strings.unmonitored_or_infrastructure -import org.meshtastic.core.strings.user -import org.meshtastic.core.strings.user_config +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.hardware_model +import org.meshtastic.core.resources.licensed_amateur_radio +import org.meshtastic.core.resources.licensed_amateur_radio_text +import org.meshtastic.core.resources.long_name +import org.meshtastic.core.resources.node_id +import org.meshtastic.core.resources.short_name +import org.meshtastic.core.resources.unmessageable +import org.meshtastic.core.resources.unmonitored_or_infrastructure +import org.meshtastic.core.resources.user +import org.meshtastic.core.resources.user_config import org.meshtastic.core.ui.component.EditTextPreference import org.meshtastic.core.ui.component.RegularPreference import org.meshtastic.core.ui.component.SwitchPreference diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/WarningDialog.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/WarningDialog.kt index a6275b41c7..7148fb738f 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/WarningDialog.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/WarningDialog.kt @@ -22,9 +22,9 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.tooling.preview.Preview import org.jetbrains.compose.resources.stringResource -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.cancel -import org.meshtastic.core.strings.send +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.cancel +import org.meshtastic.core.resources.send import org.meshtastic.core.ui.component.MeshtasticDialog import org.meshtastic.core.ui.theme.AppTheme diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/util/FixedUpdateIntervals.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/util/FixedUpdateIntervals.kt index b74451a089..636c5af3b0 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/util/FixedUpdateIntervals.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/util/FixedUpdateIntervals.kt @@ -21,12 +21,12 @@ package org.meshtastic.feature.settings.util import org.jetbrains.compose.resources.PluralStringResource import org.jetbrains.compose.resources.StringResource import org.meshtastic.core.model.util.TimeConstants -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.interval_always_on -import org.meshtastic.core.strings.interval_unset -import org.meshtastic.core.strings.plurals_hours -import org.meshtastic.core.strings.plurals_minutes -import org.meshtastic.core.strings.plurals_seconds +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.interval_always_on +import org.meshtastic.core.resources.interval_unset +import org.meshtastic.core.resources.plurals_hours +import org.meshtastic.core.resources.plurals_minutes +import org.meshtastic.core.resources.plurals_seconds import kotlin.time.Duration.Companion.hours import kotlin.time.Duration.Companion.minutes import kotlin.time.Duration.Companion.seconds diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/util/LanguageUtils.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/util/LanguageUtils.kt index 6ae1dd6143..2553d25615 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/util/LanguageUtils.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/util/LanguageUtils.kt @@ -23,12 +23,12 @@ import androidx.compose.ui.platform.LocalResources import androidx.core.os.LocaleListCompat import co.touchlab.kermit.Logger import org.jetbrains.compose.resources.stringResource -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.fr_HT -import org.meshtastic.core.strings.preferences_system_default -import org.meshtastic.core.strings.pt_BR -import org.meshtastic.core.strings.zh_CN -import org.meshtastic.core.strings.zh_TW +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.fr_HT +import org.meshtastic.core.resources.preferences_system_default +import org.meshtastic.core.resources.pt_BR +import org.meshtastic.core.resources.zh_CN +import org.meshtastic.core.resources.zh_TW import org.xmlpull.v1.XmlPullParser import java.util.Locale diff --git a/feature/settings/src/test/kotlin/org/meshtastic/feature/settings/HomoglyphSettingTest.kt b/feature/settings/src/test/kotlin/org/meshtastic/feature/settings/HomoglyphSettingTest.kt index f8760d3baf..1c1863346c 100644 --- a/feature/settings/src/test/kotlin/org/meshtastic/feature/settings/HomoglyphSettingTest.kt +++ b/feature/settings/src/test/kotlin/org/meshtastic/feature/settings/HomoglyphSettingTest.kt @@ -25,9 +25,9 @@ import androidx.compose.ui.test.onNodeWithText import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith -import org.meshtastic.core.strings.Res -import org.meshtastic.core.strings.getString -import org.meshtastic.core.strings.use_homoglyph_characters_encoding +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.getString +import org.meshtastic.core.resources.use_homoglyph_characters_encoding import org.robolectric.RobolectricTestRunner import org.robolectric.annotation.Config import java.util.Locale diff --git a/settings.gradle.kts b/settings.gradle.kts index e522fb5bb9..16c8309fb1 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -33,7 +33,7 @@ include( ":core:prefs", ":core:proto", ":core:service", - ":core:strings", + ":core:resources", ":core:ui", ":feature:intro", ":feature:messaging", From 38a35a3d8f1b180ac5d9cd707d132c0103032681 Mon Sep 17 00:00:00 2001 From: James Rich <2199651+jamesarich@users.noreply.github.com> Date: Sun, 22 Feb 2026 13:24:23 -0600 Subject: [PATCH 10/18] chore: migrate drawables to core:resources --- .../com/geeksville/mesh/model/UIViewModel.kt | 6 +-- .../mesh/service/MeshConnectionManager.kt | 4 +- .../mesh/service/MeshDataHandler.kt | 6 +-- .../mesh/service/MeshNeighborInfoHandler.kt | 2 +- .../service/MeshServiceNotificationsImpl.kt | 4 +- .../mesh/service/MeshTracerouteHandler.kt | 4 +- .../main/java/com/geeksville/mesh/ui/Main.kt | 2 +- .../mesh/ui/connections/ConnectionsScreen.kt | 2 +- .../ui/connections/components/BLEDevices.kt | 2 +- .../components/ConnectionsSegmentedBar.kt | 3 +- .../connections/components/DeviceListItem.kt | 2 +- .../connections/components/NetworkDevices.kt | 2 +- .../ui/connections/components/UsbDevices.kt | 2 +- .../mesh/ui/contact/AdaptiveContactsScreen.kt | 3 +- .../mesh/ui/contact/ContactsViewModel.kt | 2 +- .../com/geeksville/mesh/ui/sharing/Channel.kt | 2 +- .../com/geeksville/mesh/ui/sharing/Share.kt | 3 +- .../core/database/model/NodeSortOption.kt | 3 +- .../core/{strings => resources}/ContextExt.kt | 0 .../composeResources/drawable/ic_antenna.xml} | 0 .../drawable/ic_battery_alert.xml | 0 .../drawable/ic_battery_high.xml | 0 .../drawable/ic_battery_low.xml | 0 .../drawable/ic_battery_medium.xml | 0 .../drawable/ic_battery_outline.xml | 0 .../drawable/ic_battery_unknown.xml | 0 .../drawable/ic_counter_0.xml} | 0 .../drawable/ic_counter_1.xml} | 0 .../drawable/ic_counter_2.xml} | 0 .../drawable/ic_counter_3.xml} | 0 .../drawable/ic_counter_4.xml} | 0 .../drawable/ic_counter_5.xml} | 0 .../drawable/ic_counter_6.xml} | 0 .../drawable/ic_counter_7.xml} | 0 .../drawable/ic_counter_8.xml} | 0 .../drawable/ic_location_on.xml} | 0 .../drawable/ic_lock_open_right.xml} | 0 .../drawable/ic_map_location_dot.xml} | 0 .../drawable/ic_map_navigation.xml} | 0 .../drawable/ic_meshtastic.xml | 0 .../drawable/ic_mountain_flag.xml} | 0 .../drawable/ic_power_plug.xml} | 0 .../composeResources/drawable/img_chirpy.xml} | 0 .../core/ui/component/CopyIconButton.kt | 3 +- .../ui/component/EditPasswordPreference.kt | 3 +- .../core/ui/component/EditTextPreference.kt | 3 +- .../core/ui/component/LastHeardInfo.kt | 7 ++-- .../core/ui/component/MainAppBar.kt | 15 ++------ .../component/MaterialBluetoothSignalInfo.kt | 3 +- .../component/PositionPrecisionPreference.kt | 3 +- .../org/meshtastic/core/ui/icon/Counter.kt | 38 +++++++++++++------ .../org/meshtastic/core/ui/icon/Device.kt | 7 ++-- .../feature/firmware/FirmwareUpdateScreen.kt | 5 ++- .../firmware/FirmwareUpdateViewModel.kt | 4 +- .../feature/firmware/NordicDfuHandler.kt | 2 +- .../feature/firmware/UsbUpdateHandler.kt | 2 +- .../firmware/ota/Esp32OtaUpdateHandler.kt | 2 +- .../feature/intro/CriticalAlertsScreen.kt | 3 +- .../feature/intro/LocationScreen.kt | 3 +- .../feature/intro/PermissionScreenLayout.kt | 3 +- .../meshtastic/feature/intro/WelcomeScreen.kt | 3 +- .../org/meshtastic/feature/map/MapView.kt | 13 +++---- .../feature/map/MapViewExtensions.kt | 2 +- .../feature/map/component/CacheLayout.kt | 3 +- .../feature/map/component/MapButton.kt | 3 +- .../map/component/ClusterItemsListDialog.kt | 3 +- .../map/component/CustomMapLayersSheet.kt | 3 +- .../map/component/MapFilterDropdown.kt | 3 +- .../feature/map/component/MapTypeDropdown.kt | 3 +- .../feature/map/BaseMapViewModel.kt | 2 +- .../org/meshtastic/feature/map/MapScreen.kt | 3 +- .../node/component/AdministrationSection.kt | 2 +- .../feature/node/component/LastHeardInfo.kt | 6 +-- .../feature/node/component/NodeItem.kt | 2 +- .../feature/node/component/NodeStatusIcons.kt | 2 +- .../node/detail/NodeManagementActions.kt | 4 +- .../feature/node/detail/NodeRequestActions.kt | 2 +- .../feature/node/list/NodeListScreen.kt | 2 +- .../feature/node/metrics/MetricsViewModel.kt | 2 +- .../radio/CleanNodeDatabaseViewModel.kt | 2 +- .../settings/radio/RadioConfigViewModel.kt | 4 +- .../channel/component/ChannelConfigHeader.kt | 3 +- .../radio/component/MapReportingPreference.kt | 3 +- 83 files changed, 112 insertions(+), 123 deletions(-) rename core/resources/src/androidMain/kotlin/org/meshtastic/core/{strings => resources}/ContextExt.kt (100%) rename core/{ui/src/main/res/drawable/ic_antenna_24.xml => resources/src/commonMain/composeResources/drawable/ic_antenna.xml} (100%) rename core/{ui/src/main/res => resources/src/commonMain/composeResources}/drawable/ic_battery_alert.xml (100%) rename core/{ui/src/main/res => resources/src/commonMain/composeResources}/drawable/ic_battery_high.xml (100%) rename core/{ui/src/main/res => resources/src/commonMain/composeResources}/drawable/ic_battery_low.xml (100%) rename core/{ui/src/main/res => resources/src/commonMain/composeResources}/drawable/ic_battery_medium.xml (100%) rename core/{ui/src/main/res => resources/src/commonMain/composeResources}/drawable/ic_battery_outline.xml (100%) rename core/{ui/src/main/res => resources/src/commonMain/composeResources}/drawable/ic_battery_unknown.xml (100%) rename core/{ui/src/main/res/drawable/counter_0_24px.xml => resources/src/commonMain/composeResources/drawable/ic_counter_0.xml} (100%) rename core/{ui/src/main/res/drawable/counter_1_24px.xml => resources/src/commonMain/composeResources/drawable/ic_counter_1.xml} (100%) rename core/{ui/src/main/res/drawable/counter_2_24px.xml => resources/src/commonMain/composeResources/drawable/ic_counter_2.xml} (100%) rename core/{ui/src/main/res/drawable/counter_3_24px.xml => resources/src/commonMain/composeResources/drawable/ic_counter_3.xml} (100%) rename core/{ui/src/main/res/drawable/counter_4_24px.xml => resources/src/commonMain/composeResources/drawable/ic_counter_4.xml} (100%) rename core/{ui/src/main/res/drawable/counter_5_24px.xml => resources/src/commonMain/composeResources/drawable/ic_counter_5.xml} (100%) rename core/{ui/src/main/res/drawable/counter_6_24px.xml => resources/src/commonMain/composeResources/drawable/ic_counter_6.xml} (100%) rename core/{ui/src/main/res/drawable/counter_7_24px.xml => resources/src/commonMain/composeResources/drawable/ic_counter_7.xml} (100%) rename core/{ui/src/main/res/drawable/counter_8_24px.xml => resources/src/commonMain/composeResources/drawable/ic_counter_8.xml} (100%) rename core/{ui/src/main/res/drawable/ic_baseline_location_on_24.xml => resources/src/commonMain/composeResources/drawable/ic_location_on.xml} (100%) rename core/{ui/src/main/res/drawable/ic_lock_open_right_24.xml => resources/src/commonMain/composeResources/drawable/ic_lock_open_right.xml} (100%) rename core/{ui/src/main/res/drawable/ic_map_location_dot_24.xml => resources/src/commonMain/composeResources/drawable/ic_map_location_dot.xml} (100%) rename core/{ui/src/main/res/drawable/ic_map_navigation_24.xml => resources/src/commonMain/composeResources/drawable/ic_map_navigation.xml} (100%) rename core/{ui/src/main/res => resources/src/commonMain/composeResources}/drawable/ic_meshtastic.xml (100%) rename core/{ui/src/main/res/drawable/mountain_flag_24px.xml => resources/src/commonMain/composeResources/drawable/ic_mountain_flag.xml} (100%) rename core/{ui/src/main/res/drawable/ic_power_plug_24.xml => resources/src/commonMain/composeResources/drawable/ic_power_plug.xml} (100%) rename core/{ui/src/main/res/drawable/chirpy.xml => resources/src/commonMain/composeResources/drawable/img_chirpy.xml} (100%) diff --git a/app/src/main/java/com/geeksville/mesh/model/UIViewModel.kt b/app/src/main/java/com/geeksville/mesh/model/UIViewModel.kt index fa8fec8f8e..52ef78ce5e 100644 --- a/app/src/main/java/com/geeksville/mesh/model/UIViewModel.kt +++ b/app/src/main/java/com/geeksville/mesh/model/UIViewModel.kt @@ -53,13 +53,13 @@ import org.meshtastic.core.datastore.UiPreferencesDataSource import org.meshtastic.core.model.TracerouteMapAvailability import org.meshtastic.core.model.evaluateTracerouteMapAvailability import org.meshtastic.core.model.util.dispatchMeshtasticUri +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.client_notification +import org.meshtastic.core.resources.compromised_keys import org.meshtastic.core.service.IMeshService import org.meshtastic.core.service.MeshServiceNotifications import org.meshtastic.core.service.ServiceRepository import org.meshtastic.core.service.TracerouteResponse -import org.meshtastic.core.resources.Res -import org.meshtastic.core.resources.client_notification -import org.meshtastic.core.resources.compromised_keys import org.meshtastic.core.ui.component.ScrollToTopEvent import org.meshtastic.core.ui.util.AlertManager import org.meshtastic.core.ui.util.ComposableContent diff --git a/app/src/main/java/com/geeksville/mesh/service/MeshConnectionManager.kt b/app/src/main/java/com/geeksville/mesh/service/MeshConnectionManager.kt index e25febf4ad..f746684259 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshConnectionManager.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshConnectionManager.kt @@ -36,14 +36,14 @@ import org.meshtastic.core.common.util.nowSeconds import org.meshtastic.core.data.repository.NodeRepository import org.meshtastic.core.data.repository.RadioConfigRepository import org.meshtastic.core.prefs.ui.UiPrefs -import org.meshtastic.core.service.ConnectionState -import org.meshtastic.core.service.MeshServiceNotifications import org.meshtastic.core.resources.Res import org.meshtastic.core.resources.connected_count import org.meshtastic.core.resources.connecting import org.meshtastic.core.resources.device_sleeping import org.meshtastic.core.resources.disconnected import org.meshtastic.core.resources.getString +import org.meshtastic.core.service.ConnectionState +import org.meshtastic.core.service.MeshServiceNotifications import org.meshtastic.proto.AdminMessage import org.meshtastic.proto.Config import org.meshtastic.proto.Telemetry diff --git a/app/src/main/java/com/geeksville/mesh/service/MeshDataHandler.kt b/app/src/main/java/com/geeksville/mesh/service/MeshDataHandler.kt index c036241f72..36338d4934 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshDataHandler.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshDataHandler.kt @@ -43,15 +43,15 @@ import org.meshtastic.core.model.util.SfppHasher import org.meshtastic.core.model.util.decodeOrNull import org.meshtastic.core.model.util.toOneLiner import org.meshtastic.core.prefs.mesh.MeshPrefs -import org.meshtastic.core.service.MeshServiceNotifications -import org.meshtastic.core.service.ServiceRepository -import org.meshtastic.core.service.filter.MessageFilterService import org.meshtastic.core.resources.Res import org.meshtastic.core.resources.critical_alert import org.meshtastic.core.resources.error_duty_cycle import org.meshtastic.core.resources.getString import org.meshtastic.core.resources.unknown_username import org.meshtastic.core.resources.waypoint_received +import org.meshtastic.core.service.MeshServiceNotifications +import org.meshtastic.core.service.ServiceRepository +import org.meshtastic.core.service.filter.MessageFilterService import org.meshtastic.proto.AdminMessage import org.meshtastic.proto.MeshPacket import org.meshtastic.proto.Paxcount diff --git a/app/src/main/java/com/geeksville/mesh/service/MeshNeighborInfoHandler.kt b/app/src/main/java/com/geeksville/mesh/service/MeshNeighborInfoHandler.kt index 333a1a1c85..3574bf6e1c 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshNeighborInfoHandler.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshNeighborInfoHandler.kt @@ -21,10 +21,10 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob import org.meshtastic.core.common.util.nowMillis -import org.meshtastic.core.service.ServiceRepository import org.meshtastic.core.resources.Res import org.meshtastic.core.resources.getString import org.meshtastic.core.resources.unknown_username +import org.meshtastic.core.service.ServiceRepository import org.meshtastic.proto.MeshPacket import org.meshtastic.proto.NeighborInfo import java.util.Locale diff --git a/app/src/main/java/com/geeksville/mesh/service/MeshServiceNotificationsImpl.kt b/app/src/main/java/com/geeksville/mesh/service/MeshServiceNotificationsImpl.kt index b76eccd03f..0a37174ee6 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshServiceNotificationsImpl.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshServiceNotificationsImpl.kt @@ -53,8 +53,6 @@ import org.meshtastic.core.database.model.Message import org.meshtastic.core.model.DataPacket import org.meshtastic.core.model.util.formatUptime import org.meshtastic.core.navigation.DEEP_LINK_BASE_URI -import org.meshtastic.core.service.MeshServiceNotifications -import org.meshtastic.core.service.SERVICE_NOTIFY_ID import org.meshtastic.core.resources.Res import org.meshtastic.core.resources.client_notification import org.meshtastic.core.resources.getString @@ -74,6 +72,8 @@ import org.meshtastic.core.resources.new_node_seen import org.meshtastic.core.resources.no_local_stats import org.meshtastic.core.resources.reply import org.meshtastic.core.resources.you +import org.meshtastic.core.service.MeshServiceNotifications +import org.meshtastic.core.service.SERVICE_NOTIFY_ID import org.meshtastic.proto.ClientNotification import org.meshtastic.proto.DeviceMetrics import org.meshtastic.proto.LocalStats diff --git a/app/src/main/java/com/geeksville/mesh/service/MeshTracerouteHandler.kt b/app/src/main/java/com/geeksville/mesh/service/MeshTracerouteHandler.kt index daaf84984e..0ca3e3947c 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshTracerouteHandler.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshTracerouteHandler.kt @@ -26,14 +26,14 @@ import org.meshtastic.core.data.repository.NodeRepository import org.meshtastic.core.data.repository.TracerouteSnapshotRepository import org.meshtastic.core.model.fullRouteDiscovery import org.meshtastic.core.model.getFullTracerouteResponse -import org.meshtastic.core.service.ServiceRepository -import org.meshtastic.core.service.TracerouteResponse import org.meshtastic.core.resources.Res import org.meshtastic.core.resources.getString import org.meshtastic.core.resources.traceroute_duration import org.meshtastic.core.resources.traceroute_route_back_to_us import org.meshtastic.core.resources.traceroute_route_towards_dest import org.meshtastic.core.resources.unknown_username +import org.meshtastic.core.service.ServiceRepository +import org.meshtastic.core.service.TracerouteResponse import org.meshtastic.proto.MeshPacket import java.util.Locale import javax.inject.Inject 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 00d41a18d8..bc3b82a6d4 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/Main.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/Main.kt @@ -106,7 +106,6 @@ import org.meshtastic.core.navigation.NodeDetailRoutes import org.meshtastic.core.navigation.NodesRoutes import org.meshtastic.core.navigation.Route import org.meshtastic.core.navigation.SettingsRoutes -import org.meshtastic.core.service.ConnectionState import org.meshtastic.core.resources.Res import org.meshtastic.core.resources.app_too_old import org.meshtastic.core.resources.bottom_nav_settings @@ -126,6 +125,7 @@ import org.meshtastic.core.resources.should_update import org.meshtastic.core.resources.should_update_firmware import org.meshtastic.core.resources.traceroute import org.meshtastic.core.resources.view_on_map +import org.meshtastic.core.service.ConnectionState import org.meshtastic.core.ui.component.MeshtasticDialog import org.meshtastic.core.ui.component.ScrollToTopEvent import org.meshtastic.core.ui.icon.Conversations diff --git a/app/src/main/java/com/geeksville/mesh/ui/connections/ConnectionsScreen.kt b/app/src/main/java/com/geeksville/mesh/ui/connections/ConnectionsScreen.kt index 2c009810d3..7f9c74d594 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/connections/ConnectionsScreen.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/connections/ConnectionsScreen.kt @@ -64,7 +64,6 @@ import org.jetbrains.compose.resources.getString import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.navigation.Route import org.meshtastic.core.navigation.SettingsRoutes -import org.meshtastic.core.service.ConnectionState import org.meshtastic.core.resources.Res import org.meshtastic.core.resources.connected import org.meshtastic.core.resources.connected_device @@ -75,6 +74,7 @@ import org.meshtastic.core.resources.must_set_region import org.meshtastic.core.resources.no_device_selected import org.meshtastic.core.resources.not_connected import org.meshtastic.core.resources.set_your_region +import org.meshtastic.core.service.ConnectionState import org.meshtastic.core.ui.component.ListItem import org.meshtastic.core.ui.component.MainAppBar import org.meshtastic.core.ui.component.TitledCard diff --git a/app/src/main/java/com/geeksville/mesh/ui/connections/components/BLEDevices.kt b/app/src/main/java/com/geeksville/mesh/ui/connections/components/BLEDevices.kt index fd338b72d3..ed0a540bb0 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/connections/components/BLEDevices.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/connections/components/BLEDevices.kt @@ -37,9 +37,9 @@ import no.nordicsemi.android.common.scanner.view.ScannerView import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.ble.MeshtasticBleConstants.BLE_NAME_PATTERN import org.meshtastic.core.ble.MeshtasticBleConstants.SERVICE_UUID -import org.meshtastic.core.service.ConnectionState import org.meshtastic.core.resources.Res import org.meshtastic.core.resources.bluetooth_available_devices +import org.meshtastic.core.service.ConnectionState /** * Composable that displays a list of Bluetooth Low Energy (BLE) devices and allows scanning. It handles Bluetooth diff --git a/app/src/main/java/com/geeksville/mesh/ui/connections/components/ConnectionsSegmentedBar.kt b/app/src/main/java/com/geeksville/mesh/ui/connections/components/ConnectionsSegmentedBar.kt index 15b30c17b2..705918d9ac 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/connections/components/ConnectionsSegmentedBar.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/connections/components/ConnectionsSegmentedBar.kt @@ -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 . */ - package com.geeksville.mesh.ui.connections.components import androidx.compose.material.icons.Icons diff --git a/app/src/main/java/com/geeksville/mesh/ui/connections/components/DeviceListItem.kt b/app/src/main/java/com/geeksville/mesh/ui/connections/components/DeviceListItem.kt index 4f1b563fb0..78e64088cc 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/connections/components/DeviceListItem.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/connections/components/DeviceListItem.kt @@ -56,12 +56,12 @@ import com.geeksville.mesh.model.DeviceListEntry import kotlinx.coroutines.delay import no.nordicsemi.android.common.ui.view.RssiIcon import org.jetbrains.compose.resources.stringResource -import org.meshtastic.core.service.ConnectionState import org.meshtastic.core.resources.Res import org.meshtastic.core.resources.add import org.meshtastic.core.resources.bluetooth import org.meshtastic.core.resources.network import org.meshtastic.core.resources.serial +import org.meshtastic.core.service.ConnectionState import org.meshtastic.core.ui.component.NodeChip private const val RSSI_UPDATE_RATE_MS = 2000L diff --git a/app/src/main/java/com/geeksville/mesh/ui/connections/components/NetworkDevices.kt b/app/src/main/java/com/geeksville/mesh/ui/connections/components/NetworkDevices.kt index 62f837f366..ea7edb5ff3 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/connections/components/NetworkDevices.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/connections/components/NetworkDevices.kt @@ -53,7 +53,6 @@ import com.geeksville.mesh.ui.connections.ScannerViewModel import com.geeksville.mesh.ui.connections.isValidAddress import kotlinx.coroutines.launch import org.jetbrains.compose.resources.stringResource -import org.meshtastic.core.service.ConnectionState import org.meshtastic.core.resources.Res import org.meshtastic.core.resources.add_network_device import org.meshtastic.core.resources.address @@ -64,6 +63,7 @@ import org.meshtastic.core.resources.forget_connection import org.meshtastic.core.resources.ip_port import org.meshtastic.core.resources.no_network_devices import org.meshtastic.core.resources.recent_network_devices +import org.meshtastic.core.service.ConnectionState import org.meshtastic.core.ui.component.MeshtasticResourceDialog import org.meshtastic.core.ui.theme.AppTheme diff --git a/app/src/main/java/com/geeksville/mesh/ui/connections/components/UsbDevices.kt b/app/src/main/java/com/geeksville/mesh/ui/connections/components/UsbDevices.kt index c5e9f0f498..fe7aa4d708 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/connections/components/UsbDevices.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/connections/components/UsbDevices.kt @@ -27,9 +27,9 @@ import androidx.compose.ui.unit.dp import com.geeksville.mesh.model.DeviceListEntry import com.geeksville.mesh.ui.connections.ScannerViewModel import org.jetbrains.compose.resources.stringResource -import org.meshtastic.core.service.ConnectionState import org.meshtastic.core.resources.Res import org.meshtastic.core.resources.no_usb_devices +import org.meshtastic.core.service.ConnectionState @Composable fun UsbDevices( diff --git a/app/src/main/java/com/geeksville/mesh/ui/contact/AdaptiveContactsScreen.kt b/app/src/main/java/com/geeksville/mesh/ui/contact/AdaptiveContactsScreen.kt index 243b1f292f..ee1649613b 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/contact/AdaptiveContactsScreen.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/contact/AdaptiveContactsScreen.kt @@ -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 . */ - package com.geeksville.mesh.ui.contact import androidx.activity.compose.BackHandler diff --git a/app/src/main/java/com/geeksville/mesh/ui/contact/ContactsViewModel.kt b/app/src/main/java/com/geeksville/mesh/ui/contact/ContactsViewModel.kt index 977c4af50b..0ee5ed8d8f 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/contact/ContactsViewModel.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/contact/ContactsViewModel.kt @@ -39,9 +39,9 @@ import org.meshtastic.core.database.entity.Packet import org.meshtastic.core.model.DataPacket import org.meshtastic.core.model.util.getChannel import org.meshtastic.core.model.util.getShortDate -import org.meshtastic.core.service.ServiceRepository import org.meshtastic.core.resources.Res import org.meshtastic.core.resources.channel_name +import org.meshtastic.core.service.ServiceRepository import org.meshtastic.core.ui.viewmodel.stateInWhileSubscribed import org.meshtastic.proto.ChannelSet import javax.inject.Inject diff --git a/app/src/main/java/com/geeksville/mesh/ui/sharing/Channel.kt b/app/src/main/java/com/geeksville/mesh/ui/sharing/Channel.kt index c2ee346249..b3960ecd7c 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/sharing/Channel.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/sharing/Channel.kt @@ -72,7 +72,6 @@ import org.meshtastic.core.model.Channel import org.meshtastic.core.model.util.getChannelUrl import org.meshtastic.core.model.util.qrCode import org.meshtastic.core.navigation.Route -import org.meshtastic.core.service.ConnectionState import org.meshtastic.core.resources.Res import org.meshtastic.core.resources.add import org.meshtastic.core.resources.apply @@ -87,6 +86,7 @@ import org.meshtastic.core.resources.replace import org.meshtastic.core.resources.reset import org.meshtastic.core.resources.reset_to_defaults import org.meshtastic.core.resources.share_channels_qr +import org.meshtastic.core.service.ConnectionState import org.meshtastic.core.ui.component.AdaptiveTwoPane import org.meshtastic.core.ui.component.ChannelSelection import org.meshtastic.core.ui.component.MainAppBar diff --git a/app/src/main/java/com/geeksville/mesh/ui/sharing/Share.kt b/app/src/main/java/com/geeksville/mesh/ui/sharing/Share.kt index 8b9dfc6f85..0694ae7c26 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/sharing/Share.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/sharing/Share.kt @@ -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 . */ - package com.geeksville.mesh.ui.sharing import androidx.compose.foundation.layout.Column diff --git a/core/database/src/main/kotlin/org/meshtastic/core/database/model/NodeSortOption.kt b/core/database/src/main/kotlin/org/meshtastic/core/database/model/NodeSortOption.kt index 753562776f..c54a66b637 100644 --- a/core/database/src/main/kotlin/org/meshtastic/core/database/model/NodeSortOption.kt +++ b/core/database/src/main/kotlin/org/meshtastic/core/database/model/NodeSortOption.kt @@ -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 . */ - package org.meshtastic.core.database.model import org.jetbrains.compose.resources.StringResource diff --git a/core/resources/src/androidMain/kotlin/org/meshtastic/core/strings/ContextExt.kt b/core/resources/src/androidMain/kotlin/org/meshtastic/core/resources/ContextExt.kt similarity index 100% rename from core/resources/src/androidMain/kotlin/org/meshtastic/core/strings/ContextExt.kt rename to core/resources/src/androidMain/kotlin/org/meshtastic/core/resources/ContextExt.kt diff --git a/core/ui/src/main/res/drawable/ic_antenna_24.xml b/core/resources/src/commonMain/composeResources/drawable/ic_antenna.xml similarity index 100% rename from core/ui/src/main/res/drawable/ic_antenna_24.xml rename to core/resources/src/commonMain/composeResources/drawable/ic_antenna.xml diff --git a/core/ui/src/main/res/drawable/ic_battery_alert.xml b/core/resources/src/commonMain/composeResources/drawable/ic_battery_alert.xml similarity index 100% rename from core/ui/src/main/res/drawable/ic_battery_alert.xml rename to core/resources/src/commonMain/composeResources/drawable/ic_battery_alert.xml diff --git a/core/ui/src/main/res/drawable/ic_battery_high.xml b/core/resources/src/commonMain/composeResources/drawable/ic_battery_high.xml similarity index 100% rename from core/ui/src/main/res/drawable/ic_battery_high.xml rename to core/resources/src/commonMain/composeResources/drawable/ic_battery_high.xml diff --git a/core/ui/src/main/res/drawable/ic_battery_low.xml b/core/resources/src/commonMain/composeResources/drawable/ic_battery_low.xml similarity index 100% rename from core/ui/src/main/res/drawable/ic_battery_low.xml rename to core/resources/src/commonMain/composeResources/drawable/ic_battery_low.xml diff --git a/core/ui/src/main/res/drawable/ic_battery_medium.xml b/core/resources/src/commonMain/composeResources/drawable/ic_battery_medium.xml similarity index 100% rename from core/ui/src/main/res/drawable/ic_battery_medium.xml rename to core/resources/src/commonMain/composeResources/drawable/ic_battery_medium.xml diff --git a/core/ui/src/main/res/drawable/ic_battery_outline.xml b/core/resources/src/commonMain/composeResources/drawable/ic_battery_outline.xml similarity index 100% rename from core/ui/src/main/res/drawable/ic_battery_outline.xml rename to core/resources/src/commonMain/composeResources/drawable/ic_battery_outline.xml diff --git a/core/ui/src/main/res/drawable/ic_battery_unknown.xml b/core/resources/src/commonMain/composeResources/drawable/ic_battery_unknown.xml similarity index 100% rename from core/ui/src/main/res/drawable/ic_battery_unknown.xml rename to core/resources/src/commonMain/composeResources/drawable/ic_battery_unknown.xml diff --git a/core/ui/src/main/res/drawable/counter_0_24px.xml b/core/resources/src/commonMain/composeResources/drawable/ic_counter_0.xml similarity index 100% rename from core/ui/src/main/res/drawable/counter_0_24px.xml rename to core/resources/src/commonMain/composeResources/drawable/ic_counter_0.xml diff --git a/core/ui/src/main/res/drawable/counter_1_24px.xml b/core/resources/src/commonMain/composeResources/drawable/ic_counter_1.xml similarity index 100% rename from core/ui/src/main/res/drawable/counter_1_24px.xml rename to core/resources/src/commonMain/composeResources/drawable/ic_counter_1.xml diff --git a/core/ui/src/main/res/drawable/counter_2_24px.xml b/core/resources/src/commonMain/composeResources/drawable/ic_counter_2.xml similarity index 100% rename from core/ui/src/main/res/drawable/counter_2_24px.xml rename to core/resources/src/commonMain/composeResources/drawable/ic_counter_2.xml diff --git a/core/ui/src/main/res/drawable/counter_3_24px.xml b/core/resources/src/commonMain/composeResources/drawable/ic_counter_3.xml similarity index 100% rename from core/ui/src/main/res/drawable/counter_3_24px.xml rename to core/resources/src/commonMain/composeResources/drawable/ic_counter_3.xml diff --git a/core/ui/src/main/res/drawable/counter_4_24px.xml b/core/resources/src/commonMain/composeResources/drawable/ic_counter_4.xml similarity index 100% rename from core/ui/src/main/res/drawable/counter_4_24px.xml rename to core/resources/src/commonMain/composeResources/drawable/ic_counter_4.xml diff --git a/core/ui/src/main/res/drawable/counter_5_24px.xml b/core/resources/src/commonMain/composeResources/drawable/ic_counter_5.xml similarity index 100% rename from core/ui/src/main/res/drawable/counter_5_24px.xml rename to core/resources/src/commonMain/composeResources/drawable/ic_counter_5.xml diff --git a/core/ui/src/main/res/drawable/counter_6_24px.xml b/core/resources/src/commonMain/composeResources/drawable/ic_counter_6.xml similarity index 100% rename from core/ui/src/main/res/drawable/counter_6_24px.xml rename to core/resources/src/commonMain/composeResources/drawable/ic_counter_6.xml diff --git a/core/ui/src/main/res/drawable/counter_7_24px.xml b/core/resources/src/commonMain/composeResources/drawable/ic_counter_7.xml similarity index 100% rename from core/ui/src/main/res/drawable/counter_7_24px.xml rename to core/resources/src/commonMain/composeResources/drawable/ic_counter_7.xml diff --git a/core/ui/src/main/res/drawable/counter_8_24px.xml b/core/resources/src/commonMain/composeResources/drawable/ic_counter_8.xml similarity index 100% rename from core/ui/src/main/res/drawable/counter_8_24px.xml rename to core/resources/src/commonMain/composeResources/drawable/ic_counter_8.xml diff --git a/core/ui/src/main/res/drawable/ic_baseline_location_on_24.xml b/core/resources/src/commonMain/composeResources/drawable/ic_location_on.xml similarity index 100% rename from core/ui/src/main/res/drawable/ic_baseline_location_on_24.xml rename to core/resources/src/commonMain/composeResources/drawable/ic_location_on.xml diff --git a/core/ui/src/main/res/drawable/ic_lock_open_right_24.xml b/core/resources/src/commonMain/composeResources/drawable/ic_lock_open_right.xml similarity index 100% rename from core/ui/src/main/res/drawable/ic_lock_open_right_24.xml rename to core/resources/src/commonMain/composeResources/drawable/ic_lock_open_right.xml diff --git a/core/ui/src/main/res/drawable/ic_map_location_dot_24.xml b/core/resources/src/commonMain/composeResources/drawable/ic_map_location_dot.xml similarity index 100% rename from core/ui/src/main/res/drawable/ic_map_location_dot_24.xml rename to core/resources/src/commonMain/composeResources/drawable/ic_map_location_dot.xml diff --git a/core/ui/src/main/res/drawable/ic_map_navigation_24.xml b/core/resources/src/commonMain/composeResources/drawable/ic_map_navigation.xml similarity index 100% rename from core/ui/src/main/res/drawable/ic_map_navigation_24.xml rename to core/resources/src/commonMain/composeResources/drawable/ic_map_navigation.xml diff --git a/core/ui/src/main/res/drawable/ic_meshtastic.xml b/core/resources/src/commonMain/composeResources/drawable/ic_meshtastic.xml similarity index 100% rename from core/ui/src/main/res/drawable/ic_meshtastic.xml rename to core/resources/src/commonMain/composeResources/drawable/ic_meshtastic.xml diff --git a/core/ui/src/main/res/drawable/mountain_flag_24px.xml b/core/resources/src/commonMain/composeResources/drawable/ic_mountain_flag.xml similarity index 100% rename from core/ui/src/main/res/drawable/mountain_flag_24px.xml rename to core/resources/src/commonMain/composeResources/drawable/ic_mountain_flag.xml diff --git a/core/ui/src/main/res/drawable/ic_power_plug_24.xml b/core/resources/src/commonMain/composeResources/drawable/ic_power_plug.xml similarity index 100% rename from core/ui/src/main/res/drawable/ic_power_plug_24.xml rename to core/resources/src/commonMain/composeResources/drawable/ic_power_plug.xml diff --git a/core/ui/src/main/res/drawable/chirpy.xml b/core/resources/src/commonMain/composeResources/drawable/img_chirpy.xml similarity index 100% rename from core/ui/src/main/res/drawable/chirpy.xml rename to core/resources/src/commonMain/composeResources/drawable/img_chirpy.xml diff --git a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/CopyIconButton.kt b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/CopyIconButton.kt index f1d8d8d138..c6af5cd73a 100644 --- a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/CopyIconButton.kt +++ b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/CopyIconButton.kt @@ -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 . */ - package org.meshtastic.core.ui.component import android.content.ClipData diff --git a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/EditPasswordPreference.kt b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/EditPasswordPreference.kt index d0cb54241c..e8b71ee018 100644 --- a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/EditPasswordPreference.kt +++ b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/EditPasswordPreference.kt @@ -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 . */ - package org.meshtastic.core.ui.component import androidx.compose.foundation.text.KeyboardActions diff --git a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/EditTextPreference.kt b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/EditTextPreference.kt index 5eeda6aefb..5752287aec 100644 --- a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/EditTextPreference.kt +++ b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/EditTextPreference.kt @@ -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 . */ - package org.meshtastic.core.ui.component import androidx.compose.foundation.layout.Box diff --git a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/LastHeardInfo.kt b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/LastHeardInfo.kt index dbd9163f1a..34921cb09d 100644 --- a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/LastHeardInfo.kt +++ b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/LastHeardInfo.kt @@ -20,14 +20,13 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.res.vectorResource import androidx.compose.ui.tooling.preview.PreviewLightDark import org.jetbrains.compose.resources.stringResource +import org.jetbrains.compose.resources.vectorResource import org.meshtastic.core.common.util.nowSeconds import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.ic_antenna import org.meshtastic.core.resources.node_sort_last_heard -import org.meshtastic.core.ui.R import org.meshtastic.core.ui.theme.AppTheme import org.meshtastic.core.ui.util.formatAgo @@ -40,7 +39,7 @@ fun LastHeardInfo( ) { IconInfo( modifier = modifier, - icon = ImageVector.vectorResource(id = R.drawable.ic_antenna_24), + icon = vectorResource(Res.drawable.ic_antenna), contentDescription = stringResource(Res.string.node_sort_last_heard), label = if (showLabel) stringResource(Res.string.node_sort_last_heard) else null, text = formatAgo(lastHeard), diff --git a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/MainAppBar.kt b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/MainAppBar.kt index ecc0f34678..afb0539af3 100644 --- a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/MainAppBar.kt +++ b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/MainAppBar.kt @@ -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 . */ - package org.meshtastic.core.ui.component import androidx.compose.animation.AnimatedVisibility @@ -32,16 +31,15 @@ import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.res.vectorResource import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.PreviewLightDark import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import org.jetbrains.compose.resources.stringResource +import org.jetbrains.compose.resources.vectorResource import org.meshtastic.core.database.model.Node -import org.meshtastic.core.resources.R import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.ic_meshtastic import org.meshtastic.core.resources.navigate_back import org.meshtastic.core.ui.component.preview.BooleanProvider import org.meshtastic.core.ui.component.preview.previewNode @@ -82,12 +80,7 @@ fun MainAppBar( } } } else { - { - Icon( - imageVector = ImageVector.vectorResource(id = org.meshtastic.core.ui.R.drawable.ic_meshtastic), - contentDescription = null, - ) - } + { Icon(imageVector = vectorResource(Res.drawable.ic_meshtastic), contentDescription = null) } }, actions = { TopBarActions(ourNode = ourNode, showNodeChip = showNodeChip, actions = actions, onClickChip = onClickChip) diff --git a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/MaterialBluetoothSignalInfo.kt b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/MaterialBluetoothSignalInfo.kt index 444bad7333..cfc368275d 100644 --- a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/MaterialBluetoothSignalInfo.kt +++ b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/MaterialBluetoothSignalInfo.kt @@ -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 . */ - package org.meshtastic.core.ui.component import androidx.compose.foundation.layout.Arrangement diff --git a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/PositionPrecisionPreference.kt b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/PositionPrecisionPreference.kt index fdc849b300..e3fc2a914e 100644 --- a/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/PositionPrecisionPreference.kt +++ b/core/ui/src/main/kotlin/org/meshtastic/core/ui/component/PositionPrecisionPreference.kt @@ -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 . */ - package org.meshtastic.core.ui.component import androidx.compose.foundation.layout.Column diff --git a/core/ui/src/main/kotlin/org/meshtastic/core/ui/icon/Counter.kt b/core/ui/src/main/kotlin/org/meshtastic/core/ui/icon/Counter.kt index 688a80d79f..4bf0b6a976 100644 --- a/core/ui/src/main/kotlin/org/meshtastic/core/ui/icon/Counter.kt +++ b/core/ui/src/main/kotlin/org/meshtastic/core/ui/icon/Counter.kt @@ -18,33 +18,49 @@ package org.meshtastic.core.ui.icon import androidx.compose.runtime.Composable import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.res.vectorResource -import org.meshtastic.core.ui.R +import org.meshtastic.core.resources.ic_counter_0 +import org.meshtastic.core.resources.ic_counter_1 +import org.meshtastic.core.resources.ic_counter_2 +import org.meshtastic.core.resources.ic_counter_3 +import org.meshtastic.core.resources.ic_counter_4 +import org.meshtastic.core.resources.ic_counter_5 +import org.meshtastic.core.resources.ic_counter_6 +import org.meshtastic.core.resources.ic_counter_7 +import org.meshtastic.core.resources.ic_counter_8 /** These are from Material Symbols drawables. */ val MeshtasticIcons.Counter0: ImageVector - @Composable get() = ImageVector.vectorResource(R.drawable.counter_0_24px) + @Composable + get() = org.jetbrains.compose.resources.vectorResource(org.meshtastic.core.resources.Res.drawable.ic_counter_0) val MeshtasticIcons.Counter1: ImageVector - @Composable get() = ImageVector.vectorResource(R.drawable.counter_1_24px) + @Composable + get() = org.jetbrains.compose.resources.vectorResource(org.meshtastic.core.resources.Res.drawable.ic_counter_1) val MeshtasticIcons.Counter2: ImageVector - @Composable get() = ImageVector.vectorResource(R.drawable.counter_2_24px) + @Composable + get() = org.jetbrains.compose.resources.vectorResource(org.meshtastic.core.resources.Res.drawable.ic_counter_2) val MeshtasticIcons.Counter3: ImageVector - @Composable get() = ImageVector.vectorResource(R.drawable.counter_3_24px) + @Composable + get() = org.jetbrains.compose.resources.vectorResource(org.meshtastic.core.resources.Res.drawable.ic_counter_3) val MeshtasticIcons.Counter4: ImageVector - @Composable get() = ImageVector.vectorResource(R.drawable.counter_4_24px) + @Composable + get() = org.jetbrains.compose.resources.vectorResource(org.meshtastic.core.resources.Res.drawable.ic_counter_4) val MeshtasticIcons.Counter5: ImageVector - @Composable get() = ImageVector.vectorResource(R.drawable.counter_5_24px) + @Composable + get() = org.jetbrains.compose.resources.vectorResource(org.meshtastic.core.resources.Res.drawable.ic_counter_5) val MeshtasticIcons.Counter6: ImageVector - @Composable get() = ImageVector.vectorResource(R.drawable.counter_6_24px) + @Composable + get() = org.jetbrains.compose.resources.vectorResource(org.meshtastic.core.resources.Res.drawable.ic_counter_6) val MeshtasticIcons.Counter7: ImageVector - @Composable get() = ImageVector.vectorResource(R.drawable.counter_7_24px) + @Composable + get() = org.jetbrains.compose.resources.vectorResource(org.meshtastic.core.resources.Res.drawable.ic_counter_7) val MeshtasticIcons.Counter8: ImageVector - @Composable get() = ImageVector.vectorResource(R.drawable.counter_8_24px) + @Composable + get() = org.jetbrains.compose.resources.vectorResource(org.meshtastic.core.resources.Res.drawable.ic_counter_8) diff --git a/core/ui/src/main/kotlin/org/meshtastic/core/ui/icon/Device.kt b/core/ui/src/main/kotlin/org/meshtastic/core/ui/icon/Device.kt index 5c368b8fef..1c44b9a13d 100644 --- a/core/ui/src/main/kotlin/org/meshtastic/core/ui/icon/Device.kt +++ b/core/ui/src/main/kotlin/org/meshtastic/core/ui/icon/Device.kt @@ -33,9 +33,10 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.SolidColor import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.graphics.vector.path -import androidx.compose.ui.res.vectorResource import androidx.compose.ui.unit.dp -import org.meshtastic.core.ui.R +import org.jetbrains.compose.resources.vectorResource +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.ic_mountain_flag import org.meshtastic.proto.Config val MeshtasticIcons.HardwareModel: ImageVector @@ -50,7 +51,7 @@ val MeshtasticIcons.NodeId: ImageVector fun MeshtasticIcons.role(role: Config.DeviceConfig.Role?): ImageVector = when (role) { Config.DeviceConfig.Role.CLIENT -> Icons.Rounded.Person Config.DeviceConfig.Role.CLIENT_MUTE -> Icons.Rounded.PersonOff - Config.DeviceConfig.Role.ROUTER -> ImageVector.vectorResource(R.drawable.mountain_flag_24px) + Config.DeviceConfig.Role.ROUTER -> vectorResource(Res.drawable.ic_mountain_flag) Config.DeviceConfig.Role.TRACKER -> Icons.Rounded.MyLocation Config.DeviceConfig.Role.SENSOR -> Icons.Rounded.Sensors Config.DeviceConfig.Role.TAK -> Icons.Rounded.MilitaryTech diff --git a/feature/firmware/src/main/kotlin/org/meshtastic/feature/firmware/FirmwareUpdateScreen.kt b/feature/firmware/src/main/kotlin/org/meshtastic/feature/firmware/FirmwareUpdateScreen.kt index 4a91d998c5..1a52c79d26 100644 --- a/feature/firmware/src/main/kotlin/org/meshtastic/feature/firmware/FirmwareUpdateScreen.kt +++ b/feature/firmware/src/main/kotlin/org/meshtastic/feature/firmware/FirmwareUpdateScreen.kt @@ -132,6 +132,7 @@ import org.meshtastic.core.resources.firmware_update_verification_failed import org.meshtastic.core.resources.firmware_update_verifying import org.meshtastic.core.resources.firmware_update_waiting_reconnect import org.meshtastic.core.resources.i_know_what_i_m_doing +import org.meshtastic.core.resources.img_chirpy import org.meshtastic.core.resources.learn_more import org.meshtastic.core.resources.okay import org.meshtastic.core.resources.save @@ -336,7 +337,9 @@ private fun FirmwareUpdateContent( is FirmwareUpdateState.Verifying -> VerifyingState() is FirmwareUpdateState.VerificationFailed -> VerificationFailedState(onRetry = actions.onStartUpdate, onIgnore = actions.onDone) + is FirmwareUpdateState.Error -> ErrorState(error = state.error, onRetry = actions.onRetry) + is FirmwareUpdateState.Success -> SuccessState(onDone = actions.onDone) is FirmwareUpdateState.AwaitingFileSave -> AwaitingFileSaveState(state, actions.onSaveFile) } @@ -493,7 +496,7 @@ private fun ChirpyCard() { AsyncImage( model = ImageRequest.Builder(LocalContext.current) - .data(org.meshtastic.core.ui.R.drawable.chirpy) + .data(Res.drawable.img_chirpy) .crossfade(true) .build(), contentScale = ContentScale.Fit, diff --git a/feature/firmware/src/main/kotlin/org/meshtastic/feature/firmware/FirmwareUpdateViewModel.kt b/feature/firmware/src/main/kotlin/org/meshtastic/feature/firmware/FirmwareUpdateViewModel.kt index 35185ce48e..81d60db694 100644 --- a/feature/firmware/src/main/kotlin/org/meshtastic/feature/firmware/FirmwareUpdateViewModel.kt +++ b/feature/firmware/src/main/kotlin/org/meshtastic/feature/firmware/FirmwareUpdateViewModel.kt @@ -49,8 +49,6 @@ import org.meshtastic.core.prefs.radio.RadioPrefs import org.meshtastic.core.prefs.radio.isBle import org.meshtastic.core.prefs.radio.isSerial import org.meshtastic.core.prefs.radio.isTcp -import org.meshtastic.core.service.ConnectionState -import org.meshtastic.core.service.ServiceRepository import org.meshtastic.core.resources.Res import org.meshtastic.core.resources.firmware_update_battery_low import org.meshtastic.core.resources.firmware_update_copying @@ -73,6 +71,8 @@ import org.meshtastic.core.resources.firmware_update_unknown_hardware import org.meshtastic.core.resources.firmware_update_updating import org.meshtastic.core.resources.firmware_update_validating import org.meshtastic.core.resources.unknown +import org.meshtastic.core.service.ConnectionState +import org.meshtastic.core.service.ServiceRepository import java.io.File import javax.inject.Inject diff --git a/feature/firmware/src/main/kotlin/org/meshtastic/feature/firmware/NordicDfuHandler.kt b/feature/firmware/src/main/kotlin/org/meshtastic/feature/firmware/NordicDfuHandler.kt index 310a450e70..d104d18d4d 100644 --- a/feature/firmware/src/main/kotlin/org/meshtastic/feature/firmware/NordicDfuHandler.kt +++ b/feature/firmware/src/main/kotlin/org/meshtastic/feature/firmware/NordicDfuHandler.kt @@ -33,12 +33,12 @@ import no.nordicsemi.android.dfu.DfuServiceListenerHelper import org.jetbrains.compose.resources.getString import org.meshtastic.core.database.entity.FirmwareRelease import org.meshtastic.core.model.DeviceHardware -import org.meshtastic.core.service.ServiceRepository import org.meshtastic.core.resources.Res import org.meshtastic.core.resources.firmware_update_downloading_percent import org.meshtastic.core.resources.firmware_update_nordic_failed import org.meshtastic.core.resources.firmware_update_not_found_in_release import org.meshtastic.core.resources.firmware_update_starting_service +import org.meshtastic.core.service.ServiceRepository import java.io.File import javax.inject.Inject diff --git a/feature/firmware/src/main/kotlin/org/meshtastic/feature/firmware/UsbUpdateHandler.kt b/feature/firmware/src/main/kotlin/org/meshtastic/feature/firmware/UsbUpdateHandler.kt index e251b60bdd..4e7075c217 100644 --- a/feature/firmware/src/main/kotlin/org/meshtastic/feature/firmware/UsbUpdateHandler.kt +++ b/feature/firmware/src/main/kotlin/org/meshtastic/feature/firmware/UsbUpdateHandler.kt @@ -23,12 +23,12 @@ import kotlinx.coroutines.delay import org.jetbrains.compose.resources.getString import org.meshtastic.core.database.entity.FirmwareRelease import org.meshtastic.core.model.DeviceHardware -import org.meshtastic.core.service.ServiceRepository import org.meshtastic.core.resources.Res import org.meshtastic.core.resources.firmware_update_downloading_percent import org.meshtastic.core.resources.firmware_update_rebooting import org.meshtastic.core.resources.firmware_update_retrieval_failed import org.meshtastic.core.resources.firmware_update_usb_failed +import org.meshtastic.core.service.ServiceRepository import java.io.File import javax.inject.Inject diff --git a/feature/firmware/src/main/kotlin/org/meshtastic/feature/firmware/ota/Esp32OtaUpdateHandler.kt b/feature/firmware/src/main/kotlin/org/meshtastic/feature/firmware/ota/Esp32OtaUpdateHandler.kt index 3bddb2b53f..06bffbb496 100644 --- a/feature/firmware/src/main/kotlin/org/meshtastic/feature/firmware/ota/Esp32OtaUpdateHandler.kt +++ b/feature/firmware/src/main/kotlin/org/meshtastic/feature/firmware/ota/Esp32OtaUpdateHandler.kt @@ -29,7 +29,6 @@ import org.jetbrains.compose.resources.getString import org.meshtastic.core.common.util.nowMillis import org.meshtastic.core.database.entity.FirmwareRelease import org.meshtastic.core.model.DeviceHardware -import org.meshtastic.core.service.ServiceRepository import org.meshtastic.core.resources.Res import org.meshtastic.core.resources.firmware_update_connecting_attempt import org.meshtastic.core.resources.firmware_update_downloading_percent @@ -41,6 +40,7 @@ import org.meshtastic.core.resources.firmware_update_retrieval_failed import org.meshtastic.core.resources.firmware_update_starting_ota import org.meshtastic.core.resources.firmware_update_uploading import org.meshtastic.core.resources.firmware_update_waiting_reboot +import org.meshtastic.core.service.ServiceRepository import org.meshtastic.feature.firmware.FirmwareRetriever import org.meshtastic.feature.firmware.FirmwareUpdateHandler import org.meshtastic.feature.firmware.FirmwareUpdateState diff --git a/feature/intro/src/main/kotlin/org/meshtastic/feature/intro/CriticalAlertsScreen.kt b/feature/intro/src/main/kotlin/org/meshtastic/feature/intro/CriticalAlertsScreen.kt index 0daa3fbfa0..eb0f0a1906 100644 --- a/feature/intro/src/main/kotlin/org/meshtastic/feature/intro/CriticalAlertsScreen.kt +++ b/feature/intro/src/main/kotlin/org/meshtastic/feature/intro/CriticalAlertsScreen.kt @@ -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 . */ - package org.meshtastic.feature.intro import androidx.compose.foundation.layout.Column diff --git a/feature/intro/src/main/kotlin/org/meshtastic/feature/intro/LocationScreen.kt b/feature/intro/src/main/kotlin/org/meshtastic/feature/intro/LocationScreen.kt index 9ebd027bdf..3d34178d47 100644 --- a/feature/intro/src/main/kotlin/org/meshtastic/feature/intro/LocationScreen.kt +++ b/feature/intro/src/main/kotlin/org/meshtastic/feature/intro/LocationScreen.kt @@ -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 . */ - package org.meshtastic.feature.intro import android.content.Intent diff --git a/feature/intro/src/main/kotlin/org/meshtastic/feature/intro/PermissionScreenLayout.kt b/feature/intro/src/main/kotlin/org/meshtastic/feature/intro/PermissionScreenLayout.kt index 889f746716..7ecc1d3439 100644 --- a/feature/intro/src/main/kotlin/org/meshtastic/feature/intro/PermissionScreenLayout.kt +++ b/feature/intro/src/main/kotlin/org/meshtastic/feature/intro/PermissionScreenLayout.kt @@ -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 . */ - package org.meshtastic.feature.intro import androidx.compose.foundation.gestures.detectTapGestures diff --git a/feature/intro/src/main/kotlin/org/meshtastic/feature/intro/WelcomeScreen.kt b/feature/intro/src/main/kotlin/org/meshtastic/feature/intro/WelcomeScreen.kt index 1c115958fb..8a4843c877 100644 --- a/feature/intro/src/main/kotlin/org/meshtastic/feature/intro/WelcomeScreen.kt +++ b/feature/intro/src/main/kotlin/org/meshtastic/feature/intro/WelcomeScreen.kt @@ -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 . */ - package org.meshtastic.feature.intro import androidx.compose.foundation.layout.Column diff --git a/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/MapView.kt b/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/MapView.kt index 923f829119..d1c2dc20f4 100644 --- a/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/MapView.kt +++ b/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/MapView.kt @@ -287,12 +287,11 @@ fun MapView( MyLocationNewOverlay(this).apply { enableMyLocation() enableFollowLocation() - getBitmapFromVectorDrawable(context, org.meshtastic.core.ui.R.drawable.ic_map_location_dot_24) - ?.let { - setPersonIcon(it) - setPersonAnchor(0.5f, 0.5f) - } - getBitmapFromVectorDrawable(context, org.meshtastic.core.ui.R.drawable.ic_map_navigation_24)?.let { + getBitmapFromVectorDrawable(context, org.meshtastic.core.ui.R.drawable.ic_map_location_dot)?.let { + setPersonIcon(it) + setPersonAnchor(0.5f, 0.5f) + } + getBitmapFromVectorDrawable(context, org.meshtastic.core.ui.R.drawable.ic_map_navigation)?.let { setDirectionIcon(it) setDirectionAnchor(0.5f, 0.5f) } @@ -389,7 +388,7 @@ fun MapView( var hasCenteredTraceroute by remember(tracerouteOverlay) { mutableStateOf(false) } val markerIcon = remember { - AppCompatResources.getDrawable(context, org.meshtastic.core.ui.R.drawable.ic_baseline_location_on_24) + AppCompatResources.getDrawable(context, org.meshtastic.core.ui.R.drawable.ic_location_on) } fun MapView.onNodesChanged(nodes: Collection): List { diff --git a/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/MapViewExtensions.kt b/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/MapViewExtensions.kt index b82c322725..16336acff8 100644 --- a/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/MapViewExtensions.kt +++ b/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/MapViewExtensions.kt @@ -125,7 +125,7 @@ fun MapView.addPolyline(density: Density, geoPoints: List, onClick: () } fun MapView.addPositionMarkers(positions: List, onClick: () -> Unit): List { - val navIcon = ContextCompat.getDrawable(context, R.drawable.ic_map_navigation_24) + val navIcon = ContextCompat.getDrawable(context, R.drawable.ic_map_navigation) val markers = positions.map { Marker(this).apply { diff --git a/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/component/CacheLayout.kt b/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/component/CacheLayout.kt index dcdd24c291..ac8219d812 100644 --- a/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/component/CacheLayout.kt +++ b/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/component/CacheLayout.kt @@ -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 . */ - package org.meshtastic.feature.map.component import androidx.compose.foundation.background diff --git a/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/component/MapButton.kt b/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/component/MapButton.kt index 6b30c8ac87..b6a368b415 100644 --- a/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/component/MapButton.kt +++ b/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/component/MapButton.kt @@ -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 . */ - package org.meshtastic.feature.map.component import androidx.compose.foundation.layout.size diff --git a/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/ClusterItemsListDialog.kt b/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/ClusterItemsListDialog.kt index b005cc460a..6a03e663d1 100644 --- a/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/ClusterItemsListDialog.kt +++ b/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/ClusterItemsListDialog.kt @@ -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 . */ - package org.meshtastic.feature.map.component import androidx.compose.foundation.clickable diff --git a/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/CustomMapLayersSheet.kt b/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/CustomMapLayersSheet.kt index 30686eddb9..3a9875ac08 100644 --- a/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/CustomMapLayersSheet.kt +++ b/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/CustomMapLayersSheet.kt @@ -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 . */ - package org.meshtastic.feature.map.component import androidx.compose.foundation.layout.PaddingValues diff --git a/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/MapFilterDropdown.kt b/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/MapFilterDropdown.kt index f6f84e154b..6314823bdf 100644 --- a/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/MapFilterDropdown.kt +++ b/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/MapFilterDropdown.kt @@ -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 . */ - package org.meshtastic.feature.map.component import androidx.compose.foundation.layout.Column diff --git a/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/MapTypeDropdown.kt b/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/MapTypeDropdown.kt index f4b3a98f55..e3722ac29d 100644 --- a/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/MapTypeDropdown.kt +++ b/feature/map/src/google/kotlin/org/meshtastic/feature/map/component/MapTypeDropdown.kt @@ -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 . */ - package org.meshtastic.feature.map.component import androidx.compose.material.icons.Icons diff --git a/feature/map/src/main/kotlin/org/meshtastic/feature/map/BaseMapViewModel.kt b/feature/map/src/main/kotlin/org/meshtastic/feature/map/BaseMapViewModel.kt index e3384e03aa..82edfb9bb3 100644 --- a/feature/map/src/main/kotlin/org/meshtastic/feature/map/BaseMapViewModel.kt +++ b/feature/map/src/main/kotlin/org/meshtastic/feature/map/BaseMapViewModel.kt @@ -36,13 +36,13 @@ import org.meshtastic.core.database.model.Node import org.meshtastic.core.model.DataPacket import org.meshtastic.core.model.util.TimeConstants import org.meshtastic.core.prefs.map.MapPrefs -import org.meshtastic.core.service.ServiceRepository import org.meshtastic.core.resources.Res import org.meshtastic.core.resources.any import org.meshtastic.core.resources.eight_hours import org.meshtastic.core.resources.one_day import org.meshtastic.core.resources.one_hour import org.meshtastic.core.resources.two_days +import org.meshtastic.core.service.ServiceRepository import org.meshtastic.core.ui.viewmodel.stateInWhileSubscribed import org.meshtastic.feature.map.model.TracerouteOverlay import org.meshtastic.proto.Position diff --git a/feature/map/src/main/kotlin/org/meshtastic/feature/map/MapScreen.kt b/feature/map/src/main/kotlin/org/meshtastic/feature/map/MapScreen.kt index 9af91022fc..be5d93dcd4 100644 --- a/feature/map/src/main/kotlin/org/meshtastic/feature/map/MapScreen.kt +++ b/feature/map/src/main/kotlin/org/meshtastic/feature/map/MapScreen.kt @@ -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 . */ - package org.meshtastic.feature.map import androidx.compose.foundation.layout.Box diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/AdministrationSection.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/AdministrationSection.kt index bb756fbe78..0fb96c836b 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/AdministrationSection.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/AdministrationSection.kt @@ -32,7 +32,6 @@ import org.meshtastic.core.database.entity.asDeviceVersion import org.meshtastic.core.database.model.Node import org.meshtastic.core.model.DeviceVersion import org.meshtastic.core.navigation.SettingsRoutes -import org.meshtastic.core.service.ServiceAction import org.meshtastic.core.resources.Res import org.meshtastic.core.resources.administration import org.meshtastic.core.resources.firmware @@ -42,6 +41,7 @@ import org.meshtastic.core.resources.latest_alpha_firmware import org.meshtastic.core.resources.latest_stable_firmware import org.meshtastic.core.resources.remote_admin import org.meshtastic.core.resources.request_metadata +import org.meshtastic.core.service.ServiceAction import org.meshtastic.core.ui.component.ListItem import org.meshtastic.core.ui.theme.StatusColors.StatusGreen import org.meshtastic.core.ui.theme.StatusColors.StatusOrange diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/LastHeardInfo.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/LastHeardInfo.kt index 50aefe6510..8821065a04 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/LastHeardInfo.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/LastHeardInfo.kt @@ -20,14 +20,14 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.res.vectorResource import androidx.compose.ui.tooling.preview.PreviewLightDark import org.jetbrains.compose.resources.stringResource +import org.jetbrains.compose.resources.vectorResource import org.meshtastic.core.common.util.nowSeconds import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.ic_antenna import org.meshtastic.core.resources.node_sort_last_heard -import org.meshtastic.core.ui.R import org.meshtastic.core.ui.theme.AppTheme import org.meshtastic.core.ui.util.formatAgo @@ -40,7 +40,7 @@ fun LastHeardInfo( ) { IconInfo( modifier = modifier, - icon = ImageVector.vectorResource(id = R.drawable.ic_antenna_24), + icon = vectorResource(Res.drawable.ic_antenna), contentDescription = stringResource(Res.string.node_sort_last_heard), label = if (showLabel) stringResource(Res.string.node_sort_last_heard) else null, text = formatAgo(lastHeard), diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/NodeItem.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/NodeItem.kt index 182df61a01..755c681754 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/NodeItem.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/NodeItem.kt @@ -55,7 +55,6 @@ import org.meshtastic.core.database.model.Node import org.meshtastic.core.database.model.isUnmessageableRole import org.meshtastic.core.model.util.UnitConversions.celsiusToFahrenheit import org.meshtastic.core.model.util.toDistanceString -import org.meshtastic.core.service.ConnectionState import org.meshtastic.core.resources.Res import org.meshtastic.core.resources.air_utilization import org.meshtastic.core.resources.channel_utilization @@ -64,6 +63,7 @@ import org.meshtastic.core.resources.elevation_suffix import org.meshtastic.core.resources.signal_quality import org.meshtastic.core.resources.unknown_username import org.meshtastic.core.resources.voltage +import org.meshtastic.core.service.ConnectionState import org.meshtastic.core.ui.component.AirQualityInfo import org.meshtastic.core.ui.component.ChannelInfo import org.meshtastic.core.ui.component.DistanceInfo diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/NodeStatusIcons.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/NodeStatusIcons.kt index 1520c9caad..919515426f 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/NodeStatusIcons.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/NodeStatusIcons.kt @@ -37,7 +37,6 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import org.jetbrains.compose.resources.StringResource import org.jetbrains.compose.resources.stringResource -import org.meshtastic.core.service.ConnectionState import org.meshtastic.core.resources.Res import org.meshtastic.core.resources.connected import org.meshtastic.core.resources.connecting @@ -47,6 +46,7 @@ import org.meshtastic.core.resources.favorite import org.meshtastic.core.resources.mute_always import org.meshtastic.core.resources.unmessageable import org.meshtastic.core.resources.unmonitored_or_infrastructure +import org.meshtastic.core.service.ConnectionState import org.meshtastic.core.ui.icon.CloudDone import org.meshtastic.core.ui.icon.CloudOffTwoTone import org.meshtastic.core.ui.icon.CloudSync diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/detail/NodeManagementActions.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/detail/NodeManagementActions.kt index 0d50a525a6..a84617dae8 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/detail/NodeManagementActions.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/detail/NodeManagementActions.kt @@ -24,8 +24,6 @@ import kotlinx.coroutines.launch import org.jetbrains.compose.resources.getString import org.meshtastic.core.data.repository.NodeRepository import org.meshtastic.core.database.model.Node -import org.meshtastic.core.service.ServiceAction -import org.meshtastic.core.service.ServiceRepository import org.meshtastic.core.resources.Res import org.meshtastic.core.resources.favorite import org.meshtastic.core.resources.favorite_add @@ -39,6 +37,8 @@ import org.meshtastic.core.resources.mute_remove import org.meshtastic.core.resources.remove import org.meshtastic.core.resources.remove_node_text import org.meshtastic.core.resources.unmute +import org.meshtastic.core.service.ServiceAction +import org.meshtastic.core.service.ServiceRepository import org.meshtastic.core.ui.util.AlertManager import javax.inject.Inject import javax.inject.Singleton diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/detail/NodeRequestActions.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/detail/NodeRequestActions.kt index 300023bf06..b9d725f302 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/detail/NodeRequestActions.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/detail/NodeRequestActions.kt @@ -31,7 +31,6 @@ import org.jetbrains.compose.resources.StringResource import org.meshtastic.core.common.util.nowMillis import org.meshtastic.core.model.Position import org.meshtastic.core.model.TelemetryType -import org.meshtastic.core.service.ServiceRepository import org.meshtastic.core.resources.Res import org.meshtastic.core.resources.neighbor_info import org.meshtastic.core.resources.position @@ -45,6 +44,7 @@ import org.meshtastic.core.resources.requesting_from import org.meshtastic.core.resources.signal_quality import org.meshtastic.core.resources.traceroute import org.meshtastic.core.resources.user_info +import org.meshtastic.core.service.ServiceRepository import javax.inject.Inject import javax.inject.Singleton diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/list/NodeListScreen.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/list/NodeListScreen.kt index f4e9341352..6b95f55fab 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/list/NodeListScreen.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/list/NodeListScreen.kt @@ -68,7 +68,6 @@ import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.launch import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.database.model.Node -import org.meshtastic.core.service.ConnectionState import org.meshtastic.core.resources.Res import org.meshtastic.core.resources.add_favorite import org.meshtastic.core.resources.channel_invalid @@ -80,6 +79,7 @@ import org.meshtastic.core.resources.remove import org.meshtastic.core.resources.remove_favorite import org.meshtastic.core.resources.remove_ignored import org.meshtastic.core.resources.unmute +import org.meshtastic.core.service.ConnectionState import org.meshtastic.core.ui.component.MainAppBar import org.meshtastic.core.ui.component.MeshtasticImportFAB import org.meshtastic.core.ui.component.ScrollToTopEvent diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/MetricsViewModel.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/MetricsViewModel.kt index 700c35505b..0f3e2820b5 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/MetricsViewModel.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/MetricsViewModel.kt @@ -55,11 +55,11 @@ import org.meshtastic.core.model.TelemetryType import org.meshtastic.core.model.evaluateTracerouteMapAvailability import org.meshtastic.core.model.util.UnitConversions import org.meshtastic.core.navigation.NodesRoutes -import org.meshtastic.core.service.ServiceRepository import org.meshtastic.core.resources.Res import org.meshtastic.core.resources.okay import org.meshtastic.core.resources.traceroute import org.meshtastic.core.resources.view_on_map +import org.meshtastic.core.service.ServiceRepository import org.meshtastic.core.ui.util.AlertManager import org.meshtastic.core.ui.util.toMessageRes import org.meshtastic.core.ui.viewmodel.stateInWhileSubscribed diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/CleanNodeDatabaseViewModel.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/CleanNodeDatabaseViewModel.kt index cfed889682..344ee08900 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/CleanNodeDatabaseViewModel.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/CleanNodeDatabaseViewModel.kt @@ -26,11 +26,11 @@ import org.jetbrains.compose.resources.getString import org.meshtastic.core.common.util.nowSeconds import org.meshtastic.core.data.repository.NodeRepository import org.meshtastic.core.database.entity.NodeEntity -import org.meshtastic.core.service.ServiceRepository import org.meshtastic.core.resources.Res import org.meshtastic.core.resources.are_you_sure import org.meshtastic.core.resources.clean_node_database_confirmation import org.meshtastic.core.resources.clean_now +import org.meshtastic.core.service.ServiceRepository import org.meshtastic.core.ui.util.AlertManager import javax.inject.Inject import kotlin.time.Duration.Companion.days diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/RadioConfigViewModel.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/RadioConfigViewModel.kt index 67503ddf1f..3159b482da 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/RadioConfigViewModel.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/RadioConfigViewModel.kt @@ -58,11 +58,11 @@ import org.meshtastic.core.navigation.SettingsRoutes import org.meshtastic.core.prefs.analytics.AnalyticsPrefs import org.meshtastic.core.prefs.homoglyph.HomoglyphPrefs import org.meshtastic.core.prefs.map.MapConsentPrefs +import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.cant_shutdown import org.meshtastic.core.service.ConnectionState import org.meshtastic.core.service.IMeshService import org.meshtastic.core.service.ServiceRepository -import org.meshtastic.core.resources.Res -import org.meshtastic.core.resources.cant_shutdown import org.meshtastic.core.ui.util.getChannelList import org.meshtastic.feature.settings.navigation.ConfigRoute import org.meshtastic.feature.settings.navigation.ModuleRoute diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/channel/component/ChannelConfigHeader.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/channel/component/ChannelConfigHeader.kt index c4a49c2641..75be99792d 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/channel/component/ChannelConfigHeader.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/channel/component/ChannelConfigHeader.kt @@ -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 . */ - package org.meshtastic.feature.settings.radio.channel.component import androidx.compose.foundation.layout.Arrangement diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/MapReportingPreference.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/MapReportingPreference.kt index e6530647cb..fc33812ea7 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/MapReportingPreference.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/component/MapReportingPreference.kt @@ -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 . */ - package org.meshtastic.feature.settings.radio.component import androidx.compose.animation.AnimatedVisibility From 3ab20a8611f366309ca7617495ac76fcd47422d5 Mon Sep 17 00:00:00 2001 From: James Rich <2199651+jamesarich@users.noreply.github.com> Date: Sun, 22 Feb 2026 13:58:16 -0600 Subject: [PATCH 11/18] chore: migrate feature node resources to core:resources --- .../composeResources/drawable/ic_dew_point.xml | 0 .../composeResources/drawable/ic_radioactive.xml | 0 .../drawable/ic_soil_moisture.xml | 0 .../drawable/ic_soil_temperature.xml | 0 .../composeResources/drawable/ic_unverified.xml | 0 .../composeResources/drawable/img_hw_unknown.xml | 0 .../composeResources/drawable/img_qrcode.png} | Bin .../kotlin/org/meshtastic/feature/map/MapView.kt | 9 ++++++--- .../meshtastic/feature/map/MapViewExtensions.kt | 3 ++- .../src/fdroid/res/drawable/ic_location_on.xml | 14 ++++++++++++++ .../fdroid/res/drawable/ic_map_location_dot.xml | 11 +++++++++++ .../src/fdroid/res/drawable/ic_map_navigation.xml | 11 +++++++++++ .../node/component/DeviceDetailsSection.kt | 11 +++++++---- .../feature/node/component/EnvironmentMetrics.kt | 12 ++++++++---- .../meshtastic/feature/node/component/InfoCard.kt | 8 +++++--- .../meshtastic/feature/node/model/MetricInfo.kt | 4 ++-- 16 files changed, 66 insertions(+), 17 deletions(-) rename feature/node/src/main/res/drawable/ic_outlined_dew_point_24.xml => core/resources/src/commonMain/composeResources/drawable/ic_dew_point.xml (100%) rename feature/node/src/main/res/drawable/ic_filled_radioactive_24.xml => core/resources/src/commonMain/composeResources/drawable/ic_radioactive.xml (100%) rename feature/node/src/main/res/drawable/soil_moisture.xml => core/resources/src/commonMain/composeResources/drawable/ic_soil_moisture.xml (100%) rename feature/node/src/main/res/drawable/soil_temperature.xml => core/resources/src/commonMain/composeResources/drawable/ic_soil_temperature.xml (100%) rename feature/node/src/main/res/drawable/unverified.xml => core/resources/src/commonMain/composeResources/drawable/ic_unverified.xml (100%) rename feature/node/src/main/res/drawable/hw_unknown.xml => core/resources/src/commonMain/composeResources/drawable/img_hw_unknown.xml (100%) rename core/{ui/src/main/res/drawable-nodpi/qrcode.png => resources/src/commonMain/composeResources/drawable/img_qrcode.png} (100%) create mode 100644 feature/map/src/fdroid/res/drawable/ic_location_on.xml create mode 100644 feature/map/src/fdroid/res/drawable/ic_map_location_dot.xml create mode 100644 feature/map/src/fdroid/res/drawable/ic_map_navigation.xml diff --git a/feature/node/src/main/res/drawable/ic_outlined_dew_point_24.xml b/core/resources/src/commonMain/composeResources/drawable/ic_dew_point.xml similarity index 100% rename from feature/node/src/main/res/drawable/ic_outlined_dew_point_24.xml rename to core/resources/src/commonMain/composeResources/drawable/ic_dew_point.xml diff --git a/feature/node/src/main/res/drawable/ic_filled_radioactive_24.xml b/core/resources/src/commonMain/composeResources/drawable/ic_radioactive.xml similarity index 100% rename from feature/node/src/main/res/drawable/ic_filled_radioactive_24.xml rename to core/resources/src/commonMain/composeResources/drawable/ic_radioactive.xml diff --git a/feature/node/src/main/res/drawable/soil_moisture.xml b/core/resources/src/commonMain/composeResources/drawable/ic_soil_moisture.xml similarity index 100% rename from feature/node/src/main/res/drawable/soil_moisture.xml rename to core/resources/src/commonMain/composeResources/drawable/ic_soil_moisture.xml diff --git a/feature/node/src/main/res/drawable/soil_temperature.xml b/core/resources/src/commonMain/composeResources/drawable/ic_soil_temperature.xml similarity index 100% rename from feature/node/src/main/res/drawable/soil_temperature.xml rename to core/resources/src/commonMain/composeResources/drawable/ic_soil_temperature.xml diff --git a/feature/node/src/main/res/drawable/unverified.xml b/core/resources/src/commonMain/composeResources/drawable/ic_unverified.xml similarity index 100% rename from feature/node/src/main/res/drawable/unverified.xml rename to core/resources/src/commonMain/composeResources/drawable/ic_unverified.xml diff --git a/feature/node/src/main/res/drawable/hw_unknown.xml b/core/resources/src/commonMain/composeResources/drawable/img_hw_unknown.xml similarity index 100% rename from feature/node/src/main/res/drawable/hw_unknown.xml rename to core/resources/src/commonMain/composeResources/drawable/img_hw_unknown.xml diff --git a/core/ui/src/main/res/drawable-nodpi/qrcode.png b/core/resources/src/commonMain/composeResources/drawable/img_qrcode.png similarity index 100% rename from core/ui/src/main/res/drawable-nodpi/qrcode.png rename to core/resources/src/commonMain/composeResources/drawable/img_qrcode.png diff --git a/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/MapView.kt b/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/MapView.kt index d1c2dc20f4..7304fa4f28 100644 --- a/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/MapView.kt +++ b/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/MapView.kt @@ -131,6 +131,8 @@ import org.meshtastic.feature.map.component.CacheLayout import org.meshtastic.feature.map.component.DownloadButton import org.meshtastic.feature.map.component.EditWaypointDialog import org.meshtastic.feature.map.component.MapButton +import org.meshtastic.feature.map.R + import org.meshtastic.feature.map.model.CustomTileSource import org.meshtastic.feature.map.model.MarkerWithLabel import org.meshtastic.feature.map.model.TracerouteOverlay @@ -281,17 +283,18 @@ fun MapView( scope.launch { context.showToast(Res.string.location_disabled) } return } + Logger.d { "user clicked MyLocationNewOverlay ${myLocationOverlay == null}" } if (myLocationOverlay == null) { myLocationOverlay = MyLocationNewOverlay(this).apply { enableMyLocation() enableFollowLocation() - getBitmapFromVectorDrawable(context, org.meshtastic.core.ui.R.drawable.ic_map_location_dot)?.let { + getBitmapFromVectorDrawable(context, R.drawable.ic_map_location_dot)?.let { setPersonIcon(it) setPersonAnchor(0.5f, 0.5f) } - getBitmapFromVectorDrawable(context, org.meshtastic.core.ui.R.drawable.ic_map_navigation)?.let { + getBitmapFromVectorDrawable(context, R.drawable.ic_map_navigation)?.let { setDirectionIcon(it) setDirectionAnchor(0.5f, 0.5f) } @@ -388,7 +391,7 @@ fun MapView( var hasCenteredTraceroute by remember(tracerouteOverlay) { mutableStateOf(false) } val markerIcon = remember { - AppCompatResources.getDrawable(context, org.meshtastic.core.ui.R.drawable.ic_location_on) + AppCompatResources.getDrawable(context, R.drawable.ic_location_on) } fun MapView.onNodesChanged(nodes: Collection): List { diff --git a/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/MapViewExtensions.kt b/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/MapViewExtensions.kt index 16336acff8..c2c511b547 100644 --- a/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/MapViewExtensions.kt +++ b/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/MapViewExtensions.kt @@ -24,8 +24,9 @@ import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.core.content.ContextCompat -import org.meshtastic.core.ui.R import org.meshtastic.proto.Position +import org.meshtastic.feature.map.R + import org.osmdroid.util.GeoPoint import org.osmdroid.views.MapView import org.osmdroid.views.overlay.CopyrightOverlay diff --git a/feature/map/src/fdroid/res/drawable/ic_location_on.xml b/feature/map/src/fdroid/res/drawable/ic_location_on.xml new file mode 100644 index 0000000000..3bf5b7133f --- /dev/null +++ b/feature/map/src/fdroid/res/drawable/ic_location_on.xml @@ -0,0 +1,14 @@ + + + + diff --git a/feature/map/src/fdroid/res/drawable/ic_map_location_dot.xml b/feature/map/src/fdroid/res/drawable/ic_map_location_dot.xml new file mode 100644 index 0000000000..2fb6587cc7 --- /dev/null +++ b/feature/map/src/fdroid/res/drawable/ic_map_location_dot.xml @@ -0,0 +1,11 @@ + + + diff --git a/feature/map/src/fdroid/res/drawable/ic_map_navigation.xml b/feature/map/src/fdroid/res/drawable/ic_map_navigation.xml new file mode 100644 index 0000000000..6557bb984d --- /dev/null +++ b/feature/map/src/fdroid/res/drawable/ic_map_navigation.xml @@ -0,0 +1,11 @@ + + + diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/DeviceDetailsSection.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/DeviceDetailsSection.kt index e4720f2f1f..770a5e9279 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/DeviceDetailsSection.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/DeviceDetailsSection.kt @@ -47,6 +47,9 @@ import coil3.request.ImageRequest import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.model.DeviceHardware import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.ic_unverified +import org.meshtastic.core.resources.img_hw_unknown + import org.meshtastic.core.resources.device import org.meshtastic.core.resources.hardware import org.meshtastic.core.resources.supported @@ -119,7 +122,7 @@ private fun SupportStatusItem(isSupported: Boolean) { if (isSupported) { Icons.TwoTone.Verified } else { - ImageVector.vectorResource(org.meshtastic.feature.node.R.drawable.unverified) + org.jetbrains.compose.resources.vectorResource(org.meshtastic.core.resources.Res.drawable.ic_unverified) }, leadingIconTint = if (isSupported) colorScheme.StatusGreen else colorScheme.StatusRed, trailingIcon = null, @@ -134,9 +137,9 @@ private fun DeviceHardwareImage(deviceHardware: DeviceHardware, modifier: Modifi model = ImageRequest.Builder(LocalContext.current).data(imageUrl).build(), contentScale = ContentScale.Inside, contentDescription = deviceHardware.displayName, - placeholder = painterResource(org.meshtastic.feature.node.R.drawable.hw_unknown), - error = painterResource(org.meshtastic.feature.node.R.drawable.hw_unknown), - fallback = painterResource(org.meshtastic.feature.node.R.drawable.hw_unknown), + placeholder = org.jetbrains.compose.resources.painterResource(org.meshtastic.core.resources.Res.drawable.img_hw_unknown), + error = org.jetbrains.compose.resources.painterResource(org.meshtastic.core.resources.Res.drawable.img_hw_unknown), + fallback = org.jetbrains.compose.resources.painterResource(org.meshtastic.core.resources.Res.drawable.img_hw_unknown), modifier = modifier.padding(16.dp), ) } diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/EnvironmentMetrics.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/EnvironmentMetrics.kt index c8157ebdcb..7fd76e7096 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/EnvironmentMetrics.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/EnvironmentMetrics.kt @@ -47,6 +47,10 @@ import org.meshtastic.core.resources.distance import org.meshtastic.core.resources.gas_resistance import org.meshtastic.core.resources.humidity import org.meshtastic.core.resources.iaq +import org.meshtastic.core.resources.ic_dew_point +import org.meshtastic.core.resources.ic_radioactive +import org.meshtastic.core.resources.ic_soil_moisture +import org.meshtastic.core.resources.ic_soil_temperature import org.meshtastic.core.resources.lux import org.meshtastic.core.resources.pressure import org.meshtastic.core.resources.radiation @@ -136,7 +140,7 @@ internal fun EnvironmentMetrics( DrawableMetricInfo( Res.string.dew_point, dewPoint.toTempString(isFahrenheit), - org.meshtastic.feature.node.R.drawable.ic_outlined_dew_point_24, + Res.drawable.ic_dew_point, ), ) } @@ -147,7 +151,7 @@ internal fun EnvironmentMetrics( DrawableMetricInfo( Res.string.soil_temperature, st.toTempString(isFahrenheit), - org.meshtastic.feature.node.R.drawable.soil_temperature, + Res.drawable.ic_soil_temperature, ), ) } @@ -157,7 +161,7 @@ internal fun EnvironmentMetrics( DrawableMetricInfo( Res.string.soil_moisture, "%d%%".format(sm), - org.meshtastic.feature.node.R.drawable.soil_moisture, + Res.drawable.ic_soil_moisture, ), ) } @@ -166,7 +170,7 @@ internal fun EnvironmentMetrics( DrawableMetricInfo( Res.string.radiation, "%.1f µR/h".format(r), - org.meshtastic.feature.node.R.drawable.ic_filled_radioactive_24, + Res.drawable.ic_radioactive, ), ) } diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/InfoCard.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/InfoCard.kt index 70681012e3..b6e652061c 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/InfoCard.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/InfoCard.kt @@ -48,6 +48,8 @@ import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.semantics import androidx.compose.ui.unit.dp import kotlinx.coroutines.launch +import org.jetbrains.compose.resources.DrawableResource +import org.jetbrains.compose.resources.painterResource import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.resources.Res import org.meshtastic.core.resources.copy @@ -58,9 +60,9 @@ import org.meshtastic.core.ui.util.thenIf fun InfoCard( text: String, value: String, - icon: ImageVector? = null, - @DrawableRes iconRes: Int? = null, modifier: Modifier = Modifier, + icon: ImageVector? = null, + iconRes: DrawableResource? = null, rotateIcon: Float = 0f, ) { val clipboard: Clipboard = LocalClipboard.current @@ -120,6 +122,6 @@ fun InfoCard( } @Composable -internal fun DrawableInfoCard(@DrawableRes iconRes: Int, text: String, value: String, rotateIcon: Float = 0f) { +internal fun DrawableInfoCard(iconRes: DrawableResource, text: String, value: String, rotateIcon: Float = 0f) { InfoCard(iconRes = iconRes, text = text, value = value, rotateIcon = rotateIcon) } diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/model/MetricInfo.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/model/MetricInfo.kt index fd612abcdb..1cd3170d32 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/model/MetricInfo.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/model/MetricInfo.kt @@ -17,8 +17,8 @@ package org.meshtastic.feature.node.model -import androidx.annotation.DrawableRes import androidx.compose.ui.graphics.vector.ImageVector +import org.jetbrains.compose.resources.DrawableResource import org.jetbrains.compose.resources.StringResource internal data class VectorMetricInfo( @@ -31,6 +31,6 @@ internal data class VectorMetricInfo( internal data class DrawableMetricInfo( val label: StringResource, val value: String, - @DrawableRes val icon: Int, + val icon: DrawableResource, val rotateIcon: Float = 0f, ) From c11deffa9a55e301d2f13e6b8c835723f23a0020 Mon Sep 17 00:00:00 2001 From: James Rich <2199651+jamesarich@users.noreply.github.com> Date: Sun, 22 Feb 2026 14:03:34 -0600 Subject: [PATCH 12/18] chore: remove duplicate string resource and finalize map view fixes --- app/src/main/res/values/strings.xml | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 app/src/main/res/values/strings.xml diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml deleted file mode 100644 index a7f9760aee..0000000000 --- a/app/src/main/res/values/strings.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - Meshtastic - From 2720685c521b654739ea598956215ed955ee95cc Mon Sep 17 00:00:00 2001 From: James Rich <2199651+jamesarich@users.noreply.github.com> Date: Sun, 22 Feb 2026 14:09:26 -0600 Subject: [PATCH 13/18] docs: update AGENTS.md and CONTRIBUTING.md with new core:resources architecture --- AGENTS.md | 12 +++++++++--- CONTRIBUTING.md | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 2d1705a95c..69027f403e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -32,8 +32,8 @@ This file serves as a comprehensive guide for AI agents and developers working o - **Material 3:** The app uses Material 3. Look for ways to use **Material 3 Expressive** components where appropriate. - **Strings:** - Do **not** use `app/src/main/res/values/strings.xml` for UI strings. - - Use the **Compose Multiplatform Resource** library in `core/strings`. - - **Definition:** Add strings to `core/strings/src/commonMain/composeResources/values/strings.xml`. + - Use the **Compose Multiplatform Resource** library in `core:resources`. + - **Definition:** Add strings to `core/resources/src/commonMain/composeResources/values/strings.xml`. - **Usage:** ```kotlin import org.jetbrains.compose.resources.stringResource @@ -102,7 +102,7 @@ This file serves as a comprehensive guide for AI agents and developers working o 1. **Explore First:** Before making changes, read `gradle/libs.versions.toml` and the relevant `build.gradle.kts` to understand the environment. 2. **Plan:** Identify which modules (`core` or `feature`) need modification. 3. **Implement:** - - If adding a string, modify `core/strings`. + - If adding a string, modify `core:resources`. - If adding a dependency, modify `libs.versions.toml` first. 4. **Verify:** - Run `./gradlew spotlessApply` (Essential!). @@ -123,3 +123,9 @@ This file serves as a comprehensive guide for AI agents and developers working o --- *Refer to `CONTRIBUTING.md` for human-centric processes like Code of Conduct and Pull Request etiquette.* + +### E. Resources and Assets +- **Centralization:** All global app resources (Strings, Drawables, Fonts, raw files) should be placed in `:core:resources`. +- **Module Path:** `core/resources/src/commonMain/composeResources/` +- **Decentralization:** Feature-specific strings and assets can (and should) be housed in their respective feature module's `composeResources` directory to maintain modular boundaries and clean architectural dependency graphs. Crowdin localization handles globbing `/**/composeResources/values/strings.xml` perfectly. +- **Drawables:** Use `painterResource(Res.drawable.your_icon)` to access cross-platform drawables. Name them consistently (`ic_` for icons, `img_` for artwork). Avoid putting standard Drawables or Vectors in legacy Android `res/drawable` folders unless strictly required by a legacy library (like `OsmDroid` map markers) or the OS layer (like `app_icon.xml`). diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index be72c6fae0..d64fe9976d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -21,7 +21,7 @@ Thank you for your interest in contributing to Meshtastic-Android! We welcome co - Keep methods and classes focused and concise. - **Strings:** Use localised strings via the **Compose Multiplatform Resource** library in `:core:resources`. - Do **not** use the legacy `app/src/main/res/values/strings.xml`. - - **Definition:** Add strings to `core/strings/src/commonMain/composeResources/values/strings.xml`. + - **Definition:** Add strings to `core/resources/src/commonMain/composeResources/values/strings.xml`. - **Usage:** ```kotlin import org.jetbrains.compose.resources.stringResource From a1ca1271b6bf6853c8985ede17fd179da9790739 Mon Sep 17 00:00:00 2001 From: James Rich <2199651+jamesarich@users.noreply.github.com> Date: Sun, 22 Feb 2026 18:39:40 -0600 Subject: [PATCH 14/18] refactor(testing): Remove obsolete `GetDiscoveredDevicesUseCaseTest` and `NordicBleInterfaceDrainTest` This commit removes two test files that are no longer necessary. `GetDiscoveredDevicesUseCaseTest` has been made obsolete by more comprehensive and robust end-to-end (E2E) tests that cover the device discovery functionality more effectively. `NordicBleInterfaceDrainTest` is also removed. Its functionality for testing packet draining has been superseded and integrated into the broader E2E testing framework, making this specialized test redundant. Additionally, a minor Kotlin syntax update was made in `BluetoothRepository.kt`, changing an explicit property getter to a computed property for the `state` variable. Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com> --- .../GetDiscoveredDevicesUseCaseTest.kt | 101 ----------- .../radio/NordicBleInterfaceDrainTest.kt | 161 ------------------ .../core/ble/BluetoothRepository.kt | 2 +- 3 files changed, 1 insertion(+), 263 deletions(-) delete mode 100644 app/src/test/java/com/geeksville/mesh/domain/usecase/GetDiscoveredDevicesUseCaseTest.kt delete mode 100644 app/src/test/java/com/geeksville/mesh/repository/radio/NordicBleInterfaceDrainTest.kt diff --git a/app/src/test/java/com/geeksville/mesh/domain/usecase/GetDiscoveredDevicesUseCaseTest.kt b/app/src/test/java/com/geeksville/mesh/domain/usecase/GetDiscoveredDevicesUseCaseTest.kt deleted file mode 100644 index 319db5cf80..0000000000 --- a/app/src/test/java/com/geeksville/mesh/domain/usecase/GetDiscoveredDevicesUseCaseTest.kt +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2025-2026 Meshtastic LLC - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.geeksville.mesh.domain.usecase - -import android.hardware.usb.UsbManager -import com.geeksville.mesh.repository.network.NetworkRepository -import com.geeksville.mesh.repository.radio.RadioInterfaceService -import com.geeksville.mesh.repository.usb.UsbRepository -import io.mockk.every -import io.mockk.mockk -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.first -import kotlinx.coroutines.test.runTest -import org.junit.Assert.assertEquals -import org.junit.Before -import org.junit.Test -import org.meshtastic.core.ble.BluetoothRepository -import org.meshtastic.core.ble.BluetoothState -import org.meshtastic.core.data.repository.NodeRepository -import org.meshtastic.core.database.DatabaseManager -import org.meshtastic.core.datastore.RecentAddressesDataSource - -class GetDiscoveredDevicesUseCaseTest { - - private lateinit var bluetoothRepository: BluetoothRepository - private lateinit var networkRepository: NetworkRepository - private lateinit var recentAddressesDataSource: RecentAddressesDataSource - private lateinit var nodeRepository: NodeRepository - private lateinit var databaseManager: DatabaseManager - private lateinit var usbRepository: UsbRepository - private lateinit var radioInterfaceService: RadioInterfaceService - private lateinit var usbManagerLazy: dagger.Lazy - private lateinit var useCase: GetDiscoveredDevicesUseCase - - @Before - fun setUp() { - bluetoothRepository = mockk() - networkRepository = mockk() - recentAddressesDataSource = mockk(relaxed = true) - nodeRepository = mockk() - databaseManager = mockk(relaxed = true) - usbRepository = mockk() - radioInterfaceService = mockk() - usbManagerLazy = mockk() - - useCase = - GetDiscoveredDevicesUseCase( - bluetoothRepository = bluetoothRepository, - networkRepository = networkRepository, - recentAddressesDataSource = recentAddressesDataSource, - nodeRepository = nodeRepository, - databaseManager = databaseManager, - usbRepository = usbRepository, - radioInterfaceService = radioInterfaceService, - usbManagerLazy = usbManagerLazy, - ) - - // Default empty flows - every { bluetoothRepository.state } returns MutableStateFlow(BluetoothState()) - every { networkRepository.resolvedList } returns MutableStateFlow(emptyList()) - every { recentAddressesDataSource.recentAddresses } returns MutableStateFlow(emptyList()) - every { nodeRepository.nodeDBbyNum } returns MutableStateFlow(emptyMap()) - every { usbRepository.serialDevices } returns MutableStateFlow(emptyMap()) - } - - @Test - fun `invoke returns discovered devices with mock if enabled`() = runTest { - // Act - val result = useCase.invoke(showMock = true).first() - - // Assert - assertEquals(1, result.usbDevices.size) // The Demo Mode mock device - assertEquals("Demo Mode", result.usbDevices.first().name) - } - - @Test - fun `invoke returns empty lists when no devices are discovered`() = runTest { - // Act - val result = useCase.invoke(showMock = false).first() - - // Assert - assertEquals(0, result.bleDevices.size) - assertEquals(0, result.usbDevices.size) - assertEquals(0, result.discoveredTcpDevices.size) - assertEquals(0, result.recentTcpDevices.size) - } -} diff --git a/app/src/test/java/com/geeksville/mesh/repository/radio/NordicBleInterfaceDrainTest.kt b/app/src/test/java/com/geeksville/mesh/repository/radio/NordicBleInterfaceDrainTest.kt deleted file mode 100644 index b914cb7f7f..0000000000 --- a/app/src/test/java/com/geeksville/mesh/repository/radio/NordicBleInterfaceDrainTest.kt +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (c) 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 . - */ -package com.geeksville.mesh.repository.radio - -import io.mockk.clearMocks -import io.mockk.mockk -import io.mockk.verify -import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.delay -import kotlinx.coroutines.test.StandardTestDispatcher -import kotlinx.coroutines.test.runTest -import no.nordicsemi.kotlin.ble.client.android.CentralManager -import no.nordicsemi.kotlin.ble.client.android.mock.mock -import no.nordicsemi.kotlin.ble.client.mock.ConnectionResult -import no.nordicsemi.kotlin.ble.client.mock.PeripheralSpec -import no.nordicsemi.kotlin.ble.client.mock.PeripheralSpecEventHandler -import no.nordicsemi.kotlin.ble.client.mock.Proximity -import no.nordicsemi.kotlin.ble.client.mock.ReadResponse -import no.nordicsemi.kotlin.ble.client.mock.WriteResponse -import no.nordicsemi.kotlin.ble.client.mock.internal.MockRemoteCharacteristic -import no.nordicsemi.kotlin.ble.core.CharacteristicProperty -import no.nordicsemi.kotlin.ble.core.LegacyAdvertisingSetParameters -import no.nordicsemi.kotlin.ble.core.Permission -import no.nordicsemi.kotlin.ble.environment.android.mock.MockAndroidEnvironment -import org.junit.Test -import org.meshtastic.core.ble.MeshtasticBleConstants.FROMNUM_CHARACTERISTIC -import org.meshtastic.core.ble.MeshtasticBleConstants.FROMRADIO_CHARACTERISTIC -import org.meshtastic.core.ble.MeshtasticBleConstants.LOGRADIO_CHARACTERISTIC -import org.meshtastic.core.ble.MeshtasticBleConstants.SERVICE_UUID -import org.meshtastic.core.ble.MeshtasticBleConstants.TORADIO_CHARACTERISTIC -import kotlin.time.Duration.Companion.milliseconds - -@OptIn(ExperimentalCoroutinesApi::class) -class NordicBleInterfaceDrainTest { - - private val testDispatcher = StandardTestDispatcher() - private val address = "00:11:22:33:44:55" - - @Test - fun `drainPacketQueueAndDispatch reads multiple packets until empty`() = runTest(testDispatcher) { - val mockEnvironment = MockAndroidEnvironment.Api31(isBluetoothEnabled = true) - val centralManager = CentralManager.mock(mockEnvironment, scope = backgroundScope) - val service = mockk(relaxed = true) - - var fromRadioHandle: Int = -1 - var fromNumHandle: Int = -1 - val packetsToRead = mutableListOf(byteArrayOf(0x01), byteArrayOf(0x02), byteArrayOf(0x03)) - - val eventHandler = - object : PeripheralSpecEventHandler { - override fun onConnectionRequest(preferredPhy: List) = - ConnectionResult.Accept - - override fun onReadRequest(characteristic: MockRemoteCharacteristic): ReadResponse { - if (characteristic.instanceId == fromRadioHandle) { - return if (packetsToRead.isNotEmpty()) { - val p = packetsToRead.removeAt(0) - println("Mock: Returning packet ${p.contentToString()}") - ReadResponse.Success(p) - } else { - println("Mock: Queue empty, returning empty") - ReadResponse.Success(byteArrayOf()) - } - } - return ReadResponse.Success(byteArrayOf()) - } - - override fun onWriteRequest(characteristic: MockRemoteCharacteristic, value: ByteArray) = - WriteResponse.Success - } - - val peripheralSpec = - PeripheralSpec.simulatePeripheral(identifier = address, proximity = Proximity.IMMEDIATE) { - advertising( - parameters = LegacyAdvertisingSetParameters(connectable = true, interval = 100.milliseconds), - ) { - CompleteLocalName("Meshtastic_Drain") - } - connectable( - name = "Meshtastic_Drain", - isBonded = true, - eventHandler = eventHandler, - cachedServices = { - Service(uuid = SERVICE_UUID) { - Characteristic( - uuid = TORADIO_CHARACTERISTIC, - properties = - setOf( - CharacteristicProperty.WRITE, - CharacteristicProperty.WRITE_WITHOUT_RESPONSE, - ), - permission = Permission.WRITE, - ) - fromNumHandle = - Characteristic( - uuid = FROMNUM_CHARACTERISTIC, - properties = setOf(CharacteristicProperty.NOTIFY), - permission = Permission.READ, - ) - fromRadioHandle = - Characteristic( - uuid = FROMRADIO_CHARACTERISTIC, - properties = setOf(CharacteristicProperty.READ), - permission = Permission.READ, - ) - Characteristic( - uuid = LOGRADIO_CHARACTERISTIC, - properties = setOf(CharacteristicProperty.NOTIFY), - permission = Permission.READ, - ) - } - }, - ) - } - - centralManager.simulatePeripherals(listOf(peripheralSpec)) - - val nordicInterface = - NordicBleInterface( - serviceScope = this, - centralManager = centralManager, - service = service, - address = address, - ) - - // Wait for connection - delay(2000.milliseconds) - verify(timeout = 5000) { service.onConnect() } - clearMocks(service, answers = false, recordedCalls = true) - - // Trigger drain - println("Simulating FromNum notification...") - peripheralSpec.simulateValueUpdate(fromNumHandle, byteArrayOf(0x01)) - - // Wait for all packets to be processed - delay(2000.milliseconds) - - // Verify handleFromRadio was called 3 times - verify(timeout = 2000) { service.handleFromRadio(p = byteArrayOf(0x01)) } - verify(timeout = 2000) { service.handleFromRadio(p = byteArrayOf(0x02)) } - verify(timeout = 2000) { service.handleFromRadio(p = byteArrayOf(0x03)) } - - assert(packetsToRead.isEmpty()) { "All packets should have been read" } - - nordicInterface.close() - } -} diff --git a/core/ble/src/main/kotlin/org/meshtastic/core/ble/BluetoothRepository.kt b/core/ble/src/main/kotlin/org/meshtastic/core/ble/BluetoothRepository.kt index a22e0729ef..021906c0d6 100644 --- a/core/ble/src/main/kotlin/org/meshtastic/core/ble/BluetoothRepository.kt +++ b/core/ble/src/main/kotlin/org/meshtastic/core/ble/BluetoothRepository.kt @@ -53,7 +53,7 @@ constructor( hasPermissions = true, ), ) - val state: StateFlow = _state.asStateFlow() + val state: StateFlow get() = _state.asStateFlow() init { processLifecycle.coroutineScope.launch(dispatchers.default) { From b6b42470b78963d59119c79bb9c0742af4a667f9 Mon Sep 17 00:00:00 2001 From: James Rich <2199651+jamesarich@users.noreply.github.com> Date: Sun, 22 Feb 2026 18:43:30 -0600 Subject: [PATCH 15/18] spotless Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com> --- .../meshtastic/core/ble/BluetoothRepository.kt | 3 ++- .../org/meshtastic/feature/map/MapView.kt | 6 +----- .../meshtastic/feature/map/MapViewExtensions.kt | 2 -- .../node/component/DeviceDetailsSection.kt | 17 ++++++++--------- .../node/component/EnvironmentMetrics.kt | 6 +++--- .../feature/node/component/InfoCard.kt | 2 -- .../meshtastic/feature/node/model/MetricInfo.kt | 3 +-- 7 files changed, 15 insertions(+), 24 deletions(-) diff --git a/core/ble/src/main/kotlin/org/meshtastic/core/ble/BluetoothRepository.kt b/core/ble/src/main/kotlin/org/meshtastic/core/ble/BluetoothRepository.kt index 021906c0d6..e58e804b68 100644 --- a/core/ble/src/main/kotlin/org/meshtastic/core/ble/BluetoothRepository.kt +++ b/core/ble/src/main/kotlin/org/meshtastic/core/ble/BluetoothRepository.kt @@ -53,7 +53,8 @@ constructor( hasPermissions = true, ), ) - val state: StateFlow get() = _state.asStateFlow() + val state: StateFlow + get() = _state.asStateFlow() init { processLifecycle.coroutineScope.launch(dispatchers.default) { diff --git a/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/MapView.kt b/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/MapView.kt index 7304fa4f28..7f63d2b637 100644 --- a/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/MapView.kt +++ b/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/MapView.kt @@ -131,8 +131,6 @@ import org.meshtastic.feature.map.component.CacheLayout import org.meshtastic.feature.map.component.DownloadButton import org.meshtastic.feature.map.component.EditWaypointDialog import org.meshtastic.feature.map.component.MapButton -import org.meshtastic.feature.map.R - import org.meshtastic.feature.map.model.CustomTileSource import org.meshtastic.feature.map.model.MarkerWithLabel import org.meshtastic.feature.map.model.TracerouteOverlay @@ -390,9 +388,7 @@ fun MapView( val traceroutePolylines = remember { mutableStateListOf() } var hasCenteredTraceroute by remember(tracerouteOverlay) { mutableStateOf(false) } - val markerIcon = remember { - AppCompatResources.getDrawable(context, R.drawable.ic_location_on) - } + val markerIcon = remember { AppCompatResources.getDrawable(context, R.drawable.ic_location_on) } fun MapView.onNodesChanged(nodes: Collection): List { val nodesWithPosition = nodes.filter { it.validPosition != null } diff --git a/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/MapViewExtensions.kt b/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/MapViewExtensions.kt index c2c511b547..52ae76c25c 100644 --- a/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/MapViewExtensions.kt +++ b/feature/map/src/fdroid/kotlin/org/meshtastic/feature/map/MapViewExtensions.kt @@ -25,8 +25,6 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.core.content.ContextCompat import org.meshtastic.proto.Position -import org.meshtastic.feature.map.R - import org.osmdroid.util.GeoPoint import org.osmdroid.views.MapView import org.osmdroid.views.overlay.CopyrightOverlay diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/DeviceDetailsSection.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/DeviceDetailsSection.kt index 770a5e9279..198fdd3d35 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/DeviceDetailsSection.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/DeviceDetailsSection.kt @@ -36,22 +36,18 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.res.vectorResource import androidx.compose.ui.unit.dp import coil3.compose.AsyncImage import coil3.request.ImageRequest import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.model.DeviceHardware import org.meshtastic.core.resources.Res -import org.meshtastic.core.resources.ic_unverified -import org.meshtastic.core.resources.img_hw_unknown - import org.meshtastic.core.resources.device import org.meshtastic.core.resources.hardware +import org.meshtastic.core.resources.ic_unverified +import org.meshtastic.core.resources.img_hw_unknown import org.meshtastic.core.resources.supported import org.meshtastic.core.resources.supported_by_community import org.meshtastic.core.ui.component.ListItem @@ -137,9 +133,12 @@ private fun DeviceHardwareImage(deviceHardware: DeviceHardware, modifier: Modifi model = ImageRequest.Builder(LocalContext.current).data(imageUrl).build(), contentScale = ContentScale.Inside, contentDescription = deviceHardware.displayName, - placeholder = org.jetbrains.compose.resources.painterResource(org.meshtastic.core.resources.Res.drawable.img_hw_unknown), - error = org.jetbrains.compose.resources.painterResource(org.meshtastic.core.resources.Res.drawable.img_hw_unknown), - fallback = org.jetbrains.compose.resources.painterResource(org.meshtastic.core.resources.Res.drawable.img_hw_unknown), + placeholder = + org.jetbrains.compose.resources.painterResource(org.meshtastic.core.resources.Res.drawable.img_hw_unknown), + error = + org.jetbrains.compose.resources.painterResource(org.meshtastic.core.resources.Res.drawable.img_hw_unknown), + fallback = + org.jetbrains.compose.resources.painterResource(org.meshtastic.core.resources.Res.drawable.img_hw_unknown), modifier = modifier.padding(16.dp), ) } diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/EnvironmentMetrics.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/EnvironmentMetrics.kt index 7fd76e7096..05cfd5fc53 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/EnvironmentMetrics.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/EnvironmentMetrics.kt @@ -168,9 +168,9 @@ internal fun EnvironmentMetrics( radiation?.let { r -> add( DrawableMetricInfo( - Res.string.radiation, - "%.1f µR/h".format(r), - Res.drawable.ic_radioactive, + label = Res.string.radiation, + value = "%.1f µR/h".format(r), + icon = Res.drawable.ic_radioactive, ), ) } diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/InfoCard.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/InfoCard.kt index b6e652061c..927f375927 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/InfoCard.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/component/InfoCard.kt @@ -17,7 +17,6 @@ package org.meshtastic.feature.node.component import android.content.ClipData -import androidx.annotation.DrawableRes import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.layout.Arrangement @@ -42,7 +41,6 @@ import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.platform.ClipEntry import androidx.compose.ui.platform.Clipboard import androidx.compose.ui.platform.LocalClipboard -import androidx.compose.ui.res.painterResource import androidx.compose.ui.semantics.Role import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.semantics diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/model/MetricInfo.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/model/MetricInfo.kt index 1cd3170d32..24d739fc5b 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/model/MetricInfo.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/model/MetricInfo.kt @@ -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 . */ - package org.meshtastic.feature.node.model import androidx.compose.ui.graphics.vector.ImageVector From fb5d0d29f01144e79cba89afe24bd4068307b622 Mon Sep 17 00:00:00 2001 From: James Rich <2199651+jamesarich@users.noreply.github.com> Date: Sun, 22 Feb 2026 19:01:12 -0600 Subject: [PATCH 16/18] refactor(core): Centralize UiText utility and improve node name resolution This commit centralizes the `UiText` utility by moving it from the `feature/settings` module to the `core/resources` module, making it accessible across the entire application. This refactoring eliminates a duplicate implementation and provides a single, consistent way to handle dynamic and resource-based strings in the UI. The `UiText.StringResource` class has been renamed to `UiText.Resource` for clarity. It now supports nested `StringResource` arguments, which are resolved recursively. A new `resolve()` suspend function has been added to allow string resolution from non-composable contexts, such as showing a snackbar. Throughout the `feature/node` module, calls to show snackbar feedback have been updated to use the new `UiText.resolve()` method. This simplifies the presentation logic in various metric and detail screens. Additionally, node name resolution has been improved. For nodes where the hardware model is not yet known, a fallback name is now generated using the last four characters of the node's ID (e.g., "Meshtastic 1a2b"). The `NodeDetailUiState` now includes a `nodeName` property of type `UiText` to handle this logic, ensuring the UI displays a meaningful name even for partially discovered nodes. Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com> --- .../org/meshtastic/core/resources/UiText.kt | 66 +++++++++++++++++++ .../feature/node/detail/NodeDetailScreen.kt | 12 ++-- .../node/detail/NodeDetailViewModel.kt | 3 + .../feature/node/detail/NodeRequestActions.kt | 23 ++++--- .../domain/usecase/GetNodeDetailsUseCase.kt | 16 +++-- .../feature/node/metrics/DeviceMetrics.kt | 3 +- .../node/metrics/EnvironmentMetrics.kt | 3 +- .../feature/node/metrics/HostMetricsLog.kt | 3 +- .../feature/node/metrics/NeighborInfoLog.kt | 5 +- .../feature/node/metrics/PaxMetrics.kt | 3 +- .../feature/node/metrics/PositionLog.kt | 3 +- .../feature/node/metrics/PowerMetrics.kt | 3 +- .../feature/node/metrics/SignalMetrics.kt | 3 +- .../feature/node/metrics/TracerouteLog.kt | 8 +-- .../settings/radio/RadioConfigViewModel.kt | 4 +- .../feature/settings/radio/ResponseState.kt | 2 +- .../feature/settings/util/UiText.kt | 34 ---------- 17 files changed, 117 insertions(+), 77 deletions(-) create mode 100644 core/resources/src/commonMain/kotlin/org/meshtastic/core/resources/UiText.kt delete mode 100644 feature/settings/src/main/kotlin/org/meshtastic/feature/settings/util/UiText.kt diff --git a/core/resources/src/commonMain/kotlin/org/meshtastic/core/resources/UiText.kt b/core/resources/src/commonMain/kotlin/org/meshtastic/core/resources/UiText.kt new file mode 100644 index 0000000000..f2dfaacb23 --- /dev/null +++ b/core/resources/src/commonMain/kotlin/org/meshtastic/core/resources/UiText.kt @@ -0,0 +1,66 @@ +/* + * 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 . + */ +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() + + @Composable + fun asString(): String = when (this) { + is DynamicString -> value + is Resource -> { + val resolvedArgs = + args.map { arg -> + if (arg is StringResource) { + stringResource(arg) + } 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 -> + if (arg is StringResource) { + getString(arg) + } else { + arg + } + } + @Suppress("SpreadOperator") + getString(res, *resolvedArgs.toTypedArray()) + } + } +} diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/detail/NodeDetailScreen.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/detail/NodeDetailScreen.kt index 77cc1cf1ce..24c00ff34f 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/detail/NodeDetailScreen.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/detail/NodeDetailScreen.kt @@ -63,7 +63,6 @@ import org.meshtastic.core.database.model.Node import org.meshtastic.core.navigation.Route import org.meshtastic.core.resources.Res import org.meshtastic.core.resources.details -import org.meshtastic.core.resources.getString import org.meshtastic.core.resources.loading import org.meshtastic.core.ui.component.MainAppBar import org.meshtastic.core.ui.component.SharedContactDialog @@ -103,17 +102,16 @@ fun NodeDetailScreen( LaunchedEffect(nodeId) { viewModel.start(nodeId) } val snackbarHostState = remember { SnackbarHostState() } + val uiState by viewModel.uiState.collectAsStateWithLifecycle() + LaunchedEffect(Unit) { viewModel.effects.collect { effect -> if (effect is NodeRequestEffect.ShowFeedback) { - @Suppress("SpreadOperator") - snackbarHostState.showSnackbar(getString(effect.resource, *effect.args.toTypedArray())) + snackbarHostState.showSnackbar(effect.text.resolve()) } } } - val uiState by viewModel.uiState.collectAsStateWithLifecycle() - NodeDetailScaffold( modifier = modifier, uiState = uiState, @@ -149,8 +147,8 @@ private fun NodeDetailScaffold( modifier = modifier, topBar = { MainAppBar( - title = getString(Res.string.details), - subtitle = node?.user?.long_name ?: "", + title = stringResource(Res.string.details), + subtitle = uiState.nodeName.asString(), ourNode = uiState.ourNode, showNodeChip = false, canNavigateUp = true, diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/detail/NodeDetailViewModel.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/detail/NodeDetailViewModel.kt index cdafba73fc..2790cd327b 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/detail/NodeDetailViewModel.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/detail/NodeDetailViewModel.kt @@ -35,6 +35,7 @@ import kotlinx.coroutines.launch import org.meshtastic.core.database.model.Node import org.meshtastic.core.model.DataPacket import org.meshtastic.core.navigation.NodesRoutes +import org.meshtastic.core.resources.UiText import org.meshtastic.core.service.ServiceAction import org.meshtastic.core.service.ServiceRepository import org.meshtastic.feature.node.component.NodeMenuAction @@ -48,6 +49,7 @@ import javax.inject.Inject * UI state for the Node Details screen. * * @property node The node being viewed, or null if loading. + * @property nodeName The display name for the node, resolved in the UI. * @property ourNode Information about the locally connected node. * @property metricsState Aggregated sensor and signal metrics. * @property environmentState Standardized environmental sensor data. @@ -58,6 +60,7 @@ import javax.inject.Inject @androidx.compose.runtime.Stable data class NodeDetailUiState( val node: Node? = null, + val nodeName: UiText = UiText.DynamicString(""), val ourNode: Node? = null, val metricsState: MetricsState = MetricsState.Empty, val environmentState: EnvironmentMetricsState = EnvironmentMetricsState(), diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/detail/NodeRequestActions.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/detail/NodeRequestActions.kt index b9d725f302..2bad12fb92 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/detail/NodeRequestActions.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/detail/NodeRequestActions.kt @@ -27,11 +27,11 @@ import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch -import org.jetbrains.compose.resources.StringResource import org.meshtastic.core.common.util.nowMillis import org.meshtastic.core.model.Position import org.meshtastic.core.model.TelemetryType import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.UiText import org.meshtastic.core.resources.neighbor_info import org.meshtastic.core.resources.position import org.meshtastic.core.resources.request_air_quality_metrics @@ -49,7 +49,7 @@ import javax.inject.Inject import javax.inject.Singleton sealed class NodeRequestEffect { - data class ShowFeedback(val resource: StringResource, val args: List = emptyList()) : NodeRequestEffect() + data class ShowFeedback(val text: UiText) : NodeRequestEffect() } @Singleton @@ -70,7 +70,9 @@ class NodeRequestActions @Inject constructor(private val serviceRepository: Serv try { serviceRepository.meshService?.requestUserInfo(destNum) _effects.emit( - NodeRequestEffect.ShowFeedback(Res.string.requesting_from, listOf(Res.string.user_info, longName)), + NodeRequestEffect.ShowFeedback( + UiText.Resource(Res.string.requesting_from, Res.string.user_info, longName), + ), ) } catch (ex: android.os.RemoteException) { Logger.e { "Request NodeInfo error: ${ex.message}" } @@ -87,8 +89,7 @@ class NodeRequestActions @Inject constructor(private val serviceRepository: Serv _lastRequestNeighborTimes.update { it + (destNum to nowMillis) } _effects.emit( NodeRequestEffect.ShowFeedback( - Res.string.requesting_from, - listOf(Res.string.neighbor_info, longName), + UiText.Resource(Res.string.requesting_from, Res.string.neighbor_info, longName), ), ) } catch (ex: android.os.RemoteException) { @@ -108,7 +109,9 @@ class NodeRequestActions @Inject constructor(private val serviceRepository: Serv try { serviceRepository.meshService?.requestPosition(destNum, position) _effects.emit( - NodeRequestEffect.ShowFeedback(Res.string.requesting_from, listOf(Res.string.position, longName)), + NodeRequestEffect.ShowFeedback( + UiText.Resource(Res.string.requesting_from, Res.string.position, longName), + ), ) } catch (ex: android.os.RemoteException) { Logger.e { "Request position error: ${ex.message}" } @@ -134,7 +137,9 @@ class NodeRequestActions @Inject constructor(private val serviceRepository: Serv TelemetryType.PAX -> Res.string.request_pax_metrics } - _effects.emit(NodeRequestEffect.ShowFeedback(Res.string.requesting_from, listOf(typeRes, longName))) + _effects.emit( + NodeRequestEffect.ShowFeedback(UiText.Resource(Res.string.requesting_from, typeRes, longName)), + ) } catch (ex: android.os.RemoteException) { Logger.e { "Request telemetry error: ${ex.message}" } } @@ -149,7 +154,9 @@ class NodeRequestActions @Inject constructor(private val serviceRepository: Serv serviceRepository.meshService?.requestTraceroute(packetId, destNum) _lastTracerouteTimes.update { it + (destNum to nowMillis) } _effects.emit( - NodeRequestEffect.ShowFeedback(Res.string.requesting_from, listOf(Res.string.traceroute, longName)), + NodeRequestEffect.ShowFeedback( + UiText.Resource(Res.string.requesting_from, Res.string.traceroute, longName), + ), ) } catch (ex: android.os.RemoteException) { Logger.e { "Request traceroute error: ${ex.message}" } diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/domain/usecase/GetNodeDetailsUseCase.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/domain/usecase/GetNodeDetailsUseCase.kt index 229a8539aa..24a26280c8 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/domain/usecase/GetNodeDetailsUseCase.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/domain/usecase/GetNodeDetailsUseCase.kt @@ -35,8 +35,8 @@ import org.meshtastic.core.model.MyNodeInfo import org.meshtastic.core.model.util.hasValidEnvironmentMetrics import org.meshtastic.core.model.util.isDirectSignal import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.UiText import org.meshtastic.core.resources.fallback_node_name -import org.meshtastic.core.resources.getString import org.meshtastic.core.ui.util.toPosition import org.meshtastic.feature.node.detail.NodeDetailUiState import org.meshtastic.feature.node.detail.NodeRequestActions @@ -46,6 +46,7 @@ import org.meshtastic.feature.node.model.MetricsState import org.meshtastic.proto.Config import org.meshtastic.proto.DeviceProfile import org.meshtastic.proto.FirmwareEdition +import org.meshtastic.proto.HardwareModel import org.meshtastic.proto.MeshPacket import org.meshtastic.proto.PortNum import org.meshtastic.proto.Telemetry @@ -72,9 +73,7 @@ constructor( @Suppress("LongMethod", "CyclomaticComplexMethod") private fun buildFlow(nodeId: Int, effectiveNodeId: Int): Flow { val nodeFlow = - nodeRepository.nodeDBbyNum - .map { it[nodeId] ?: Node.createFallback(nodeId, getString(Res.string.fallback_node_name)) } - .distinctUntilChanged() + nodeRepository.nodeDBbyNum.map { it[nodeId] ?: Node.createFallback(nodeId, "") }.distinctUntilChanged() // 1. Logs & Metrics Data val metricsLogsFlow = @@ -206,8 +205,17 @@ constructor( if (metricsState.hasPaxMetrics()) add(LogsType.PAX) } + @Suppress("MagicNumber") + val nodeName = + if (node.user.hw_model == HardwareModel.UNSET) { + UiText.Resource(Res.string.fallback_node_name, node.user.id.takeLast(4)) + } else { + UiText.DynamicString(node.user.long_name ?: "") + } + NodeDetailUiState( node = node, + nodeName = nodeName, ourNode = identity.ourNode, metricsState = metricsState, environmentState = environmentState, diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/DeviceMetrics.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/DeviceMetrics.kt index 721808e6b0..d7ee8782e9 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/DeviceMetrics.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/DeviceMetrics.kt @@ -73,7 +73,6 @@ import org.meshtastic.core.resources.battery import org.meshtastic.core.resources.ch_util_definition import org.meshtastic.core.resources.channel_utilization import org.meshtastic.core.resources.device_metrics_log -import org.meshtastic.core.resources.getString import org.meshtastic.core.resources.uptime import org.meshtastic.core.resources.voltage import org.meshtastic.core.ui.component.MaterialBatteryInfo @@ -141,7 +140,7 @@ fun DeviceMetricsScreen(viewModel: MetricsViewModel = hiltViewModel(), onNavigat when (effect) { is NodeRequestEffect.ShowFeedback -> { @Suppress("SpreadOperator") - snackbarHostState.showSnackbar(getString(effect.resource, *effect.args.toTypedArray())) + snackbarHostState.showSnackbar(effect.text.resolve()) } } } diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/EnvironmentMetrics.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/EnvironmentMetrics.kt index ecdd8268b9..cffc3d383c 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/EnvironmentMetrics.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/EnvironmentMetrics.kt @@ -55,7 +55,6 @@ import org.meshtastic.core.resources.Res import org.meshtastic.core.resources.current import org.meshtastic.core.resources.env_metrics_log import org.meshtastic.core.resources.gas_resistance -import org.meshtastic.core.resources.getString import org.meshtastic.core.resources.humidity import org.meshtastic.core.resources.iaq import org.meshtastic.core.resources.iaq_definition @@ -87,7 +86,7 @@ fun EnvironmentMetricsScreen(viewModel: MetricsViewModel = hiltViewModel(), onNa when (effect) { is NodeRequestEffect.ShowFeedback -> { @Suppress("SpreadOperator") - snackbarHostState.showSnackbar(getString(effect.resource, *effect.args.toTypedArray())) + snackbarHostState.showSnackbar(effect.text.resolve()) } } } diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/HostMetricsLog.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/HostMetricsLog.kt index d4b76e0640..c870b5e2ce 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/HostMetricsLog.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/HostMetricsLog.kt @@ -62,7 +62,6 @@ import org.meshtastic.core.model.util.formatUptime import org.meshtastic.core.resources.Res import org.meshtastic.core.resources.disk_free_indexed import org.meshtastic.core.resources.free_memory -import org.meshtastic.core.resources.getString import org.meshtastic.core.resources.load_indexed import org.meshtastic.core.resources.uptime import org.meshtastic.core.resources.user_string @@ -88,7 +87,7 @@ fun HostMetricsLogScreen(metricsViewModel: MetricsViewModel = hiltViewModel(), o when (effect) { is NodeRequestEffect.ShowFeedback -> { @Suppress("SpreadOperator") - snackbarHostState.showSnackbar(getString(effect.resource, *effect.args.toTypedArray())) + snackbarHostState.showSnackbar(effect.text.resolve()) } } } diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/NeighborInfoLog.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/NeighborInfoLog.kt index ac45d3e206..eec2f13051 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/NeighborInfoLog.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/NeighborInfoLog.kt @@ -46,7 +46,6 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import org.jetbrains.compose.resources.stringResource import org.meshtastic.core.model.getNeighborInfoResponse import org.meshtastic.core.resources.Res -import org.meshtastic.core.resources.getString import org.meshtastic.core.resources.neighbor_info import org.meshtastic.core.resources.routing_error_no_response import org.meshtastic.core.ui.component.MainAppBar @@ -77,7 +76,7 @@ fun NeighborInfoLogScreen( when (effect) { is NodeRequestEffect.ShowFeedback -> { @Suppress("SpreadOperator") - snackbarHostState.showSnackbar(getString(effect.resource, *effect.args.toTypedArray())) + snackbarHostState.showSnackbar(effect.text.resolve()) } } } @@ -151,7 +150,7 @@ fun NeighborInfoLogScreen( ?.packet ?.getNeighborInfoResponse( ::getUsername, - header = getString(Res.string.neighbor_info), + header = stringResource(Res.string.neighbor_info), ) ?.let { val message = diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/PaxMetrics.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/PaxMetrics.kt index 037214424b..f566fd088d 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/PaxMetrics.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/PaxMetrics.kt @@ -61,7 +61,6 @@ import org.meshtastic.core.model.TelemetryType import org.meshtastic.core.model.util.formatUptime import org.meshtastic.core.resources.Res import org.meshtastic.core.resources.ble_devices -import org.meshtastic.core.resources.getString import org.meshtastic.core.resources.no_pax_metrics_logs import org.meshtastic.core.resources.pax import org.meshtastic.core.resources.pax_metrics_log @@ -189,7 +188,7 @@ fun PaxMetricsScreen(metricsViewModel: MetricsViewModel = hiltViewModel(), onNav when (effect) { is NodeRequestEffect.ShowFeedback -> { @Suppress("SpreadOperator") - snackbarHostState.showSnackbar(getString(effect.resource, *effect.args.toTypedArray())) + snackbarHostState.showSnackbar(effect.text.resolve()) } } } diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/PositionLog.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/PositionLog.kt index 0a9879ee67..55d7939575 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/PositionLog.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/PositionLog.kt @@ -68,7 +68,6 @@ import org.meshtastic.core.model.util.toString import org.meshtastic.core.resources.Res import org.meshtastic.core.resources.alt import org.meshtastic.core.resources.clear -import org.meshtastic.core.resources.getString import org.meshtastic.core.resources.heading import org.meshtastic.core.resources.latitude import org.meshtastic.core.resources.longitude @@ -182,7 +181,7 @@ fun PositionLogScreen(viewModel: MetricsViewModel = hiltViewModel(), onNavigateU when (effect) { is NodeRequestEffect.ShowFeedback -> { @Suppress("SpreadOperator") - snackbarHostState.showSnackbar(getString(effect.resource, *effect.args.toTypedArray())) + snackbarHostState.showSnackbar(effect.text.resolve()) } } } diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/PowerMetrics.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/PowerMetrics.kt index 93dfba8304..bdd89a0593 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/PowerMetrics.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/PowerMetrics.kt @@ -69,7 +69,6 @@ import org.meshtastic.core.resources.channel_1 import org.meshtastic.core.resources.channel_2 import org.meshtastic.core.resources.channel_3 import org.meshtastic.core.resources.current -import org.meshtastic.core.resources.getString import org.meshtastic.core.resources.power_metrics_log import org.meshtastic.core.resources.voltage import org.meshtastic.core.ui.theme.GraphColors.Gold @@ -121,7 +120,7 @@ fun PowerMetricsScreen(viewModel: MetricsViewModel = hiltViewModel(), onNavigate when (effect) { is NodeRequestEffect.ShowFeedback -> { @Suppress("SpreadOperator") - snackbarHostState.showSnackbar(getString(effect.resource, *effect.args.toTypedArray())) + snackbarHostState.showSnackbar(effect.text.resolve()) } } } diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/SignalMetrics.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/SignalMetrics.kt index c2e90197cb..0cee152ce3 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/SignalMetrics.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/SignalMetrics.kt @@ -59,7 +59,6 @@ import com.patrykandpatrick.vico.compose.cartesian.layer.LineCartesianLayer import com.patrykandpatrick.vico.compose.cartesian.layer.rememberLineCartesianLayer import org.meshtastic.core.model.TelemetryType import org.meshtastic.core.resources.Res -import org.meshtastic.core.resources.getString import org.meshtastic.core.resources.rssi import org.meshtastic.core.resources.rssi_definition import org.meshtastic.core.resources.signal_quality @@ -98,7 +97,7 @@ fun SignalMetricsScreen(viewModel: MetricsViewModel = hiltViewModel(), onNavigat when (effect) { is NodeRequestEffect.ShowFeedback -> { @Suppress("SpreadOperator") - snackbarHostState.showSnackbar(getString(effect.resource, *effect.args.toTypedArray())) + snackbarHostState.showSnackbar(effect.text.resolve()) } } } diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/TracerouteLog.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/TracerouteLog.kt index 5d7494c6e6..f4711200b2 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/TracerouteLog.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/TracerouteLog.kt @@ -53,7 +53,6 @@ import org.meshtastic.core.common.util.nowMillis import org.meshtastic.core.model.fullRouteDiscovery import org.meshtastic.core.model.getTracerouteResponse import org.meshtastic.core.resources.Res -import org.meshtastic.core.resources.getString import org.meshtastic.core.resources.routing_error_no_response import org.meshtastic.core.resources.traceroute import org.meshtastic.core.resources.traceroute_diff @@ -98,7 +97,7 @@ fun TracerouteLogScreen( when (effect) { is NodeRequestEffect.ShowFeedback -> { @Suppress("SpreadOperator") - snackbarHostState.showSnackbar(getString(effect.resource, *effect.args.toTypedArray())) + snackbarHostState.showSnackbar(effect.text.resolve()) } } } @@ -214,8 +213,9 @@ fun TracerouteLogScreen( ?.packet ?.getTracerouteResponse( ::getUsername, - headerTowards = getString(Res.string.traceroute_route_towards_dest), - headerBack = getString(Res.string.traceroute_route_back_to_us), + headerTowards = + stringResource(Res.string.traceroute_route_towards_dest), + headerBack = stringResource(Res.string.traceroute_route_back_to_us), ) ?.let { annotateTraceroute( diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/RadioConfigViewModel.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/RadioConfigViewModel.kt index 3159b482da..3f9adf6ee3 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/RadioConfigViewModel.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/RadioConfigViewModel.kt @@ -59,6 +59,7 @@ import org.meshtastic.core.prefs.analytics.AnalyticsPrefs import org.meshtastic.core.prefs.homoglyph.HomoglyphPrefs import org.meshtastic.core.prefs.map.MapConsentPrefs import org.meshtastic.core.resources.Res +import org.meshtastic.core.resources.UiText import org.meshtastic.core.resources.cant_shutdown import org.meshtastic.core.service.ConnectionState import org.meshtastic.core.service.IMeshService @@ -66,7 +67,6 @@ import org.meshtastic.core.service.ServiceRepository import org.meshtastic.core.ui.util.getChannelList import org.meshtastic.feature.settings.navigation.ConfigRoute import org.meshtastic.feature.settings.navigation.ModuleRoute -import org.meshtastic.feature.settings.util.UiText import org.meshtastic.proto.AdminMessage import org.meshtastic.proto.Channel import org.meshtastic.proto.ChannelSettings @@ -683,7 +683,7 @@ constructor( private fun sendError(error: String) = setResponseStateError(UiText.DynamicString(error)) - private fun sendError(id: StringResource) = setResponseStateError(UiText.StringResource(id)) + private fun sendError(id: StringResource) = setResponseStateError(UiText.Resource(id)) private fun setResponseStateError(error: UiText) { _radioConfigState.update { it.copy(responseState = ResponseState.Error(error)) } diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/ResponseState.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/ResponseState.kt index 96e5e3df7c..7da3f8f35c 100644 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/ResponseState.kt +++ b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/radio/ResponseState.kt @@ -16,7 +16,7 @@ */ package org.meshtastic.feature.settings.radio -import org.meshtastic.feature.settings.util.UiText +import org.meshtastic.core.resources.UiText /** Generic sealed class defines each possible state of a response. */ sealed class ResponseState { diff --git a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/util/UiText.kt b/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/util/UiText.kt deleted file mode 100644 index a894ddfcbe..0000000000 --- a/feature/settings/src/main/kotlin/org/meshtastic/feature/settings/util/UiText.kt +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2025 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 . - */ - -package org.meshtastic.feature.settings.util - -import androidx.compose.runtime.Composable -import org.jetbrains.compose.resources.stringResource - -@Suppress("SpreadOperator") -sealed class UiText { - data class DynamicString(val value: String) : UiText() - - class StringResource(val resId: org.jetbrains.compose.resources.StringResource, vararg val args: Any) : UiText() - - @Composable - fun asString(): String = when (this) { - is DynamicString -> value - is StringResource -> stringResource(resId, *args) - } -} From 297d09d312e6f5e36ca0a2c2285b3a79c2038217 Mon Sep 17 00:00:00 2001 From: James Rich <2199651+jamesarich@users.noreply.github.com> Date: Sun, 22 Feb 2026 19:14:28 -0600 Subject: [PATCH 17/18] fix(ui): improve KMP compose resource usage, fix UiText stability, simplify UseCase flow combination --- .../org/meshtastic/core/resources/UiText.kt | 36 ++++++++++++++----- .../domain/usecase/GetNodeDetailsUseCase.kt | 18 +++------- .../feature/node/metrics/NeighborInfoLog.kt | 6 ++-- .../feature/node/metrics/TracerouteLog.kt | 11 +++--- 4 files changed, 39 insertions(+), 32 deletions(-) diff --git a/core/resources/src/commonMain/kotlin/org/meshtastic/core/resources/UiText.kt b/core/resources/src/commonMain/kotlin/org/meshtastic/core/resources/UiText.kt index f2dfaacb23..843ab7883c 100644 --- a/core/resources/src/commonMain/kotlin/org/meshtastic/core/resources/UiText.kt +++ b/core/resources/src/commonMain/kotlin/org/meshtastic/core/resources/UiText.kt @@ -28,7 +28,25 @@ import org.jetbrains.compose.resources.stringResource sealed class UiText { data class DynamicString(val value: String) : UiText() - class Resource(val res: StringResource, vararg val args: Any) : 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) { @@ -36,10 +54,10 @@ sealed class UiText { is Resource -> { val resolvedArgs = args.map { arg -> - if (arg is StringResource) { - stringResource(arg) - } else { - arg + when (arg) { + is StringResource -> stringResource(arg) + is UiText -> arg.asString() + else -> arg } } @Suppress("SpreadOperator") @@ -53,10 +71,10 @@ sealed class UiText { is Resource -> { val resolvedArgs = args.map { arg -> - if (arg is StringResource) { - getString(arg) - } else { - arg + when (arg) { + is StringResource -> getString(arg) + is UiText -> arg.resolve() + else -> arg } } @Suppress("SpreadOperator") diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/domain/usecase/GetNodeDetailsUseCase.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/domain/usecase/GetNodeDetailsUseCase.kt index 24a26280c8..665dd1af6c 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/domain/usecase/GetNodeDetailsUseCase.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/domain/usecase/GetNodeDetailsUseCase.kt @@ -46,7 +46,6 @@ import org.meshtastic.feature.node.model.MetricsState import org.meshtastic.proto.Config import org.meshtastic.proto.DeviceProfile import org.meshtastic.proto.FirmwareEdition -import org.meshtastic.proto.HardwareModel import org.meshtastic.proto.MeshPacket import org.meshtastic.proto.PortNum import org.meshtastic.proto.Telemetry @@ -126,14 +125,8 @@ constructor( firmwareReleaseRepository.alphaRelease, nodeRequestActions.lastTracerouteTimes.map { it[nodeId] }, nodeRequestActions.lastRequestNeighborTimes.map { it[nodeId] }, - ) { args: Array -> - MetadataGroup( - edition = args[0] as? FirmwareEdition, - stable = args[1] as? FirmwareRelease, - alpha = args[2] as? FirmwareRelease, - trTime = args[3] as? Long, - niTime = args[4] as? Long, - ) + ) { edition, stable, alpha, trTime, niTime -> + MetadataGroup(edition = edition, stable = stable, alpha = alpha, trTime = trTime, niTime = niTime) } // 4. Requests History (we still query request logs by the target nodeId) @@ -207,11 +200,8 @@ constructor( @Suppress("MagicNumber") val nodeName = - if (node.user.hw_model == HardwareModel.UNSET) { - UiText.Resource(Res.string.fallback_node_name, node.user.id.takeLast(4)) - } else { - UiText.DynamicString(node.user.long_name ?: "") - } + node.user.long_name?.takeIf { it.isNotBlank() }?.let { UiText.DynamicString(it) } + ?: UiText.Resource(Res.string.fallback_node_name, node.user.id.takeLast(4)) NodeDetailUiState( node = node, diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/NeighborInfoLog.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/NeighborInfoLog.kt index eec2f13051..6b9dc777f7 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/NeighborInfoLog.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/NeighborInfoLog.kt @@ -136,6 +136,7 @@ fun NeighborInfoLogScreen( ) val text = if (result != null) "Success" else stringResource(Res.string.routing_error_no_response) val icon = if (result != null) MeshtasticIcons.Groups else MeshtasticIcons.PersonOff + val header = stringResource(Res.string.neighbor_info) var expanded by remember { mutableStateOf(false) } Box { @@ -148,10 +149,7 @@ fun NeighborInfoLogScreen( result ?.fromRadio ?.packet - ?.getNeighborInfoResponse( - ::getUsername, - header = stringResource(Res.string.neighbor_info), - ) + ?.getNeighborInfoResponse(::getUsername, header = header) ?.let { val message = annotateNeighborInfo( diff --git a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/TracerouteLog.kt b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/TracerouteLog.kt index f4711200b2..0846fa7568 100644 --- a/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/TracerouteLog.kt +++ b/feature/node/src/main/kotlin/org/meshtastic/feature/node/metrics/TracerouteLog.kt @@ -141,6 +141,8 @@ fun TracerouteLogScreen( contentPadding = PaddingValues(horizontal = 16.dp), ) { items(state.tracerouteRequests, key = { it.uuid }) { log -> + val headerTowardsStr = stringResource(Res.string.traceroute_route_towards_dest) + val headerBackStr = stringResource(Res.string.traceroute_route_back_to_us) val result = remember(state.tracerouteRequests, log.fromRadio.packet?.id) { state.tracerouteResults.find { @@ -168,7 +170,7 @@ fun TracerouteLogScreen( res.fromRadio.packet?.getTracerouteResponse( ::getUsername, headerTowards = stringResource(Res.string.traceroute_route_towards_dest), - headerBack = stringResource(Res.string.traceroute_route_back_to_us), + headerBack = headerBackStr, ), statusGreen = statusGreen, statusYellow = statusYellow, @@ -185,7 +187,7 @@ fun TracerouteLogScreen( ?.getTracerouteResponse( ::getUsername, headerTowards = stringResource(Res.string.traceroute_route_towards_dest), - headerBack = stringResource(Res.string.traceroute_route_back_to_us), + headerBack = headerBackStr, ) ?.let { AnnotatedString(it) } } @@ -213,9 +215,8 @@ fun TracerouteLogScreen( ?.packet ?.getTracerouteResponse( ::getUsername, - headerTowards = - stringResource(Res.string.traceroute_route_towards_dest), - headerBack = stringResource(Res.string.traceroute_route_back_to_us), + headerTowards = headerTowardsStr, + headerBack = headerBackStr, ) ?.let { annotateTraceroute( From a456df8e5dbfd1af12abd01886602e29a0bc0f0f Mon Sep 17 00:00:00 2001 From: James Rich <2199651+jamesarich@users.noreply.github.com> Date: Sun, 22 Feb 2026 21:24:23 -0600 Subject: [PATCH 18/18] fix(test): Prevent service crash in tests before Hilt is ready Catches an `IllegalStateException` that can be thrown during `MeshService.onCreate()` in a testing environment. This issue occurs if the service is started by the Android system (for example, after a crash or on boot) before the `HiltAndroidRule` has initialized the necessary Hilt components for the test. The fix specifically checks if the exception message contains "HiltAndroidRule". If it does, the exception is logged as a warning, and `stopSelf()` is called to gracefully shut down the service, preventing the test from crashing. If the exception is unrelated to Hilt, it is re-thrown. Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com> --- .../com/geeksville/mesh/service/MeshService.kt | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt index 34e1adf4da..db1a6066ff 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt @@ -107,7 +107,19 @@ class MeshService : Service() { } override fun onCreate() { - super.onCreate() + try { + super.onCreate() + } catch (e: IllegalStateException) { + // Hilt can throw IllegalStateException in tests if the component is not created. + // This can happen if the service is started by the system (e.g. after a crash or on boot) + // before the test rule has a chance to create the component. + if (e.message?.contains("HiltAndroidRule") == true) { + Logger.w(e) { "MeshService created before Hilt component was ready in test. Stopping service." } + stopSelf() + return + } + throw e + } Logger.i { "Creating mesh service" } serviceNotifications.initChannels()