Move more Start and due date logic into composables

pull/1952/head
Alex Baker 2 years ago
parent e39bc8b8cc
commit 5c3af50c9d

@ -5,6 +5,7 @@ import android.content.Context
import android.content.Intent
import android.content.res.Configuration
import android.os.Bundle
import android.view.ViewGroup
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material.ContentAlpha
@ -12,6 +13,7 @@ import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.stringResource
@ -26,6 +28,8 @@ import com.todoroo.andlib.utility.DateUtilities.now
import com.todoroo.astrid.ui.StartDateControlSet.Companion.getRelativeDateString
import dagger.hilt.android.AndroidEntryPoint
import org.tasks.R
import org.tasks.compose.TaskEditIcon
import org.tasks.compose.TaskEditRow
import org.tasks.compose.collectAsStateLifecycleAware
import org.tasks.date.DateTimeUtils.newDateTime
import org.tasks.dialogs.StartDatePicker
@ -39,6 +43,7 @@ import org.tasks.dialogs.StartDatePicker.Companion.NO_TIME
import org.tasks.dialogs.StartDatePicker.Companion.WEEK_BEFORE_DUE
import org.tasks.preferences.Preferences
import org.tasks.ui.TaskEditControlComposeFragment
import org.tasks.ui.TaskEditViewModel
import java.time.format.FormatStyle
import java.util.*
import javax.inject.Inject
@ -50,19 +55,6 @@ class StartDateControlSet : TaskEditControlComposeFragment() {
private val vm: StartDateViewModel by viewModels()
override fun onRowClick() {
val fragmentManager = parentFragmentManager
if (fragmentManager.findFragmentByTag(FRAG_TAG_DATE_PICKER) == null) {
StartDatePicker.newDateTimePicker(
this,
REQUEST_START_DATE,
vm.selectedDay.value,
vm.selectedTime.value,
preferences.getBoolean(R.string.p_auto_dismiss_datetime_edit_screen, false))
.show(fragmentManager, FRAG_TAG_DATE_PICKER)
}
}
override fun createView(savedInstanceState: Bundle?) {
if (savedInstanceState == null) {
vm.init(viewModel.dueDate.value, viewModel.startDate.value, viewModel.isNew)
@ -74,23 +66,39 @@ class StartDateControlSet : TaskEditControlComposeFragment() {
}
}
@Composable
override fun Body() {
StartDate(
startDate = viewModel.startDate.collectAsStateLifecycleAware().value,
selectedDay = vm.selectedDay.collectAsStateLifecycleAware().value,
selectedTime = vm.selectedTime.collectAsStateLifecycleAware().value,
displayFullDate = preferences.alwaysDisplayFullDate,
locale = locale,
)
}
override val icon = R.drawable.ic_pending_actions_24px
override fun bind(parent: ViewGroup?) =
(parent as ComposeView).apply {
setContent {
MdcTheme {
StartDateRow(
viewModel = viewModel,
vm = vm,
preferences = preferences,
locale = locale,
onClick = {
val fragmentManager = parentFragmentManager
if (fragmentManager.findFragmentByTag(FRAG_TAG_DATE_PICKER) == null) {
StartDatePicker.newDateTimePicker(
this@StartDateControlSet,
REQUEST_START_DATE,
vm.selectedDay.value,
vm.selectedTime.value,
preferences.getBoolean(
R.string.p_auto_dismiss_datetime_edit_screen,
false
)
)
.show(fragmentManager, FRAG_TAG_DATE_PICKER)
}
}
)
}
}
}
override fun controlId() = TAG
override val isClickable = true
@Deprecated("Deprecated in Java")
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == REQUEST_START_DATE) {
if (resultCode == Activity.RESULT_OK) {
@ -123,6 +131,41 @@ class StartDateControlSet : TaskEditControlComposeFragment() {
}
}
@Composable
fun StartDateRow(
viewModel: TaskEditViewModel,
vm: StartDateViewModel,
preferences: Preferences,
locale: Locale,
onClick: () -> Unit,
) {
TaskEditRow(
icon = {
TaskEditIcon(
id = R.drawable.ic_pending_actions_24px,
modifier = Modifier
.padding(
start = 16.dp,
top = 20.dp,
end = 32.dp,
bottom = 20.dp
)
)
},
content = {
StartDate(
startDate = viewModel.startDate.collectAsStateLifecycleAware().value,
selectedDay = vm.selectedDay.collectAsStateLifecycleAware().value,
selectedTime = vm.selectedTime.collectAsStateLifecycleAware().value,
displayFullDate = preferences.alwaysDisplayFullDate,
locale = locale,
hasDueDate = viewModel.dueDate.collectAsStateLifecycleAware().value > 0
)
},
onClick = onClick
)
}
@Composable
fun StartDate(
startDate: Long,
@ -131,6 +174,7 @@ fun StartDate(
displayFullDate: Boolean,
locale: Locale = Locale.getDefault(),
currentTime: Long = now(),
hasDueDate: Boolean,
) {
val context = LocalContext.current
Text(
@ -150,11 +194,14 @@ fun StartDate(
else -> stringResource(id = R.string.no_start_date)
},
color = when {
selectedDay < 0 && !hasDueDate -> colorResource(id = R.color.overdue)
startDate == 0L -> MaterialTheme.colors.onSurface.copy(alpha = ContentAlpha.disabled)
startDate < currentTime -> colorResource(id = R.color.overdue)
else -> MaterialTheme.colors.onSurface
},
modifier = Modifier.padding(vertical = 20.dp).height(24.dp),
modifier = Modifier
.padding(vertical = 20.dp)
.height(24.dp),
)
}
@ -168,7 +215,8 @@ fun NoStartDate() {
selectedDay = NO_DAY,
selectedTime = NO_TIME,
displayFullDate = false,
currentTime = 1657080392000L
currentTime = 1657080392000L,
hasDueDate = false,
)
}
}
@ -183,7 +231,8 @@ fun FutureStartDate() {
selectedDay = DUE_DATE,
selectedTime = NO_TIME,
displayFullDate = false,
currentTime = 1657080392000L
currentTime = 1657080392000L,
hasDueDate = false,
)
}
}
@ -198,7 +247,8 @@ fun PastStartDate() {
selectedDay = DUE_TIME,
selectedTime = NO_TIME,
displayFullDate = false,
currentTime = 1657080392001L
currentTime = 1657080392001L,
hasDueDate = false,
)
}
}

@ -13,6 +13,6 @@ fun TaskEditIcon(@DrawableRes id: Int, modifier: Modifier = Modifier) {
Icon(
painter = painterResource(id = id),
contentDescription = null,
modifier = modifier.alpha(ContentAlpha.high),
modifier = modifier.alpha(ContentAlpha.medium),
)
}

@ -2,25 +2,30 @@ package org.tasks.ui
import android.app.Activity
import android.content.Intent
import android.view.ViewGroup
import androidx.compose.foundation.layout.padding
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.google.android.material.composethemeadapter.MdcTheme
import com.todoroo.andlib.utility.DateUtilities
import com.todoroo.astrid.data.Task.Companion.hasDueTime
import dagger.hilt.android.AndroidEntryPoint
import org.tasks.R
import org.tasks.compose.DisabledText
import org.tasks.compose.TaskEditIcon
import org.tasks.compose.TaskEditRow
import org.tasks.compose.collectAsStateLifecycleAware
import org.tasks.date.DateTimeUtils
import org.tasks.dialogs.DateTimePicker
import org.tasks.dialogs.DateTimePicker.Companion.newDateTimePicker
import org.tasks.preferences.Preferences
import org.tasks.ui.DeadlineControlSet.Companion.isOverdue
import java.time.format.FormatStyle
import java.util.*
import javax.inject.Inject
@ -30,49 +35,29 @@ class DeadlineControlSet : TaskEditControlComposeFragment() {
@Inject lateinit var locale: Locale
@Inject lateinit var preferences: Preferences
override fun onRowClick() {
val fragmentManager = parentFragmentManager
if (fragmentManager.findFragmentByTag(FRAG_TAG_DATE_PICKER) == null) {
newDateTimePicker(
this,
REQUEST_DATE,
viewModel.dueDate.value,
preferences.getBoolean(R.string.p_auto_dismiss_datetime_edit_screen, false))
.show(fragmentManager, FRAG_TAG_DATE_PICKER)
}
}
override val isClickable = true
@Composable
override fun Body() {
val dueDate = viewModel.dueDate.collectAsStateLifecycleAware().value
if (dueDate == 0L) {
DisabledText(
text = stringResource(id = R.string.no_due_date),
modifier = Modifier.padding(vertical = 20.dp)
)
} else {
Text(
text = DateUtilities.getRelativeDateTime(
LocalContext.current,
dueDate,
locale,
FormatStyle.FULL,
preferences.alwaysDisplayFullDate,
false
),
color = if (dueDate.isOverdue) {
colorResource(id = R.color.overdue)
} else {
MaterialTheme.colors.onSurface
},
modifier = Modifier.padding(vertical = 20.dp)
)
override fun bind(parent: ViewGroup?) =
(parent as ComposeView).apply {
setContent {
MdcTheme {
DueDateRow(
viewModel = viewModel,
locale = locale,
displayFullDate = preferences.alwaysDisplayFullDate,
onClick = {
val fragmentManager = parentFragmentManager
if (fragmentManager.findFragmentByTag(FRAG_TAG_DATE_PICKER) == null) {
DateTimePicker.newDateTimePicker(
this@DeadlineControlSet,
REQUEST_DATE,
viewModel.dueDate.value,
preferences.getBoolean(R.string.p_auto_dismiss_datetime_edit_screen, false))
.show(fragmentManager, FRAG_TAG_DATE_PICKER)
}
}
)
}
}
}
}
override val icon = R.drawable.ic_outline_schedule_24px
override fun controlId() = TAG
@ -91,11 +76,68 @@ class DeadlineControlSet : TaskEditControlComposeFragment() {
private const val REQUEST_DATE = 504
private const val FRAG_TAG_DATE_PICKER = "frag_tag_date_picker"
private val Long.isOverdue: Boolean
val Long.isOverdue: Boolean
get() = if (hasDueTime(this)) {
DateTimeUtils.newDateTime(this).isBeforeNow
} else {
DateTimeUtils.newDateTime(this).endOfDay().isBeforeNow
}
}
}
@Composable
fun DueDateRow(
viewModel: TaskEditViewModel,
locale: Locale,
displayFullDate: Boolean,
onClick: () -> Unit,
) {
TaskEditRow(
icon = {
TaskEditIcon(
id = R.drawable.ic_outline_schedule_24px,
modifier = Modifier.padding(
start = 16.dp,
top = 20.dp,
end = 32.dp,
bottom = 20.dp
)
)
},
content = {
DueDate(
dueDate = viewModel.dueDate.collectAsStateLifecycleAware().value,
locale = locale,
displayFullDate = displayFullDate,
)
},
onClick = onClick,
)
}
@Composable
fun DueDate(dueDate: Long, locale: Locale, displayFullDate: Boolean) {
if (dueDate == 0L) {
DisabledText(
text = stringResource(id = R.string.no_due_date),
modifier = Modifier.padding(vertical = 20.dp)
)
} else {
Text(
text = DateUtilities.getRelativeDateTime(
LocalContext.current,
dueDate,
locale,
FormatStyle.FULL,
displayFullDate,
false
),
color = if (dueDate.isOverdue) {
colorResource(id = R.color.overdue)
} else {
MaterialTheme.colors.onSurface
},
modifier = Modifier.padding(vertical = 20.dp)
)
}
}

@ -57,5 +57,5 @@ abstract class TaskEditControlComposeFragment : TaskEditControlFragment() {
}
@Composable
protected abstract fun Body()
protected open fun Body() {}
}

@ -15,7 +15,7 @@ abstract class TaskEditControlFragment : Fragment() {
protected open val isClickable: Boolean
get() = false
protected abstract val icon: Int
protected open val icon = 0
abstract fun controlId(): Int
protected abstract fun bind(parent: ViewGroup?): View
}
Loading…
Cancel
Save