diff --git a/app/src/main/java/com/bitcointxoko/gudariwallet/ui/common/BrightnessUtils.kt b/app/src/main/java/com/bitcointxoko/gudariwallet/ui/common/BrightnessUtils.kt new file mode 100644 index 0000000..d04313d --- /dev/null +++ b/app/src/main/java/com/bitcointxoko/gudariwallet/ui/common/BrightnessUtils.kt @@ -0,0 +1,41 @@ +package com.bitcointxoko.gudariwallet.ui.common + +import android.app.Activity +import android.view.WindowManager +import androidx.compose.runtime.* +import androidx.compose.ui.platform.LocalContext + +/** + * Manages screen brightness for QR-display screens. + * Returns a [BrightnessController] with [isOn] state and a [toggle] callback. + * Restores system brightness unconditionally when it leaves composition. + */ +@Composable +fun rememberBrightnessController(): BrightnessController { + val window = (LocalContext.current as? Activity)?.window + var isOn by remember { mutableStateOf(false) } + + LaunchedEffect(isOn) { + window?.attributes = window?.attributes?.apply { + screenBrightness = if (isOn) 1f + else WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE + } + } + + DisposableEffect(Unit) { + onDispose { + window?.attributes = window?.attributes?.apply { + screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE + } + } + } + + return remember(isOn) { + BrightnessController(isOn = isOn, toggle = { isOn = !isOn }) + } +} + +data class BrightnessController( + val isOn : Boolean, + val toggle : () -> Unit +) diff --git a/app/src/main/java/com/bitcointxoko/gudariwallet/ui/nwc/NwcPairingDialog.kt b/app/src/main/java/com/bitcointxoko/gudariwallet/ui/nwc/NwcPairingDialog.kt index 433b92f..2a1f0d0 100644 --- a/app/src/main/java/com/bitcointxoko/gudariwallet/ui/nwc/NwcPairingDialog.kt +++ b/app/src/main/java/com/bitcointxoko/gudariwallet/ui/nwc/NwcPairingDialog.kt @@ -23,35 +23,19 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.unit.dp import androidx.core.net.toUri +import com.bitcointxoko.gudariwallet.ui.common.rememberBrightnessController import com.bitcointxoko.gudariwallet.ui.receive.QrDisplayCard @Composable internal fun NwcPairingUrlDialog( url : String, - onDismiss : () -> Unit + onDismiss : () -> Unit, + onNoAppFound : () -> Unit ) { // Brightness state lives here so the dialog owns the screen-brightness side-effect - var brightnessOn by remember { mutableStateOf(false) } - val window = (LocalContext.current as? Activity)?.window + val brightness = rememberBrightnessController() val context = LocalContext.current - // Boost / restore screen brightness when the toggle changes - LaunchedEffect(brightnessOn) { - window?.attributes = window.attributes?.apply { - screenBrightness = if (brightnessOn) 1f - else WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE - } - } - - // Restore brightness unconditionally when the dialog leaves composition - DisposableEffect(Unit) { - onDispose { - window?.attributes = window.attributes?.apply { - screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE - } - } - } - AlertDialog( onDismissRequest = onDismiss, title = { Text("Connection created") }, @@ -63,31 +47,24 @@ internal fun NwcPairingUrlDialog( color = MaterialTheme.colorScheme.onSurfaceVariant ) QrDisplayCard( - modifier = Modifier.fillMaxWidth(), - content = url, - contentDescription = "NWC pairing QR code", - clipLabel = "NWC connection string", - shareTitle = "Share NWC connection string", - textToCopy = url, - brightnessOn = brightnessOn, - onToggleBrightness = { brightnessOn = !brightnessOn }, - // No NFC for a one-shot pairing string - isNfcEmulating = null, - qrModifier = Modifier.fillMaxWidth(), - onOpenUri = { + modifier = Modifier.fillMaxWidth(), + content = url, + contentDescription = "NWC pairing QR code", + clipLabel = "NWC connection string", + shareTitle = "Share NWC connection string", + textToCopy = url, + brightnessOn = brightness.isOn, + onToggleBrightness = brightness.toggle, + isNfcEmulating = null, + qrModifier = Modifier.fillMaxWidth(), + onOpenUri = { val intent = Intent(Intent.ACTION_VIEW, url.toUri()) try { context.startActivity( Intent.createChooser(intent, "Open in app") ) } catch (e: ActivityNotFoundException) { - // No app installed that handles nostr+walletconnect:// - // Show a snackbar / toast as appropriate for your app - Toast.makeText( - context, - "No compatible app found", // "No compatible app found" - Toast.LENGTH_SHORT - ).show() + onNoAppFound() // #17: no Toast — caller handles it } } ) diff --git a/app/src/main/java/com/bitcointxoko/gudariwallet/ui/nwc/NwcScreen.kt b/app/src/main/java/com/bitcointxoko/gudariwallet/ui/nwc/NwcScreen.kt index 9ac0e0f..52d67c4 100644 --- a/app/src/main/java/com/bitcointxoko/gudariwallet/ui/nwc/NwcScreen.kt +++ b/app/src/main/java/com/bitcointxoko/gudariwallet/ui/nwc/NwcScreen.kt @@ -13,6 +13,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle +import kotlinx.coroutines.launch @OptIn(ExperimentalMaterial3Api::class) @Composable @@ -27,6 +28,8 @@ fun NwcScreen( val pairingUrl by viewModel.pairingUrl.collectAsStateWithLifecycle() val showAddSheet by viewModel.showAddSheet.collectAsStateWithLifecycle() val pendingDeletePubkey by viewModel.pendingDeletePubkey.collectAsStateWithLifecycle() + val snackbarHostState = remember { SnackbarHostState() } + val scope = rememberCoroutineScope() // ── Shared refresh lambda (item #13) ────────────────────────────────────── val refresh = { viewModel.loadConnections(includeExpired = true) } @@ -46,7 +49,8 @@ fun NwcScreen( FloatingActionButton(onClick = { viewModel.openAddSheet() }) { Icon(Icons.Default.Add, contentDescription = "Add connection") } - } + }, + snackbarHost = { SnackbarHost(snackbarHostState) } ) { innerPadding -> val isRefreshing = uiState is NwcUiState.Loading @@ -127,7 +131,12 @@ fun NwcScreen( pairingUrl?.let { url -> NwcPairingUrlDialog( url = url, - onDismiss = { viewModel.clearPairingUrl() } + onDismiss = { viewModel.clearPairingUrl() }, + onNoAppFound = { + scope.launch { + snackbarHostState.showSnackbar("No compatible app found") + } + } ) }