mirror of
https://github.com/permissionlesstech/bitchat-android.git
synced 2026-07-24 23:45:19 +00:00
focus around
This commit is contained in:
@@ -13,6 +13,8 @@ import androidx.compose.runtime.livedata.observeAsState
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.focus.FocusRequester
|
||||
import androidx.compose.ui.focus.focusRequester
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.text.font.FontFamily
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
@@ -33,9 +35,49 @@ fun ReceiveView(
|
||||
val currentMintQuote by viewModel.currentMintQuote.observeAsState()
|
||||
val isLoading by viewModel.isLoading.observeAsState(false)
|
||||
|
||||
// Focus requesters for each input type
|
||||
val cashuFocusRequester = remember { FocusRequester() }
|
||||
val lightningFocusRequester = remember { FocusRequester() }
|
||||
|
||||
// Determine if we should show type selector
|
||||
val showTypeSelector = decodedToken == null && currentMintQuote == null
|
||||
|
||||
// Focus the appropriate input when switching types
|
||||
LaunchedEffect(receiveType) {
|
||||
if (showTypeSelector) {
|
||||
when (receiveType) {
|
||||
WalletViewModel.ReceiveType.CASHU -> {
|
||||
if (decodedToken == null) {
|
||||
cashuFocusRequester.requestFocus()
|
||||
}
|
||||
}
|
||||
WalletViewModel.ReceiveType.LIGHTNING -> {
|
||||
if (currentMintQuote == null) {
|
||||
lightningFocusRequester.requestFocus()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Initial focus when the view is first shown
|
||||
LaunchedEffect(Unit) {
|
||||
if (showTypeSelector) {
|
||||
when (receiveType) {
|
||||
WalletViewModel.ReceiveType.CASHU -> {
|
||||
if (decodedToken == null) {
|
||||
cashuFocusRequester.requestFocus()
|
||||
}
|
||||
}
|
||||
WalletViewModel.ReceiveType.LIGHTNING -> {
|
||||
if (currentMintQuote == null) {
|
||||
lightningFocusRequester.requestFocus()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
@@ -145,14 +187,16 @@ fun ReceiveView(
|
||||
ReceiveEcashDialog(
|
||||
viewModel = viewModel,
|
||||
decodedToken = decodedToken,
|
||||
isLoading = isLoading
|
||||
isLoading = isLoading,
|
||||
focusRequester = cashuFocusRequester
|
||||
)
|
||||
}
|
||||
WalletViewModel.ReceiveType.LIGHTNING -> {
|
||||
ReceiveLightningDialog(
|
||||
viewModel = viewModel,
|
||||
currentMintQuote = currentMintQuote,
|
||||
isLoading = isLoading
|
||||
isLoading = isLoading,
|
||||
focusRequester = lightningFocusRequester
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.text.selection.SelectionContainer
|
||||
import androidx.compose.foundation.text.BasicTextField
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.*
|
||||
import androidx.compose.material3.*
|
||||
@@ -13,6 +14,8 @@ import androidx.compose.runtime.livedata.observeAsState
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.focus.FocusRequester
|
||||
import androidx.compose.ui.focus.focusRequester
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalClipboardManager
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
@@ -31,7 +34,8 @@ import com.bitchat.android.wallet.viewmodel.WalletViewModel
|
||||
fun ReceiveEcashDialog(
|
||||
viewModel: WalletViewModel,
|
||||
decodedToken: CashuToken?,
|
||||
isLoading: Boolean
|
||||
isLoading: Boolean,
|
||||
focusRequester: FocusRequester
|
||||
) {
|
||||
val token by viewModel.tokenInput.observeAsState("")
|
||||
val clipboardManager = LocalClipboardManager.current
|
||||
@@ -206,7 +210,8 @@ fun ReceiveEcashDialog(
|
||||
),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(bottom = 24.dp),
|
||||
.padding(bottom = 24.dp)
|
||||
.focusRequester(focusRequester),
|
||||
minLines = 3,
|
||||
maxLines = 4,
|
||||
shape = RoundedCornerShape(16.dp),
|
||||
|
||||
@@ -5,6 +5,7 @@ import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.foundation.text.BasicTextField
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.*
|
||||
import androidx.compose.material3.*
|
||||
@@ -12,6 +13,8 @@ import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.focus.FocusRequester
|
||||
import androidx.compose.ui.focus.focusRequester
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalClipboardManager
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
@@ -30,7 +33,8 @@ import com.bitchat.android.wallet.viewmodel.WalletViewModel
|
||||
fun ReceiveLightningDialog(
|
||||
viewModel: WalletViewModel,
|
||||
currentMintQuote: MintQuote?,
|
||||
isLoading: Boolean
|
||||
isLoading: Boolean,
|
||||
focusRequester: FocusRequester
|
||||
) {
|
||||
var amount by remember { mutableStateOf("") }
|
||||
var description by remember { mutableStateOf("") }
|
||||
@@ -196,7 +200,8 @@ fun ReceiveLightningDialog(
|
||||
),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(bottom = 16.dp),
|
||||
.padding(bottom = 16.dp)
|
||||
.focusRequester(focusRequester),
|
||||
shape = RoundedCornerShape(16.dp)
|
||||
)
|
||||
|
||||
|
||||
@@ -45,12 +45,17 @@ class LightningManager(
|
||||
coroutineScope.launch {
|
||||
try {
|
||||
uiStateManager.setLoading(true)
|
||||
cashuService.createMintQuote(amount, description).onSuccess { quote ->
|
||||
|
||||
// Create the mint quote first
|
||||
val mintQuoteResult = cashuService.createMintQuote(amount, description)
|
||||
mintQuoteResult.onSuccess { quote ->
|
||||
_currentMintQuote.value = quote
|
||||
|
||||
// Save quote for tracking
|
||||
repository.saveMintQuote(quote).onSuccess {
|
||||
loadPendingQuotes()
|
||||
val saveResult = repository.saveMintQuote(quote)
|
||||
saveResult.onSuccess {
|
||||
// Now load pending quotes directly in current coroutine
|
||||
loadPendingQuotesInternal()
|
||||
}.onFailure { error ->
|
||||
Log.e(TAG, "Failed to save mint quote", error)
|
||||
_errorMessage.value = "Failed to save invoice: ${error.message}"
|
||||
@@ -71,12 +76,17 @@ class LightningManager(
|
||||
coroutineScope.launch {
|
||||
try {
|
||||
uiStateManager.setLoading(true)
|
||||
cashuService.createMeltQuote(invoice).onSuccess { quote ->
|
||||
|
||||
// Create the melt quote first
|
||||
val meltQuoteResult = cashuService.createMeltQuote(invoice)
|
||||
meltQuoteResult.onSuccess { quote ->
|
||||
_currentMeltQuote.value = quote
|
||||
|
||||
// Save quote for tracking
|
||||
repository.saveMeltQuote(quote).onSuccess {
|
||||
loadPendingQuotes()
|
||||
val saveResult = repository.saveMeltQuote(quote)
|
||||
saveResult.onSuccess {
|
||||
// Load pending quotes directly in current coroutine
|
||||
loadPendingQuotesInternal()
|
||||
onQuoteCreated()
|
||||
}.onFailure { error ->
|
||||
Log.e(TAG, "Failed to save melt quote", error)
|
||||
@@ -201,17 +211,24 @@ class LightningManager(
|
||||
}
|
||||
|
||||
/**
|
||||
* Load pending quotes from repository
|
||||
* Load pending quotes from repository (internal suspend method)
|
||||
*/
|
||||
private suspend fun loadPendingQuotesInternal() {
|
||||
repository.getMintQuotes().onSuccess { quotes ->
|
||||
_pendingMintQuotes.value = quotes.filter { !it.paid }
|
||||
}
|
||||
|
||||
repository.getMeltQuotes().onSuccess { quotes ->
|
||||
_pendingMeltQuotes.value = quotes.filter { it.state != MeltQuoteState.PAID }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load pending quotes from repository (public method for external calls)
|
||||
*/
|
||||
fun loadPendingQuotes() {
|
||||
coroutineScope.launch {
|
||||
repository.getMintQuotes().onSuccess { quotes ->
|
||||
_pendingMintQuotes.value = quotes.filter { !it.paid }
|
||||
}
|
||||
|
||||
repository.getMeltQuotes().onSuccess { quotes ->
|
||||
_pendingMeltQuotes.value = quotes.filter { it.state != MeltQuoteState.PAID }
|
||||
}
|
||||
loadPendingQuotesInternal()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user