Merge pull request #2116 from Naveen3Singh/recurring_event_edit_fix

Properly handle `Update the selected occurrence only`
This commit is contained in:
Tibor Kaputa
2023-06-18 20:42:23 +02:00
committed by GitHub
6 changed files with 65 additions and 21 deletions

View File

@@ -1155,7 +1155,7 @@ class EventActivity : SimpleActivity() {
DeleteEventDialog(this, arrayListOf(mEvent.id!!), mEvent.repeatInterval > 0) {
ensureBackgroundThread {
when (it) {
DELETE_SELECTED_OCCURRENCE -> eventsHelper.addEventRepetitionException(mEvent.id!!, mEventOccurrenceTS, true)
DELETE_SELECTED_OCCURRENCE -> eventsHelper.deleteRepeatingEventOccurrence(mEvent.id!!, mEventOccurrenceTS, true)
DELETE_FUTURE_OCCURRENCES -> eventsHelper.addEventRepeatLimit(mEvent.id!!, mEventOccurrenceTS)
DELETE_ALL_OCCURRENCES -> eventsHelper.deleteEvent(mEvent.id!!, true)
}
@@ -1361,7 +1361,6 @@ class EventActivity : SimpleActivity() {
when (it) {
EDIT_SELECTED_OCCURRENCE -> {
ensureBackgroundThread {
eventsHelper.addEventRepetitionException(mEvent.id!!, mEventOccurrenceTS, true)
mEvent.apply {
parentId = id!!.toLong()
id = null
@@ -1370,7 +1369,7 @@ class EventActivity : SimpleActivity() {
repeatLimit = 0
}
eventsHelper.insertEvent(mEvent, true, true) {
eventsHelper.insertEvent(mEvent, addToCalDAV = true, showToasts = true) {
finish()
}
}

View File

@@ -474,7 +474,6 @@ class TaskActivity : SimpleActivity() {
when (it) {
EDIT_SELECTED_OCCURRENCE -> {
ensureBackgroundThread {
eventsHelper.addEventRepetitionException(mTask.id!!, mTaskOccurrenceTS, addToCalDAV = false)
mTask.apply {
parentId = id!!.toLong()
id = null
@@ -533,9 +532,9 @@ class TaskActivity : SimpleActivity() {
DeleteEventDialog(this, arrayListOf(mTask.id!!), mTask.repeatInterval > 0, isTask = true) {
ensureBackgroundThread {
when (it) {
DELETE_SELECTED_OCCURRENCE -> eventsHelper.addEventRepetitionException(mTask.id!!, mTaskOccurrenceTS, true)
DELETE_SELECTED_OCCURRENCE -> eventsHelper.deleteRepeatingEventOccurrence(mTask.id!!, mTaskOccurrenceTS, false)
DELETE_FUTURE_OCCURRENCES -> eventsHelper.addEventRepeatLimit(mTask.id!!, mTaskOccurrenceTS)
DELETE_ALL_OCCURRENCES -> eventsHelper.deleteEvent(mTask.id!!, true)
DELETE_ALL_OCCURRENCES -> eventsHelper.deleteEvent(mTask.id!!, false)
}
runOnUiThread {

View File

@@ -697,7 +697,7 @@ fun Context.handleEventDeleting(eventIds: List<Long>, timestamps: List<Long>, ac
when (action) {
DELETE_SELECTED_OCCURRENCE -> {
eventIds.forEachIndexed { index, value ->
eventsHelper.addEventRepetitionException(value, timestamps[index], true)
eventsHelper.deleteRepeatingEventOccurrence(value, timestamps[index], true)
}
}
DELETE_FUTURE_OCCURRENCES -> {

View File

@@ -185,6 +185,7 @@ class CalDAVHelper(val context: Context) {
Events.CALENDAR_TIME_ZONE,
Events.DELETED,
Events.AVAILABILITY,
Events.STATUS,
Events.EVENT_COLOR
)
@@ -214,6 +215,7 @@ class CalDAVHelper(val context: Context) {
val reminders = getCalDAVEventReminders(id)
val attendees = Gson().toJson(getCalDAVEventAttendees(id))
val availability = cursor.getIntValue(Events.AVAILABILITY)
val status = cursor.getIntValue(Events.STATUS)
val color = cursor.getIntValueOrNull(Events.EVENT_COLOR)
val displayColor = if (color != null) {
getDisplayColorFromColor(color)
@@ -255,14 +257,28 @@ class CalDAVHelper(val context: Context) {
val parentImportId = "$source-$originalId"
val parentEvent = context.eventsDB.getEventWithImportId(parentImportId)
val originalDayCode = Formatter.getDayCodeFromTS(originalInstanceTime / 1000L)
if (parentEvent != null && !parentEvent.repetitionExceptions.contains(originalDayCode)) {
if (parentEvent != null) {
// add this event to the parent event's list of exceptions
if (!parentEvent.repetitionExceptions.contains(originalDayCode)) {
parentEvent.addRepetitionException(originalDayCode)
eventsHelper.insertEvent(parentEvent, addToCalDAV = false, showToasts = false)
}
// store the event in the local db only if it is an occurrence that has been modified and not deleted
if (status != Events.STATUS_CANCELED && title.isNotEmpty()) {
val storedEventId = context.eventsDB.getEventIdWithImportId(importId)
if (storedEventId != null) {
event.id = storedEventId
}
event.parentId = parentEvent.id!!
parentEvent.addRepetitionException(originalDayCode)
eventsHelper.insertEvent(parentEvent, addToCalDAV = false, showToasts = false)
eventsHelper.insertEvent(event, addToCalDAV = false, showToasts = false)
} else {
// delete the deleted exception event from local db
val storedEventId = context.eventsDB.getEventIdWithImportId(importId)
if (storedEventId != null) {
eventsHelper.deleteEvent(storedEventId, true)
}
}
return@queryCursorInlined
}
@@ -432,6 +448,25 @@ class CalDAVHelper(val context: Context) {
put(Events.ALL_DAY, 0)
}
val parentEventId = event.parentId
if (parentEventId != 0L) {
val parentEvent = context.eventsDB.getEventWithId(parentEventId) ?: return@apply
val isParentAllDay = parentEvent.getIsAllDay()
// original instance time must be in UTC when the parent is an all-day event
val originalInstanceTS = if (isParentAllDay && !event.getIsAllDay()) {
Formatter.getShiftedUtcTS(event.startTS)
} else {
event.startTS
}
put(Events.ORIGINAL_ID, parentEvent.getCalDAVEventId())
put(Events.ORIGINAL_INSTANCE_TIME, originalInstanceTS * 1000L)
if (isParentAllDay) {
put(Events.ORIGINAL_ALL_DAY, 1)
} else {
put(Events.ORIGINAL_ALL_DAY, 0)
}
}
put(Events.DTSTART, event.startTS * 1000L)
put(Events.EVENT_TIMEZONE, event.getTimeZoneString())
if (event.repeatInterval > 0) {

View File

@@ -116,6 +116,7 @@ class EventsHelper(val context: Context) {
return
}
maybeUpdateParentExceptions(event)
event.id = eventsDB.insertOrUpdate(event)
context.updateWidgets()
@@ -129,12 +130,24 @@ class EventsHelper(val context: Context) {
}
fun insertTask(task: Event, showToasts: Boolean, callback: () -> Unit) {
maybeUpdateParentExceptions(task)
task.id = eventsDB.insertOrUpdate(task)
context.updateWidgets()
context.scheduleNextEventReminder(task, showToasts)
callback()
}
private fun maybeUpdateParentExceptions(event: Event) {
// if the event is an exception from another event, update the parent event's exceptions list
val parentEventId = event.parentId
if (parentEventId != 0L) {
val parentEvent = eventsDB.getEventOrTaskWithId(parentEventId) ?: return
val startDayCode = Formatter.getDayCodeFromTS(event.startTS)
parentEvent.addRepetitionException(startDayCode)
eventsDB.updateEventRepetitionExceptions(parentEvent.repetitionExceptions.toString(), parentEventId)
}
}
fun insertEvents(events: ArrayList<Event>, addToCalDAV: Boolean) {
try {
for (event in events) {
@@ -232,14 +245,12 @@ class EventsHelper(val context: Context) {
}
}
fun addEventRepetitionException(parentEventId: Long, occurrenceTS: Long, addToCalDAV: Boolean) {
fun deleteRepeatingEventOccurrence(parentEventId: Long, occurrenceTS: Long, addToCalDAV: Boolean) {
ensureBackgroundThread {
val parentEvent = eventsDB.getEventOrTaskWithId(parentEventId) ?: return@ensureBackgroundThread
var repetitionExceptions = parentEvent.repetitionExceptions
repetitionExceptions.add(Formatter.getDayCodeFromTS(occurrenceTS))
repetitionExceptions = repetitionExceptions.distinct().toMutableList() as ArrayList<String>
eventsDB.updateEventRepetitionExceptions(repetitionExceptions.toString(), parentEventId)
val occurrenceDayCode = Formatter.getDayCodeFromTS(occurrenceTS)
parentEvent.addRepetitionException(occurrenceDayCode)
eventsDB.updateEventRepetitionExceptions(parentEvent.repetitionExceptions.toString(), parentEventId)
context.scheduleNextEventReminder(parentEvent, false)
if (addToCalDAV && config.caldavSync) {

View File

@@ -103,7 +103,7 @@ interface EventsDao {
@Query("SELECT id FROM events WHERE event_type IN (:eventTypeIds) AND type = $TYPE_EVENT")
fun getEventIdsByEventType(eventTypeIds: List<Long>): List<Long>
@Query("SELECT id FROM events WHERE parent_id IN (:parentIds) AND type = $TYPE_EVENT")
@Query("SELECT id FROM events WHERE parent_id IN (:parentIds)")
fun getEventIdsWithParentIds(parentIds: List<Long>): List<Long>
@Query("SELECT id FROM events WHERE source = :source AND import_id != \"\" AND type = $TYPE_EVENT")