mirror of https://github.com/tasks/tasks
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.
206 lines
8.0 KiB
Kotlin
206 lines
8.0 KiB
Kotlin
package com.todoroo.astrid.service
|
|
|
|
import com.todoroo.andlib.utility.DateUtilities
|
|
import com.todoroo.astrid.api.CaldavFilter
|
|
import com.todoroo.astrid.api.Filter
|
|
import com.todoroo.astrid.api.GtasksFilter
|
|
import com.todoroo.astrid.api.PermaSql
|
|
import com.todoroo.astrid.dao.TaskDao
|
|
import com.todoroo.astrid.data.Task
|
|
import com.todoroo.astrid.data.Task.Companion.DUE_DATE
|
|
import com.todoroo.astrid.data.Task.Companion.HIDE_UNTIL
|
|
import com.todoroo.astrid.data.Task.Companion.HIDE_UNTIL_NONE
|
|
import com.todoroo.astrid.data.Task.Companion.IMPORTANCE
|
|
import com.todoroo.astrid.data.Task.Companion.createDueDate
|
|
import com.todoroo.astrid.gcal.GCalHelper
|
|
import com.todoroo.astrid.helper.UUIDHelper
|
|
import com.todoroo.astrid.utility.TitleParser.parse
|
|
import org.tasks.R
|
|
import org.tasks.Strings.isNullOrEmpty
|
|
import org.tasks.data.*
|
|
import org.tasks.data.Alarm.Companion.TYPE_RANDOM
|
|
import org.tasks.data.Alarm.Companion.whenDue
|
|
import org.tasks.data.Alarm.Companion.whenOverdue
|
|
import org.tasks.data.Alarm.Companion.whenStarted
|
|
import org.tasks.preferences.DefaultFilterProvider
|
|
import org.tasks.preferences.Preferences
|
|
import org.tasks.time.DateTimeUtils.startOfDay
|
|
import timber.log.Timber
|
|
import javax.inject.Inject
|
|
|
|
class TaskCreator @Inject constructor(
|
|
private val gcalHelper: GCalHelper,
|
|
private val preferences: Preferences,
|
|
private val tagDataDao: TagDataDao,
|
|
private val taskDao: TaskDao,
|
|
private val tagDao: TagDao,
|
|
private val googleTaskDao: GoogleTaskDao,
|
|
private val defaultFilterProvider: DefaultFilterProvider,
|
|
private val caldavDao: CaldavDao,
|
|
private val locationDao: LocationDao,
|
|
private val alarmDao: AlarmDao,
|
|
) {
|
|
|
|
suspend fun basicQuickAddTask(title: String): Task {
|
|
val task = createWithValues(title.trim { it <= ' ' })
|
|
taskDao.createNew(task)
|
|
val gcalCreateEventEnabled = preferences.isDefaultCalendarSet && task.hasDueDate() // $NON-NLS-1$
|
|
if (!isNullOrEmpty(task.title)
|
|
&& gcalCreateEventEnabled
|
|
&& isNullOrEmpty(task.calendarURI)) {
|
|
val calendarUri = gcalHelper.createTaskEvent(task, preferences.defaultCalendar)
|
|
task.calendarURI = calendarUri.toString()
|
|
}
|
|
createTags(task)
|
|
val addToTop = preferences.addTasksToTop()
|
|
if (task.hasTransitory(GoogleTask.KEY)) {
|
|
googleTaskDao.insertAndShift(
|
|
task,
|
|
CaldavTask(task.id, task.getTransitory<String>(GoogleTask.KEY)!!, remoteId = null),
|
|
addToTop
|
|
)
|
|
} else if (task.hasTransitory(CaldavTask.KEY)) {
|
|
caldavDao.insert(
|
|
task, CaldavTask(task.id, task.getTransitory<String>(CaldavTask.KEY)), addToTop)
|
|
} else {
|
|
val remoteList = defaultFilterProvider.getDefaultList()
|
|
if (remoteList is GtasksFilter) {
|
|
googleTaskDao.insertAndShift(
|
|
task,
|
|
CaldavTask(task.id, remoteList.remoteId, remoteId = null),
|
|
addToTop
|
|
)
|
|
} else if (remoteList is CaldavFilter) {
|
|
caldavDao.insert(
|
|
task, CaldavTask(task.id, remoteList.uuid), addToTop)
|
|
}
|
|
}
|
|
if (task.hasTransitory(Place.KEY)) {
|
|
val place = locationDao.getPlace(task.getTransitory<String>(Place.KEY)!!)
|
|
if (place != null) {
|
|
locationDao.insert(Geofence(place.uid, preferences))
|
|
}
|
|
}
|
|
taskDao.save(task, null)
|
|
alarmDao.insert(task.getDefaultAlarms())
|
|
return task
|
|
}
|
|
|
|
suspend fun createWithValues(title: String?): Task {
|
|
return create(null, title)
|
|
}
|
|
|
|
suspend fun createWithValues(filter: Filter?, title: String?): Task {
|
|
return create(filter?.valuesForNewTasks, title)
|
|
}
|
|
|
|
/**
|
|
* Create task from the given content values, saving it. This version doesn't need to start with a
|
|
* base task model.
|
|
*/
|
|
internal suspend fun create(values: Map<String, Any>?, title: String?): Task {
|
|
val task = Task()
|
|
task.creationDate = DateUtilities.now()
|
|
task.modificationDate = DateUtilities.now()
|
|
if (title != null) {
|
|
task.title = title.trim { it <= ' ' }
|
|
}
|
|
task.uuid = UUIDHelper.newUUID()
|
|
task.priority = preferences.defaultPriority
|
|
preferences.getStringValue(R.string.p_default_recurrence)
|
|
?.takeIf { it.isNotBlank() }
|
|
?.let {
|
|
task.recurrence = it
|
|
task.repeatFrom = if (preferences.getIntegerFromString(R.string.p_default_recurrence_from, 0) == 1) {
|
|
Task.RepeatFrom.COMPLETION_DATE
|
|
} else {
|
|
Task.RepeatFrom.DUE_DATE
|
|
}
|
|
}
|
|
preferences.getStringValue(R.string.p_default_location)
|
|
?.takeIf { it.isNotBlank() }
|
|
?.let { task.putTransitory(Place.KEY, it) }
|
|
task.setDefaultReminders(preferences)
|
|
val tags = ArrayList<String>()
|
|
values?.entries?.forEach { (key, value) ->
|
|
when (key) {
|
|
Tag.KEY -> tags.add(value as String)
|
|
GoogleTask.KEY, CaldavTask.KEY, Place.KEY -> task.putTransitory(key, value)
|
|
DUE_DATE.name -> value.substitute()?.toLongOrNull()?.let { task.dueDate =
|
|
createDueDate(Task.URGENCY_SPECIFIC_DAY, it) }
|
|
IMPORTANCE.name -> value.substitute()?.toIntOrNull()?.let { task.priority = it }
|
|
HIDE_UNTIL.name ->
|
|
value.substitute()?.toLongOrNull()?.let { task.hideUntil = it.startOfDay() }
|
|
}
|
|
}
|
|
if (values?.containsKey(DUE_DATE.name) != true) {
|
|
task.dueDate = createDueDate(
|
|
preferences.getIntegerFromString(R.string.p_default_urgency_key, Task.URGENCY_NONE),
|
|
0)
|
|
}
|
|
if (values?.containsKey(HIDE_UNTIL.name) != true) {
|
|
task.hideUntil = task.createHideUntil(
|
|
preferences.getIntegerFromString(R.string.p_default_hideUntil_key, HIDE_UNTIL_NONE),
|
|
0
|
|
)
|
|
}
|
|
if (tags.isEmpty()) {
|
|
preferences.getStringValue(R.string.p_default_tags)
|
|
?.split(",")
|
|
?.map { tagDataDao.getByUuid(it) }
|
|
?.mapNotNull { it?.name }
|
|
?.let { tags.addAll(it) }
|
|
}
|
|
try {
|
|
parse(tagDataDao, task, tags)
|
|
} catch (e: Throwable) {
|
|
Timber.e(e)
|
|
}
|
|
task.setTags(tags)
|
|
return task
|
|
}
|
|
|
|
suspend fun createTags(task: Task) {
|
|
for (tag in task.tags) {
|
|
var tagData = tagDataDao.getTagByName(tag)
|
|
if (tagData == null) {
|
|
tagData = TagData()
|
|
tagData.name = tag
|
|
tagDataDao.createNew(tagData)
|
|
}
|
|
tagDao.insert(Tag(task, tagData))
|
|
}
|
|
}
|
|
|
|
companion object {
|
|
fun Task.setDefaultReminders(preferences: Preferences) {
|
|
randomReminder = DateUtilities.ONE_HOUR * preferences.getIntegerFromString(
|
|
R.string.p_rmd_default_random_hours,
|
|
0
|
|
)
|
|
defaultReminders(preferences.defaultReminders)
|
|
ringFlags = preferences.defaultRingMode
|
|
}
|
|
|
|
private fun Any?.substitute(): String? =
|
|
(this as? String)?.let { PermaSql.replacePlaceholdersForNewTask(it) }
|
|
|
|
fun Task.getDefaultAlarms(): List<Alarm> = ArrayList<Alarm>().apply {
|
|
if (hasStartDate() && isNotifyAtStart) {
|
|
add(whenStarted(id))
|
|
}
|
|
if (hasDueDate()) {
|
|
if (isNotifyAtDeadline) {
|
|
add(whenDue(id))
|
|
}
|
|
if (isNotifyAfterDeadline) {
|
|
add(whenOverdue(id))
|
|
}
|
|
}
|
|
if (randomReminder > 0) {
|
|
add(Alarm(id, randomReminder, TYPE_RANDOM))
|
|
}
|
|
}
|
|
}
|
|
}
|