Update schema for recurrence

* Move repeat until into recurrence
* Move repeat from out of recurrence
pull/1935/head
Alex Baker 2 years ago
parent c52f90adb9
commit 57ca2f013a

File diff suppressed because it is too large Load Diff

@ -4,39 +4,8 @@ import androidx.room.AutoMigration
import androidx.room.Database
import androidx.room.RoomDatabase
import com.todoroo.astrid.data.Task
import org.tasks.data.Alarm
import org.tasks.data.AlarmDao
import org.tasks.data.CaldavAccount
import org.tasks.data.CaldavCalendar
import org.tasks.data.CaldavDao
import org.tasks.data.CaldavTask
import org.tasks.data.ContentProviderDao
import org.tasks.data.DeletionDao
import org.tasks.data.Filter
import org.tasks.data.FilterDao
import org.tasks.data.Geofence
import org.tasks.data.GoogleTask
import org.tasks.data.GoogleTaskAccount
import org.tasks.data.GoogleTaskDao
import org.tasks.data.GoogleTaskList
import org.tasks.data.GoogleTaskListDao
import org.tasks.data.LocationDao
import org.tasks.data.Place
import org.tasks.data.Principal
import org.tasks.data.PrincipalAccess
import org.tasks.data.PrincipalDao
import org.tasks.data.Tag
import org.tasks.data.TagDao
import org.tasks.data.TagData
import org.tasks.data.TagDataDao
import org.tasks.data.TaskAttachment
import org.tasks.data.TaskAttachmentDao
import org.tasks.data.*
import org.tasks.data.TaskDao
import org.tasks.data.TaskListMetadata
import org.tasks.data.TaskListMetadataDao
import org.tasks.data.UpgraderDao
import org.tasks.data.UserActivity
import org.tasks.data.UserActivityDao
import org.tasks.db.Migrations
import org.tasks.notifications.Notification
import org.tasks.notifications.NotificationDao
@ -66,7 +35,7 @@ import org.tasks.notifications.NotificationDao
autoMigrations = [
AutoMigration(from = 83, to = 84, spec = Migrations.AutoMigrate83to84::class),
],
version = 84
version = 85
)
abstract class Database : RoomDatabase() {
abstract fun notificationDao(): NotificationDao

@ -15,7 +15,6 @@ import org.tasks.Strings
import org.tasks.data.Tag
import org.tasks.date.DateTimeUtils
import org.tasks.date.DateTimeUtils.toDateTime
import org.tasks.time.DateTime
import org.tasks.time.DateTimeUtils.startOfDay
import timber.log.Timber
@ -87,8 +86,8 @@ class Task : Parcelable {
@ColumnInfo(name = "recurrence")
var recurrence: String? = null
@ColumnInfo(name = "repeatUntil")
var repeatUntil = 0L
@ColumnInfo(name = "repeat_from", defaultValue = RepeatFrom.DUE_DATE.toString())
var repeatFrom: Int = RepeatFrom.DUE_DATE
@ColumnInfo(name = "calendarUri")
var calendarURI: String? = null
@ -127,7 +126,6 @@ class Task : Parcelable {
recurrence = parcel.readString()
ringFlags = parcel.readInt()
reminderLast = parcel.readLong()
repeatUntil = parcel.readLong()
timerStart = parcel.readLong()
title = parcel.readString()
remoteId = parcel.readString() ?: NO_UUID
@ -197,7 +195,7 @@ class Task : Parcelable {
return dueDate < compareTo && !isCompleted
}
fun repeatAfterCompletion(): Boolean = recurrence.isRepeatAfterCompletion()
fun repeatAfterCompletion(): Boolean = repeatFrom == RepeatFrom.COMPLETION_DATE
fun setDueDateAdjustingHideUntil(newDueDate: Long) {
if (dueDate > 0) {
@ -211,18 +209,8 @@ class Task : Parcelable {
val isRecurring: Boolean
get() = !Strings.isNullOrEmpty(recurrence)
fun setRecurrence(rrule: String, afterCompletion: Boolean) {
recurrence = rrule + if (afterCompletion) ";FROM=COMPLETION" else ""
}
fun setRecurrence(rrule: Recur?) {
if (rrule == null) {
repeatUntil = 0
recurrence = null
} else {
repeatUntil = rrule.until?.let { DateTime(it).millis } ?: 0
recurrence = rrule.toString() + if (repeatAfterCompletion()) ";FROM=COMPLETION" else ""
}
recurrence = rrule?.toString()
}
fun hasNotes(): Boolean {
@ -271,7 +259,6 @@ class Task : Parcelable {
dest.writeString(recurrence)
dest.writeInt(ringFlags)
dest.writeLong(reminderLast)
dest.writeLong(repeatUntil)
dest.writeLong(timerStart)
dest.writeString(title)
dest.writeString(remoteId)
@ -300,7 +287,6 @@ class Task : Parcelable {
&& elapsedSeconds == task.elapsedSeconds
&& ringFlags == task.ringFlags
&& recurrence == task.recurrence
&& repeatUntil == task.repeatUntil
&& calendarURI == task.calendarURI
&& parent == task.parent
&& remoteId == task.remoteId
@ -335,7 +321,6 @@ class Task : Parcelable {
&& notes == original.notes
&& recurrence == original.recurrence
&& parent == original.parent
&& repeatUntil == original.repeatUntil
&& isCollapsed == original.isCollapsed
}
@ -418,7 +403,6 @@ class Task : Parcelable {
if (ringFlags != other.ringFlags) return false
if (reminderLast != other.reminderLast) return false
if (recurrence != other.recurrence) return false
if (repeatUntil != other.repeatUntil) return false
if (calendarURI != other.calendarURI) return false
if (remoteId != other.remoteId) return false
if (isCollapsed != other.isCollapsed) return false
@ -445,7 +429,6 @@ class Task : Parcelable {
result = 31 * result + ringFlags
result = 31 * result + reminderLast.hashCode()
result = 31 * result + (recurrence?.hashCode() ?: 0)
result = 31 * result + repeatUntil.hashCode()
result = 31 * result + (calendarURI?.hashCode() ?: 0)
result = 31 * result + remoteId.hashCode()
result = 31 * result + isCollapsed.hashCode()
@ -455,7 +438,7 @@ class Task : Parcelable {
}
override fun toString(): String {
return "Task(id=$id, title=$title, priority=$priority, dueDate=$dueDate, hideUntil=$hideUntil, creationDate=$creationDate, modificationDate=$modificationDate, completionDate=$completionDate, deletionDate=$deletionDate, notes=$notes, estimatedSeconds=$estimatedSeconds, elapsedSeconds=$elapsedSeconds, timerStart=$timerStart, ringFlags=$ringFlags, reminderLast=$reminderLast, recurrence=$recurrence, repeatUntil=$repeatUntil, calendarURI=$calendarURI, remoteId='$remoteId', isCollapsed=$isCollapsed, parent=$parent, transitoryData=$transitoryData)"
return "Task(id=$id, title=$title, priority=$priority, dueDate=$dueDate, hideUntil=$hideUntil, creationDate=$creationDate, modificationDate=$modificationDate, completionDate=$completionDate, deletionDate=$deletionDate, notes=$notes, estimatedSeconds=$estimatedSeconds, elapsedSeconds=$elapsedSeconds, timerStart=$timerStart, ringFlags=$ringFlags, reminderLast=$reminderLast, recurrence=$recurrence, calendarURI=$calendarURI, remoteId='$remoteId', isCollapsed=$isCollapsed, parent=$parent, transitoryData=$transitoryData)"
}
@Retention(AnnotationRetention.SOURCE)
@ -469,6 +452,15 @@ class Task : Parcelable {
}
}
@Retention(AnnotationRetention.SOURCE)
@IntDef(RepeatFrom.DUE_DATE, RepeatFrom.COMPLETION_DATE)
annotation class RepeatFrom {
companion object {
const val DUE_DATE = 0
const val COMPLETION_DATE = 1
}
}
fun clone(): Task {
val parcel = Parcel.obtain()
writeToParcel(parcel, 0)
@ -615,8 +607,5 @@ class Task : Parcelable {
return NO_UUID == uuid || Strings.isNullOrEmpty(uuid)
}
fun String?.isRepeatAfterCompletion() = this?.contains("FROM=COMPLETION") ?: false
fun String?.withoutFrom(): String? = this?.replace(";?FROM=[^;]*".toRegex(), "")
}
}

@ -65,7 +65,7 @@ class RepeatTaskHelper @Inject constructor(
}
if (count > 1) {
rrule.count = count - 1
task.setRecurrence(rrule.toString(), repeatAfterCompletion)
task.setRecurrence(rrule)
}
task.reminderLast = 0L
task.completionDate = 0L
@ -95,7 +95,7 @@ class RepeatTaskHelper @Inject constructor(
if (count > 0) {
recur.count = count + 1
}
task.setRecurrence(recur.toString(), task.repeatAfterCompletion())
task.setRecurrence(recur)
val newDueDate = task.dueDate
task.setDueDateAdjustingHideUntil(
if (oldDueDate > 0) {
@ -128,8 +128,7 @@ class RepeatTaskHelper @Inject constructor(
companion object {
private val weekdayCompare = Comparator { object1: WeekDay, object2: WeekDay -> WeekDay.getCalendarDay(object1) - WeekDay.getCalendarDay(object2) }
private fun repeatFinished(newDueDate: Long, repeatUntil: Long): Boolean {
return (repeatUntil > 0
&& newDateTime(newDueDate).startOfDay().isAfter(newDateTime(repeatUntil).startOfDay()))
return repeatUntil > 0 && newDateTime(newDueDate).startOfDay().millis > repeatUntil
}
/** Compute next due date */
@ -267,5 +266,14 @@ class RepeatTaskHelper @Inject constructor(
val newDueDate = startDate.millis + millis * recur.interval
return createDueDate(Task.URGENCY_SPECIFIC_DAY_TIME, newDueDate)
}
private val Task.repeatUntil: Long
get() = recurrence
?.takeIf { it.isNotBlank() }
?.let { newRecur(it) }
?.until
?.let { DateTime.from(it) }
?.millis
?: 0L
}
}

@ -17,23 +17,11 @@ 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.Alarm
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.data.AlarmDao
import org.tasks.data.CaldavDao
import org.tasks.data.CaldavTask
import org.tasks.data.Geofence
import org.tasks.data.GoogleTask
import org.tasks.data.GoogleTaskDao
import org.tasks.data.LocationDao
import org.tasks.data.Place
import org.tasks.data.Tag
import org.tasks.data.TagDao
import org.tasks.data.TagData
import org.tasks.data.TagDataDao
import org.tasks.preferences.DefaultFilterProvider
import org.tasks.preferences.Preferences
import org.tasks.time.DateTimeUtils.startOfDay
@ -116,9 +104,12 @@ class TaskCreator @Inject constructor(
preferences.getStringValue(R.string.p_default_recurrence)
?.takeIf { it.isNotBlank() }
?.let {
task.setRecurrence(
it,
preferences.getIntegerFromString(R.string.p_default_recurrence_from, 0) == 1)
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() }

@ -18,22 +18,7 @@ import org.tasks.caldav.iCalendar
import org.tasks.caldav.iCalendar.Companion.fromVtodo
import org.tasks.caldav.iCalendar.Companion.order
import org.tasks.caldav.iCalendar.Companion.parent
import org.tasks.data.CaldavDao
import org.tasks.data.CaldavTask
import org.tasks.data.CaldavTaskContainer
import org.tasks.data.FilterDao
import org.tasks.data.GoogleTaskAccount
import org.tasks.data.GoogleTaskDao
import org.tasks.data.GoogleTaskListDao
import org.tasks.data.Location
import org.tasks.data.LocationDao
import org.tasks.data.Tag
import org.tasks.data.TagDao
import org.tasks.data.TagData
import org.tasks.data.TagDataDao
import org.tasks.data.TaskAttachmentDao
import org.tasks.data.UpgraderDao
import org.tasks.data.UserActivityDao
import org.tasks.data.*
import org.tasks.preferences.DefaultFilterProvider
import org.tasks.preferences.Preferences
import org.tasks.widget.AppWidgetManager
@ -367,6 +352,7 @@ class Upgrader @Inject constructor(
const val V11_13 = 111300
const val V12_4 = 120400
const val V12_6 = 120601
const val V12_8 = 120800
@JvmStatic
fun getAndroidColor(context: Context, index: Int): Int {

@ -12,26 +12,16 @@ import com.todoroo.astrid.service.TaskCreator.Companion.getDefaultAlarms
import com.todoroo.astrid.service.TaskMover
import com.todoroo.astrid.service.Upgrader
import com.todoroo.astrid.service.Upgrader.Companion.V12_4
import com.todoroo.astrid.service.Upgrader.Companion.V12_8
import com.todoroo.astrid.service.Upgrader.Companion.V6_4
import com.todoroo.astrid.service.Upgrader.Companion.getAndroidColor
import org.tasks.LocalBroadcastManager
import org.tasks.R
import org.tasks.caldav.VtodoCache
import org.tasks.data.AlarmDao
import org.tasks.data.CaldavDao
import org.tasks.data.FilterDao
import org.tasks.data.Geofence
import org.tasks.data.GoogleTaskDao
import org.tasks.data.GoogleTaskListDao
import org.tasks.data.LocationDao
import org.tasks.data.*
import org.tasks.data.Place.Companion.newPlace
import org.tasks.data.Tag
import org.tasks.data.TagDao
import org.tasks.data.TagData
import org.tasks.data.TagDataDao
import org.tasks.data.TaskAttachmentDao
import org.tasks.data.TaskListMetadataDao
import org.tasks.data.UserActivityDao
import org.tasks.db.Migrations.isRepeatAfterCompletion
import org.tasks.db.Migrations.withoutFrom
import org.tasks.preferences.Preferences
import timber.log.Timber
import java.io.FileNotFoundException
@ -166,6 +156,14 @@ class TasksJsonImporter @Inject constructor(
}
taskDao.save(task)
}
if (version < V12_8) {
task.repeatFrom = if (task.recurrence.isRepeatAfterCompletion()) {
Task.RepeatFrom.COMPLETION_DATE
} else {
Task.RepeatFrom.DUE_DATE
}
task.recurrence = task.recurrence.withoutFrom()
}
for (comment in backup.comments) {
comment.targetId = taskUuid
if (version < V6_4) {

@ -17,36 +17,16 @@ import net.fortuna.ical4j.model.Parameter
import net.fortuna.ical4j.model.Property
import net.fortuna.ical4j.model.component.VAlarm
import net.fortuna.ical4j.model.parameter.RelType
import net.fortuna.ical4j.model.property.Action
import net.fortuna.ical4j.model.property.Completed
import net.fortuna.ical4j.model.property.DateProperty
import net.fortuna.ical4j.model.property.DtStart
import net.fortuna.ical4j.model.property.Due
import net.fortuna.ical4j.model.property.Geo
import net.fortuna.ical4j.model.property.RelatedTo
import net.fortuna.ical4j.model.property.Status
import net.fortuna.ical4j.model.property.XProperty
import net.fortuna.ical4j.model.property.*
import org.tasks.Strings.isNullOrEmpty
import org.tasks.caldav.GeoUtils.equalish
import org.tasks.caldav.GeoUtils.toGeo
import org.tasks.caldav.GeoUtils.toLikeString
import org.tasks.caldav.extensions.toAlarms
import org.tasks.caldav.extensions.toVAlarms
import org.tasks.data.Alarm
import org.tasks.data.*
import org.tasks.data.Alarm.Companion.TYPE_RANDOM
import org.tasks.data.Alarm.Companion.TYPE_SNOOZE
import org.tasks.data.AlarmDao
import org.tasks.data.CaldavAccount
import org.tasks.data.CaldavAccount.Companion.SERVER_SYNOLOGY_CALENDAR
import org.tasks.data.CaldavCalendar
import org.tasks.data.CaldavDao
import org.tasks.data.CaldavTask
import org.tasks.data.Geofence
import org.tasks.data.LocationDao
import org.tasks.data.Place
import org.tasks.data.TagDao
import org.tasks.data.TagData
import org.tasks.data.TagDataDao
import org.tasks.date.DateTimeUtils.newDateTime
import org.tasks.date.DateTimeUtils.toDateTime
import org.tasks.date.DateTimeUtils.toLocal
@ -55,7 +35,6 @@ import org.tasks.location.GeofenceApi
import org.tasks.notifications.NotificationManager
import org.tasks.preferences.Preferences
import org.tasks.repeats.RecurrenceUtils.newRRule
import org.tasks.repeats.RecurrenceUtils.newRecur
import org.tasks.time.DateTimeUtils.startOfDay
import org.tasks.time.DateTimeUtils.startOfMinute
import org.tasks.time.DateTimeUtils.toDate
@ -434,14 +413,7 @@ class iCalendar @Inject constructor(
}
rRule = if (task.isRecurring) {
try {
val recur = newRecur(task.recurrence!!)
val repeatUntil = task.repeatUntil
recur.until = if (repeatUntil > 0) {
DateTime(newDateTime(repeatUntil).toUTC().millis)
} else {
null
}
newRRule(recur.toString())
newRRule(task.recurrence!!)
} catch (e: ParseException) {
Timber.e(e)
null

@ -2,7 +2,6 @@ package org.tasks.caldav
import at.bitfire.ical4android.Task
import com.todoroo.andlib.utility.DateUtilities
import com.todoroo.astrid.data.Task.Companion.withoutFrom
import com.todoroo.astrid.data.Task.Priority.Companion.HIGH
import com.todoroo.astrid.data.Task.Priority.Companion.LOW
import com.todoroo.astrid.data.Task.Priority.Companion.MEDIUM
@ -16,7 +15,6 @@ import org.tasks.caldav.iCalendar.Companion.toMillis
import org.tasks.data.CaldavTask
import org.tasks.date.DateTimeUtils.newDateTime
import org.tasks.time.DateTime.UTC
import org.tasks.time.DateTimeUtils.startOfMinute
import org.tasks.time.DateTimeUtils.startOfSecond
fun com.todoroo.astrid.data.Task.applyRemote(
@ -87,7 +85,7 @@ private fun com.todoroo.astrid.data.Task.applyPriority(remote: Task, local: Task
}
private fun com.todoroo.astrid.data.Task.applyRecurrence(remote: Task, local: Task?) {
if (local == null || local.rRule?.recur?.toString() == recurrence.withoutFrom()) {
if (local == null || local.rRule?.recur?.toString() == recurrence) {
setRecurrence(remote.rRule?.recur)
}
}

@ -6,6 +6,7 @@ import androidx.room.migration.AutoMigrationSpec
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
import com.todoroo.astrid.api.FilterListItem.NO_ORDER
import com.todoroo.astrid.data.Task
import com.todoroo.astrid.data.Task.Companion.NOTIFY_AFTER_DEADLINE
import com.todoroo.astrid.data.Task.Companion.NOTIFY_AT_DEADLINE
import com.todoroo.astrid.data.Task.Companion.NOTIFY_AT_START
@ -15,7 +16,10 @@ import org.tasks.data.Alarm.Companion.TYPE_REL_END
import org.tasks.data.Alarm.Companion.TYPE_REL_START
import org.tasks.data.Alarm.Companion.TYPE_SNOOZE
import org.tasks.data.CaldavAccount.Companion.SERVER_UNKNOWN
import org.tasks.data.OpenTaskDao.Companion.getLong
import org.tasks.extensions.getString
import org.tasks.repeats.RecurrenceUtils.newRecur
import org.tasks.time.DateTime
import timber.log.Timber
import java.io.File
import java.util.concurrent.TimeUnit.HOURS
@ -530,6 +534,36 @@ object Migrations {
}
}
private val MIGRATION_84_85 = object : Migration(84, 85) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE `tasks` ADD COLUMN `repeat_from` INTEGER NOT NULL DEFAULT ${Task.RepeatFrom.DUE_DATE}")
database
.query("SELECT `_id`, `repeatUntil`, `recurrence` FROM `tasks` WHERE `repeatUntil` > 0")
.use {
while (it.moveToNext()) {
val id = it.getLong("_id")
val repeatUntil = it.getLong("repeatUntil")
val recurrence = it.getString("recurrence") ?: continue
val recur = newRecur(recurrence.withoutFrom()!!).apply {
until = DateTime(repeatUntil).toDate()
}
val repeatFrom = if (recurrence.isRepeatAfterCompletion()) {
Task.RepeatFrom.COMPLETION_DATE
} else {
Task.RepeatFrom.DUE_DATE
}
database.execSQL("UPDATE `tasks` SET `repeat_from` = $repeatFrom, `recurrence` = '$recur' WHERE `_id` = $id")
}
}
database.execSQL("CREATE TABLE IF NOT EXISTS `_new_tasks` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `title` TEXT, `importance` INTEGER NOT NULL, `dueDate` INTEGER NOT NULL, `hideUntil` INTEGER NOT NULL, `created` INTEGER NOT NULL, `modified` INTEGER NOT NULL, `completed` INTEGER NOT NULL, `deleted` INTEGER NOT NULL, `notes` TEXT, `estimatedSeconds` INTEGER NOT NULL, `elapsedSeconds` INTEGER NOT NULL, `timerStart` INTEGER NOT NULL, `notificationFlags` INTEGER NOT NULL, `lastNotified` INTEGER NOT NULL, `recurrence` TEXT, `repeat_from` INTEGER NOT NULL DEFAULT 0, `calendarUri` TEXT, `remoteId` TEXT, `collapsed` INTEGER NOT NULL, `parent` INTEGER NOT NULL)")
database.execSQL("INSERT INTO `_new_tasks` (`parent`,`notes`,`timerStart`,`estimatedSeconds`,`importance`,`created`,`collapsed`,`dueDate`,`completed`,`title`,`hideUntil`,`remoteId`,`recurrence`,`deleted`,`notificationFlags`,`calendarUri`,`modified`,`_id`,`lastNotified`,`elapsedSeconds`,`repeat_from`) SELECT `parent`,`notes`,`timerStart`,`estimatedSeconds`,`importance`,`created`,`collapsed`,`dueDate`,`completed`,`title`,`hideUntil`,`remoteId`,`recurrence`,`deleted`,`notificationFlags`,`calendarUri`,`modified`,`_id`,`lastNotified`,`elapsedSeconds`,`repeat_from` FROM `tasks`")
database.execSQL("DROP TABLE `tasks`")
database.execSQL("ALTER TABLE `_new_tasks` RENAME TO `tasks`")
database.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS `t_rid` ON `tasks` (`remoteId`)")
database.execSQL("CREATE INDEX IF NOT EXISTS `active_and_visible` ON `tasks` (`completed`, `deleted`, `hideUntil`)")
}
}
fun migrations(fileStorage: FileStorage) = arrayOf(
MIGRATION_35_36,
MIGRATION_36_37,
@ -570,9 +604,14 @@ object Migrations {
MIGRATION_80_81,
migration_81_82(fileStorage),
MIGRATION_82_83,
MIGRATION_84_85,
)
private fun noop(from: Int, to: Int): Migration = object : Migration(from, to) {
override fun migrate(database: SupportSQLiteDatabase) {}
}
fun String?.isRepeatAfterCompletion() = this?.contains("FROM=COMPLETION") ?: false
fun String?.withoutFrom(): String? = this?.replace(";?FROM=[^;]*".toRegex(), "")
}

@ -1,7 +1,6 @@
package org.tasks.repeats
import com.todoroo.astrid.data.Task.Companion.sanitizeRecur
import com.todoroo.astrid.data.Task.Companion.withoutFrom
import net.fortuna.ical4j.model.Recur
import net.fortuna.ical4j.model.property.RRule
@ -15,6 +14,6 @@ object RecurrenceUtils {
fun newRecur(rrule: String): Recur = newRRule(rrule).recur
fun newRRule(rrule: String): RRule =
RRule(rrule.replace(LEGACY_RRULE_PREFIX, "").withoutFrom().sanitizeRecur())
RRule(rrule.replace(LEGACY_RRULE_PREFIX, "").sanitizeRecur())
}

@ -104,10 +104,6 @@ public class DateTime {
}
}
public DateTime(Date date) {
this(date.getTime());
}
private DateTime setTime(int hours, int minutes, int seconds, int milliseconds) {
Calendar calendar = getCalendar();
calendar.set(Calendar.HOUR_OF_DAY, hours);

@ -15,8 +15,6 @@ import com.todoroo.astrid.data.Task.Companion.NOTIFY_MODE_FIVE
import com.todoroo.astrid.data.Task.Companion.NOTIFY_MODE_NONSTOP
import com.todoroo.astrid.data.Task.Companion.createDueDate
import com.todoroo.astrid.data.Task.Companion.hasDueTime
import com.todoroo.astrid.data.Task.Companion.isRepeatAfterCompletion
import com.todoroo.astrid.data.Task.Companion.withoutFrom
import com.todoroo.astrid.gcal.GCalHelper
import com.todoroo.astrid.service.TaskCompleter
import com.todoroo.astrid.service.TaskDeleter
@ -45,7 +43,6 @@ import org.tasks.location.GeofenceApi
import org.tasks.preferences.PermissionChecker
import org.tasks.preferences.Preferences
import org.tasks.repeats.RecurrenceUtils.newRecur
import org.tasks.time.DateTime
import org.tasks.time.DateTimeUtils.currentTimeMillis
import org.tasks.time.DateTimeUtils.startOfDay
import timber.log.Timber
@ -171,54 +168,27 @@ class TaskEditViewModel @Inject constructor(
var recurrence: String? = null
get() = field ?: task.recurrence
var repeatUntil: Long? = null
get() = field ?: task.repeatUntil
var repeatAfterCompletion: Boolean? = null
get() = field ?: task.repeatAfterCompletion()
set(value) {
field = value
if (value == true) {
if (!recurrence.isRepeatAfterCompletion()) {
recurrence += ";FROM=COMPLETION"
}
} else if (recurrence.isRepeatAfterCompletion()) {
recurrence = recurrence.withoutFrom()
}
}
var recur: Recur?
get() = if (recurrence.isNullOrBlank()) {
null
} else {
val rrule = newRecur(recurrence!!)
repeatUntil?.takeIf { it > 0 }?.let {
rrule.until = DateTime(it).toDate()
}
rrule
newRecur(recurrence!!)
}
set(value) {
if (value == null) {
recurrence = ""
repeatUntil = 0
return
}
val copy = try {
newRecur(value.toString())
} catch (e: ParseException) {
recurrence = ""
repeatUntil = 0
return
}
repeatUntil = DateTime.from(copy.until).millis
if (repeatUntil ?: 0 > 0) {
copy.until = null
}
var result = copy.toString()
if (repeatAfterCompletion!! && result.isNotBlank()) {
result += ";FROM=COMPLETION"
}
recurrence = result
recurrence = copy.toString()
}
var originalCalendar: String? = null
@ -295,7 +265,6 @@ class TaskEditViewModel @Inject constructor(
task.recurrence != recurrence
} ||
task.repeatAfterCompletion() != repeatAfterCompletion ||
task.repeatUntil != repeatUntil ||
originalCalendar != selectedCalendar.value ||
if (task.calendarURI.isNullOrBlank()) {
!eventUri.value.isNullOrBlank()
@ -331,7 +300,11 @@ class TaskEditViewModel @Inject constructor(
task.notes = description
task.hideUntil = startDate.value
task.recurrence = recurrence
task.repeatUntil = repeatUntil!!
task.repeatFrom = if (repeatAfterCompletion == true) {
Task.RepeatFrom.COMPLETION_DATE
} else {
Task.RepeatFrom.DUE_DATE
}
task.elapsedSeconds = elapsedSeconds.value
task.estimatedSeconds = estimatedSeconds.value
task.ringFlags = getRingFlags()

Loading…
Cancel
Save