diff --git a/app/src/main/java/com/ivy/wallet/ui/csv/CSVScreen.kt b/app/src/main/java/com/ivy/wallet/ui/csv/CSVScreen.kt index 446ae307d6..d38c423c4e 100644 --- a/app/src/main/java/com/ivy/wallet/ui/csv/CSVScreen.kt +++ b/app/src/main/java/com/ivy/wallet/ui/csv/CSVScreen.kt @@ -7,13 +7,13 @@ import androidx.compose.foundation.horizontalScroll import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyListScope -import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.rememberScrollState import androidx.compose.material.Button import androidx.compose.material.ButtonDefaults import androidx.compose.material.Text import androidx.compose.material.TextField import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.text.font.FontWeight @@ -69,6 +69,9 @@ private fun ImportButton( ) { val ivyContext = ivyWalletCtx() Button( + modifier = Modifier + .fillMaxWidth() + .height(48.dp), onClick = { ivyContext.openFile { onFilePicked(it) @@ -98,9 +101,19 @@ fun Spacer8(horizontal: Boolean = false) { private fun LazyListScope.csvTable( csv: List ) { - itemsIndexed(items = csv.take(10)) { index, row -> - CSVRow(row = row, header = index == 0, even = index % 2 == 0) + item { + Column( + modifier = Modifier + .fillMaxWidth() + .horizontalScroll(rememberScrollState()) + ) { + val visibleRows = remember(csv) { csv.take(10) } + visibleRows.forEachIndexed { index, row -> + CSVRow(row = row, header = index == 0, even = index % 2 == 0) + } + } } + } @Composable @@ -112,7 +125,6 @@ private fun CSVRow( Row( modifier = Modifier .fillMaxWidth() - .horizontalScroll(rememberScrollState()) ) { row.values.forEach { value -> CSVCell(text = value, header = header, even = even) @@ -128,15 +140,15 @@ private fun CSVCell( ) { Text( modifier = Modifier - .width(120.dp) + .width(140.dp) .border(1.dp, UI.colors.pureInverse) .thenIf(even) { this.background(UI.colors.medium) } .padding(all = 4.dp), - text = text, + text = text.ifEmpty { " " }, style = UI.typo.nB1, - fontWeight = if (header) FontWeight.ExtraBold else FontWeight.Normal, + fontWeight = if (header) FontWeight.Bold else FontWeight.Normal, overflow = TextOverflow.Ellipsis, maxLines = 1, ) diff --git a/app/src/main/java/com/ivy/wallet/ui/csv/CSVViewModel.kt b/app/src/main/java/com/ivy/wallet/ui/csv/CSVViewModel.kt index 1a516719c2..93cd24d97c 100644 --- a/app/src/main/java/com/ivy/wallet/ui/csv/CSVViewModel.kt +++ b/app/src/main/java/com/ivy/wallet/ui/csv/CSVViewModel.kt @@ -1,12 +1,12 @@ package com.ivy.wallet.ui.csv +import android.net.Uri import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.ivy.wallet.domain.deprecated.logic.csv.CSVNormalizer import com.ivy.wallet.domain.deprecated.logic.csv.IvyFileReader import com.opencsv.CSVReaderBuilder import com.opencsv.validators.LineValidator @@ -17,6 +17,7 @@ import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import java.io.StringReader +import java.nio.charset.Charset import javax.inject.Inject @HiltViewModel @@ -59,13 +60,26 @@ class CSVViewModel @Inject constructor( } private suspend fun handleFilePicked(event: CSVEvent.FilePicked) = withContext(Dispatchers.IO) { - val fileContent = fileReader.read(event.uri, Charsets.UTF_8) ?: return@withContext - csv = parseCSV(fileContent).takeIf { it.isNotEmpty() } + csv = processFile(event.uri) + } + + private suspend fun processFile( + uri: Uri, + charset: Charset = Charsets.UTF_8 + ): List? { + return try { + val fileContent = fileReader.read(uri, charset) ?: return null + parseCSV(fileContent).takeIf { it.isNotEmpty() } + } catch (e: Exception) { + if (charset != Charsets.UTF_16) { + return processFile(uri, Charsets.UTF_16) + } + null + } } private suspend fun parseCSV(csv: String): List { val csvReader = CSVReaderBuilder(StringReader(csv)) - .withSkipLines(1) .withLineValidator(object : LineValidator { override fun isValid(line: String?): Boolean { return true