Skip to content

Commit 99f0e0f

Browse files
authored
Merge pull request #1722 from Naveen3Singh/fix_event_offset
Properly handle repeating events
2 parents 8f4aa38 + ac55c06 commit 99f0e0f

6 files changed

Lines changed: 44 additions & 31 deletions

File tree

app/src/main/kotlin/com/simplemobiletools/calendar/pro/extensions/Range.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@ package com.simplemobiletools.calendar.pro.extensions
22

33
import android.util.Range
44

5-
fun Range<Int>.touch(other: Range<Int>) = (upper >= other.lower && lower <= other.upper) || (other.upper >= lower && other.lower <= upper)
5+
fun Range<Int>.intersects(other: Range<Int>) = (upper >= other.lower && lower <= other.upper) || (other.upper >= lower && other.lower <= upper)

app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/MonthFragment.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ class MonthFragment : Fragment(), MonthlyCalendar {
103103
contentDescription = text
104104

105105
if (activity != null) {
106-
setTextColor(activity!!.getProperTextColor())
106+
setTextColor(requireActivity().getProperTextColor())
107107
}
108108
}
109109
updateDays(days)

app/src/main/kotlin/com/simplemobiletools/calendar/pro/fragments/WeekFragment.kt

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ import kotlinx.android.synthetic.main.week_event_marker.view.*
3535
import org.joda.time.DateTime
3636
import org.joda.time.Days
3737
import java.util.*
38+
import kotlin.math.max
39+
import kotlin.math.min
40+
import kotlin.math.roundToInt
3841

3942
class WeekFragment : Fragment(), WeeklyCalendar {
4043
private val WEEKLY_EVENT_ID_LABEL = "event_id_label"
@@ -132,7 +135,7 @@ class WeekFragment : Fragment(), WeeklyCalendar {
132135
}
133136

134137
val initialScrollY = (rowHeight * config.startWeeklyAt).toInt()
135-
updateScrollY(Math.max(listener?.getCurrScrollY() ?: 0, initialScrollY))
138+
updateScrollY(max(listener?.getCurrScrollY() ?: 0, initialScrollY))
136139
}
137140

138141
wasFragmentInit = true
@@ -361,7 +364,7 @@ class WeekFragment : Fragment(), WeeklyCalendar {
361364
prevScaleSpanY = detector.currentSpanY
362365

363366
val wantedFactor = config.weeklyViewItemHeightMultiplier - (SCALE_RANGE * percent)
364-
var newFactor = Math.max(Math.min(wantedFactor, MAX_SCALE_FACTOR), MIN_SCALE_FACTOR)
367+
var newFactor = max(min(wantedFactor, MAX_SCALE_FACTOR), MIN_SCALE_FACTOR)
365368
if (scrollView.height > defaultRowHeight * newFactor * 24) {
366369
newFactor = scrollView.height / 24f / defaultRowHeight
367370
}
@@ -422,7 +425,7 @@ class WeekFragment : Fragment(), WeeklyCalendar {
422425
rowHeight = context?.getWeeklyViewItemHeight() ?: return
423426

424427
val oneDp = res.getDimension(R.dimen.one_dp).toInt()
425-
val fullHeight = Math.max(rowHeight.toInt() * 24, scrollView.height + oneDp)
428+
val fullHeight = max(rowHeight.toInt() * 24, scrollView.height + oneDp)
426429
scrollView.layoutParams.height = fullHeight - oneDp
427430
mView.week_horizontal_grid_holder.layoutParams.height = fullHeight
428431
mView.week_events_columns_holder.layoutParams.height = fullHeight
@@ -440,7 +443,7 @@ class WeekFragment : Fragment(), WeeklyCalendar {
440443

441444
val minuteHeight = rowHeight / 60
442445
val minimalHeight = res.getDimension(R.dimen.weekly_view_minimal_event_height).toInt()
443-
val density = Math.round(res.displayMetrics.density)
446+
val density = res.displayMetrics.density.roundToInt()
444447

445448
for (event in events) {
446449
val startDateTime = Formatter.getDateTimeFromTS(event.startTS)
@@ -493,7 +496,7 @@ class WeekFragment : Fragment(), WeeklyCalendar {
493496
eventsCollisionChecked.add(eventId)
494497
val eventWeeklyViewsToCheck = eventDayList.filter { !eventsCollisionChecked.contains(it.key) }
495498
for ((toCheckId, eventWeeklyViewToCheck) in eventWeeklyViewsToCheck) {
496-
val areTouching = eventWeeklyView.range.touch(eventWeeklyViewToCheck.range)
499+
val areTouching = eventWeeklyView.range.intersects(eventWeeklyViewToCheck.range)
497500
val doHaveCommonMinutes = if (areTouching) {
498501
eventWeeklyView.range.upper > eventWeeklyViewToCheck.range.lower || (eventWeeklyView.range.lower == eventWeeklyView.range.upper &&
499502
eventWeeklyView.range.upper == eventWeeklyViewToCheck.range.lower)
@@ -507,7 +510,7 @@ class WeekFragment : Fragment(), WeeklyCalendar {
507510
val slotRange = Array(eventWeeklyView.slot_max) { it + 1 }
508511
val collisionEventWeeklyViews = eventDayList.filter { eventWeeklyView.collisions.contains(it.key) }
509512
for ((_, collisionEventWeeklyView) in collisionEventWeeklyViews) {
510-
if (collisionEventWeeklyView.range.touch(eventWeeklyViewToCheck.range)) {
513+
if (collisionEventWeeklyView.range.intersects(eventWeeklyViewToCheck.range)) {
511514
slotRange[collisionEventWeeklyView.slot - 1] = nextSlot
512515
}
513516
}
@@ -723,8 +726,8 @@ class WeekFragment : Fragment(), WeeklyCalendar {
723726
val startDateTime = Formatter.getDateTimeFromTS(event.startTS)
724727
val endDateTime = Formatter.getDateTimeFromTS(event.endTS)
725728

726-
val minTS = Math.max(startDateTime.seconds(), weekTimestamp)
727-
val maxTS = Math.min(endDateTime.seconds(), weekTimestamp + 2 * WEEK_SECONDS)
729+
val minTS = max(startDateTime.seconds(), weekTimestamp)
730+
val maxTS = min(endDateTime.seconds(), weekTimestamp + 2 * WEEK_SECONDS)
728731

729732
// fix a visual glitch with all-day events or events lasting multiple days starting at midnight on monday, being shown the previous week too
730733
if (minTS == maxTS && (minTS - weekTimestamp == WEEK_SECONDS.toLong())) {

app/src/main/kotlin/com/simplemobiletools/calendar/pro/helpers/MonthlyCalendarImpl.kt

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ import com.simplemobiletools.calendar.pro.interfaces.MonthlyCalendar
88
import com.simplemobiletools.calendar.pro.models.DayMonthly
99
import com.simplemobiletools.calendar.pro.models.Event
1010
import org.joda.time.DateTime
11-
import java.util.*
12-
import kotlin.collections.ArrayList
11+
import kotlin.math.min
1312

1413
class MonthlyCalendarImpl(val callback: MonthlyCalendar, val context: Context) {
1514
private val DAYS_CNT = 42
@@ -83,25 +82,25 @@ class MonthlyCalendarImpl(val callback: MonthlyCalendar, val context: Context) {
8382
}
8483
}
8584

86-
// it works more often than not, dont touch
85+
// it works more often than not, don't touch
8786
private fun markDaysWithEvents(days: ArrayList<DayMonthly>) {
8887
val dayEvents = HashMap<String, ArrayList<Event>>()
89-
mEvents.forEach {
90-
val startDateTime = Formatter.getDateTimeFromTS(it.startTS)
91-
val endDateTime = Formatter.getDateTimeFromTS(it.endTS)
88+
mEvents.forEach { event ->
89+
val startDateTime = Formatter.getDateTimeFromTS(event.startTS)
90+
val endDateTime = Formatter.getDateTimeFromTS(event.endTS)
9291
val endCode = Formatter.getDayCodeFromDateTime(endDateTime)
9392

9493
var currDay = startDateTime
9594
var dayCode = Formatter.getDayCodeFromDateTime(currDay)
9695
var currDayEvents = dayEvents[dayCode] ?: ArrayList()
97-
currDayEvents.add(it)
96+
currDayEvents.add(event)
9897
dayEvents[dayCode] = currDayEvents
9998

10099
while (Formatter.getDayCodeFromDateTime(currDay) != endCode) {
101100
currDay = currDay.plusDays(1)
102101
dayCode = Formatter.getDayCodeFromDateTime(currDay)
103102
currDayEvents = dayEvents[dayCode] ?: ArrayList()
104-
currDayEvents.add(it)
103+
currDayEvents.add(event)
105104
dayEvents[dayCode] = currDayEvents
106105
}
107106
}
@@ -114,7 +113,7 @@ class MonthlyCalendarImpl(val callback: MonthlyCalendar, val context: Context) {
114113

115114
private fun isToday(targetDate: DateTime, curDayInMonth: Int): Boolean {
116115
val targetMonthDays = targetDate.dayOfMonth().maximumValue
117-
return targetDate.withDayOfMonth(Math.min(curDayInMonth, targetMonthDays)).toString(Formatter.DAYCODE_PATTERN) == mToday
116+
return targetDate.withDayOfMonth(min(curDayInMonth, targetMonthDays)).toString(Formatter.DAYCODE_PATTERN) == mToday
118117
}
119118

120119
private val monthName: String

app/src/main/kotlin/com/simplemobiletools/calendar/pro/views/MonthView.kt

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ import com.simplemobiletools.commons.helpers.LOWER_ALPHA
2323
import com.simplemobiletools.commons.helpers.MEDIUM_ALPHA
2424
import org.joda.time.DateTime
2525
import org.joda.time.Days
26+
import kotlin.math.max
27+
import kotlin.math.min
2628

2729
// used in the Monthly view fragment, 1 view per screen
2830
class MonthView(context: Context, attrs: AttributeSet, defStyle: Int) : View(context, attrs, defStyle) {
@@ -113,16 +115,15 @@ class MonthView(context: Context, attrs: AttributeSet, defStyle: Int) : View(con
113115
}
114116

115117
private fun groupAllEvents() {
116-
days.forEach {
117-
val day = it
118-
day.dayEvents.forEach {
119-
val event = it
118+
days.forEach { day ->
120119

120+
day.dayEvents.forEach { event ->
121121
// make sure we properly handle events lasting multiple days and repeating ones
122122
val lastEvent = allEvents.lastOrNull { it.id == event.id }
123123
val daysCnt = getEventLastingDaysCount(event)
124124
val validDayEvent = isDayValid(event, day.code)
125-
if ((lastEvent == null || lastEvent.startDayIndex + daysCnt <= day.indexOnMonthView) && !validDayEvent) {
125+
126+
if ((lastEvent == null || lastEvent.startDayIndex + daysCnt <= findLastDay(event).indexOnMonthView) && !validDayEvent) {
126127
val monthViewEvent = MonthViewEvent(
127128
event.id!!, event.title, event.startTS, event.endTS, event.color, day.indexOnMonthView,
128129
daysCnt, day.indexOnMonthView, event.getIsAllDay(), event.isPastEvent, event.isTask(), event.isTaskCompleted()
@@ -133,8 +134,9 @@ class MonthView(context: Context, attrs: AttributeSet, defStyle: Int) : View(con
133134
}
134135

135136
allEvents =
136-
allEvents.asSequence().sortedWith(compareBy({ -it.daysCnt }, { !it.isAllDay }, { it.startTS }, { it.endTS }, { it.startDayIndex }, { it.title }))
137-
.toMutableList() as ArrayList<MonthViewEvent>
137+
allEvents.asSequence().sortedWith(
138+
compareBy({ -it.daysCnt }, { !it.isAllDay }, { it.startTS }, { it.endTS }, { it.startDayIndex }, { it.title })
139+
).toMutableList() as ArrayList<MonthViewEvent>
138140
}
139141

140142
override fun onDraw(canvas: Canvas) {
@@ -255,8 +257,8 @@ class MonthView(context: Context, attrs: AttributeSet, defStyle: Int) : View(con
255257

256258
private fun drawEvent(event: MonthViewEvent, canvas: Canvas) {
257259
var verticalOffset = 0
258-
for (i in 0 until Math.min(event.daysCnt, 7 - event.startDayIndex % 7)) {
259-
verticalOffset = Math.max(verticalOffset, dayVerticalOffsets[event.startDayIndex + i])
260+
for (i in 0 until min(event.daysCnt, 7 - event.startDayIndex % 7)) {
261+
verticalOffset = max(verticalOffset, dayVerticalOffsets[event.startDayIndex + i])
260262
}
261263
val xPos = event.startDayIndex % 7 * dayWidth + horizontalOffset
262264
val yPos = (event.startDayIndex / 7) * dayHeight
@@ -285,7 +287,7 @@ class MonthView(context: Context, attrs: AttributeSet, defStyle: Int) : View(con
285287
}
286288

287289
val startDayIndex = days[event.originalStartDayIndex]
288-
val endDayIndex = days[Math.min(event.startDayIndex + event.daysCnt - 1, 41)]
290+
val endDayIndex = days[min(event.startDayIndex + event.daysCnt - 1, 41)]
289291
bgRectF.set(bgLeft, bgTop, bgRight, bgBottom)
290292
canvas.drawRoundRect(bgRectF, BG_CORNER_RADIUS, BG_CORNER_RADIUS, getEventBackgroundColor(event, startDayIndex, endDayIndex))
291293

@@ -301,7 +303,7 @@ class MonthView(context: Context, attrs: AttributeSet, defStyle: Int) : View(con
301303

302304
drawEventTitle(event, canvas, xPos + taskIconWidth, yPos + verticalOffset, bgRight - bgLeft - smallPadding - taskIconWidth, specificEventTitlePaint)
303305

304-
for (i in 0 until Math.min(event.daysCnt, 7 - event.startDayIndex % 7)) {
306+
for (i in 0 until min(event.daysCnt, 7 - event.startDayIndex % 7)) {
305307
dayVerticalOffsets.put(event.startDayIndex + i, verticalOffset + eventTitleHeight + smallPadding * 2)
306308
}
307309
}
@@ -429,6 +431,12 @@ class MonthView(context: Context, attrs: AttributeSet, defStyle: Int) : View(con
429431
return event.startTS != event.endTS && Formatter.getDateTimeFromTS(event.endTS) == Formatter.getDateTimeFromTS(date.seconds()).withTimeAtStartOfDay()
430432
}
431433

434+
private fun findLastDay(event: Event): DayMonthly {
435+
return days.last { day ->
436+
day.dayEvents.find { it.id == event.id } != null
437+
}
438+
}
439+
432440
fun togglePrintMode() {
433441
isPrintVersion = !isPrintVersion
434442
textColor = if (isPrintVersion) {

app/src/main/kotlin/com/simplemobiletools/calendar/pro/views/MonthViewWrapper.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,10 @@ class MonthViewWrapper(context: Context, attrs: AttributeSet, defStyle: Int) : F
5959
continue
6060
}
6161

62-
child.measure(MeasureSpec.makeMeasureSpec(dayWidth.toInt(), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(dayHeight.toInt(), MeasureSpec.EXACTLY))
62+
child.measure(
63+
MeasureSpec.makeMeasureSpec(dayWidth.toInt(), MeasureSpec.EXACTLY),
64+
MeasureSpec.makeMeasureSpec(dayHeight.toInt(), MeasureSpec.EXACTLY)
65+
)
6366

6467
val childLeft = x * dayWidth + horizontalOffset - child.translationX
6568
val childTop = y * dayHeight + weekDaysLetterHeight - child.translationY

0 commit comments

Comments
 (0)