diff --git a/app/src/main/java/com/geeksville/mesh/MainActivity.kt b/app/src/main/java/com/geeksville/mesh/MainActivity.kt index 888c35074..812c6e001 100644 --- a/app/src/main/java/com/geeksville/mesh/MainActivity.kt +++ b/app/src/main/java/com/geeksville/mesh/MainActivity.kt @@ -25,6 +25,7 @@ import android.hardware.usb.UsbManager import android.net.Uri import android.os.Build import android.os.Bundle +import android.widget.Toast import androidx.activity.SystemBarStyle import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge @@ -44,6 +45,7 @@ import com.geeksville.mesh.ui.MainScreen import dagger.hilt.android.AndroidEntryPoint import org.meshtastic.core.datastore.UiPreferencesDataSource import org.meshtastic.core.navigation.DEEP_LINK_BASE_URI +import org.meshtastic.core.strings.R import org.meshtastic.core.ui.theme.AppTheme import org.meshtastic.core.ui.theme.MODE_DYNAMIC import org.meshtastic.feature.intro.AppIntroductionScreen @@ -115,10 +117,16 @@ class MainActivity : AppCompatActivity() { Timber.d("App link data: $it") if (it.path?.startsWith("/e/") == true || it.path?.startsWith("/E/") == true) { Timber.d("App link data is a channel set") - model.requestChannelUrl(it) + model.requestChannelUrl( + url = it, + onFailure = { Toast.makeText(this, R.string.channel_invalid, Toast.LENGTH_SHORT).show() }, + ) } else if (it.path?.startsWith("/v/") == true || it.path?.startsWith("/V/") == true) { Timber.d("App link data is a shared contact") - model.setSharedContactRequested(it) + model.setSharedContactRequested( + url = it, + onFailure = { Toast.makeText(this, R.string.contact_invalid, Toast.LENGTH_SHORT).show() }, + ) } else { Timber.d("App link data is not a channel set") } diff --git a/app/src/main/java/com/geeksville/mesh/model/UIState.kt b/app/src/main/java/com/geeksville/mesh/model/UIState.kt index 4a0ae5954..5d3e56939 100644 --- a/app/src/main/java/com/geeksville/mesh/model/UIState.kt +++ b/app/src/main/java/com/geeksville/mesh/model/UIState.kt @@ -19,9 +19,6 @@ package com.geeksville.mesh.model import android.app.Application import android.net.Uri -import androidx.compose.material3.SnackbarDuration -import androidx.compose.material3.SnackbarHostState -import androidx.compose.material3.SnackbarResult import androidx.compose.runtime.Composable import androidx.lifecycle.LiveData import androidx.lifecycle.ViewModel @@ -42,7 +39,6 @@ import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.mapNotNull import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.shareIn -import kotlinx.coroutines.launch import org.meshtastic.core.analytics.platform.PlatformAnalytics import org.meshtastic.core.data.repository.FirmwareReleaseRepository import org.meshtastic.core.data.repository.MeshLogRepository @@ -177,26 +173,6 @@ constructor( val myNodeInfo: StateFlow get() = nodeDB.myNodeInfo - val snackBarHostState = SnackbarHostState() - - fun showSnackBar(text: Int) = showSnackBar(app.getString(text)) - - fun showSnackBar( - text: String, - actionLabel: String? = null, - withDismissAction: Boolean = false, - duration: SnackbarDuration = if (actionLabel == null) SnackbarDuration.Short else SnackbarDuration.Indefinite, - onActionPerformed: (() -> Unit) = {}, - onDismissed: (() -> Unit) = {}, - ) = viewModelScope.launch { - snackBarHostState.showSnackbar(text, actionLabel, withDismissAction, duration).run { - when (this) { - SnackbarResult.ActionPerformed -> onActionPerformed() - SnackbarResult.Dismissed -> onDismissed() - } - } - } - init { serviceRepository.errorMessage .filterNotNull() @@ -217,11 +193,11 @@ constructor( val sharedContactRequested: StateFlow get() = _sharedContactRequested.asStateFlow() - fun setSharedContactRequested(url: Uri) { + fun setSharedContactRequested(url: Uri, onFailure: () -> Unit) { runCatching { _sharedContactRequested.value = url.toSharedContact() } .onFailure { ex -> Timber.e(ex, "Shared contact error") - showSnackBar(R.string.contact_invalid) + onFailure() } } @@ -238,11 +214,12 @@ constructor( val requestChannelSet: StateFlow get() = _requestChannelSet - fun requestChannelUrl(url: Uri) = runCatching { _requestChannelSet.value = url.toChannelSet() } - .onFailure { ex -> - Timber.e(ex, "Channel url error") - showSnackBar(R.string.channel_invalid) - } + fun requestChannelUrl(url: Uri, onFailure: () -> Unit) = + runCatching { _requestChannelSet.value = url.toChannelSet() } + .onFailure { ex -> + Timber.e(ex, "Channel url error") + onFailure() + } val latestStableFirmwareRelease = firmwareReleaseRepository.stableRelease.mapNotNull { it?.asDeviceVersion() } 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 49c5c733f..7f1a6cacd 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/Main.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/Main.kt @@ -34,7 +34,6 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.imePadding -import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.recalculateWindowInsets import androidx.compose.foundation.layout.safeDrawingPadding import androidx.compose.foundation.rememberScrollState @@ -48,8 +47,6 @@ import androidx.compose.material3.Icon import androidx.compose.material3.LocalContentColor import androidx.compose.material3.MaterialTheme.colorScheme import androidx.compose.material3.PlainTooltip -import androidx.compose.material3.Scaffold -import androidx.compose.material3.SnackbarHost import androidx.compose.material3.Text import androidx.compose.material3.TooltipBox import androidx.compose.material3.TooltipDefaults @@ -373,21 +370,17 @@ fun MainScreen(uIViewModel: UIViewModel = hiltViewModel(), scanModel: BTScanMode } }, ) { - Scaffold(snackbarHost = { SnackbarHost(uIViewModel.snackBarHostState) }) { paddingValues -> - Column(modifier = Modifier.fillMaxSize().padding(paddingValues)) { - NavHost( - navController = navController, - startDestination = NodesRoutes.NodesGraph, - modifier = Modifier.fillMaxSize().recalculateWindowInsets().safeDrawingPadding().imePadding(), - ) { - contactsGraph(navController) - nodesGraph(navController) - mapGraph(navController) - channelsGraph(navController) - connectionsGraph(navController) - settingsGraph(navController) - } - } + NavHost( + navController = navController, + startDestination = NodesRoutes.NodesGraph, + modifier = Modifier.fillMaxSize().recalculateWindowInsets().safeDrawingPadding().imePadding(), + ) { + contactsGraph(navController) + nodesGraph(navController) + mapGraph(navController) + channelsGraph(navController) + connectionsGraph(navController) + settingsGraph(navController) } } }