taler-android

Android apps for GNU Taler (wallet, PoS, cashier)
Log | Files | Refs | README | LICENSE

commit 4ef136060c74e18458d55e3a59be31000a6345e7
parent 0ea0dc8b531a4c3e418a540449db67b7add53cd5
Author: Martin Schanzenbach <schanzen@gnunet.org>
Date:   Wed, 15 Jul 2026 11:10:08 +0200

allow to access mailbox from notifications

Diffstat:
Mwallet/src/main/java/net/taler/wallet/mailbox/MailboxManager.kt | 8+++++---
Mwallet/src/main/java/net/taler/wallet/mailbox/MailboxScreen.kt | 20++++++++++++++++++--
Mwallet/src/main/java/net/taler/wallet/main/MainScreen.kt | 17+++++++++++++++--
Mwallet/src/main/java/net/taler/wallet/main/MainViewModel.kt | 31++++++++++++++++++++++++++++++-
4 files changed, 68 insertions(+), 8 deletions(-)

diff --git a/wallet/src/main/java/net/taler/wallet/mailbox/MailboxManager.kt b/wallet/src/main/java/net/taler/wallet/mailbox/MailboxManager.kt @@ -72,7 +72,7 @@ class MailboxManager( private val api: WalletBackendApi, private val scope: CoroutineScope, private val isDevMode: () -> Boolean, - private val onMessage: ((String) -> Unit)? = null, + private val onMessage: ((msg: String, actionLabel: String?, onAction: (() -> Unit)?) -> Unit)? = null, ) { private val _mailbox = MutableStateFlow<MailboxResult>(MailboxResult.Loading) val mailbox = _mailbox.asStateFlow() @@ -152,7 +152,9 @@ class MailboxManager( response.messages.forEach { msg -> addMessage(msg) } - onMessage?.invoke("Received ${response.messages.size} new message(s)") + onMessage?.invoke("Received ${response.messages.size} new message(s)", "View") { + // The UI should handle navigation when this is called + } } getMessages(config) }.onError { @@ -190,7 +192,7 @@ class MailboxManager( put("talerUri", talerUri) }.onSuccess { Log.i(TAG, "Message sent successfully to ${contact.petname}") - onMessage?.invoke("Message sent to ${contact.petname}") + onMessage?.invoke("Message sent to ${contact.petname}", null, null) }.onError { Log.e(TAG, "Error sending message to ${contact.petname}: $it") } diff --git a/wallet/src/main/java/net/taler/wallet/mailbox/MailboxScreen.kt b/wallet/src/main/java/net/taler/wallet/mailbox/MailboxScreen.kt @@ -39,8 +39,10 @@ import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Scaffold +import androidx.compose.material3.SnackbarDuration import androidx.compose.material3.SnackbarHost import androidx.compose.material3.SnackbarHostState +import androidx.compose.material3.SnackbarResult import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.material3.TopAppBar @@ -84,8 +86,22 @@ fun MailboxScreen( var showAddressDialog by remember { mutableStateOf(false) } LaunchedEffect(showMessageEvent) { - showMessageEvent?.getIfNotConsumed()?.let { msg -> - snackbarHostState.showSnackbar(msg) + showMessageEvent?.getIfNotConsumed()?.let { notify -> + val result = snackbarHostState.showSnackbar( + message = notify.content, + actionLabel = notify.actionLabel, + duration = SnackbarDuration.Short + ) + if (result == SnackbarResult.ActionPerformed) { + notify.onAction?.invoke() + } + } + } + + LaunchedEffect(Unit) { + val state = mailboxManager.mailbox.value + if (state is MailboxResult.Success) { + mailboxManager.refreshMailbox(state.config) } } diff --git a/wallet/src/main/java/net/taler/wallet/main/MainScreen.kt b/wallet/src/main/java/net/taler/wallet/main/MainScreen.kt @@ -31,8 +31,11 @@ import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.NavigationBar import androidx.compose.material3.NavigationBarItem +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.SnackbarDuration import androidx.compose.material3.SnackbarHost import androidx.compose.material3.SnackbarHostState +import androidx.compose.material3.SnackbarResult import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.material3.rememberModalBottomSheetState @@ -110,8 +113,18 @@ fun MainScreen( val showMessageEvent by model.showMessageEvent.observeAsState() LaunchedEffect(showMessageEvent) { - showMessageEvent?.getIfNotConsumed()?.let { msg -> - snackbarHostState.showSnackbar(msg) + showMessageEvent?.getIfNotConsumed()?.let { notify -> + val result = snackbarHostState.showSnackbar( + message = notify.content, + actionLabel = notify.actionLabel, + duration = SnackbarDuration.Short + ) + if (result == SnackbarResult.ActionPerformed) { + if (notify.actionLabel == "View") { + onNavigate(WalletDestination.Mailbox, false) + } + notify.onAction?.invoke() + } } } diff --git a/wallet/src/main/java/net/taler/wallet/main/MainViewModel.kt b/wallet/src/main/java/net/taler/wallet/main/MainViewModel.kt @@ -68,6 +68,24 @@ import java.util.UUID const val TAG = "taler-wallet" const val OBSERVABILITY_LIMIT = 100 +<<<<<<< HEAD +======= +private val transactionNotifications = listOf( + "transaction-state-transition", +) + +private val observabilityNotifications = listOf( + "task-observability-event", + "request-observability-event", +) + +data class NotifyMessage( + val content: String, + val actionLabel: String? = null, + val onAction: (() -> Unit)? = null, +) + +>>>>>>> 194dea06 (allow to access mailbox from notifications) class MainViewModel( app: Application, ) : AndroidViewModel(app), InitReceiver, NotificationReceiver { @@ -120,7 +138,9 @@ class MainViewModel( api = api, scope = viewModelScope, isDevMode = { devMode.value == true }, - ) { showInfoMessage(it) } + ) { msg, actionLabel, onAction -> + showInfoMessage(msg, actionLabel, onAction) + } private val mAuthenticated = MutableStateFlow(false) val authenticated: StateFlow<Boolean> = mAuthenticated @@ -134,6 +154,15 @@ class MainViewModel( private val mShowObservabilityLog = MutableStateFlow(false) val showObservabilityLog: StateFlow<Boolean> = mShowObservabilityLog +<<<<<<< HEAD +======= + private val mScanCodeEvent = MutableLiveData<Event<Boolean>>() + val scanCodeEvent: LiveData<Event<Boolean>> = mScanCodeEvent + + private val mShowMessageEvent = MutableLiveData<Event<NotifyMessage>>() + val showMessageEvent: LiveData<Event<NotifyMessage>> = mShowMessageEvent + +>>>>>>> 194dea06 (allow to access mailbox from notifications) private val mViewMode = MutableStateFlow<ViewMode>(ViewMode.Assets) val viewMode: StateFlow<ViewMode> = mViewMode