Skip to content

Commit

Permalink
Revert back to using builder pattern
Browse files Browse the repository at this point in the history
This is more extensible for the date library modules.
  • Loading branch information
thellmund committed Jan 27, 2022
1 parent f5235d9 commit 420a19e
Show file tree
Hide file tree
Showing 13 changed files with 169 additions and 168 deletions.
78 changes: 62 additions & 16 deletions core/src/main/java/com/alamkanak/weekview/WeekViewItem.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import java.util.Calendar
* The item is rendered based on the information provided in its [style] and [configuration]
* properties.
*/
data class WeekViewItem(
data class WeekViewItem internal constructor(
val id: Long = 0L,
val title: CharSequence,
val subtitle: CharSequence? = null,
Expand Down Expand Up @@ -100,6 +100,67 @@ data class WeekViewItem(
}
}

companion object {
fun of(data: Any): Builder = Builder(data)
}

/**
* Builder to construct a [WeekViewItem]. A [WeekViewItem] needs an [id], a [title], and
* a [duration]. The latter can be a [WeekViewItem.Duration.AllDay] or a
* [WeekViewItem.Duration.Bounded].
*/
class Builder internal constructor(private val data: Any) {

private var id: Long? = null
private var title: CharSequence? = null
private var subtitle: CharSequence? = null
private var duration: Duration? = null
private var style: Style = Style()
private var configuration = Configuration()

fun setId(id: Long): Builder {
this.id = id
return this
}

fun setTitle(title: CharSequence): Builder {
this.title = title
return this
}

fun setSubtitle(subtitle: CharSequence): Builder {
this.subtitle = subtitle
return this
}

fun setAllDayDuration(date: Calendar): Builder {
this.duration = Duration.AllDay(date)
return this
}

fun setBoundedDuration(startTime: Calendar, endTime: Calendar): Builder {
this.duration = Duration.Bounded(startTime, endTime)
return this
}

fun setStyle(style: Style): Builder {
this.style = style
return this
}

fun setConfiguration(configuration: Configuration): Builder {
this.configuration = configuration
return this
}

fun build(): WeekViewItem {
val id = requireNotNull(id) { "id == null" }
val title = requireNotNull(title) { "title == null" }
val duration = requireNotNull(duration) { "duration == null" }
return WeekViewItem(id, title, subtitle, duration, style, configuration, data)
}
}

internal val isAllDay: Boolean = duration is Duration.AllDay

internal val isNotAllDay: Boolean = !isAllDay
Expand Down Expand Up @@ -141,21 +202,6 @@ data class WeekViewItem(
internal fun collidesWith(other: WeekViewItem): Boolean = duration.overlapsWith(other.duration)
}

/**
* Creates an [WeekViewItem.Duration.AllDay] with the receiving [Calendar] as the date.
*/
fun Calendar.toAllDayDuration(): WeekViewItem.Duration.AllDay {
return WeekViewItem.Duration.AllDay(date = this.atStartOfDay)
}

/**
* Creates an [WeekViewItem.Duration.Bounded] with the receiving [Calendar] as the start time and
* the provided parameter as the end time.
*/
fun Calendar.toBoundedDurationUntil(endTime: Calendar): WeekViewItem.Duration.Bounded {
return WeekViewItem.Duration.Bounded(startTime = this, endTime = endTime)
}

private fun WeekViewItem.Duration.overlapsWith(other: WeekViewItem.Duration): Boolean {
if (this is WeekViewItem.Duration.AllDay || other is WeekViewItem.Duration.AllDay) {
return false
Expand Down
6 changes: 3 additions & 3 deletions core/src/test/java/com/alamkanak/weekview/DiffResultTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class DiffResultTest {
val existingEntity = Mocks.weekViewItem()
val newEntity = existingEntity.copyWith(
startTime = existingEntity.duration.startTime,
endTime = existingEntity.duration.endTime + Hours(1)
endTime = existingEntity.duration.endTime.plusMinutes(60),
)

val result = DiffResult.calculateDiff(
Expand All @@ -60,12 +60,12 @@ class DiffResultTest {
@Test
fun `New and updated entities are correctly recognized together`() {
val startTime = Calendar.getInstance()
val endTime = startTime + Hours(1)
val endTime = startTime.plusMinutes(60)

val existingEntity = Mocks.weekViewItem(startTime, endTime)
val updatedEntity = existingEntity.copyWith(
startTime = existingEntity.duration.startTime,
endTime = existingEntity.duration.endTime + Hours(1),
endTime = existingEntity.duration.endTime.plusMinutes(60),
)
val newEntity = Mocks.weekViewItem(startTime, endTime)

Expand Down
5 changes: 2 additions & 3 deletions core/src/test/java/com/alamkanak/weekview/util/Mocks.kt
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package com.alamkanak.weekview.util

import com.alamkanak.weekview.Hours
import com.alamkanak.weekview.WeekViewItem
import com.alamkanak.weekview.plus
import com.alamkanak.weekview.plusMinutes
import java.util.Calendar
import kotlin.random.Random

Expand All @@ -14,7 +13,7 @@ internal object Mocks {

fun weekViewItem(
startTime: Calendar = Calendar.getInstance(),
endTime: Calendar = Calendar.getInstance() + Hours(1),
endTime: Calendar = Calendar.getInstance().plusMinutes(60),
): WeekViewItem {
val id = Random.nextLong()
return WeekViewItem(
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.alamkanak.weekview.jodatime

import com.alamkanak.weekview.WeekViewItem
import org.joda.time.LocalDate
import org.joda.time.LocalDateTime

fun WeekViewItem.Builder.setAllDayDuration(date: LocalDate): WeekViewItem.Builder {
return setAllDayDuration(date.toCalendar())
}

fun WeekViewItem.Builder.setBoundedDuration(
startTime: LocalDateTime,
endTime: LocalDateTime,
): WeekViewItem.Builder {
return setBoundedDuration(startTime.toCalendar(), endTime.toCalendar())
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.alamkanak.weekview.jsr310

import com.alamkanak.weekview.WeekViewItem
import java.time.LocalDate
import java.time.LocalDateTime

fun WeekViewItem.Builder.setAllDayDuration(date: LocalDate): WeekViewItem.Builder {
return setAllDayDuration(date.toCalendar())
}

fun WeekViewItem.Builder.setBoundedDuration(
startTime: LocalDateTime,
endTime: LocalDateTime,
): WeekViewItem.Builder {
return setBoundedDuration(startTime.toCalendar(), endTime.toCalendar())
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class EventsRepository(private val context: Context) {

fun fetch(
yearMonths: List<YearMonth>,
onSuccess: (List<CalendarItem>) -> Unit
onSuccess: (List<CalendarItem>) -> Unit,
) {
val handlerThread = HandlerThread("events-fetching")
handlerThread.start()
Expand All @@ -34,7 +34,7 @@ class EventsRepository(private val context: Context) {

val calendarEntities = yearMonths.flatMap { yearMonth ->
apiEntities.mapIndexedNotNull { index, apiResult ->
apiResult.toCalendarEntity(yearMonth, index)
apiResult.toCalendarItem(yearMonth, index)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import java.time.LocalTime
import java.time.YearMonth

interface ApiResult {
fun toCalendarEntity(yearMonth: YearMonth, index: Int): CalendarItem?
fun toCalendarItem(yearMonth: YearMonth, index: Int): CalendarItem?
}

data class ApiEvent(
Expand All @@ -18,16 +18,16 @@ data class ApiEvent(
@SerializedName("duration") val duration: Int,
@SerializedName("color") val color: String,
@SerializedName("is_canceled") val isCanceled: Boolean,
@SerializedName("is_all_day") val isAllDay: Boolean
@SerializedName("is_all_day") val isAllDay: Boolean,
) : ApiResult {

override fun toCalendarEntity(yearMonth: YearMonth, index: Int): CalendarItem? {
override fun toCalendarItem(yearMonth: YearMonth, index: Int): CalendarItem? {
return try {
val startTime = LocalTime.parse(startTime)
val startDateTime = yearMonth.atDay(dayOfMonth).atTime(startTime)
val endDateTime = startDateTime.plusMinutes(duration.toLong())
CalendarItem.Event(
id = "100${yearMonth.year}00${yearMonth.monthValue}00$index".toLong(),
id = generateId(yearMonth, index),
title = title,
location = location,
startTime = startDateTime,
Expand All @@ -45,16 +45,16 @@ data class ApiEvent(
data class ApiBlockedTime(
@SerializedName("day_of_month") val dayOfMonth: Int,
@SerializedName("start_time") val startTime: String,
@SerializedName("duration") val duration: Int
@SerializedName("duration") val duration: Int,
) : ApiResult {

override fun toCalendarEntity(yearMonth: YearMonth, index: Int): CalendarItem? {
override fun toCalendarItem(yearMonth: YearMonth, index: Int): CalendarItem? {
return try {
val startTime = LocalTime.parse(startTime)
val startDateTime = yearMonth.atDay(dayOfMonth).atTime(startTime)
val endDateTime = startDateTime.plusMinutes(duration.toLong())
CalendarItem.BlockedTimeSlot(
id = "200${yearMonth.year}00${yearMonth.monthValue}00$index".toLong(),
id = generateId(yearMonth, index),
startTime = startDateTime,
endTime = endDateTime
)
Expand All @@ -63,3 +63,10 @@ data class ApiBlockedTime(
}
}
}

private fun generateId(yearMonth: YearMonth, index: Int): Long {
val eventNumber = index.toString().padStart(length = 4, padChar = '0')
val year = yearMonth.year * 1_000_000
val month = yearMonth.monthValue * 1_000
return "$year$month$eventNumber".toLong()
}
Loading

0 comments on commit 420a19e

Please sign in to comment.