taler-android

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

TokenManager.kt (3071B)


      1 /*
      2  * This file is part of GNU Taler
      3  * (C) 2026 Taler Systems S.A.
      4  *
      5  * GNU Taler is free software; you can redistribute it and/or modify it under the
      6  * terms of the GNU General Public License as published by the Free Software
      7  * Foundation; either version 3, or (at your option) any later version.
      8  *
      9  * GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
     10  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
     11  * A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
     12  *
     13  * You should have received a copy of the GNU General Public License along with
     14  * GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
     15  */
     16 
     17 package net.taler.wallet.tokens
     18 
     19 import kotlinx.coroutines.ExperimentalCoroutinesApi
     20 import kotlinx.coroutines.flow.Flow
     21 import kotlinx.coroutines.flow.MutableSharedFlow
     22 import kotlinx.coroutines.flow.flatMapLatest
     23 import kotlinx.coroutines.flow.flow
     24 import net.taler.common.Timestamp
     25 import net.taler.wallet.backend.TalerErrorInfo
     26 import net.taler.wallet.backend.WalletBackendApi
     27 import net.taler.wallet.backend.WalletResponse
     28 
     29 sealed class UiState<out T> {
     30     object Loading: UiState<Nothing>()
     31     data class Success<out T>(val data: T): UiState<T>()
     32     data class Error(val error: TalerErrorInfo): UiState<Nothing>()
     33 }
     34 
     35 fun <T, U> WalletResponse<T>.toUiState(transform: (r: T) -> U): UiState<U> = when(this) {
     36     is WalletResponse.Success -> UiState.Success(transform(this.result))
     37     is WalletResponse.Error -> UiState.Error(this.error)
     38 }
     39 
     40 sealed class TokenFilter() {
     41     // data object All: TokenFilter()
     42     data object Valid: TokenFilter()
     43     data object Expired: TokenFilter()
     44 }
     45 
     46 class TokenManager(private val api: WalletBackendApi){
     47     private val refreshTrigger =
     48         MutableSharedFlow<Unit>(replay = 1).apply { tryEmit(Unit) }
     49 
     50     @OptIn(ExperimentalCoroutinesApi::class)
     51     val discounts: Flow<UiState<List<DiscountListDetail>>> = refreshTrigger.flatMapLatest {
     52         flow {
     53             emit(UiState.Loading)
     54             emit(api.request("listDiscounts", ListDiscountsResponse.serializer())
     55                 .toUiState { it.discounts })
     56         }
     57     }
     58 
     59     @OptIn(ExperimentalCoroutinesApi::class)
     60     val passes: Flow<UiState<List<SubscriptionListDetail>>> = refreshTrigger.flatMapLatest {
     61         flow {
     62             emit(UiState.Loading)
     63             emit(api.request("listSubscriptions", ListSubscriptionsResponse.serializer())
     64                 .toUiState { it.subscriptions })
     65         }
     66     }
     67 
     68     fun refresh() { refreshTrigger.tryEmit(Unit) }
     69 }
     70 
     71 fun List<DiscountListDetail>.filterDiscounts(filter: TokenFilter): List<DiscountListDetail> {
     72     return when(filter) {
     73         TokenFilter.Valid -> filter { !it.isExpired }
     74         TokenFilter.Expired -> filter { it.isExpired }
     75     }
     76 }
     77 
     78 fun List<SubscriptionListDetail>.filterPasses(filter: TokenFilter): List<SubscriptionListDetail> {
     79     return when(filter) {
     80         TokenFilter.Valid -> filter { !it.isExpired }
     81         TokenFilter.Expired -> filter { it.isExpired }
     82     }
     83 }