Skip to content

Commit

Permalink
We render the no category assigned icon via Google Icons in order to …
Browse files Browse the repository at this point in the history
…bypass loading of FontAwesome Icons

Fixes #1565
emToDp failed on Tools Preview
  • Loading branch information
mtotschnig committed Sep 28, 2024
1 parent 87d859c commit 6d065e0
Show file tree
Hide file tree
Showing 8 changed files with 180 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import androidx.compose.foundation.text.appendInlineContent
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.CallSplit
import androidx.compose.material.icons.filled.Archive
import androidx.compose.material.icons.filled.Remove
import androidx.compose.material3.Icon
import androidx.compose.material3.LocalTextStyle
import androidx.compose.material3.MaterialTheme
Expand Down Expand Up @@ -201,16 +202,14 @@ abstract class ItemRenderer(
) {
val showMenu = remember { mutableStateOf(false) }
val activatedBackgroundColor = colorResource(id = R.color.activatedBackground)
val voidMarkerHeight = with(LocalDensity.current) { 2.dp.toPx() }
val voidStatus = stringResource(id = R.string.status_void)
Row(modifier = modifier
.height()
.conditional(selectionHandler?.isSelectable(transaction) == true,
ifTrue = {
combinedClickable(
onLongClick = { selectionHandler!!.toggle(transaction) },
onClick = {
if ( selectionHandler!!.selectionCount == 0) {
if (selectionHandler!!.selectionCount == 0) {
showMenu.value = true
} else {
selectionHandler.toggle(transaction)
Expand All @@ -225,18 +224,7 @@ abstract class ItemRenderer(
.conditional(selectionHandler?.isSelected(transaction) == true) {
background(activatedBackgroundColor)
}
.conditional(transaction.crStatus == CrStatus.VOID) {
drawWithContent {
drawContent()
drawLine(
Color.Red,
Offset(0F, size.height / 2),
Offset(size.width, size.height / 2),
voidMarkerHeight
)
}
.semantics { contentDescription = voidStatus }
}
.voidMarker(transaction.crStatus)
.padding(horizontal = mainScreenPadding, vertical = 3.dp),
verticalAlignment = Alignment.CenterVertically
) {
Expand Down Expand Up @@ -295,7 +283,11 @@ abstract class ItemRenderer(
modifier = Modifier.fillMaxSize()
)

else -> Icon("minus")
else -> Icon(
imageVector = Icons.Filled.Remove,
contentDescription = stringResource(id = R.string.action_archive),
modifier = Modifier.fillMaxSize()
)
}
}
}
Expand Down Expand Up @@ -480,6 +472,35 @@ fun Modifier.tagBorder(color: Color) =
)
.padding(vertical = 4.dp, horizontal = 6.dp)

@Composable
fun Modifier.voidMarker(crStatus: CrStatus): Modifier {
val voidMarkerHeight = with(LocalDensity.current) { 2.dp.toPx() }
val voidStatus = stringResource(id = R.string.status_void)
return conditional(crStatus == CrStatus.VOID) {
drawWithContent {
drawContent()
drawLine(
Color.Red,
Offset(0F, size.height / 2),
Offset(size.width, size.height / 2),
voidMarkerHeight
)
}
.semantics { contentDescription = voidStatus }
}
}

@Composable
fun InlineChip(text: String, color: Color?) {
Text(
text = text,
modifier = Modifier
.tagBorder(color ?: MaterialTheme.colorScheme.onSurface)
.padding(bottom = 2.dp),
style = MaterialTheme.typography.bodySmall
)
}

@Preview
@Composable
private fun RenderNew(@PreviewParameter(SampleProvider::class) transaction: Transaction2) {
Expand All @@ -496,37 +517,27 @@ private fun RenderCompact(@PreviewParameter(SampleProvider::class) transaction:
).Render(transaction)
}

@Composable
fun InlineChip(text: String, color: Color?) {
Text(
text = text,
modifier = Modifier
.tagBorder(color ?: MaterialTheme.colorScheme.onSurface)
.padding(bottom = 2.dp),
style = MaterialTheme.typography.bodySmall
)
}

class SampleProvider : PreviewParameterProvider<Transaction2> {
private val originalCurrency = CurrencyUnit("TRY", "", 2)
override val values = sequenceOf(
Transaction2(
id = -1,
_date = System.currentTimeMillis() / 1000,
amount = Money(CurrencyUnit.DebugInstance, 7000),
amount = Money(CurrencyUnit.DebugInstance, 8000),
originalAmount = Money(originalCurrency, 1234500),
methodLabel = "CHEQUE",
methodIcon = "credit-card",
//methodIcon = "credit-card",
referenceNumber = "1",
accountId = -1,
catId = 1,
categoryPath = "Obst und Gemüse",
comment = "Erika Musterfrau",
icon = "apple",
//icon = "apple",
year = 2022,
month = 1,
day = 1,
week = 1,
crStatus = CrStatus.VOID,
tagList = listOf(
Triple(1, "Hund", android.graphics.Color.RED),
Triple(2,"Katz", android.graphics.Color.GREEN)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.sp
import app.futured.donut.compose.DonutProgress
import app.futured.donut.compose.data.DonutModel
import app.futured.donut.compose.data.DonutSection
Expand Down Expand Up @@ -130,4 +131,6 @@ fun TypeConfiguration(
}

@Composable
fun emToDp(em: Float): Dp = with(LocalDensity.current) { LocalTextStyle.current.fontSize.toDp() } * em
fun emToDp(em: Float): Dp = with(LocalDensity.current) {
(LocalTextStyle.current.fontSize.takeIf { it.isSp } ?: 12.sp).toDp()
} * em
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ data class ArchiveInfo(
val statuses: List<CrStatus>
) : Parcelable {
val canArchive: Boolean
get() = count > 0 && !hasNested && statuses.size == 1
get() = count > 0 && !hasNested && statuses.filter { it != CrStatus.VOID }.size <= 1
}

@OptIn(ExperimentalMaterial3Api::class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ import org.totschnig.myexpenses.compose.LocalDateFormatter
import org.totschnig.myexpenses.compose.conditional
import org.totschnig.myexpenses.compose.emToDp
import org.totschnig.myexpenses.compose.size
import org.totschnig.myexpenses.compose.voidMarker
import org.totschnig.myexpenses.db2.FinTsAttribute
import org.totschnig.myexpenses.feature.BankingFeature
import org.totschnig.myexpenses.injector
Expand Down Expand Up @@ -228,6 +229,7 @@ class TransactionDetailFragment : ComposeBaseDialogFragment3() {
) { expanded ->
if (expanded) {
OutlinedCard(modifier = Modifier
.voidMarker(part.crStatus)
.clickable {
selectedArchivedTransaction = 0
}
Expand Down Expand Up @@ -529,7 +531,7 @@ class TransactionDetailFragment : ComposeBaseDialogFragment3() {
withDate: Boolean = false
) {
Row(
modifier = modifier,
modifier = modifier.voidMarker(part.crStatus),
verticalAlignment = Alignment.CenterVertically
) {
if (withDate) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ fun SupportSQLiteDatabase.unarchive(
}
}

private const val ARCHIVE_SELECTION = "$KEY_ACCOUNTID = ? AND $KEY_PARENTID is null AND $KEY_STATUS != $STATUS_UNCOMMITTED AND $KEY_DATE > ? AND $KEY_DATE < ?"
private const val ARCHIVE_SELECTION =
"$KEY_ACCOUNTID = ? AND $KEY_PARENTID is null AND $KEY_STATUS != $STATUS_UNCOMMITTED AND $KEY_DATE > ? AND $KEY_DATE < ?"

private fun SupportSQLiteDatabase.archiveInfo(
accountId: Long,
Expand Down Expand Up @@ -111,14 +112,45 @@ private fun Bundle.parseArchiveArguments() = Triple(
fun SupportSQLiteDatabase.archive(extras: Bundle): Long {
val (accountId, start, end) = extras.parseArchiveArguments()

val (crStatus, archiveSum, archiveDate) = archiveInfo(accountId, start, end, false).use {
if (it.count > 1) throw IllegalStateException("Transactions in archive have different states.")
it.moveToFirst()
if (it.hasNested()) throw IllegalStateException("Nested archive is not supported.")
Triple(it.getString(0), it.getLong(2), it.getLong(3))
val (crStatus, archiveSum, archiveDate) = archiveInfo(
accountId,
start,
end,
false
).use { cursor ->
when (cursor.count) {
0 -> throw IllegalStateException("No transactions to archive.")
1 -> {
cursor.moveToFirst()
if (cursor.hasNested()) throw IllegalStateException("Nested archive is not supported.")
Triple(cursor.getString(0), cursor.getLong(2), cursor.getLong(3))
}

2 -> {
val states = cursor.useAndMapToMap {
it.getString(0) to Triple(
it.hasNested(),
it.getLong(2),
it.getLong(3)
)
}
if (states.any { it.value.first }) {
throw IllegalStateException("Nested archive is not supported.")
}
if (!states.containsKey(CrStatus.VOID.name)) {
throw IllegalStateException("Transactions in archive have different states.")
}
val archive = states.entries.first { it.key != CrStatus.VOID.name }
Triple(archive.key, archive.value.second, archive.value.third)
}

else -> {
throw IllegalStateException("Transactions in archive have different states.")
}
}
}

return safeUpdateWithSealed {
return safeUpdateWithSealed {
val archiveId = insert(TABLE_TRANSACTIONS, ContentValues().apply {
put(KEY_ACCOUNTID, accountId)
put(KEY_DATE, archiveDate)
Expand All @@ -144,7 +176,7 @@ fun SupportSQLiteDatabase.archive(extras: Bundle): Long {
archiveId
)
)
archiveId
archiveId
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,16 @@ fun <T> Cursor.useAndMapToSet(mapper: (Cursor) -> T) =
it.asSequence.map(mapper).toSet()
}

fun <K,V> Cursor.useAndMapToMap(mapper: (Cursor) -> Pair<K,V>) =
use {
buildMap {
it.asSequence.forEach {
val (key, value) = mapper(it)
put(key, value)
}
}
}

/**
* requires the Cursor to be positioned BEFORE first row
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import org.mockito.Mockito.mock
import org.mockito.Mockito.`when`
import org.totschnig.myexpenses.db2.Repository
import org.totschnig.myexpenses.db2.saveCategory
import org.totschnig.myexpenses.model.CrStatus
import org.totschnig.myexpenses.model.CurrencyContext
import org.totschnig.myexpenses.model.CurrencyUnit
import org.totschnig.myexpenses.model.Grouping
Expand Down Expand Up @@ -44,11 +45,17 @@ abstract class BaseTestWithRepository {
fun writeCategory(label: String, parentId: Long? = null) =
repository.saveCategory(Category(label = label, parentId = parentId))!!

protected fun insertTransaction(accountId: Long, amount: Long, categoryId: Long? = null): Pair<Long, String> {
protected fun insertTransaction(
accountId: Long,
amount: Long,
categoryId: Long? = null,
crStatus: CrStatus = CrStatus.UNRECONCILED
): Pair<Long, String> {
val contentValues = TransactionInfo(
accountId = accountId,
amount = amount,
catId = categoryId
catId = categoryId,
crStatus = crStatus
).contentValues
val id = ContentUris.parseId(contentResolver.insert(TransactionProvider.TRANSACTIONS_URI, contentValues)!!)
return id to contentValues.getAsString(DatabaseConstants.KEY_UUID)
Expand Down
Loading

0 comments on commit 6d065e0

Please sign in to comment.