Skip to content
This repository has been archived by the owner on Nov 5, 2024. It is now read-only.

Add setting to toggle keypad layout between numeric & standard #3609

Merged
merged 2 commits into from
Oct 13, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import com.ivy.domain.features.Features
import com.ivy.domain.features.IvyFeatures
import dagger.Binds
import dagger.Module
import dagger.hilt.EntryPoint
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent

Expand All @@ -13,3 +14,9 @@ interface IvyCoreBindingsModule {
@Binds
fun bindFeatures(features: IvyFeatures): Features
}

@EntryPoint
@InstallIn(SingletonComponent::class)
interface FeaturesEntryPoint {
fun getFeatures(): Features
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ interface Features {
val showCategorySearchBar: BoolFeature
val hideTotalBalance: BoolFeature
val showDecimalNumber: BoolFeature
val standardKeypadLayout: BoolFeature

val allFeatures: List<BoolFeature>
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,14 @@ class IvyFeatures @Inject constructor() : Features {
defaultValue = true
)

override val standardKeypadLayout = BoolFeature(
key = "enable_standard_keypad_layout",
group = FeatureGroup.Other,
name = "Standard keypad layout",
description = "Enable standard phone keypad layout instead of numeric calculator layout",
defaultValue = false
)

override val allFeatures: List<BoolFeature>
get() = listOf(
sortCategoriesAscending,
Expand All @@ -67,6 +75,7 @@ class IvyFeatures @Inject constructor() : Features {
showTitleSuggestions,
showCategorySearchBar,
hideTotalBalance,
standardKeypadLayout
/* will be uncommented when this functionality
* will be available across the application in up-coming PRs
showDecimalNumber
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.stringResource
Expand All @@ -39,6 +40,7 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.ivy.design.l0_system.UI
import com.ivy.design.l0_system.style
import com.ivy.domain.di.FeaturesEntryPoint
import com.ivy.legacy.IvyWalletPreview
import com.ivy.legacy.utils.amountToDouble
import com.ivy.legacy.utils.amountToDoubleOrNull
Expand All @@ -54,6 +56,7 @@ import com.ivy.wallet.ui.theme.components.IvyIcon
import com.ivy.wallet.ui.theme.modal.IvyModal
import com.ivy.wallet.ui.theme.modal.ModalPositiveButton
import com.ivy.wallet.ui.theme.modal.modalPreviewActionRowHeight
import dagger.hilt.android.EntryPointAccessors
import java.util.UUID
import kotlin.math.truncate

Expand Down Expand Up @@ -224,8 +227,7 @@ fun AmountInput(
amount: String,
decimalCountMax: Int = 2,
setAmount: (String) -> Unit,

) {
) {
var firstInput by remember { mutableStateOf(true) }

AmountKeyboard(
Expand Down Expand Up @@ -317,6 +319,36 @@ fun AmountKeyboard(
FourthRowExtra: (@Composable RowScope.() -> Unit)? = null,
onBackspace: () -> Unit,
) {
/**
* Retrieve `features` via EntryPointAccessors. `isStandardLayout` is stable and
* only changes via settings, so there isn't unnecessary recompositions.
* `isStandardLayout` doesn't change while the keyboard is shown.
* `AmountKeyboard` is self-contained, making it easy to reuse without passing parameters.
* Layout changes are rare, so recomposition has minimal impact on performance.
**/

val context = LocalContext.current
val features = EntryPointAccessors.fromApplication(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this must be remember {}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would also break previews and screenshot tests but such doesn't seem to exist

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my testing I didn't notice it breaking previews, and yes my bad it should be remember

context.applicationContext,
FeaturesEntryPoint::class.java
).getFeatures()
val isStandardLayout = features.standardKeypadLayout.asEnabledState()

// Decide the order of the numbers based on the keypad layout
val countButtonValues = if (isStandardLayout) {
listOf(
listOf("1", "2", "3"),
listOf("4", "5", "6"),
listOf("7", "8", "9"),
)
} else { // Calculator like numeric keypad layout
listOf(
listOf("7", "8", "9"),
listOf("4", "5", "6"),
listOf("1", "2", "3"),
)
}

if (ZeroRow != null) {
Row(
modifier = Modifier
Expand All @@ -331,97 +363,33 @@ fun AmountKeyboard(
Spacer(Modifier.height(8.dp))
}

Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = horizontalPadding),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceEvenly

) {
CircleNumberButton(
forCalculator = forCalculator,
value = "7",
onNumberPressed = onNumberPressed
)

CircleNumberButton(
forCalculator = forCalculator,
value = "8",
onNumberPressed = onNumberPressed
)

CircleNumberButton(
forCalculator = forCalculator,
value = "9",
onNumberPressed = onNumberPressed
)

FirstRowExtra?.invoke(this)
}

Spacer(Modifier.height(8.dp))

Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = horizontalPadding),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceEvenly
) {
CircleNumberButton(
forCalculator = forCalculator,
value = "4",
onNumberPressed = onNumberPressed
)

CircleNumberButton(
forCalculator = forCalculator,
value = "5",
onNumberPressed = onNumberPressed
)

CircleNumberButton(
forCalculator = forCalculator,
value = "6",
onNumberPressed = onNumberPressed
)

SecondRowExtra?.invoke(this)
}

Spacer(Modifier.height(8.dp))

Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = horizontalPadding),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceEvenly
) {
CircleNumberButton(
forCalculator = forCalculator,
value = "1",
onNumberPressed = onNumberPressed
)

CircleNumberButton(
forCalculator = forCalculator,
value = "2",
onNumberPressed = onNumberPressed
)
// Loop through the rows to create CircleNumberButtons
countButtonValues.forEachIndexed { rowIndex, rowNumbers ->
Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = horizontalPadding),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceEvenly
) {
rowNumbers.forEach { num ->
CircleNumberButton(
forCalculator = forCalculator,
value = num,
onNumberPressed = onNumberPressed
)
}

CircleNumberButton(
forCalculator = forCalculator,
value = "3",
onNumberPressed = onNumberPressed
)
when (rowIndex) {
0 -> FirstRowExtra?.invoke(this)
1 -> SecondRowExtra?.invoke(this)
2 -> ThirdRowExtra?.invoke(this)
}
}

ThirdRowExtra?.invoke(this)
Spacer(Modifier.height(8.dp))
}

Spacer(Modifier.height(8.dp))

Row(
modifier = Modifier
.fillMaxWidth()
Expand Down