Skip to content

Commit 64f3f47

Browse files
authored
fix: Improve IntegerInput and expand ranges (#78)
2 parents 19ce942 + f0a75e3 commit 64f3f47

6 files changed

Lines changed: 111 additions & 166 deletions

File tree

app/build.gradle.kts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ android {
1919
applicationId = "co.adityarajput.notifilter"
2020
minSdk = 29
2121
targetSdk = 36
22-
versionCode = 26
23-
versionName = "4.8.0"
22+
versionCode = 27
23+
versionName = "4.8.1"
2424

2525
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
2626
}

app/src/main/java/co/adityarajput/notifilter/data/models/Action.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ sealed class Action {
9292
val entries by lazy {
9393
listOf(
9494
DISMISS, TAP_NOTIFICATION, TAP_BUTTON(""), BATCH(3),
95-
DELAY, DEBOUNCE(2), MUTE, ALERT, DISTURB(5), DISMISS_STALE(10),
95+
DELAY, DEBOUNCE(2), MUTE, ALERT, DISTURB(5), DISMISS_STALE(15),
9696
)
9797
}
9898

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package co.adityarajput.notifilter.views.screens
2+
3+
import androidx.compose.foundation.combinedClickable
4+
import androidx.compose.foundation.layout.*
5+
import androidx.compose.material3.Icon
6+
import androidx.compose.material3.Text
7+
import androidx.compose.runtime.Composable
8+
import androidx.compose.ui.Alignment
9+
import androidx.compose.ui.Modifier
10+
import androidx.compose.ui.res.dimensionResource
11+
import androidx.compose.ui.res.painterResource
12+
import androidx.compose.ui.res.stringResource
13+
import co.adityarajput.notifilter.R
14+
import kotlin.math.max
15+
import kotlin.math.min
16+
17+
@Composable
18+
fun IntegerInput(
19+
value: Int,
20+
minValue: Int,
21+
maxValue: Int,
22+
stringResource: Int,
23+
delta: Int = 1,
24+
largeDelta: Int = delta * 5,
25+
padLength: Int = 2,
26+
onValueChange: (Int) -> Unit,
27+
) {
28+
Row(
29+
Modifier.fillMaxWidth(),
30+
Arrangement.Center,
31+
Alignment.CenterVertically,
32+
) {
33+
Box(
34+
Modifier
35+
.padding(dimensionResource(R.dimen.padding_small))
36+
.combinedClickable(
37+
onClick = { onValueChange(max(minValue, value - delta)) },
38+
onLongClick = { onValueChange(max(minValue, value - largeDelta)) },
39+
),
40+
) {
41+
Icon(
42+
painterResource(R.drawable.remove),
43+
contentDescription = stringResource(R.string.alttext_subtract),
44+
)
45+
}
46+
Text(
47+
stringResource(
48+
stringResource,
49+
value.toString().padStart(padLength, '0'),
50+
),
51+
)
52+
Box(
53+
Modifier
54+
.padding(dimensionResource(R.dimen.padding_small))
55+
.combinedClickable(
56+
onClick = { onValueChange(min(maxValue, value + delta)) },
57+
onLongClick = { onValueChange(min(maxValue, value + largeDelta)) },
58+
),
59+
) {
60+
Icon(
61+
painterResource(R.drawable.add),
62+
contentDescription = stringResource(R.string.alttext_add),
63+
)
64+
}
65+
}
66+
}

app/src/main/java/co/adityarajput/notifilter/views/screens/UpsertFilterScreen.kt

Lines changed: 39 additions & 161 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import androidx.compose.ui.Modifier
2121
import androidx.compose.ui.graphics.Color
2222
import androidx.compose.ui.platform.LocalContext
2323
import androidx.compose.ui.res.dimensionResource
24-
import androidx.compose.ui.res.painterResource
2524
import androidx.compose.ui.res.stringArrayResource
2625
import androidx.compose.ui.res.stringResource
2726
import androidx.compose.ui.text.AnnotatedString
@@ -555,94 +554,33 @@ private fun ColumnScope.ActionPage(viewModel: UpsertFilterViewModel) {
555554
}
556555
}
557556
AnimatedVisibility(it is Action.BATCH && viewModel.state.values.action is Action.BATCH) {
558-
Row(
559-
Modifier.fillMaxWidth(),
560-
Arrangement.Center,
561-
Alignment.CenterVertically,
562-
) {
563-
val batchLength = (viewModel.state.values.action as? Action.BATCH)?.batchLength ?: 3
564-
IconButton(
565-
{
566-
viewModel.updateForm(
567-
viewModel.state.page,
568-
viewModel.state.values.copy(action = Action.BATCH((batchLength - 1))),
569-
)
570-
},
571-
enabled = batchLength > 1,
572-
) {
573-
Icon(
574-
painterResource(R.drawable.remove),
575-
contentDescription = stringResource(R.string.alttext_subtract),
576-
)
577-
}
578-
Text(
579-
stringResource(
580-
R.string.batch_frequency,
581-
batchLength.toString().padStart(2, '0'),
582-
),
557+
IntegerInput(
558+
(viewModel.state.values.action as? Action.BATCH)?.batchLength ?: 3,
559+
1,
560+
12,
561+
R.string.batch_frequency,
562+
) { value ->
563+
viewModel.updateForm(
564+
viewModel.state.page,
565+
viewModel.state.values.copy(action = Action.BATCH(value)),
583566
)
584-
IconButton(
585-
{
586-
viewModel.updateForm(
587-
viewModel.state.page,
588-
viewModel.state.values.copy(action = Action.BATCH((batchLength + 1))),
589-
)
590-
},
591-
enabled = batchLength < 12,
592-
) {
593-
Icon(
594-
painterResource(R.drawable.add),
595-
contentDescription = stringResource(R.string.alttext_add),
596-
)
597-
}
598567
}
599568
}
600569
AnimatedVisibility(it is Action.DEBOUNCE && viewModel.state.values.action is Action.DEBOUNCE) {
601570
Column(
602571
Modifier.fillMaxWidth(),
603572
Arrangement.spacedBy(dimensionResource(R.dimen.padding_medium)),
604573
) {
605-
Row(
606-
Modifier.fillMaxWidth(),
607-
Arrangement.Center,
608-
Alignment.CenterVertically,
609-
) {
610-
val cooldownLength =
611-
(viewModel.state.values.action as? Action.DEBOUNCE)?.cooldownLength ?: 2
612-
IconButton(
613-
{
614-
viewModel.updateForm(
615-
viewModel.state.page,
616-
viewModel.state.values.copy(action = Action.DEBOUNCE((cooldownLength - 1))),
617-
)
618-
},
619-
enabled = cooldownLength > 1,
620-
) {
621-
Icon(
622-
painterResource(R.drawable.remove),
623-
contentDescription = stringResource(R.string.alttext_subtract),
624-
)
625-
}
626-
Text(
627-
stringResource(
628-
R.string.cooldown_length,
629-
cooldownLength.toString().padStart(2, '0'),
630-
),
574+
IntegerInput(
575+
(viewModel.state.values.action as? Action.DEBOUNCE)?.cooldownLength ?: 2,
576+
1,
577+
30,
578+
R.string.cooldown_length,
579+
) { value ->
580+
viewModel.updateForm(
581+
viewModel.state.page,
582+
viewModel.state.values.copy(action = Action.DEBOUNCE(value)),
631583
)
632-
IconButton(
633-
{
634-
viewModel.updateForm(
635-
viewModel.state.page,
636-
viewModel.state.values.copy(action = Action.DEBOUNCE((cooldownLength + 1))),
637-
)
638-
},
639-
enabled = cooldownLength < 15,
640-
) {
641-
Icon(
642-
painterResource(R.drawable.add),
643-
contentDescription = stringResource(R.string.alttext_add),
644-
)
645-
}
646584
}
647585
Text(
648586
stringResource(R.string.explain_debounce),
@@ -682,47 +620,16 @@ private fun ColumnScope.ActionPage(viewModel: UpsertFilterViewModel) {
682620
Modifier.fillMaxWidth(),
683621
Arrangement.spacedBy(dimensionResource(R.dimen.padding_medium)),
684622
) {
685-
Row(
686-
Modifier.fillMaxWidth(),
687-
Arrangement.Center,
688-
Alignment.CenterVertically,
689-
) {
690-
val pauseLength =
691-
(viewModel.state.values.action as? Action.DISTURB)?.pauseLength ?: 5
692-
IconButton(
693-
{
694-
viewModel.updateForm(
695-
viewModel.state.page,
696-
viewModel.state.values.copy(action = Action.DISTURB((pauseLength - 1))),
697-
)
698-
},
699-
enabled = pauseLength > 1,
700-
) {
701-
Icon(
702-
painterResource(R.drawable.remove),
703-
contentDescription = stringResource(R.string.alttext_subtract),
704-
)
705-
}
706-
Text(
707-
stringResource(
708-
R.string.pause_length,
709-
pauseLength.toString().padStart(2, '0'),
710-
),
623+
IntegerInput(
624+
(viewModel.state.values.action as? Action.DISTURB)?.pauseLength ?: 5,
625+
1,
626+
30,
627+
R.string.pause_length,
628+
) { value ->
629+
viewModel.updateForm(
630+
viewModel.state.page,
631+
viewModel.state.values.copy(action = Action.DISTURB(value)),
711632
)
712-
IconButton(
713-
{
714-
viewModel.updateForm(
715-
viewModel.state.page,
716-
viewModel.state.values.copy(action = Action.DISTURB((pauseLength + 1))),
717-
)
718-
},
719-
enabled = pauseLength < 15,
720-
) {
721-
Icon(
722-
painterResource(R.drawable.add),
723-
contentDescription = stringResource(R.string.alttext_add),
724-
)
725-
}
726633
}
727634
if (!hasPermissions.getValue(Permission.NOTIFICATION_POLICY)) {
728635
ErrorText(R.string.notification_policy_permission_description)
@@ -747,48 +654,19 @@ private fun ColumnScope.ActionPage(viewModel: UpsertFilterViewModel) {
747654
Modifier.fillMaxWidth(),
748655
Arrangement.spacedBy(dimensionResource(R.dimen.padding_medium)),
749656
) {
750-
Row(
751-
Modifier.fillMaxWidth(),
752-
Arrangement.Center,
753-
Alignment.CenterVertically,
754-
) {
755-
val retentionLength =
756-
(viewModel.state.values.action as? Action.DISMISS_STALE)?.retentionLength
757-
?: 10
758-
IconButton(
759-
{
760-
viewModel.updateForm(
761-
viewModel.state.page,
762-
viewModel.state.values.copy(action = Action.DISMISS_STALE((retentionLength - 5))),
763-
)
764-
},
765-
enabled = retentionLength > 5,
766-
) {
767-
Icon(
768-
painterResource(R.drawable.remove),
769-
contentDescription = stringResource(R.string.alttext_subtract),
770-
)
771-
}
772-
Text(
773-
stringResource(
774-
R.string.retention_length,
775-
retentionLength.toString().padStart(2, '0'),
776-
),
657+
IntegerInput(
658+
(viewModel.state.values.action as? Action.DISMISS_STALE)?.retentionLength ?: 15,
659+
5,
660+
300,
661+
R.string.retention_length,
662+
5,
663+
30,
664+
3,
665+
) { value ->
666+
viewModel.updateForm(
667+
viewModel.state.page,
668+
viewModel.state.values.copy(action = Action.DISMISS_STALE(value)),
777669
)
778-
IconButton(
779-
{
780-
viewModel.updateForm(
781-
viewModel.state.page,
782-
viewModel.state.values.copy(action = Action.DISMISS_STALE((retentionLength + 5))),
783-
)
784-
},
785-
enabled = retentionLength < 60,
786-
) {
787-
Icon(
788-
painterResource(R.drawable.add),
789-
contentDescription = stringResource(R.string.alttext_add),
790-
)
791-
}
792670
}
793671
if (!hasPermissions.getValue(Permission.SCHEDULE_EXACT_ALARM)) {
794672
ErrorText(R.string.exact_alarm_permission_description)

app/src/main/res/values/strings.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<resources>
33
<string name="app_name" translatable="false">NotiFilter</string>
44
<string name="app_name_launcher" translatable="false">NotiFilter</string>
5-
<string name="app_version" translatable="false">4.8.0</string>
5+
<string name="app_version" translatable="false">4.8.1</string>
66

77
<!-- region FiltersScreen -->
88
<string name="no_filters">No filters added.\nTap + to get started.</string>
@@ -115,7 +115,7 @@
115115
<string name="pause_length">Enable after %1$s min(s)</string>
116116
<string name="notification_policy_permission_description">NotiFilter requires access to the Notification Policy to change DND status.</string>
117117
<string name="dismiss_stale_long">Remove stale notifications</string>
118-
<string name="retention_length">Dismiss after %1$s min(s)</string>
118+
<string name="retention_length">Dismiss after %1$s mins</string>
119119
<string name="exact_alarm_permission_description">NotiFilter requires exemption from battery optimization to execute delayed dismissal.</string>
120120
<string name="display_options">Choose where to display caught notification</string>
121121
<string name="describe_history_screen">In-app History screen</string>

metadata/en-US/changelogs/27.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
fix: Improve "IntegerInput" and expand ranges

0 commit comments

Comments
 (0)