taler-android

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

ObservabilityDialog.kt (4678B)


      1 /*
      2  * This file is part of GNU Taler
      3  * (C) 2024 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.events
     18 
     19 import androidx.compose.foundation.background
     20 import androidx.compose.foundation.layout.Box
     21 import androidx.compose.foundation.layout.Column
     22 import androidx.compose.foundation.layout.fillMaxSize
     23 import androidx.compose.foundation.layout.fillMaxWidth
     24 import androidx.compose.foundation.layout.padding
     25 import androidx.compose.foundation.lazy.LazyColumn
     26 import androidx.compose.foundation.lazy.items
     27 import androidx.compose.material3.AlertDialog
     28 import androidx.compose.material3.Button
     29 import androidx.compose.material3.ButtonDefaults
     30 import androidx.compose.material3.ListItem
     31 import androidx.compose.material3.MaterialTheme
     32 import androidx.compose.material3.Text
     33 import androidx.compose.material3.TextButton
     34 import androidx.compose.runtime.Composable
     35 import androidx.compose.runtime.getValue
     36 import androidx.compose.runtime.mutableStateOf
     37 import androidx.compose.runtime.remember
     38 import androidx.compose.runtime.setValue
     39 import androidx.compose.ui.Alignment
     40 import androidx.compose.ui.Modifier
     41 import androidx.compose.ui.res.stringResource
     42 import androidx.compose.ui.text.font.FontFamily
     43 import androidx.compose.ui.unit.dp
     44 import kotlinx.serialization.ExperimentalSerializationApi
     45 import kotlinx.serialization.json.Json
     46 import net.taler.wallet.R
     47 import net.taler.wallet.compose.CopyToClipboardButton
     48 import java.time.format.DateTimeFormatter
     49 import java.time.format.FormatStyle
     50 
     51 @OptIn(ExperimentalSerializationApi::class)
     52 private val observabilityJson = Json {
     53     prettyPrint = true
     54     prettyPrintIndent = "  "
     55 }
     56 
     57 @Composable
     58 fun ObservabilityDialog(
     59     events: List<ObservabilityEvent>,
     60     onDismiss: () -> Unit,
     61 ) {
     62     var showJson by remember { mutableStateOf(false) }
     63 
     64     AlertDialog(
     65         title = { Text(stringResource(R.string.observability_title)) },
     66         text = {
     67             LazyColumn(modifier = Modifier.fillMaxSize()) {
     68                 items(events) { event ->
     69                     ObservabilityItem(event, showJson)
     70                 }
     71             }
     72         },
     73         onDismissRequest = onDismiss,
     74         dismissButton = {
     75             Button(onClick = { showJson = !showJson }) {
     76                 Text(if (showJson) {
     77                     stringResource(R.string.observability_hide_json)
     78                 } else {
     79                     stringResource(R.string.observability_show_json)
     80                 })
     81             }
     82         },
     83         confirmButton = {
     84             TextButton(onClick = onDismiss) {
     85                 Text(stringResource(R.string.close))
     86             }
     87         },
     88     )
     89 }
     90 
     91 @Composable
     92 fun ObservabilityItem(
     93     event: ObservabilityEvent,
     94     showJson: Boolean,
     95 ) {
     96     val body = observabilityJson.encodeToString(event.body)
     97     val timestamp = DateTimeFormatter
     98         .ofLocalizedDateTime(FormatStyle.MEDIUM)
     99         .format(event.timestamp)
    100 
    101     ListItem(
    102         modifier = Modifier.fillMaxWidth(),
    103         headlineContent = { Text(event.type) },
    104         overlineContent = { Text(timestamp) },
    105         supportingContent = if (!showJson) null else { ->
    106             Column(
    107                 horizontalAlignment = Alignment.CenterHorizontally,
    108             ) {
    109                 Box(
    110                     modifier = Modifier.background(
    111                         MaterialTheme.colorScheme.secondaryContainer,
    112                         shape = MaterialTheme.shapes.small,
    113                     )
    114                 ) {
    115                     Text(
    116                         modifier = Modifier
    117                             .padding(10.dp)
    118                             .fillMaxWidth(),
    119                         text = body,
    120                         fontFamily = FontFamily.Monospace,
    121                         style = MaterialTheme.typography.bodySmall,
    122                     )
    123                 }
    124 
    125                 CopyToClipboardButton(
    126                     label = "Event",
    127                     content = body,
    128                     colors = ButtonDefaults.textButtonColors(),
    129                 )
    130             }
    131         },
    132     )
    133 }