View model due date as state flow

pull/1923/head
Alex Baker 2 years ago
parent 1f3b8fd228
commit 6513c40c97

@ -23,13 +23,9 @@ import com.todoroo.astrid.data.Task
import com.todoroo.astrid.service.TaskCreator import com.todoroo.astrid.service.TaskCreator
import com.todoroo.astrid.timers.TimerControlSet.TimerControlSetCallback import com.todoroo.astrid.timers.TimerControlSet.TimerControlSetCallback
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.*
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.tasks.BuildConfig import org.tasks.BuildConfig
import org.tasks.LocalBroadcastManager import org.tasks.LocalBroadcastManager
import org.tasks.R import org.tasks.R
@ -54,19 +50,14 @@ import org.tasks.preferences.Preferences
import org.tasks.themes.ColorProvider import org.tasks.themes.ColorProvider
import org.tasks.themes.Theme import org.tasks.themes.Theme
import org.tasks.themes.ThemeColor import org.tasks.themes.ThemeColor
import org.tasks.ui.DeadlineControlSet.DueDateChangeListener import org.tasks.ui.*
import org.tasks.ui.EmptyTaskEditFragment.Companion.newEmptyTaskEditFragment import org.tasks.ui.EmptyTaskEditFragment.Companion.newEmptyTaskEditFragment
import org.tasks.ui.MainActivityEvent
import org.tasks.ui.MainActivityEventBus
import org.tasks.ui.NavigationDrawerFragment
import org.tasks.ui.NavigationDrawerFragment.Companion.newNavigationDrawer import org.tasks.ui.NavigationDrawerFragment.Companion.newNavigationDrawer
import org.tasks.ui.TaskListEvent
import org.tasks.ui.TaskListEventBus
import timber.log.Timber import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
@AndroidEntryPoint @AndroidEntryPoint
class MainActivity : InjectingAppCompatActivity(), TaskListFragmentCallbackHandler, TimerControlSetCallback, DueDateChangeListener, CommentBarFragmentCallback, SortDialogCallback { class MainActivity : InjectingAppCompatActivity(), TaskListFragmentCallbackHandler, TimerControlSetCallback, CommentBarFragmentCallback, SortDialogCallback {
@Inject lateinit var preferences: Preferences @Inject lateinit var preferences: Preferences
@Inject lateinit var defaultFilterProvider: DefaultFilterProvider @Inject lateinit var defaultFilterProvider: DefaultFilterProvider
@Inject lateinit var theme: Theme @Inject lateinit var theme: Theme
@ -471,10 +462,6 @@ class MainActivity : InjectingAppCompatActivity(), TaskListFragmentCallbackHandl
actionMode = null actionMode = null
} }
override fun dueDateChanged() {
taskEditFragment!!.onDueDateChanged()
}
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()

@ -40,9 +40,7 @@ import com.todoroo.astrid.api.Filter
import com.todoroo.astrid.dao.TaskDao import com.todoroo.astrid.dao.TaskDao
import com.todoroo.astrid.data.Task import com.todoroo.astrid.data.Task
import com.todoroo.astrid.notes.CommentsController import com.todoroo.astrid.notes.CommentsController
import com.todoroo.astrid.repeats.RepeatControlSet
import com.todoroo.astrid.timers.TimerPlugin import com.todoroo.astrid.timers.TimerPlugin
import com.todoroo.astrid.ui.StartDateControlSet
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.NonCancellable import kotlinx.coroutines.NonCancellable
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
@ -63,7 +61,6 @@ import org.tasks.fragments.TaskEditControlSetFragmentManager
import org.tasks.markdown.MarkdownProvider import org.tasks.markdown.MarkdownProvider
import org.tasks.notifications.NotificationManager import org.tasks.notifications.NotificationManager
import org.tasks.preferences.Preferences import org.tasks.preferences.Preferences
import org.tasks.ui.TaskEditControlFragment
import org.tasks.ui.TaskEditEvent import org.tasks.ui.TaskEditEvent
import org.tasks.ui.TaskEditEventBus import org.tasks.ui.TaskEditEventBus
import org.tasks.ui.TaskEditViewModel import org.tasks.ui.TaskEditViewModel
@ -327,21 +324,6 @@ class TaskEditFragment : Fragment(), Toolbar.OnMenuItemClickListener {
/* /*
* ====================================================================== * ======================================================================
* =============================================== model reading / saving
* ======================================================================
*/
private val repeatControlSet: RepeatControlSet?
get() = getFragment<RepeatControlSet>(RepeatControlSet.TAG)
private val startDateControlSet: StartDateControlSet?
get() = getFragment<StartDateControlSet>(StartDateControlSet.TAG)
private fun <T : TaskEditControlFragment?> getFragment(tag: Int): T? {
return childFragmentManager.findFragmentByTag(getString(tag)) as T?
}
/*
* ======================================================================
* ======================================================= event handlers * ======================================================= event handlers
* ====================================================================== * ======================================================================
*/ */
@ -378,10 +360,6 @@ class TaskEditFragment : Fragment(), Toolbar.OnMenuItemClickListener {
* ========================================== UI component helper classes * ========================================== UI component helper classes
* ====================================================================== * ======================================================================
*/ */
fun onDueDateChanged() {
repeatControlSet?.onDueDateChanged()
startDateControlSet?.onDueDateChanged()
}
fun addComment(message: String?, picture: Uri?) { fun addComment(message: String?, picture: Uri?) {
val model = editViewModel.task!! val model = editViewModel.task!!

@ -15,6 +15,7 @@ import android.widget.AdapterView
import android.widget.LinearLayout import android.widget.LinearLayout
import android.widget.Spinner import android.widget.Spinner
import android.widget.TextView import android.widget.TextView
import androidx.lifecycle.lifecycleScope
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import net.fortuna.ical4j.model.Recur import net.fortuna.ical4j.model.Recur
import net.fortuna.ical4j.model.WeekDay import net.fortuna.ical4j.model.WeekDay
@ -31,7 +32,6 @@ import org.tasks.time.DateTimeUtils.currentTimeMillis
import org.tasks.ui.HiddenTopArrayAdapter import org.tasks.ui.HiddenTopArrayAdapter
import org.tasks.ui.OnItemSelected import org.tasks.ui.OnItemSelected
import org.tasks.ui.TaskEditControlFragment import org.tasks.ui.TaskEditControlFragment
import java.util.*
import javax.inject.Inject import javax.inject.Inject
/** /**
@ -68,7 +68,7 @@ class RepeatControlSet : TaskEditControlFragment() {
} }
} }
fun onDueDateChanged() { private fun onDueDateChanged() {
viewModel.recur?.let { recur -> viewModel.recur?.let { recur ->
if (recur.frequency == Recur.Frequency.MONTHLY && recur.dayList.isNotEmpty()) { if (recur.frequency == Recur.Frequency.MONTHLY && recur.dayList.isNotEmpty()) {
val weekdayNum = recur.dayList[0] val weekdayNum = recur.dayList[0]
@ -111,6 +111,12 @@ class RepeatControlSet : TaskEditControlFragment() {
typeSpinner.adapter = typeAdapter typeSpinner.adapter = typeAdapter
typeSpinner.setSelection(if (viewModel.repeatAfterCompletion!!) TYPE_COMPLETION_DATE else TYPE_DUE_DATE) typeSpinner.setSelection(if (viewModel.repeatAfterCompletion!!) TYPE_COMPLETION_DATE else TYPE_DUE_DATE)
refreshDisplayView() refreshDisplayView()
lifecycleScope.launchWhenResumed {
viewModel.dueDate.collect {
onDueDateChanged()
}
}
} }
private fun onRepeatTypeChanged(position: Int) { private fun onRepeatTypeChanged(position: Int) {
@ -120,7 +126,7 @@ class RepeatControlSet : TaskEditControlFragment() {
} }
private val dueDate: Long private val dueDate: Long
get() = viewModel.dueDate!!.let { if (it > 0) it else currentTimeMillis() } get() = viewModel.dueDate.value.let { if (it > 0) it else currentTimeMillis() }
override fun onRowClick() { override fun onRowClick() {
BasicRecurrenceDialog.newBasicRecurrenceDialog( BasicRecurrenceDialog.newBasicRecurrenceDialog(

@ -5,6 +5,7 @@ import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.TextView import android.widget.TextView
import androidx.lifecycle.lifecycleScope
import com.todoroo.andlib.utility.DateUtilities import com.todoroo.andlib.utility.DateUtilities
import com.todoroo.andlib.utility.DateUtilities.now import com.todoroo.andlib.utility.DateUtilities.now
import com.todoroo.astrid.data.Task import com.todoroo.astrid.data.Task
@ -39,7 +40,7 @@ class StartDateControlSet : TaskEditControlFragment() {
private lateinit var startDate: TextView private lateinit var startDate: TextView
private val dueDateTime private val dueDateTime
get() = viewModel.dueDate!! get() = viewModel.dueDate.value
private var selectedDay = NO_DAY private var selectedDay = NO_DAY
private var selectedTime = NO_TIME private var selectedTime = NO_TIME
@ -92,8 +93,12 @@ class StartDateControlSet : TaskEditControlFragment() {
selectedDay = savedInstanceState.getLong(EXTRA_DAY) selectedDay = savedInstanceState.getLong(EXTRA_DAY)
selectedTime = savedInstanceState.getInt(EXTRA_TIME) selectedTime = savedInstanceState.getInt(EXTRA_TIME)
} }
lifecycleScope.launchWhenResumed {
viewModel.dueDate.collect {
applySelectionToHideUntil() applySelectionToHideUntil()
} }
}
}
override fun bind(parent: ViewGroup?) = override fun bind(parent: ViewGroup?) =
ControlSetHideBinding.inflate(layoutInflater, parent, true).let { ControlSetHideBinding.inflate(layoutInflater, parent, true).let {
@ -153,8 +158,6 @@ class StartDateControlSet : TaskEditControlFragment() {
) )
} }
fun onDueDateChanged() = applySelectionToHideUntil()
private fun applySelectionToHideUntil() { private fun applySelectionToHideUntil() {
val due = dueDateTime.takeIf { it > 0 }?.toDateTime() val due = dueDateTime.takeIf { it > 0 }?.toDateTime()
val millisOfDay = selectedTime val millisOfDay = selectedTime

@ -25,12 +25,6 @@ class DeadlineControlSet : TaskEditControlFragment() {
@Inject lateinit var preferences: Preferences @Inject lateinit var preferences: Preferences
private lateinit var dueDate: TextView private lateinit var dueDate: TextView
private lateinit var callback: DueDateChangeListener
override fun onAttach(activity: Activity) {
super.onAttach(activity)
callback = activity as DueDateChangeListener
}
override fun createView(savedInstanceState: Bundle?) { override fun createView(savedInstanceState: Bundle?) {
refreshDisplayView() refreshDisplayView()
@ -42,7 +36,7 @@ class DeadlineControlSet : TaskEditControlFragment() {
newDateTimePicker( newDateTimePicker(
this, this,
REQUEST_DATE, REQUEST_DATE,
viewModel.dueDate!!, viewModel.dueDate.value,
preferences.getBoolean(R.string.p_auto_dismiss_datetime_edit_screen, false)) preferences.getBoolean(R.string.p_auto_dismiss_datetime_edit_screen, false))
.show(fragmentManager, FRAG_TAG_DATE_PICKER) .show(fragmentManager, FRAG_TAG_DATE_PICKER)
} }
@ -63,8 +57,7 @@ class DeadlineControlSet : TaskEditControlFragment() {
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == REQUEST_DATE) { if (requestCode == REQUEST_DATE) {
if (resultCode == Activity.RESULT_OK) { if (resultCode == Activity.RESULT_OK) {
viewModel.dueDate = data!!.getLongExtra(DateTimePicker.EXTRA_TIMESTAMP, 0L) viewModel.setDueDate(data!!.getLongExtra(DateTimePicker.EXTRA_TIMESTAMP, 0L))
callback.dueDateChanged()
} }
refreshDisplayView() refreshDisplayView()
} else { } else {
@ -73,7 +66,7 @@ class DeadlineControlSet : TaskEditControlFragment() {
} }
private fun refreshDisplayView() { private fun refreshDisplayView() {
val date = viewModel.dueDate!! val date = viewModel.dueDate.value
if (date == 0L) { if (date == 0L) {
dueDate.text = "" dueDate.text = ""
setTextColor(false) setTextColor(false)
@ -99,10 +92,6 @@ class DeadlineControlSet : TaskEditControlFragment() {
activity.getColor(if (overdue) R.color.overdue else R.color.text_primary)) activity.getColor(if (overdue) R.color.overdue else R.color.text_primary))
} }
interface DueDateChangeListener {
fun dueDateChanged()
}
companion object { companion object {
const val TAG = R.string.TEA_ctrl_when_pref const val TAG = R.string.TEA_ctrl_when_pref
private const val REQUEST_DATE = 504 private const val REQUEST_DATE = 504

@ -86,6 +86,7 @@ class TaskEditViewModel @Inject constructor(
alarms: List<Alarm>, alarms: List<Alarm>,
) { ) {
this.task = task this.task = task
dueDate.value = task.dueDate
isNew = task.isNew isNew = task.isNew
originalList = list originalList = list
selectedList.value = list selectedList.value = list
@ -138,11 +139,10 @@ class TaskEditViewModel @Inject constructor(
var completed: Boolean? = null var completed: Boolean? = null
get() = field ?: task.isCompleted get() = field ?: task.isCompleted
var dueDate: Long? = null val dueDate = MutableStateFlow(0L)
get() = field ?: task.dueDate
set(value) { fun setDueDate(value: Long) {
field = when { dueDate.value = when {
value == null -> null
value == 0L -> 0 value == 0L -> 0
hasDueTime(value) -> createDueDate(Task.URGENCY_SPECIFIC_DAY_TIME, value) hasDueTime(value) -> createDueDate(Task.URGENCY_SPECIFIC_DAY_TIME, value)
else -> createDueDate(Task.URGENCY_SPECIFIC_DAY, value) else -> createDueDate(Task.URGENCY_SPECIFIC_DAY, value)
@ -287,7 +287,7 @@ class TaskEditViewModel @Inject constructor(
fun hasChanges(): Boolean = fun hasChanges(): Boolean =
(task.title != title || (isNew && title?.isNotBlank() == true)) || (task.title != title || (isNew && title?.isNotBlank() == true)) ||
task.isCompleted != completed || task.isCompleted != completed ||
task.dueDate != dueDate || task.dueDate != dueDate.value ||
task.priority != priority.value || task.priority != priority.value ||
if (task.notes.isNullOrBlank()) { if (task.notes.isNullOrBlank()) {
!description.isNullOrBlank() !description.isNullOrBlank()
@ -332,7 +332,7 @@ class TaskEditViewModel @Inject constructor(
} }
clear(remove) clear(remove)
task.title = if (title.isNullOrBlank()) context.getString(R.string.no_title) else title task.title = if (title.isNullOrBlank()) context.getString(R.string.no_title) else title
task.dueDate = dueDate!! task.dueDate = dueDate.value
task.priority = priority.value task.priority = priority.value
task.notes = description task.notes = description
task.hideUntil = hideUntil!! task.hideUntil = hideUntil!!

Loading…
Cancel
Save