Simplify task edit view model

pull/1952/head
Alex Baker 2 years ago
parent 9c8e897f3a
commit c532abc87f

@ -32,7 +32,6 @@ import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.appbar.AppBarLayout.Behavior.DragCallback
import com.google.android.material.appbar.AppBarLayout.OnOffsetChangedListener
import com.google.android.material.composethemeadapter.MdcTheme
import com.todoroo.andlib.utility.AndroidUtilities
import com.todoroo.andlib.utility.DateUtilities
@ -91,26 +90,11 @@ class TaskEditFragment : Fragment(), Toolbar.OnMenuItemClickListener {
lateinit var binding: FragmentTaskEditBinding
private var showKeyboard = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (savedInstanceState == null) {
val args = requireArguments()
editViewModel.setup(
args.getParcelable(EXTRA_TASK)!!,
args.getParcelable(EXTRA_LIST)!!,
args.getParcelable(EXTRA_LOCATION),
args.getParcelableArrayList(EXTRA_TAGS)!!,
args.getParcelableArrayList(EXTRA_ALARMS)!!
)
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
binding = FragmentTaskEditBinding.inflate(inflater)
val view: View = binding.root
val model = editViewModel.task!!
val model = editViewModel.task
val toolbar = binding.toolbar
toolbar.navigationIcon = context.getDrawable(R.drawable.ic_outline_save_24px)
toolbar.setNavigationOnClickListener {
@ -161,12 +145,12 @@ class TaskEditFragment : Fragment(), Toolbar.OnMenuItemClickListener {
title.maxLines = 5
if (model.isNew || preferences.getBoolean(R.string.p_hide_check_button, false)) {
binding.fab.visibility = View.INVISIBLE
} else if (editViewModel.completed!!) {
} else if (editViewModel.completed) {
title.paintFlags = title.paintFlags or Paint.STRIKE_THRU_TEXT_FLAG
binding.fab.setImageResource(R.drawable.ic_outline_check_box_outline_blank_24px)
}
binding.fab.setOnClickListener {
if (editViewModel.completed!!) {
if (editViewModel.completed) {
editViewModel.completed = false
title.paintFlags = title.paintFlags and Paint.STRIKE_THRU_TEXT_FLAG.inv()
binding.fab.setImageResource(R.drawable.ic_outline_check_box_24px)
@ -177,17 +161,16 @@ class TaskEditFragment : Fragment(), Toolbar.OnMenuItemClickListener {
}
}
}
binding.appbarlayout.addOnOffsetChangedListener(
OnOffsetChangedListener { appBarLayout: AppBarLayout, verticalOffset: Int ->
if (verticalOffset == 0) {
title.visibility = View.VISIBLE
binding.collapsingtoolbarlayout.isTitleEnabled = false
} else if (abs(verticalOffset) < appBarLayout.totalScrollRange) {
title.visibility = View.INVISIBLE
binding.collapsingtoolbarlayout.title = title.text
binding.collapsingtoolbarlayout.isTitleEnabled = true
}
})
binding.appbarlayout.addOnOffsetChangedListener { appBarLayout, verticalOffset ->
if (verticalOffset == 0) {
title.visibility = View.VISIBLE
binding.collapsingtoolbarlayout.isTitleEnabled = false
} else if (abs(verticalOffset) < appBarLayout.totalScrollRange) {
title.visibility = View.INVISIBLE
binding.collapsingtoolbarlayout.title = title.text
binding.collapsingtoolbarlayout.isTitleEnabled = true
}
}
if (!model.isNew) {
lifecycleScope.launch {
notificationManager.cancel(model.id)
@ -233,7 +216,6 @@ class TaskEditFragment : Fragment(), Toolbar.OnMenuItemClickListener {
.launchIn(viewLifecycleOwner.lifecycleScope)
}
@OptIn(ExperimentalAnimationApi::class)
private suspend fun process(event: TaskEditEvent) {
when (event) {
is TaskEditEvent.Discard ->
@ -302,7 +284,7 @@ class TaskEditFragment : Fragment(), Toolbar.OnMenuItemClickListener {
}
suspend fun stopTimer(): Task {
val model = editViewModel.task!!
val model = editViewModel.task
timerPlugin.stopTimer(model)
val elapsedTime = DateUtils.formatElapsedTime(model.elapsedSeconds.toLong())
addComment(String.format(
@ -316,7 +298,7 @@ class TaskEditFragment : Fragment(), Toolbar.OnMenuItemClickListener {
}
suspend fun startTimer(): Task {
val model = editViewModel.task!!
val model = editViewModel.task
timerPlugin.startTimer(model)
addComment(String.format(
"%s %s",
@ -368,7 +350,7 @@ class TaskEditFragment : Fragment(), Toolbar.OnMenuItemClickListener {
*/
fun addComment(message: String?, picture: Uri?) {
val model = editViewModel.task!!
val model = editViewModel.task
val userActivity = UserActivity()
if (picture != null) {
val output = FileHelper.copyToUri(context, preferences.attachmentsDirectory!!, picture)
@ -388,11 +370,11 @@ class TaskEditFragment : Fragment(), Toolbar.OnMenuItemClickListener {
companion object {
const val TAG_TASKEDIT_FRAGMENT = "taskedit_fragment"
private const val FRAG_TAG_COMMENT_BAR = "comment_bar"
private const val EXTRA_TASK = "extra_task"
private const val EXTRA_LIST = "extra_list"
private const val EXTRA_LOCATION = "extra_location"
private const val EXTRA_TAGS = "extra_tags"
private const val EXTRA_ALARMS = "extra_alarms"
const val EXTRA_TASK = "extra_task"
const val EXTRA_LIST = "extra_list"
const val EXTRA_LOCATION = "extra_location"
const val EXTRA_TAGS = "extra_tags"
const val EXTRA_ALARMS = "extra_alarms"
fun newTaskEditFragment(
task: Task,

@ -2,8 +2,10 @@ package org.tasks.ui
import android.content.Context
import androidx.annotation.MainThread
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import com.todoroo.andlib.utility.DateUtilities.now
import com.todoroo.astrid.activity.TaskEditFragment
import com.todoroo.astrid.alarms.AlarmService
import com.todoroo.astrid.api.CaldavFilter
import com.todoroo.astrid.api.Filter
@ -31,12 +33,8 @@ import org.tasks.Strings
import org.tasks.analytics.Firebase
import org.tasks.calendars.CalendarEventProvider
import org.tasks.data.*
import org.tasks.data.Alarm.Companion.TYPE_RANDOM
import org.tasks.data.Alarm.Companion.TYPE_REL_END
import org.tasks.data.Alarm.Companion.TYPE_REL_START
import org.tasks.data.Alarm.Companion.whenDue
import org.tasks.data.Alarm.Companion.whenOverdue
import org.tasks.data.Alarm.Companion.whenStarted
import org.tasks.date.DateTimeUtils.toDateTime
import org.tasks.location.GeofenceApi
import org.tasks.preferences.PermissionChecker
@ -48,7 +46,8 @@ import javax.inject.Inject
@HiltViewModel
class TaskEditViewModel @Inject constructor(
@ApplicationContext private val context: Context,
@ApplicationContext context: Context,
savedStateHandle: SavedStateHandle,
private val taskDao: TaskDao,
private val taskDeleter: TaskDeleter,
private val timerPlugin: TimerPlugin,
@ -60,7 +59,7 @@ class TaskEditViewModel @Inject constructor(
private val geofenceApi: GeofenceApi,
private val tagDao: TagDao,
private val tagDataDao: TagDataDao,
private val preferences: Preferences,
preferences: Preferences,
private val googleTaskDao: GoogleTaskDao,
private val caldavDao: CaldavDao,
private val taskCompleter: TaskCompleter,
@ -69,76 +68,29 @@ class TaskEditViewModel @Inject constructor(
private val mainActivityEvents: MainActivityEventBus,
private val firebase: Firebase? = null,
) : ViewModel() {
private val resources = context.resources
private var cleared = false
fun setup(
task: Task,
list: Filter,
location: Location?,
tags: List<TagData>,
alarms: List<Alarm>,
) {
this.task = task
dueDate.value = task.dueDate
startDate.value = task.hideUntil
isNew = task.isNew
originalList = list
selectedList.value = list
originalLocation = location
originalTags = tags.toList()
selectedTags.value = ArrayList(tags)
originalAlarms =
if (isNew) {
ArrayList<Alarm>().apply {
if (task.isNotifyAtStart) {
add(whenStarted(0))
}
if (task.isNotifyAtDeadline) {
add(whenDue(0))
}
if (task.isNotifyAfterDeadline) {
add(whenOverdue(0))
}
if (task.randomReminder > 0) {
add(Alarm(0, task.randomReminder, TYPE_RANDOM))
}
}
} else {
alarms
}
selectedAlarms.value = originalAlarms
if (isNew && permissionChecker.canAccessCalendars()) {
originalCalendar = preferences.defaultCalendar
}
eventUri.value = task.calendarURI
priority.value = task.priority
elapsedSeconds.value = task.elapsedSeconds
estimatedSeconds.value = task.estimatedSeconds
timerStarted.value = task.timerStart
recurrence.value = task.recurrence
repeatAfterCompletion.value = task.repeatAfterCompletion()
}
lateinit var task: Task
private set
var creationDate: Long? = null
get() = field ?: task.creationDate
var modificationDate: Long? = null
get() = field ?: task.modificationDate
var completionDate: Long? = null
get() = field ?: task.completionDate
var title: String? = null
get() = field ?: task.title
var completed: Boolean? = null
get() = field ?: task.isCompleted
val task: Task = savedStateHandle[TaskEditFragment.EXTRA_TASK]!!
val isNew = task.isNew
var creationDate: Long = task.creationDate
var modificationDate: Long = task.modificationDate
var completionDate: Long = task.completionDate
var title: String? = task.title
var completed: Boolean = task.isCompleted
var priority = MutableStateFlow(task.priority)
var description: String? = task.notes.stripCarriageReturns()
val recurrence = MutableStateFlow(task.recurrence)
val repeatAfterCompletion = MutableStateFlow(task.repeatAfterCompletion())
var eventUri = MutableStateFlow(task.calendarURI)
val timerStarted = MutableStateFlow(task.timerStart)
val estimatedSeconds = MutableStateFlow(task.estimatedSeconds)
val elapsedSeconds = MutableStateFlow(task.elapsedSeconds)
var newSubtasks = MutableStateFlow(emptyList<Task>())
val dueDate = MutableStateFlow(0L)
val dueDate = MutableStateFlow(task.dueDate)
fun setDueDate(value: Long) {
dueDate.value = when {
@ -148,12 +100,7 @@ class TaskEditViewModel @Inject constructor(
}
}
var priority = MutableStateFlow(Task.Priority.NONE)
var description: String? = null
get() = field ?: task.notes.stripCarriageReturns()
val startDate = MutableStateFlow(0L)
val startDate = MutableStateFlow(task.hideUntil)
fun setStartDate(value: Long) {
startDate.value = when {
@ -164,62 +111,56 @@ class TaskEditViewModel @Inject constructor(
}
}
val recurrence = MutableStateFlow<String?>(null)
val repeatAfterCompletion = MutableStateFlow(false)
private var originalCalendar: String? = null
private set(value) {
field = value
selectedCalendar.value = value
}
var selectedCalendar = MutableStateFlow<String?>(null)
var eventUri = MutableStateFlow<String?>(null)
var isNew: Boolean = false
private set
private var originalCalendar: String? = if (isNew && permissionChecker.canAccessCalendars()) {
preferences.defaultCalendar
} else {
null
}
var selectedCalendar = MutableStateFlow(originalCalendar)
val timerStarted = MutableStateFlow(0L)
val estimatedSeconds = MutableStateFlow(0)
val elapsedSeconds = MutableStateFlow(0)
private val originalList: Filter = savedStateHandle[TaskEditFragment.EXTRA_LIST]!!
var selectedList = MutableStateFlow(originalList)
private lateinit var originalList: Filter
private var originalLocation: Location? = savedStateHandle[TaskEditFragment.EXTRA_LOCATION]
var selectedLocation = MutableStateFlow(originalLocation)
var selectedList = MutableStateFlow(null as Filter?)
private val originalTags: List<TagData> =
savedStateHandle.get<ArrayList<TagData>>(TaskEditFragment.EXTRA_TAGS) ?: emptyList()
val selectedTags = MutableStateFlow(ArrayList(originalTags))
var originalLocation: Location? = null
private set(value) {
field = value
selectedLocation.value = value
private val originalAlarms: List<Alarm> = if (isNew) {
ArrayList<Alarm>().apply {
if (task.isNotifyAtStart) {
add(Alarm.whenStarted(0))
}
if (task.isNotifyAtDeadline) {
add(Alarm.whenDue(0))
}
if (task.isNotifyAfterDeadline) {
add(Alarm.whenOverdue(0))
}
if (task.randomReminder > 0) {
add(Alarm(0, task.randomReminder, Alarm.TYPE_RANDOM))
}
}
} else {
savedStateHandle[TaskEditFragment.EXTRA_ALARMS]!!
}
var selectedLocation = MutableStateFlow<Location?>(null)
private lateinit var originalTags: List<TagData>
val selectedTags = MutableStateFlow(ArrayList<TagData>())
var newSubtasks = MutableStateFlow(emptyList<Task>())
private lateinit var originalAlarms: List<Alarm>
var selectedAlarms = MutableStateFlow(emptyList<Alarm>())
var selectedAlarms = MutableStateFlow(originalAlarms)
var ringNonstop: Boolean? = null
get() = field ?: task.isNotifyModeNonstop
var ringNonstop: Boolean = task.isNotifyModeNonstop
set(value) {
field = value
if (value == true) {
if (value) {
ringFiveTimes = false
}
}
var ringFiveTimes:Boolean? = null
get() = field ?: task.isNotifyModeFive
var ringFiveTimes:Boolean = task.isNotifyModeFive
set(value) {
field = value
if (value == true) {
if (value) {
ringNonstop = false
}
}
@ -270,7 +211,7 @@ class TaskEditViewModel @Inject constructor(
return@withContext false
}
clear(remove)
task.title = if (title.isNullOrBlank()) context.getString(R.string.no_title) else title
task.title = if (title.isNullOrBlank()) resources.getString(R.string.no_title) else title
task.dueDate = dueDate.value
task.priority = priority.value
task.notes = description
@ -287,15 +228,13 @@ class TaskEditViewModel @Inject constructor(
applyCalendarChanges()
val isNew = task.isNew
if (isNew) {
taskDao.createNew(task)
}
if (isNew || originalList != selectedList.value) {
task.parent = 0
taskMover.move(listOf(task.id), selectedList.value!!)
taskMover.move(listOf(task.id), selectedList.value)
}
if ((isNew && selectedLocation.value != null) || originalLocation != selectedLocation.value) {
@ -370,8 +309,8 @@ class TaskEditViewModel @Inject constructor(
task.modificationDate = now()
}
if (task.isCompleted != completed!!) {
taskCompleter.setComplete(task, completed!!)
if (task.isCompleted != completed) {
taskCompleter.setComplete(task, completed)
}
if (isNew) {
@ -405,8 +344,8 @@ class TaskEditViewModel @Inject constructor(
}
private fun getRingFlags() = when {
ringNonstop == true -> NOTIFY_MODE_NONSTOP
ringFiveTimes == true -> NOTIFY_MODE_FIVE
ringNonstop -> NOTIFY_MODE_NONSTOP
ringFiveTimes -> NOTIFY_MODE_FIVE
else -> 0
}
@ -416,7 +355,7 @@ class TaskEditViewModel @Inject constructor(
}
suspend fun discard(remove: Boolean = true) {
if (task.isNew) {
if (isNew) {
timerPlugin.stopTimer(task)
}
clear(remove)
@ -444,4 +383,4 @@ class TaskEditViewModel @Inject constructor(
companion object {
fun String?.stripCarriageReturns(): String? = this?.replace("\\r\\n?".toRegex(), "\n")
}
}
}

Loading…
Cancel
Save