mirror of https://github.com/tasks/tasks
Move more composable logic
parent
e7b6c96576
commit
00c80337de
@ -0,0 +1,103 @@
|
|||||||
|
package org.tasks.compose.edit
|
||||||
|
|
||||||
|
import android.content.res.Configuration
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.material.Icon
|
||||||
|
import androidx.compose.material.IconButton
|
||||||
|
import androidx.compose.material.Text
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.outlined.Delete
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.core.net.toUri
|
||||||
|
import com.google.android.material.composethemeadapter.MdcTheme
|
||||||
|
import org.tasks.R
|
||||||
|
import org.tasks.compose.DisabledText
|
||||||
|
import org.tasks.compose.TaskEditRow
|
||||||
|
import org.tasks.data.TaskAttachment
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun AttachmentRow(
|
||||||
|
attachments: List<TaskAttachment>,
|
||||||
|
openAttachment: (TaskAttachment) -> Unit,
|
||||||
|
deleteAttachment: (TaskAttachment) -> Unit,
|
||||||
|
addAttachment: () -> Unit,
|
||||||
|
) {
|
||||||
|
TaskEditRow(
|
||||||
|
iconRes = R.drawable.ic_outline_attachment_24px,
|
||||||
|
content = {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier.padding(top = if (attachments.isEmpty()) 0.dp else 8.dp),
|
||||||
|
) {
|
||||||
|
attachments.forEach {
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.clickable { openAttachment(it) },
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = it.name!!,
|
||||||
|
modifier = Modifier.weight(1f),
|
||||||
|
)
|
||||||
|
IconButton(onClick = { deleteAttachment(it) }) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Outlined.Delete,
|
||||||
|
contentDescription = stringResource(
|
||||||
|
id = R.string.delete
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DisabledText(
|
||||||
|
text = stringResource(id = R.string.add_attachment),
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.clickable { addAttachment() }
|
||||||
|
.padding(
|
||||||
|
top = if (attachments.isEmpty()) 20.dp else 8.dp,
|
||||||
|
bottom = 20.dp,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Preview(showBackground = true, widthDp = 320)
|
||||||
|
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES, widthDp = 320)
|
||||||
|
@Composable
|
||||||
|
fun NoAttachments() {
|
||||||
|
MdcTheme {
|
||||||
|
AttachmentRow(
|
||||||
|
attachments = emptyList(),
|
||||||
|
openAttachment = {},
|
||||||
|
deleteAttachment = {},
|
||||||
|
addAttachment = {},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Preview(showBackground = true, widthDp = 320)
|
||||||
|
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES, widthDp = 320)
|
||||||
|
@Composable
|
||||||
|
fun AttachmentPreview() {
|
||||||
|
MdcTheme {
|
||||||
|
AttachmentRow(
|
||||||
|
attachments = listOf(
|
||||||
|
TaskAttachment("", "file://attachment.txt".toUri(), "attachment.txt")
|
||||||
|
),
|
||||||
|
openAttachment = {},
|
||||||
|
deleteAttachment = {},
|
||||||
|
addAttachment = {},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,93 @@
|
|||||||
|
package org.tasks.compose.edit
|
||||||
|
|
||||||
|
import android.content.res.Configuration
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.material.ContentAlpha
|
||||||
|
import androidx.compose.material.Icon
|
||||||
|
import androidx.compose.material.IconButton
|
||||||
|
import androidx.compose.material.Text
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.outlined.Delete
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.alpha
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.google.android.material.composethemeadapter.MdcTheme
|
||||||
|
import org.tasks.R
|
||||||
|
import org.tasks.compose.DisabledText
|
||||||
|
import org.tasks.compose.TaskEditRow
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun CalendarRow(
|
||||||
|
eventUri: String?,
|
||||||
|
selectedCalendar: String?,
|
||||||
|
onClick: () -> Unit,
|
||||||
|
clear: () -> Unit,
|
||||||
|
) {
|
||||||
|
TaskEditRow(
|
||||||
|
iconRes = R.drawable.ic_outline_event_24px,
|
||||||
|
content = {
|
||||||
|
if (eventUri?.isNotBlank() == true) {
|
||||||
|
Row {
|
||||||
|
Text(
|
||||||
|
text = stringResource(id = R.string.gcal_TEA_showCalendar_label),
|
||||||
|
modifier = Modifier
|
||||||
|
.weight(1f)
|
||||||
|
.padding(vertical = 20.dp)
|
||||||
|
)
|
||||||
|
IconButton(
|
||||||
|
onClick = { clear() },
|
||||||
|
Modifier.padding(vertical = 8.dp),
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Outlined.Delete,
|
||||||
|
contentDescription = stringResource(id = R.string.delete),
|
||||||
|
modifier = Modifier.alpha(ContentAlpha.medium),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (selectedCalendar?.isNotBlank() == true) {
|
||||||
|
Text(
|
||||||
|
text = selectedCalendar,
|
||||||
|
modifier = Modifier.padding(vertical = 20.dp),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
DisabledText(
|
||||||
|
text = stringResource(id = R.string.dont_add_to_calendar),
|
||||||
|
modifier = Modifier.padding(vertical = 20.dp),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onClick = onClick
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Preview(showBackground = true, widthDp = 320)
|
||||||
|
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES, widthDp = 320)
|
||||||
|
@Composable
|
||||||
|
fun NoCalendar() {
|
||||||
|
MdcTheme {
|
||||||
|
CalendarRow(eventUri = null, selectedCalendar = null, onClick = {}, clear = {})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Preview(showBackground = true, widthDp = 320)
|
||||||
|
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES, widthDp = 320)
|
||||||
|
@Composable
|
||||||
|
fun NewCalendar() {
|
||||||
|
MdcTheme {
|
||||||
|
CalendarRow(eventUri = null, selectedCalendar = "Personal", onClick = {}, clear = {})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Preview(showBackground = true, widthDp = 320)
|
||||||
|
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES, widthDp = 320)
|
||||||
|
@Composable
|
||||||
|
fun ExistingCalendar() {
|
||||||
|
MdcTheme {
|
||||||
|
CalendarRow(eventUri = "abcd", selectedCalendar = null, onClick = {}, clear = {})
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,73 @@
|
|||||||
|
package org.tasks.compose.edit
|
||||||
|
|
||||||
|
import android.content.res.Configuration
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.material.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.ExperimentalComposeUiApi
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.google.android.material.composethemeadapter.MdcTheme
|
||||||
|
import org.tasks.R
|
||||||
|
import org.tasks.compose.TaskEditRow
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun InfoRow(
|
||||||
|
creationDate: Long?,
|
||||||
|
modificationDate: Long?,
|
||||||
|
completionDate: Long?,
|
||||||
|
locale: Locale = Locale.getDefault(),
|
||||||
|
) {
|
||||||
|
TaskEditRow(
|
||||||
|
iconRes = R.drawable.ic_outline_info_24px,
|
||||||
|
content = {
|
||||||
|
Column(modifier = Modifier.padding(vertical = 20.dp)) {
|
||||||
|
val formatter = SimpleDateFormat("yyyy-MM-dd HH:mm", locale)
|
||||||
|
creationDate?.let {
|
||||||
|
Text(
|
||||||
|
text = stringResource(
|
||||||
|
id = R.string.sort_created_group,
|
||||||
|
formatter.format(it)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
modificationDate?.let {
|
||||||
|
Text(
|
||||||
|
text = stringResource(
|
||||||
|
id = R.string.sort_modified_group,
|
||||||
|
formatter.format(it)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
completionDate?.takeIf { it > 0 }?.let {
|
||||||
|
Text(
|
||||||
|
text = stringResource(
|
||||||
|
id = R.string.sort_completion_group,
|
||||||
|
formatter.format(it)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExperimentalComposeUiApi
|
||||||
|
@Preview(showBackground = true, widthDp = 320)
|
||||||
|
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES, widthDp = 320)
|
||||||
|
@Composable
|
||||||
|
fun InfoPreview() {
|
||||||
|
MdcTheme {
|
||||||
|
InfoRow(
|
||||||
|
creationDate = 1658727180000,
|
||||||
|
modificationDate = 1658813557000,
|
||||||
|
completionDate = 1658813557000,
|
||||||
|
locale = Locale.US,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,125 @@
|
|||||||
|
package org.tasks.compose.edit
|
||||||
|
|
||||||
|
import android.content.res.Configuration
|
||||||
|
import android.text.format.DateUtils
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.material.ContentAlpha
|
||||||
|
import androidx.compose.material.Icon
|
||||||
|
import androidx.compose.material.IconButton
|
||||||
|
import androidx.compose.material.Text
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.outlined.Pause
|
||||||
|
import androidx.compose.material.icons.outlined.PlayArrow
|
||||||
|
import androidx.compose.runtime.*
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.alpha
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.google.android.material.composethemeadapter.MdcTheme
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
|
import org.tasks.R
|
||||||
|
import org.tasks.compose.DisabledText
|
||||||
|
import org.tasks.compose.TaskEditRow
|
||||||
|
import kotlin.time.Duration.Companion.seconds
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun TimerRow(
|
||||||
|
started: Long,
|
||||||
|
estimated: Int,
|
||||||
|
elapsed: Int,
|
||||||
|
timerClicked: () -> Unit,
|
||||||
|
onClick: () -> Unit,
|
||||||
|
) {
|
||||||
|
TaskEditRow(
|
||||||
|
iconRes = R.drawable.ic_outline_timer_24px,
|
||||||
|
content = {
|
||||||
|
var now by remember { mutableStateOf(System.currentTimeMillis()) }
|
||||||
|
|
||||||
|
val newElapsed = if (started > 0) (now - started) / 1000L else 0
|
||||||
|
val estimatedString = estimated
|
||||||
|
.takeIf { it > 0 }
|
||||||
|
?.let {
|
||||||
|
stringResource(
|
||||||
|
id = R.string.TEA_timer_est,
|
||||||
|
DateUtils.formatElapsedTime(it.toLong())
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val elapsedString =
|
||||||
|
(newElapsed + elapsed)
|
||||||
|
.takeIf { it > 0 }
|
||||||
|
?.let {
|
||||||
|
stringResource(
|
||||||
|
id = R.string.TEA_timer_elap,
|
||||||
|
DateUtils.formatElapsedTime(it)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val text = when {
|
||||||
|
estimatedString != null && elapsedString != null -> "$estimatedString, $elapsedString"
|
||||||
|
estimatedString != null -> estimatedString
|
||||||
|
elapsedString != null -> elapsedString
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
Row {
|
||||||
|
if (text == null) {
|
||||||
|
DisabledText(
|
||||||
|
text = stringResource(id = R.string.TEA_timer_controls),
|
||||||
|
modifier = Modifier
|
||||||
|
.weight(1f)
|
||||||
|
.padding(vertical = 20.dp),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
Text(
|
||||||
|
text = text,
|
||||||
|
modifier = Modifier
|
||||||
|
.weight(1f)
|
||||||
|
.padding(vertical = 20.dp),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
IconButton(
|
||||||
|
onClick = {
|
||||||
|
now = System.currentTimeMillis()
|
||||||
|
timerClicked()
|
||||||
|
},
|
||||||
|
modifier = Modifier.padding(vertical = 8.dp),
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
imageVector = if (started > 0) {
|
||||||
|
Icons.Outlined.Pause
|
||||||
|
} else {
|
||||||
|
Icons.Outlined.PlayArrow
|
||||||
|
},
|
||||||
|
modifier = Modifier.alpha(ContentAlpha.medium),
|
||||||
|
contentDescription = null
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LaunchedEffect(key1 = started) {
|
||||||
|
while (started > 0) {
|
||||||
|
delay(1.seconds)
|
||||||
|
now = System.currentTimeMillis()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onClick = onClick
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Preview(showBackground = true, widthDp = 320)
|
||||||
|
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES, widthDp = 320)
|
||||||
|
@Composable
|
||||||
|
fun NoTimer() {
|
||||||
|
MdcTheme {
|
||||||
|
TimerRow(started = 0, estimated = 0, elapsed = 0, timerClicked = {}, onClick = {})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Preview(showBackground = true, widthDp = 320)
|
||||||
|
@Preview(showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES, widthDp = 320)
|
||||||
|
@Composable
|
||||||
|
fun RunningTimer() {
|
||||||
|
MdcTheme {
|
||||||
|
TimerRow(started = System.currentTimeMillis(), estimated = 900, elapsed = 400, timerClicked = {}, onClick = {})
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,50 +1,36 @@
|
|||||||
package org.tasks.ui
|
package org.tasks.ui
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Column
|
import android.view.View
|
||||||
import androidx.compose.foundation.layout.padding
|
import android.view.ViewGroup
|
||||||
import androidx.compose.material.Text
|
import androidx.compose.ui.platform.ComposeView
|
||||||
import androidx.compose.runtime.Composable
|
import com.google.android.material.composethemeadapter.MdcTheme
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import org.tasks.R
|
import org.tasks.R
|
||||||
import org.tasks.preferences.Preferences
|
import org.tasks.compose.edit.InfoRow
|
||||||
import java.text.SimpleDateFormat
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class CreationDateControlSet : TaskEditControlComposeFragment() {
|
class CreationDateControlSet : TaskEditControlFragment() {
|
||||||
@Inject lateinit var locale: Locale
|
@Inject lateinit var locale: Locale
|
||||||
|
|
||||||
@Composable
|
override fun bind(parent: ViewGroup?): View =
|
||||||
override fun Body() {
|
(parent as ComposeView).apply {
|
||||||
Column(modifier = Modifier.padding(vertical = 20.dp)) {
|
setContent {
|
||||||
val formatter = SimpleDateFormat("yyyy-MM-dd HH:mm", locale)
|
MdcTheme {
|
||||||
viewModel.creationDate?.let {
|
InfoRow(
|
||||||
Text(
|
creationDate = viewModel.creationDate,
|
||||||
text = stringResource(id = R.string.sort_created_group, formatter.format(it))
|
modificationDate = viewModel.modificationDate,
|
||||||
)
|
completionDate = viewModel.completionDate,
|
||||||
}
|
locale = locale,
|
||||||
viewModel.modificationDate?.let {
|
)
|
||||||
Text(
|
}
|
||||||
text = stringResource(id = R.string.sort_modified_group, formatter.format(it))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
viewModel.completionDate?.takeIf { it > 0 }?.let {
|
|
||||||
Text(
|
|
||||||
text = stringResource(id = R.string.sort_completion_group, formatter.format(it))
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
override val icon = R.drawable.ic_outline_info_24px
|
|
||||||
|
|
||||||
override fun controlId() = TAG
|
override fun controlId() = TAG
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = R.string.TEA_ctrl_creation_date
|
const val TAG = R.string.TEA_ctrl_creation_date
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,61 +0,0 @@
|
|||||||
package org.tasks.ui
|
|
||||||
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.material.ContentAlpha
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.draw.alpha
|
|
||||||
import androidx.compose.ui.platform.ComposeView
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import androidx.lifecycle.ViewModelProvider
|
|
||||||
import com.google.android.material.composethemeadapter.MdcTheme
|
|
||||||
import org.tasks.compose.TaskEditIcon
|
|
||||||
import org.tasks.compose.TaskEditRow
|
|
||||||
|
|
||||||
abstract class TaskEditControlComposeFragment : TaskEditControlFragment() {
|
|
||||||
|
|
||||||
override fun onCreateView(
|
|
||||||
inflater: LayoutInflater,
|
|
||||||
container: ViewGroup?,
|
|
||||||
savedInstanceState: Bundle?
|
|
||||||
): View? {
|
|
||||||
val composeView = ComposeView(requireActivity())
|
|
||||||
viewModel = ViewModelProvider(requireParentFragment())[TaskEditViewModel::class.java]
|
|
||||||
bind(composeView)
|
|
||||||
createView(savedInstanceState)
|
|
||||||
return composeView
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun bind(parent: ViewGroup?): View =
|
|
||||||
(parent as ComposeView).apply {
|
|
||||||
setContent {
|
|
||||||
MdcTheme {
|
|
||||||
TaskEditRow(
|
|
||||||
icon = { Icon() },
|
|
||||||
content = { Body() },
|
|
||||||
onClick = if (this@TaskEditControlComposeFragment.isClickable)
|
|
||||||
this@TaskEditControlComposeFragment::onRowClick
|
|
||||||
else
|
|
||||||
null
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
protected open fun Icon() {
|
|
||||||
TaskEditIcon(
|
|
||||||
id = icon,
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(start = 16.dp, top = 20.dp, end = 32.dp, bottom = 20.dp)
|
|
||||||
.alpha(ContentAlpha.medium),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
protected open fun Body() {}
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue