pull/3782/merge
Milosch Füllgraf 2 weeks ago committed by GitHub
commit 27fb45ebe8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -150,6 +150,12 @@ class Upgrader @Inject constructor(
}
}
}
run(from, V14_7_5) {
upgraderDao.tasksWithVtodos()
.filter { it.task.estimatedSeconds > 0 || it.task.elapsedSeconds > 0 }
.map { it.id }
.let { taskDao.touch(it) }
}
run(from, V14_8) {
WorkManager.getInstance(context).enqueueUniqueWork(
uniqueWorkName = "upload_icons",
@ -421,6 +427,7 @@ class Upgrader @Inject constructor(
const val V12_8 = 120800
const val V14_5_4 = 140516
const val V14_6_1 = 140602
const val V14_7_5 = 140705
const val V14_8 = 140800
@JvmStatic

@ -296,11 +296,16 @@ class iCalendar @Inject constructor(
it === RelType.PARENT || it == null || it.value.isNullOrBlank()
}
}
// custom X- properties to sync internal fields
private const val TASKS_ESTIMATED_SECONDS = "X-TASKS-ESTIMATED-SECONDS"
private const val TASKS_ELAPSED_SECONDS = "X-TASKS-ELAPSED-SECONDS"
internal val IS_APPLE_SORT_ORDER = { x: Property? -> x?.name.equals(APPLE_SORT_ORDER, true) }
private val IS_OC_HIDESUBTASKS = { x: Property? -> x?.name.equals(OC_HIDESUBTASKS, true) }
private val IS_MOZ_SNOOZE_TIME = { x: Property? -> x?.name.equals(MOZ_SNOOZE_TIME, true) }
private val IS_MOZ_LASTACK = { x: Property? -> x?.name.equals(MOZ_LASTACK, true) }
private val IS_TASKS_ESTIMATED_SECONDS = { x: Property? -> x?.name.equals(TASKS_ESTIMATED_SECONDS, true) }
private val IS_TASKS_ELAPSED_SECONDS = { x: Property? -> x?.name.equals(TASKS_ELAPSED_SECONDS, true) }
fun Due?.apply(task: org.tasks.data.entity.Task) {
task.dueDate = toMillis()
@ -442,6 +447,36 @@ class iCalendar @Inject constructor(
?: unknownProperties.removeIf(IS_MOZ_SNOOZE_TIME)
}
var Task.estimatedSeconds: Int?
get() = unknownProperties.find(IS_TASKS_ESTIMATED_SECONDS)?.value?.toInt()
set(value) {
value
?.takeIf { it != 0 }
?.let { dur ->
unknownProperties.find(IS_TASKS_ESTIMATED_SECONDS)
?.let { it.value = dur.toString() }
?: unknownProperties.add(
XProperty(TASKS_ESTIMATED_SECONDS, dur.toString())
)
}
?: unknownProperties.removeIf(IS_TASKS_ESTIMATED_SECONDS)
}
var Task.elapsedSeconds: Int?
get() = unknownProperties.find(IS_TASKS_ELAPSED_SECONDS)?.value?.toInt()
set(value) {
value
?.takeIf { it != 0 }
?.let { dur ->
unknownProperties.find(IS_TASKS_ELAPSED_SECONDS)
?.let { it.value = dur.toString() }
?: unknownProperties.add(
XProperty(TASKS_ELAPSED_SECONDS, dur.toString())
)
}
?: unknownProperties.removeIf(IS_TASKS_ELAPSED_SECONDS)
}
fun Task.applyLocal(caldavTask: CaldavTask, task: org.tasks.data.entity.Task) {
createdAt = newDateTime(task.creationDate).toUTC().millis
summary = task.title
@ -494,6 +529,8 @@ class iCalendar @Inject constructor(
parent = if (task.parent == 0L) null else caldavTask.remoteParent
order = task.order
collapsed = task.isCollapsed
estimatedSeconds = task.estimatedSeconds
elapsedSeconds = task.elapsedSeconds
}
val List<VAlarm>.filtered: List<VAlarm>

@ -3,6 +3,8 @@ package org.tasks.caldav
import at.bitfire.ical4android.Task
import net.fortuna.ical4j.model.property.Status
import org.tasks.caldav.iCalendar.Companion.collapsed
import org.tasks.caldav.iCalendar.Companion.elapsedSeconds
import org.tasks.caldav.iCalendar.Companion.estimatedSeconds
import org.tasks.caldav.iCalendar.Companion.getLocal
import org.tasks.caldav.iCalendar.Companion.order
import org.tasks.caldav.iCalendar.Companion.parent
@ -32,6 +34,8 @@ fun org.tasks.data.entity.Task.applyRemote(
applyStart(remote, local)
applyCollapsed(remote, local)
applyOrder(remote, local)
applyEstimatedSeconds(remote, local)
applyElapsedSeconds(remote, local)
return this
}
@ -121,6 +125,18 @@ private fun CaldavTask.applyParent(remote: Task, local: Task?) {
}
}
private fun org.tasks.data.entity.Task.applyEstimatedSeconds(remote: Task, local: Task?) {
if (local == null || local.estimatedSeconds == estimatedSeconds) {
estimatedSeconds = remote.estimatedSeconds ?: 0
}
}
private fun org.tasks.data.entity.Task.applyElapsedSeconds(remote: Task, local: Task?) {
if (local == null || local.elapsedSeconds == elapsedSeconds) {
elapsedSeconds = remote.elapsedSeconds ?: 0
}
}
private val Task.tasksPriority: Int
get() = when (this.priority) {
// https://tools.ietf.org/html/rfc5545#section-3.8.1.9

@ -655,6 +655,94 @@ class iCalendarMergeTest {
assertEquals("789", it.remoteParent)
}
@Test
fun remoteSetsEstimated() =
newTask()
.applyRemote(
remote = newIcal(with(iCalMaker.ESTIMATED_SECONDS, 2*60*60)),
local = null
)
.let {
assertEquals(2*60*60, it.estimatedSeconds)
}
@Test
fun remoteRemovesEstimated() =
newTask(with(TaskMaker.ESTIMATED_SECONDS, 2*60*60))
.applyRemote(
remote = newIcal(),
local = newIcal(with(iCalMaker.ESTIMATED_SECONDS, 2*60*60))
)
.let {
assertEquals(0, it.estimatedSeconds)
}
@Test
fun localResetsEstimated() =
newTask()
.applyRemote(
remote = newIcal(with(iCalMaker.ESTIMATED_SECONDS, 2*60*60)),
local = newIcal(with(iCalMaker.ESTIMATED_SECONDS, 2*60*60))
)
.let {
assertEquals(0, it.estimatedSeconds)
}
@Test
fun localBeatsRemoteEstimated() =
newTask(with(TaskMaker.ESTIMATED_SECONDS, 2*60*60))
.applyRemote(
remote = newIcal(with(iCalMaker.ESTIMATED_SECONDS, 4*60*60)),
local = newIcal(with(iCalMaker.ESTIMATED_SECONDS, 3*60*60))
)
.let {
assertEquals(2*60*60, it.estimatedSeconds)
}
@Test
fun remoteSetsElapsed() =
newTask()
.applyRemote(
remote = newIcal(with(iCalMaker.ELAPSED_SECONDS, 2*60*60)),
local = null
)
.let {
assertEquals(2*60*60, it.elapsedSeconds)
}
@Test
fun remoteRemovesElapsed() =
newTask(with(TaskMaker.ELAPSED_SECONDS, 2*60*60))
.applyRemote(
remote = newIcal(),
local = newIcal(with(iCalMaker.ELAPSED_SECONDS, 2*60*60))
)
.let {
assertEquals(0, it.elapsedSeconds)
}
@Test
fun localResetsElapsed() =
newTask()
.applyRemote(
remote = newIcal(with(iCalMaker.ELAPSED_SECONDS, 2*60*60)),
local = newIcal(with(iCalMaker.ELAPSED_SECONDS, 2*60*60))
)
.let {
assertEquals(0, it.elapsedSeconds)
}
@Test
fun localBeatsRemoteElapsed() =
newTask(with(TaskMaker.ELAPSED_SECONDS, 2*60*60))
.applyRemote(
remote = newIcal(with(iCalMaker.ELAPSED_SECONDS, 4*60*60)),
local = newIcal(with(iCalMaker.ELAPSED_SECONDS, 3*60*60))
)
.let {
assertEquals(2*60*60, it.elapsedSeconds)
}
companion object {
private fun DateTime.allDay() =
createDueDate(URGENCY_SPECIFIC_DAY, millis)

@ -35,6 +35,8 @@ object TaskMaker {
val COLLAPSED: Property<Task, Boolean> = newProperty()
val DESCRIPTION: Property<Task, String?> = newProperty()
val ORDER: Property<Task, Long> = newProperty()
val ESTIMATED_SECONDS: Property<Task, Int> = newProperty()
val ELAPSED_SECONDS: Property<Task, Int> = newProperty()
private val instantiator = Instantiator { lookup: PropertyLookup<Task> ->
val creationTime = lookup.valueOf(CREATION_TIME, DateTimeUtils.newDateTime())
@ -62,6 +64,8 @@ object TaskMaker {
order = lookup.valueOf(ORDER, null as Long?),
creationDate = creationTime.millis,
modificationDate = lookup.valueOf(MODIFICATION_TIME, creationTime).millis,
estimatedSeconds = lookup.valueOf(ESTIMATED_SECONDS, 0),
elapsedSeconds = lookup.valueOf(ELAPSED_SECONDS, 0)
)
lookup.valueOf(START_DATE, null as DateTime?)?.let {
task.hideUntil = task.createHideUntil(HIDE_UNTIL_SPECIFIC_DAY, it.millis)

@ -14,6 +14,8 @@ import net.fortuna.ical4j.model.property.RRule
import net.fortuna.ical4j.model.property.Status
import org.tasks.caldav.iCalendar
import org.tasks.caldav.iCalendar.Companion.collapsed
import org.tasks.caldav.iCalendar.Companion.elapsedSeconds
import org.tasks.caldav.iCalendar.Companion.estimatedSeconds
import org.tasks.caldav.iCalendar.Companion.order
import org.tasks.caldav.iCalendar.Companion.parent
import org.tasks.time.DateTime
@ -35,6 +37,8 @@ object iCalMaker {
val COLLAPSED: Property<Task, Boolean> = newProperty()
val RRULE: Property<Task, String?> = newProperty()
val STATUS: Property<Task, Status?> = newProperty()
val ESTIMATED_SECONDS: Property<Task, Int> = newProperty()
val ELAPSED_SECONDS: Property<Task, Int> = newProperty()
private val instantiator = Instantiator { lookup: PropertyLookup<Task> ->
val task = Task()
@ -65,6 +69,8 @@ object iCalMaker {
task.collapsed = lookup.valueOf(COLLAPSED, false)
task.rRule = lookup.valueOf(RRULE, null as String?)?.let { RRule(it) }
task.status = lookup.valueOf(STATUS, null as Status?)
task.estimatedSeconds = lookup.valueOf(ESTIMATED_SECONDS, 0)
task.elapsedSeconds = lookup.valueOf(ELAPSED_SECONDS, 0)
task
}
fun newIcal(vararg properties: PropertyValue<in Task?, *>): Task {

Loading…
Cancel
Save