Load initial data in task edit view model

pull/2803/head
Alex Baker 2 months ago
parent 3448808c94
commit b2efb42d55

@ -52,10 +52,6 @@ open class BaseTaskEditViewModelTest : InjectingTestCase() {
context,
SavedStateHandle().apply {
set(TaskEditFragment.EXTRA_TASK, task)
set(TaskEditFragment.EXTRA_LIST, defaultFilterProvider.getList(task))
set(TaskEditFragment.EXTRA_LOCATION, locationDao.getLocation(task, preferences))
set(TaskEditFragment.EXTRA_TAGS, tagDataDao.getTags(task))
set(TaskEditFragment.EXTRA_ALARMS, alarmDao.getAlarms(task))
},
taskDao,
taskDeleter,
@ -78,6 +74,7 @@ open class BaseTaskEditViewModelTest : InjectingTestCase() {
userActivityDao = userActivityDao,
taskAttachmentDao = db.taskAttachmentDao,
alarmDao = db.alarmDao,
defaultFilterProvider = defaultFilterProvider,
)
}

@ -28,7 +28,6 @@ import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import com.google.android.material.composethemeadapter.MdcTheme
import com.todoroo.andlib.utility.AndroidUtilities
import com.todoroo.astrid.activity.TaskEditFragment.Companion.newTaskEditFragment
import com.todoroo.astrid.adapter.SubheaderClickHandler
import com.todoroo.astrid.api.Filter
import com.todoroo.astrid.dao.TaskDao
@ -36,14 +35,11 @@ import com.todoroo.astrid.data.Task
import com.todoroo.astrid.service.TaskCreator
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.tasks.BuildConfig
import org.tasks.R
import org.tasks.Tasks.Companion.IS_GENERIC
@ -426,25 +422,10 @@ class MainActivity : AppCompatActivity() {
}
}
private suspend fun newTaskEditFragment(task: Task): TaskEditFragment {
private fun newTaskEditFragment(task: Task): TaskEditFragment {
AndroidUtilities.assertMainThread()
clearUi()
return coroutineScope {
withContext(Dispatchers.Default) {
val freshTask = async { if (task.isNew) task else taskDao.fetch(task.id) ?: task }
val list = async { defaultFilterProvider.getList(task) }
val location = async { locationDao.getLocation(task, preferences) }
val tags = async { tagDataDao.getTags(task) }
val alarms = async { alarmDao.getAlarms(task) }
newTaskEditFragment(
freshTask.await(),
list.await(),
location.await(),
tags.await(),
alarms.await(),
)
}
}
return TaskEditFragment.newTaskEditFragment(task)
}
private val isSinglePaneLayout: Boolean

@ -44,7 +44,6 @@ import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.appbar.AppBarLayout.Behavior.DragCallback
import com.google.android.material.composethemeadapter.MdcTheme
import com.todoroo.andlib.utility.DateUtilities
import com.todoroo.astrid.api.Filter
import com.todoroo.astrid.dao.TaskDao
import com.todoroo.astrid.data.Task
import com.todoroo.astrid.files.FilesControlSet
@ -70,9 +69,6 @@ import org.tasks.compose.edit.DueDateRow
import org.tasks.compose.edit.InfoRow
import org.tasks.compose.edit.ListRow
import org.tasks.compose.edit.PriorityRow
import org.tasks.data.Alarm
import org.tasks.data.Location
import org.tasks.data.TagData
import org.tasks.data.UserActivityDao
import org.tasks.databinding.FragmentTaskEditBinding
import org.tasks.databinding.TaskEditCalendarBinding
@ -519,10 +515,6 @@ class TaskEditFragment : Fragment(), Toolbar.OnMenuItemClickListener {
companion object {
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"
private const val FRAG_TAG_GOOGLE_TASK_LIST_SELECTION =
"frag_tag_google_task_list_selection"
@ -540,18 +532,10 @@ class TaskEditFragment : Fragment(), Toolbar.OnMenuItemClickListener {
fun newTaskEditFragment(
task: Task,
list: Filter,
location: Location?,
tags: ArrayList<TagData>,
alarms: ArrayList<Alarm>,
): TaskEditFragment {
val taskEditFragment = TaskEditFragment()
val arguments = Bundle()
arguments.putParcelable(EXTRA_TASK, task)
arguments.putParcelable(EXTRA_LIST, list)
arguments.putParcelable(EXTRA_LOCATION, location)
arguments.putParcelableArrayList(EXTRA_TAGS, tags)
arguments.putParcelableArrayList(EXTRA_ALARMS, alarms)
taskEditFragment.arguments = arguments
return taskEditFragment
}

@ -2,13 +2,15 @@ package org.tasks.compose.edit
import android.content.res.Configuration
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.material.ripple.rememberRipple
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
@ -23,10 +25,15 @@ import com.google.accompanist.permissions.PermissionStatus
import com.google.android.material.composethemeadapter.MdcTheme
import com.todoroo.astrid.ui.ReminderControlSetViewModel
import org.tasks.R
import org.tasks.compose.*
import org.tasks.compose.AddAlarmDialog
import org.tasks.compose.AddReminderDialog
import org.tasks.compose.ClearButton
import org.tasks.compose.DisabledText
import org.tasks.compose.TaskEditRow
import org.tasks.compose.collectAsStateLifecycleAware
import org.tasks.data.Alarm
import org.tasks.reminders.AlarmToString
import java.util.*
import java.util.Locale
@OptIn(ExperimentalPermissionsApi::class, ExperimentalComposeUiApi::class)
@Composable
@ -144,11 +151,7 @@ fun Alarms(
text = stringResource(id = R.string.add_reminder),
modifier = Modifier
.padding(vertical = 12.dp)
.clickable(
interactionSource = remember { MutableInteractionSource() },
indication = rememberRipple(bounded = false),
onClick = addAlarm,
)
.clickable(onClick = addAlarm)
)
Spacer(modifier = Modifier.weight(1f))
if (alarms.isNotEmpty()) {
@ -165,11 +168,7 @@ fun Alarms(
),
modifier = Modifier
.padding(vertical = 12.dp, horizontal = 16.dp)
.clickable(
interactionSource = remember { MutableInteractionSource() },
indication = rememberRipple(bounded = false),
onClick = openRingType
)
.clickable(onClick = openRingType)
)
}
}

@ -58,6 +58,7 @@ import org.tasks.data.UserActivityDao
import org.tasks.date.DateTimeUtils.toDateTime
import org.tasks.files.FileHelper
import org.tasks.location.GeofenceApi
import org.tasks.preferences.DefaultFilterProvider
import org.tasks.preferences.PermissionChecker
import org.tasks.preferences.Preferences
import org.tasks.time.DateTimeUtils.currentTimeMillis
@ -67,32 +68,33 @@ import javax.inject.Inject
@HiltViewModel
class TaskEditViewModel @Inject constructor(
@ApplicationContext private val context: Context,
savedStateHandle: SavedStateHandle,
private val taskDao: TaskDao,
private val taskDeleter: TaskDeleter,
private val timerPlugin: TimerPlugin,
private val permissionChecker: PermissionChecker,
private val calendarEventProvider: CalendarEventProvider,
private val gCalHelper: GCalHelper,
private val taskMover: TaskMover,
private val locationDao: LocationDao,
private val geofenceApi: GeofenceApi,
private val tagDao: TagDao,
private val tagDataDao: TagDataDao,
private val preferences: Preferences,
private val googleTaskDao: GoogleTaskDao,
private val caldavDao: CaldavDao,
private val taskCompleter: TaskCompleter,
private val alarmService: AlarmService,
private val taskListEvents: TaskListEventBus,
private val mainActivityEvents: MainActivityEventBus,
private val firebase: Firebase? = null,
private val userActivityDao: UserActivityDao,
private val alarmDao: AlarmDao,
private val taskAttachmentDao: TaskAttachmentDao,
@ApplicationContext private val applicationContext: Context,
savedStateHandle: SavedStateHandle,
private val taskDao: TaskDao,
private val taskDeleter: TaskDeleter,
private val timerPlugin: TimerPlugin,
private val permissionChecker: PermissionChecker,
private val calendarEventProvider: CalendarEventProvider,
private val gCalHelper: GCalHelper,
private val taskMover: TaskMover,
private val locationDao: LocationDao,
private val geofenceApi: GeofenceApi,
private val tagDao: TagDao,
private val tagDataDao: TagDataDao,
private val preferences: Preferences,
private val googleTaskDao: GoogleTaskDao,
private val caldavDao: CaldavDao,
private val taskCompleter: TaskCompleter,
private val alarmService: AlarmService,
private val taskListEvents: TaskListEventBus,
private val mainActivityEvents: MainActivityEventBus,
private val firebase: Firebase? = null,
private val userActivityDao: UserActivityDao,
private val alarmDao: AlarmDao,
private val taskAttachmentDao: TaskAttachmentDao,
private val defaultFilterProvider: DefaultFilterProvider,
) : ViewModel() {
private val resources = context.resources
private val resources = applicationContext.resources
private var cleared = false
val task: Task = savedStateHandle[TaskEditFragment.EXTRA_TASK]!!
@ -144,18 +146,19 @@ class TaskEditViewModel @Inject constructor(
}
var selectedCalendar = MutableStateFlow(originalCalendar)
val originalList: Filter = savedStateHandle[TaskEditFragment.EXTRA_LIST]!!
val originalList: Filter = runBlocking { defaultFilterProvider.getList(task) }
var selectedList = MutableStateFlow(originalList)
private var originalLocation: Location? = savedStateHandle[TaskEditFragment.EXTRA_LOCATION]
private val originalLocation: Location? =
runBlocking { locationDao.getLocation(task, preferences) }
var selectedLocation = MutableStateFlow(originalLocation)
private val originalTags: List<TagData> =
savedStateHandle.get<ArrayList<TagData>>(TaskEditFragment.EXTRA_TAGS) ?: emptyList()
private val originalTags: List<TagData> = runBlocking { tagDataDao.getTags(task) }
val selectedTags = MutableStateFlow(ArrayList(originalTags))
private lateinit var originalAttachments: List<TaskAttachment>
val selectedAttachments = MutableStateFlow(emptyList<TaskAttachment>())
private val originalAttachments: List<TaskAttachment> =
runBlocking { taskAttachmentDao.getAttachments(task.id) }
val selectedAttachments = MutableStateFlow(originalAttachments)
private val originalAlarms: List<Alarm> = if (isNew) {
ArrayList<Alarm>().apply {
@ -173,9 +176,8 @@ class TaskEditViewModel @Inject constructor(
}
}
} else {
savedStateHandle[TaskEditFragment.EXTRA_ALARMS]!!
runBlocking { alarmDao.getAlarms(task) }
}
var selectedAlarms = MutableStateFlow(originalAlarms)
var ringNonstop: Boolean = task.isNotifyModeNonstop
@ -226,8 +228,7 @@ class TaskEditViewModel @Inject constructor(
originalList != selectedList.value ||
originalLocation != selectedLocation.value ||
originalTags.toHashSet() != selectedTags.value.toHashSet() ||
(::originalAttachments.isInitialized &&
originalAttachments.toHashSet() != selectedAttachments.value.toHashSet()) ||
originalAttachments.toHashSet() != selectedAttachments.value.toHashSet() ||
newSubtasks.value.isNotEmpty() ||
getRingFlags() != when {
task.isNotifyModeFive -> NOTIFY_MODE_FIVE
@ -362,10 +363,7 @@ class TaskEditViewModel @Inject constructor(
task.modificationDate = now()
}
if (
this@TaskEditViewModel::originalAttachments.isInitialized &&
selectedAttachments.value.toHashSet() != originalAttachments.toHashSet()
) {
if (selectedAttachments.value.toHashSet() != originalAttachments.toHashSet()) {
originalAttachments
.minus(selectedAttachments.value.toSet())
.map { it.remoteId }
@ -430,7 +428,7 @@ class TaskEditViewModel @Inject constructor(
if (isNew) {
timerPlugin.stopTimer(task)
originalAttachments.plus(selectedAttachments.value).toSet().takeIf { it.isNotEmpty() }
?.onEach { FileHelper.delete(context, it.uri.toUri()) }
?.onEach { FileHelper.delete(applicationContext, it.uri.toUri()) }
?.let { taskAttachmentDao.delete(it.toList()) }
}
clear(remove)
@ -470,7 +468,7 @@ class TaskEditViewModel @Inject constructor(
fun addComment(message: String?, picture: Uri?) {
val userActivity = UserActivity()
if (picture != null) {
val output = FileHelper.copyToUri(context, preferences.attachmentsDirectory!!, picture)
val output = FileHelper.copyToUri(applicationContext, preferences.attachmentsDirectory!!, picture)
userActivity.setPicture(output)
}
userActivity.message = message
@ -483,15 +481,6 @@ class TaskEditViewModel @Inject constructor(
}
}
init {
viewModelScope.launch {
taskAttachmentDao.getAttachments(task.id).let { attachments ->
selectedAttachments.update { attachments }
originalAttachments = attachments
}
}
}
companion object {
fun String?.stripCarriageReturns(): String? = this?.replace("\\r\\n?".toRegex(), "\n")
}

Loading…
Cancel
Save