Add recurring reminders

pull/1806/head
Alex Baker 4 years ago
parent 50dde0b4c8
commit 73eeec9663

@ -227,6 +227,7 @@ dependencies {
implementation("androidx.compose.runtime:runtime-livedata:${Versions.compose}") implementation("androidx.compose.runtime:runtime-livedata:${Versions.compose}")
implementation("com.google.android.material:compose-theme-adapter:${Versions.compose_theme_adapter}") implementation("com.google.android.material:compose-theme-adapter:${Versions.compose_theme_adapter}")
implementation("androidx.activity:activity-compose:1.4.0") implementation("androidx.activity:activity-compose:1.4.0")
implementation("androidx.compose.material:material-icons-extended:${Versions.compose}")
releaseCompileOnly("androidx.compose.ui:ui-tooling:${Versions.compose}") releaseCompileOnly("androidx.compose.ui:ui-tooling:${Versions.compose}")
googleplayImplementation("com.google.firebase:firebase-crashlytics:${Versions.crashlytics}") googleplayImplementation("com.google.firebase:firebase-crashlytics:${Versions.crashlytics}")

@ -3,7 +3,6 @@ package org.tasks.compose
import android.content.res.Configuration import android.content.res.Configuration
import androidx.annotation.StringRes import androidx.annotation.StringRes
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
@ -14,13 +13,16 @@ import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
import androidx.compose.material.AlertDialog import androidx.compose.material.AlertDialog
import androidx.compose.material.Divider
import androidx.compose.material.Icon
import androidx.compose.material.IconButton
import androidx.compose.material.MaterialTheme import androidx.compose.material.MaterialTheme
import androidx.compose.material.OutlinedTextField import androidx.compose.material.OutlinedTextField
import androidx.compose.material.RadioButton import androidx.compose.material.RadioButton
import androidx.compose.material.Text import androidx.compose.material.Text
import androidx.compose.material.TextFieldDefaults import androidx.compose.material.TextFieldDefaults
import androidx.compose.material.darkColors import androidx.compose.material.icons.Icons
import androidx.compose.material.lightColors import androidx.compose.material.icons.outlined.Autorenew
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.MutableState import androidx.compose.runtime.MutableState
@ -30,6 +32,7 @@ import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Alignment.Companion.CenterVertically import androidx.compose.ui.Alignment.Companion.CenterVertically
import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
@ -41,9 +44,12 @@ import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.core.content.res.ResourcesCompat
import com.google.android.material.composethemeadapter.MdcTheme
import kotlinx.coroutines.android.awaitFrame import kotlinx.coroutines.android.awaitFrame
import org.tasks.R import org.tasks.R
import org.tasks.data.Alarm import org.tasks.data.Alarm
import org.tasks.reminders.AlarmToString.Companion.getRepeatString
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
@ExperimentalComposeUiApi @ExperimentalComposeUiApi
@ -54,16 +60,16 @@ object AddReminderDialog {
addAlarm: (Alarm) -> Unit, addAlarm: (Alarm) -> Unit,
closeDialog: () -> Unit, closeDialog: () -> Unit,
) { ) {
val interval = rememberSaveable { mutableStateOf(15L as Long?) } val time = rememberSaveable { mutableStateOf(15) }
val multiplier = rememberSaveable { mutableStateOf(0) } val units = rememberSaveable { mutableStateOf(0) }
if (openDialog.value) { if (openDialog.value) {
AlertDialog( AlertDialog(
onDismissRequest = closeDialog, onDismissRequest = closeDialog,
text = { AddRandomReminder(openDialog, interval, multiplier) }, text = { AddRandomReminder(openDialog, time, units) },
confirmButton = { confirmButton = {
Constants.TextButton(text = R.string.ok, onClick = { Constants.TextButton(text = R.string.ok, onClick = {
interval.value?.let { i -> time.value.takeIf { it > 0 }?.let { i ->
addAlarm(Alarm(0, i * multiplier.millis, Alarm.TYPE_RANDOM)) addAlarm(Alarm(0, i * units.millis, Alarm.TYPE_RANDOM))
closeDialog() closeDialog()
} }
}) })
@ -76,8 +82,8 @@ object AddReminderDialog {
}, },
) )
} else { } else {
interval.value = 15 time.value = 15
multiplier.value = 0 units.value = 0
} }
} }
@ -87,16 +93,45 @@ object AddReminderDialog {
addAlarm: (Alarm) -> Unit, addAlarm: (Alarm) -> Unit,
closeDialog: () -> Unit, closeDialog: () -> Unit,
) { ) {
val interval = rememberSaveable { mutableStateOf(15L as Long?) } val time = rememberSaveable { mutableStateOf(15) }
val multiplier = rememberSaveable { mutableStateOf(0) } val units = rememberSaveable { mutableStateOf(0) }
if (openDialog.value) { val openRecurringDialog = rememberSaveable { mutableStateOf(false) }
val interval = rememberSaveable { mutableStateOf(0) }
val recurringUnits = rememberSaveable { mutableStateOf(0) }
val repeat = rememberSaveable { mutableStateOf(0) }
if (openDialog.value && !openRecurringDialog.value) {
AlertDialog( AlertDialog(
onDismissRequest = closeDialog, onDismissRequest = closeDialog,
text = { AddCustomReminder(openDialog, interval, multiplier) }, text = {
AddCustomReminder(
openDialog,
time,
units,
interval,
recurringUnits,
repeat,
showRecurring = {
if (interval.value == 0 && repeat.value == 0) {
interval.value = 15
recurringUnits.value = 0
repeat.value = 4
}
openRecurringDialog.value = true
}
)
},
confirmButton = { confirmButton = {
Constants.TextButton(text = R.string.ok, onClick = { Constants.TextButton(text = R.string.ok, onClick = {
interval.value?.let { i -> time.value.takeIf { it >= 0 }?.let { i ->
addAlarm(Alarm(0, -1 * i * multiplier.millis, Alarm.TYPE_REL_END)) addAlarm(
Alarm(
0,
-1 * i * units.millis,
Alarm.TYPE_REL_END,
repeat.value,
interval.value * recurringUnits.millis
)
)
closeDialog() closeDialog()
} }
}) })
@ -108,17 +143,75 @@ object AddReminderDialog {
) )
}, },
) )
} else if (openRecurringDialog.value) {
AddRepeatReminderDialog(
openDialog = openRecurringDialog,
initialInterval = interval.value,
initialUnits = recurringUnits.value,
initialRepeat = repeat.value,
selected = { i, u, r ->
interval.value = i
recurringUnits.value = u
repeat.value = r
}
)
} else { } else {
interval.value = 15 time.value = 15
multiplier.value = 0 units.value = 0
interval.value = 0
recurringUnits.value = 0
repeat.value = 0
} }
} }
@Composable
fun AddRepeatReminderDialog(
openDialog: MutableState<Boolean>,
initialInterval: Int,
initialUnits: Int,
initialRepeat: Int,
selected: (Int, Int, Int) -> Unit,
) {
val interval = rememberSaveable { mutableStateOf(initialInterval) }
val units = rememberSaveable { mutableStateOf(initialUnits) }
val repeat = rememberSaveable { mutableStateOf(initialRepeat) }
val closeDialog = {
openDialog.value = false
interval.value = initialInterval
units.value = initialUnits
repeat.value = initialRepeat
}
AlertDialog(
onDismissRequest = closeDialog,
text = {
AddRecurringReminder(
openDialog,
interval,
units,
repeat,
) },
confirmButton = {
Constants.TextButton(text = R.string.ok, onClick = {
if (interval.value > 0 && repeat.value > 0) {
selected(interval.value, units.value, repeat.value)
openDialog.value = false
}
})
},
dismissButton = {
Constants.TextButton(
text = R.string.cancel,
onClick = closeDialog
)
},
)
}
@Composable @Composable
fun AddRandomReminder( fun AddRandomReminder(
visible: MutableState<Boolean>, visible: MutableState<Boolean>,
interval: MutableState<Long?>, time: MutableState<Int>,
selected: MutableState<Int> units: MutableState<Int>,
) { ) {
val scrollState = rememberScrollState() val scrollState = rememberScrollState()
Column( Column(
@ -128,10 +221,15 @@ object AddReminderDialog {
) { ) {
CenteredH6(text = stringResource(id = R.string.randomly_every, "").trim()) CenteredH6(text = stringResource(id = R.string.randomly_every, "").trim())
val focusRequester = remember { FocusRequester() } val focusRequester = remember { FocusRequester() }
OutlinedLongInput(interval, focusRequester) OutlinedIntInput(
time,
modifier = Modifier
.fillMaxWidth()
.focusRequester(focusRequester)
)
Spacer(modifier = Modifier.height(16.dp)) Spacer(modifier = Modifier.height(16.dp))
options.forEachIndexed { index, option -> options.forEachIndexed { index, option ->
RadioRow(index, option, interval, selected) RadioRow(index, option, time, units)
} }
ShowKeyboard(visible, focusRequester) ShowKeyboard(visible, focusRequester)
} }
@ -140,8 +238,12 @@ object AddReminderDialog {
@Composable @Composable
fun AddCustomReminder( fun AddCustomReminder(
visible: MutableState<Boolean>, visible: MutableState<Boolean>,
interval: MutableState<Long?>, time: MutableState<Int>,
selected: MutableState<Int>, units: MutableState<Int>,
interval: MutableState<Int>,
recurringUnits: MutableState<Int>,
repeat: MutableState<Int>,
showRecurring: () -> Unit,
) { ) {
val scrollState = rememberScrollState() val scrollState = rememberScrollState()
Column( Column(
@ -151,15 +253,109 @@ object AddReminderDialog {
) { ) {
CenteredH6(resId = R.string.custom_notification) CenteredH6(resId = R.string.custom_notification)
val focusRequester = remember { FocusRequester() } val focusRequester = remember { FocusRequester() }
OutlinedLongInput(interval, focusRequester) OutlinedIntInput(
time,
minValue = 0,
modifier = Modifier
.fillMaxWidth()
.focusRequester(focusRequester)
)
Spacer(modifier = Modifier.height(16.dp)) Spacer(modifier = Modifier.height(16.dp))
options.forEachIndexed { index, option -> options.forEachIndexed { index, option ->
RadioRow(index, option, interval, selected, R.string.alarm_before_due) RadioRow(index, option, time, units, R.string.alarm_before_due)
}
Divider(modifier = Modifier.padding(vertical = 4.dp), thickness = 1.dp)
Row(modifier = Modifier
.fillMaxWidth()
.clickable { showRecurring() })
{
IconButton(onClick = showRecurring) {
Icon(
imageVector = Icons.Outlined.Autorenew,
contentDescription = null,
modifier = Modifier
.align(CenterVertically)
.alpha(
ResourcesCompat.getFloat(
LocalContext.current.resources,
R.dimen.alpha_secondary
)
),
)
}
val repeating = repeat.value > 0 && interval.value > 0
val text = if (repeating) {
LocalContext.current.resources.getRepeatString(
repeat.value,
interval.value * recurringUnits.millis
)
} else {
stringResource(id = R.string.repeat_option_does_not_repeat)
}
BodyText(
text = text,
modifier = Modifier
.fillMaxWidth()
.weight(1f)
.align(CenterVertically)
)
if (repeating) {
ClearButton {
repeat.value = 0
interval.value = 0
recurringUnits.value = 0
}
}
} }
ShowKeyboard(visible, focusRequester) ShowKeyboard(visible, focusRequester)
} }
} }
@Composable
fun AddRecurringReminder(
openDialog: MutableState<Boolean>,
interval: MutableState<Int>,
units: MutableState<Int>,
repeat: MutableState<Int>
) {
val scrollState = rememberScrollState()
Column(
modifier = Modifier
.fillMaxWidth()
.verticalScroll(scrollState)
) {
CenteredH6(text = stringResource(id = R.string.repeats_plural, "").trim())
val focusRequester = remember { FocusRequester() }
OutlinedIntInput(
time = interval,
modifier = Modifier.focusRequester(focusRequester),
)
Spacer(modifier = Modifier.height(16.dp))
options.forEachIndexed { index, option ->
RadioRow(index, option, interval, units)
}
Divider(modifier = Modifier.padding(vertical = 4.dp), thickness = 1.dp)
Row(modifier = Modifier.fillMaxWidth()) {
OutlinedIntInput(
time = repeat,
modifier = Modifier.weight(0.5f),
autoSelect = false,
)
BodyText(
text = LocalContext.current.resources.getQuantityString(
R.plurals.repeat_times,
repeat.value
),
modifier = Modifier
.weight(0.5f)
.align(CenterVertically)
)
}
ShowKeyboard(openDialog, focusRequester)
}
}
private val options = listOf( private val options = listOf(
R.plurals.reminder_minutes, R.plurals.reminder_minutes,
R.plurals.reminder_hours, R.plurals.reminder_hours,
@ -189,30 +385,34 @@ fun ShowKeyboard(visible: MutableState<Boolean>, focusRequester: FocusRequester)
} }
@Composable @Composable
fun OutlinedLongInput( fun OutlinedIntInput(
interval: MutableState<Long?>, time: MutableState<Int>,
focusRequester: FocusRequester modifier: Modifier = Modifier,
minValue: Int = 1,
autoSelect: Boolean = true,
) { ) {
val value = rememberSaveable(stateSaver = TextFieldValue.Saver) { val value = rememberSaveable(stateSaver = TextFieldValue.Saver) {
val text = interval.value.toString() val text = time.value.toString()
mutableStateOf(TextFieldValue(text = text, selection = TextRange(0, text.length))) mutableStateOf(
TextFieldValue(
text = text,
selection = TextRange(0, if (autoSelect) text.length else 0)
)
)
} }
OutlinedTextField( OutlinedTextField(
value = value.value, value = value.value,
onValueChange = { onValueChange = {
value.value = it.copy(text = it.text.filter { t -> t.isDigit() }) value.value = it.copy(text = it.text.filter { t -> t.isDigit() })
interval.value = value.value.text.toLongOrNull() time.value = value.value.text.toIntOrNull() ?: 0
}, },
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number), keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
modifier = Modifier modifier = modifier.padding(horizontal = 16.dp),
.fillMaxWidth()
.padding(horizontal = 16.dp)
.focusRequester(focusRequester),
colors = TextFieldDefaults.outlinedTextFieldColors( colors = TextFieldDefaults.outlinedTextFieldColors(
textColor = MaterialTheme.colors.onSurface, textColor = MaterialTheme.colors.onSurface,
focusedBorderColor = MaterialTheme.colors.onSurface focusedBorderColor = MaterialTheme.colors.onSurface
), ),
isError = value.value.text.toLongOrNull() == null, isError = value.value.text.toIntOrNull()?.let { it < minValue } ?: true,
) )
} }
@ -238,28 +438,23 @@ fun CenteredH6(text: String) {
fun RadioRow( fun RadioRow(
index: Int, index: Int,
option: Int, option: Int,
interval: MutableState<Long?>, time: MutableState<Int>,
selected: MutableState<Int>, units: MutableState<Int>,
formatString: Int? = null, formatString: Int? = null,
) { ) {
val number = interval.value?.toInt() ?: 1 val optionString = LocalContext.current.resources.getQuantityString(option, time.value)
val optionString = LocalContext.current.resources.getQuantityString(option, number)
Row( Row(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.clickable { .clickable { units.value = index }
selected.value = index
}
) { ) {
RadioButton( RadioButton(
selected = index == selected.value, selected = index == units.value,
onClick = { onClick = { units.value = index },
selected.value = index
},
modifier = Modifier.align(CenterVertically) modifier = Modifier.align(CenterVertically)
) )
Text( BodyText(
text = if (index == selected.value) { text = if (index == units.value) {
formatString formatString
?.let { stringResource(id = formatString, optionString) } ?.let { stringResource(id = formatString, optionString) }
?: optionString ?: optionString
@ -268,22 +463,34 @@ fun RadioRow(
optionString optionString
}, },
modifier = Modifier.align(CenterVertically), modifier = Modifier.align(CenterVertically),
color = MaterialTheme.colors.onSurface,
style = MaterialTheme.typography.body1,
) )
} }
} }
@Composable
fun BodyText(modifier: Modifier = Modifier, text: String) {
Text(
text = text,
modifier = modifier,
color = MaterialTheme.colors.onSurface,
style = MaterialTheme.typography.body1,
)
}
@ExperimentalComposeUiApi @ExperimentalComposeUiApi
@Preview(showBackground = true) @Preview(showBackground = true)
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES) @Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable @Composable
fun AddCustomReminderOne() = fun AddCustomReminderOne() =
MaterialTheme(if (isSystemInDarkTheme()) darkColors() else lightColors()) { MdcTheme {
AddReminderDialog.AddCustomReminder( AddReminderDialog.AddCustomReminder(
visible = remember { mutableStateOf(true) }, visible = remember { mutableStateOf(true) },
interval = remember { mutableStateOf(1L) }, time = remember { mutableStateOf(1) },
selected = remember { mutableStateOf(0) } units = remember { mutableStateOf(0) },
interval = remember { mutableStateOf(0) },
recurringUnits = remember { mutableStateOf(0) },
repeat = remember { mutableStateOf(0) },
showRecurring = {},
) )
} }
@ -292,11 +499,43 @@ fun AddCustomReminderOne() =
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES) @Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable @Composable
fun AddCustomReminder() = fun AddCustomReminder() =
MaterialTheme(if (isSystemInDarkTheme()) darkColors() else lightColors()) { MdcTheme {
AddReminderDialog.AddCustomReminder( AddReminderDialog.AddCustomReminder(
visible = remember { mutableStateOf(true) }, visible = remember { mutableStateOf(true) },
interval = remember { mutableStateOf(15L) }, time = remember { mutableStateOf(15) },
selected = remember { mutableStateOf(1) } units = remember { mutableStateOf(1) },
interval = remember { mutableStateOf(0) },
recurringUnits = remember { mutableStateOf(0) },
repeat = remember { mutableStateOf(0) },
showRecurring = {},
)
}
@ExperimentalComposeUiApi
@Preview(showBackground = true)
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
fun AddRepeatingReminderOne() =
MdcTheme {
AddReminderDialog.AddRecurringReminder(
openDialog = remember { mutableStateOf(true) },
interval = remember { mutableStateOf(1) },
units = remember { mutableStateOf(0) },
repeat = remember { mutableStateOf(1) },
)
}
@ExperimentalComposeUiApi
@Preview(showBackground = true)
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
fun AddRepeatingReminder() =
MdcTheme {
AddReminderDialog.AddRecurringReminder(
openDialog = remember { mutableStateOf(true) },
interval = remember { mutableStateOf(15) },
units = remember { mutableStateOf(1) },
repeat = remember { mutableStateOf(4) },
) )
} }
@ -305,11 +544,11 @@ fun AddCustomReminder() =
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES) @Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable @Composable
fun AddRandomReminderOne() = fun AddRandomReminderOne() =
MaterialTheme(if (isSystemInDarkTheme()) darkColors() else lightColors()) { MdcTheme {
AddReminderDialog.AddRandomReminder( AddReminderDialog.AddRandomReminder(
visible = remember { mutableStateOf(true) }, visible = remember { mutableStateOf(true) },
interval = remember { mutableStateOf(1L) }, time = remember { mutableStateOf(1) },
selected = remember { mutableStateOf(0) } units = remember { mutableStateOf(0) }
) )
} }
@ -318,10 +557,10 @@ fun AddRandomReminderOne() =
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES) @Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable @Composable
fun AddRandomReminder() = fun AddRandomReminder() =
MaterialTheme(if (isSystemInDarkTheme()) darkColors() else lightColors()) { MdcTheme {
AddReminderDialog.AddRandomReminder( AddReminderDialog.AddRandomReminder(
visible = remember { mutableStateOf(true) }, visible = remember { mutableStateOf(true) },
interval = remember { mutableStateOf(15L) }, time = remember { mutableStateOf(15) },
selected = remember { mutableStateOf(1) } units = remember { mutableStateOf(1) }
) )
} }

@ -11,13 +11,14 @@ import androidx.compose.material.Icon
import androidx.compose.material.MaterialTheme import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text import androidx.compose.material.Text
import androidx.compose.material.darkColors import androidx.compose.material.darkColors
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Clear
import androidx.compose.material.lightColors import androidx.compose.material.lightColors
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha import androidx.compose.ui.draw.alpha
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
@ -37,26 +38,28 @@ fun AlarmRow(text: String, remove: () -> Unit = {}) {
.padding(vertical = 12.dp) .padding(vertical = 12.dp)
.weight(weight = 1f), .weight(weight = 1f),
) )
Icon( ClearButton(onClick = remove)
painter = painterResource(id = R.drawable.ic_outline_clear_24px),
modifier = Modifier
.padding(12.dp)
.clickable(
interactionSource = remember { MutableInteractionSource() },
indication = null,
onClick = remove
)
.alpha(
ResourcesCompat.getFloat(
LocalContext.current.resources,
R.dimen.alpha_secondary
)
),
contentDescription = stringResource(id = R.string.delete)
)
} }
} }
@Composable
fun ClearButton(onClick: () -> Unit) {
Icon(
imageVector = Icons.Outlined.Clear,
modifier = Modifier
.padding(12.dp)
.clickable(
interactionSource = remember { MutableInteractionSource() },
indication = null,
onClick = onClick
)
.alpha(
ResourcesCompat.getFloat(LocalContext.current.resources, R.dimen.alpha_secondary)
),
contentDescription = stringResource(id = R.string.delete)
)
}
@Preview(showBackground = true) @Preview(showBackground = true)
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES) @Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable @Composable

Loading…
Cancel
Save