You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tasks/app/src/main/java/com/todoroo/astrid/ui/StartDateControlSet.kt

176 lines
6.9 KiB
Kotlin

package com.todoroo.astrid.ui
import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.view.ViewGroup
import android.widget.TextView
import com.todoroo.andlib.utility.DateUtilities
import com.todoroo.andlib.utility.DateUtilities.now
import com.todoroo.astrid.data.Task
import dagger.hilt.android.AndroidEntryPoint
import org.tasks.R
import org.tasks.databinding.ControlSetHideBinding
import org.tasks.date.DateTimeUtils.newDateTime
import org.tasks.date.DateTimeUtils.toDateTime
import org.tasks.dialogs.StartDatePicker
import org.tasks.dialogs.StartDatePicker.Companion.DAY_BEFORE_DUE
import org.tasks.dialogs.StartDatePicker.Companion.DUE_DATE
import org.tasks.dialogs.StartDatePicker.Companion.DUE_TIME
import org.tasks.dialogs.StartDatePicker.Companion.EXTRA_DAY
import org.tasks.dialogs.StartDatePicker.Companion.EXTRA_TIME
import org.tasks.dialogs.StartDatePicker.Companion.NO_DAY
import org.tasks.dialogs.StartDatePicker.Companion.NO_TIME
import org.tasks.dialogs.StartDatePicker.Companion.WEEK_BEFORE_DUE
import org.tasks.locale.Locale
import org.tasks.preferences.Preferences
import org.tasks.time.DateTimeUtils.millisOfDay
import org.tasks.time.DateTimeUtils.startOfDay
import org.tasks.ui.TaskEditControlFragment
import java.time.format.FormatStyle
import javax.inject.Inject
@AndroidEntryPoint
class StartDateControlSet : TaskEditControlFragment() {
@Inject lateinit var activity: Activity
@Inject lateinit var preferences: Preferences
@Inject lateinit var locale: Locale
private lateinit var startDate: TextView
private val dueDateTime
get() = viewModel.dueDate!!
private var selectedDay = NO_DAY
private var selectedTime = NO_TIME
override fun onRowClick() {
val fragmentManager = parentFragmentManager
if (fragmentManager.findFragmentByTag(FRAG_TAG_DATE_PICKER) == null) {
StartDatePicker.newDateTimePicker(
this,
REQUEST_HIDE_UNTIL,
selectedDay,
selectedTime,
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) {
val dueDay = dueDateTime.startOfDay()
val dueTime = dueDateTime.millisOfDay()
val hideUntil = viewModel.hideUntil?.takeIf { it > 0 }?.toDateTime()
if (hideUntil == null) {
if (viewModel.isNew) {
when (preferences.getIntegerFromString(R.string.p_default_hideUntil_key, Task.HIDE_UNTIL_NONE)) {
Task.HIDE_UNTIL_DUE -> selectedDay = DUE_DATE
Task.HIDE_UNTIL_DUE_TIME -> selectedDay = DUE_TIME
Task.HIDE_UNTIL_DAY_BEFORE -> selectedDay = DAY_BEFORE_DUE
Task.HIDE_UNTIL_WEEK_BEFORE -> selectedDay = WEEK_BEFORE_DUE
}
}
} else {
selectedDay = hideUntil.startOfDay().millis
selectedTime = hideUntil.millisOfDay
selectedDay = when (selectedDay) {
dueDay -> if (selectedTime == dueTime) {
selectedTime = NO_TIME
DUE_TIME
} else {
DUE_DATE
}
dueDay.toDateTime().minusDays(1).millis ->
DAY_BEFORE_DUE
dueDay.toDateTime().minusDays(7).millis ->
WEEK_BEFORE_DUE
else -> selectedDay
}
}
} else {
selectedDay = savedInstanceState.getLong(EXTRA_DAY)
selectedTime = savedInstanceState.getInt(EXTRA_TIME)
}
applySelectionToHideUntil()
}
override fun bind(parent: ViewGroup?) =
ControlSetHideBinding.inflate(layoutInflater, parent, true).let {
startDate = it.startDate
it.root
}
override val icon = R.drawable.ic_pending_actions_24px
override fun controlId() = TAG
override val isClickable = true
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == REQUEST_HIDE_UNTIL) {
if (resultCode == Activity.RESULT_OK) {
selectedDay = data?.getLongExtra(EXTRA_DAY, 0L) ?: NO_DAY
selectedTime = data?.getIntExtra(EXTRA_TIME, 0) ?: NO_TIME
applySelectionToHideUntil()
}
} else {
super.onActivityResult(requestCode, resultCode, data)
}
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putLong(EXTRA_DAY, selectedDay)
outState.putInt(EXTRA_TIME, selectedTime)
}
private fun getRelativeDateString(resId: Int) = if (selectedTime == NO_TIME) {
getString(resId)
} else {
"${getString(resId)} ${DateUtilities.getTimeString(context, newDateTime().withMillisOfDay(selectedTime))}"
}
private fun refreshDisplayView() {
startDate.text = when (selectedDay) {
DUE_DATE -> getRelativeDateString(R.string.due_date)
DUE_TIME -> getString(R.string.due_time)
DAY_BEFORE_DUE -> getRelativeDateString(R.string.day_before_due)
WEEK_BEFORE_DUE -> getRelativeDateString(R.string.week_before_due)
in 1..Long.MAX_VALUE -> DateUtilities.getRelativeDateTime(
activity,
selectedDay + selectedTime,
locale.locale,
FormatStyle.FULL,
preferences.alwaysDisplayFullDate,
false
)
else -> null
}
val started = viewModel.hideUntil?.takeIf { it > 0 }?.let { it < now() } ?: false
startDate.setTextColor(
activity.getColor(if (started) R.color.overdue else R.color.text_primary)
)
}
fun onDueDateChanged() = applySelectionToHideUntil()
private fun applySelectionToHideUntil() {
val due = dueDateTime.takeIf { it > 0 }?.toDateTime()
val millisOfDay = selectedTime
viewModel.hideUntil = when (selectedDay) {
DUE_DATE -> due?.withMillisOfDay(millisOfDay)?.millis ?: 0
DUE_TIME -> due?.millis ?: 0
DAY_BEFORE_DUE -> due?.minusDays(1)?.withMillisOfDay(millisOfDay)?.millis ?: 0
WEEK_BEFORE_DUE -> due?.minusDays(7)?.withMillisOfDay(millisOfDay)?.millis ?: 0
else -> selectedDay + selectedTime
}
refreshDisplayView()
}
companion object {
const val TAG = R.string.TEA_ctrl_hide_until_pref
private const val REQUEST_HIDE_UNTIL = 11011
private const val FRAG_TAG_DATE_PICKER = "frag_tag_date_picker"
}
}