Skip to content

Commit 7dcbd05

Browse files
committed
Revert back to using builder pattern
This is more extensible for the date library modules.
1 parent f5235d9 commit 7dcbd05

File tree

11 files changed

+164
-162
lines changed

11 files changed

+164
-162
lines changed

core/src/main/java/com/alamkanak/weekview/WeekViewItem.kt

Lines changed: 62 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import java.util.Calendar
1212
* The item is rendered based on the information provided in its [style] and [configuration]
1313
* properties.
1414
*/
15-
data class WeekViewItem(
15+
data class WeekViewItem internal constructor(
1616
val id: Long = 0L,
1717
val title: CharSequence,
1818
val subtitle: CharSequence? = null,
@@ -100,6 +100,67 @@ data class WeekViewItem(
100100
}
101101
}
102102

103+
companion object {
104+
fun of(data: Any): Builder = Builder(data)
105+
}
106+
107+
/**
108+
* Builder to construct a [WeekViewItem]. A [WeekViewItem] needs an [id], a [title], and
109+
* a [duration]. The latter can be a [WeekViewItem.Duration.AllDay] or a
110+
* [WeekViewItem.Duration.Bounded].
111+
*/
112+
class Builder internal constructor(private val data: Any) {
113+
114+
private var id: Long? = null
115+
private var title: CharSequence? = null
116+
private var subtitle: CharSequence? = null
117+
private var duration: Duration? = null
118+
private var style: Style = Style()
119+
private var configuration = Configuration()
120+
121+
fun setId(id: Long): Builder {
122+
this.id = id
123+
return this
124+
}
125+
126+
fun setTitle(title: CharSequence): Builder {
127+
this.title = title
128+
return this
129+
}
130+
131+
fun setSubtitle(subtitle: CharSequence): Builder {
132+
this.subtitle = subtitle
133+
return this
134+
}
135+
136+
fun setAllDayDuration(date: Calendar): Builder {
137+
this.duration = Duration.AllDay(date)
138+
return this
139+
}
140+
141+
fun setBoundedDuration(startTime: Calendar, endTime: Calendar): Builder {
142+
this.duration = Duration.Bounded(startTime, endTime)
143+
return this
144+
}
145+
146+
fun setStyle(style: Style): Builder {
147+
this.style = style
148+
return this
149+
}
150+
151+
fun setConfiguration(configuration: Configuration): Builder {
152+
this.configuration = configuration
153+
return this
154+
}
155+
156+
fun build(): WeekViewItem {
157+
val id = requireNotNull(id) { "id == null" }
158+
val title = requireNotNull(title) { "title == null" }
159+
val duration = requireNotNull(duration) { "duration == null" }
160+
return WeekViewItem(id, title, subtitle, duration, style, configuration, data)
161+
}
162+
}
163+
103164
internal val isAllDay: Boolean = duration is Duration.AllDay
104165

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

144-
/**
145-
* Creates an [WeekViewItem.Duration.AllDay] with the receiving [Calendar] as the date.
146-
*/
147-
fun Calendar.toAllDayDuration(): WeekViewItem.Duration.AllDay {
148-
return WeekViewItem.Duration.AllDay(date = this.atStartOfDay)
149-
}
150-
151-
/**
152-
* Creates an [WeekViewItem.Duration.Bounded] with the receiving [Calendar] as the start time and
153-
* the provided parameter as the end time.
154-
*/
155-
fun Calendar.toBoundedDurationUntil(endTime: Calendar): WeekViewItem.Duration.Bounded {
156-
return WeekViewItem.Duration.Bounded(startTime = this, endTime = endTime)
157-
}
158-
159205
private fun WeekViewItem.Duration.overlapsWith(other: WeekViewItem.Duration): Boolean {
160206
if (this is WeekViewItem.Duration.AllDay || other is WeekViewItem.Duration.AllDay) {
161207
return false

jodatime/src/main/java/com/alamkanak/weekview/jodatime/DurationExtensions.kt

Lines changed: 0 additions & 35 deletions
This file was deleted.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.alamkanak.weekview.jodatime
2+
3+
import com.alamkanak.weekview.WeekViewItem
4+
import org.joda.time.LocalDate
5+
import org.joda.time.LocalDateTime
6+
7+
fun WeekViewItem.Builder.setAllDayDuration(date: LocalDate): WeekViewItem.Builder {
8+
return setAllDayDuration(date.toCalendar())
9+
}
10+
11+
fun WeekViewItem.Builder.setBoundedDuration(
12+
startTime: LocalDateTime,
13+
endTime: LocalDateTime,
14+
): WeekViewItem.Builder {
15+
return setBoundedDuration(startTime.toCalendar(), endTime.toCalendar())
16+
}

jsr310/src/main/java/com/alamkanak/weekview/jsr310/DurationExtensions.kt

Lines changed: 0 additions & 35 deletions
This file was deleted.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.alamkanak.weekview.jsr310
2+
3+
import com.alamkanak.weekview.WeekViewItem
4+
import java.time.LocalDate
5+
import java.time.LocalDateTime
6+
7+
fun WeekViewItem.Builder.setAllDayDuration(date: LocalDate): WeekViewItem.Builder {
8+
return setAllDayDuration(date.toCalendar())
9+
}
10+
11+
fun WeekViewItem.Builder.setBoundedDuration(
12+
startTime: LocalDateTime,
13+
endTime: LocalDateTime,
14+
): WeekViewItem.Builder {
15+
return setBoundedDuration(startTime.toCalendar(), endTime.toCalendar())
16+
}

sample/src/main/java/com/alamkanak/weekview/sample/data/EventsRepository.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class EventsRepository(private val context: Context) {
2121

2222
fun fetch(
2323
yearMonths: List<YearMonth>,
24-
onSuccess: (List<CalendarItem>) -> Unit
24+
onSuccess: (List<CalendarItem>) -> Unit,
2525
) {
2626
val handlerThread = HandlerThread("events-fetching")
2727
handlerThread.start()
@@ -34,7 +34,7 @@ class EventsRepository(private val context: Context) {
3434

3535
val calendarEntities = yearMonths.flatMap { yearMonth ->
3636
apiEntities.mapIndexedNotNull { index, apiResult ->
37-
apiResult.toCalendarEntity(yearMonth, index)
37+
apiResult.toCalendarItem(yearMonth, index)
3838
}
3939
}
4040

sample/src/main/java/com/alamkanak/weekview/sample/data/model/ApiEvent.kt

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import java.time.LocalTime
77
import java.time.YearMonth
88

99
interface ApiResult {
10-
fun toCalendarEntity(yearMonth: YearMonth, index: Int): CalendarItem?
10+
fun toCalendarItem(yearMonth: YearMonth, index: Int): CalendarItem?
1111
}
1212

1313
data class ApiEvent(
@@ -18,16 +18,16 @@ data class ApiEvent(
1818
@SerializedName("duration") val duration: Int,
1919
@SerializedName("color") val color: String,
2020
@SerializedName("is_canceled") val isCanceled: Boolean,
21-
@SerializedName("is_all_day") val isAllDay: Boolean
21+
@SerializedName("is_all_day") val isAllDay: Boolean,
2222
) : ApiResult {
2323

24-
override fun toCalendarEntity(yearMonth: YearMonth, index: Int): CalendarItem? {
24+
override fun toCalendarItem(yearMonth: YearMonth, index: Int): CalendarItem? {
2525
return try {
2626
val startTime = LocalTime.parse(startTime)
2727
val startDateTime = yearMonth.atDay(dayOfMonth).atTime(startTime)
2828
val endDateTime = startDateTime.plusMinutes(duration.toLong())
2929
CalendarItem.Event(
30-
id = "100${yearMonth.year}00${yearMonth.monthValue}00$index".toLong(),
30+
id = generateId(yearMonth, index),
3131
title = title,
3232
location = location,
3333
startTime = startDateTime,
@@ -45,16 +45,16 @@ data class ApiEvent(
4545
data class ApiBlockedTime(
4646
@SerializedName("day_of_month") val dayOfMonth: Int,
4747
@SerializedName("start_time") val startTime: String,
48-
@SerializedName("duration") val duration: Int
48+
@SerializedName("duration") val duration: Int,
4949
) : ApiResult {
5050

51-
override fun toCalendarEntity(yearMonth: YearMonth, index: Int): CalendarItem? {
51+
override fun toCalendarItem(yearMonth: YearMonth, index: Int): CalendarItem? {
5252
return try {
5353
val startTime = LocalTime.parse(startTime)
5454
val startDateTime = yearMonth.atDay(dayOfMonth).atTime(startTime)
5555
val endDateTime = startDateTime.plusMinutes(duration.toLong())
5656
CalendarItem.BlockedTimeSlot(
57-
id = "200${yearMonth.year}00${yearMonth.monthValue}00$index".toLong(),
57+
id = generateId(yearMonth, index),
5858
startTime = startDateTime,
5959
endTime = endDateTime
6060
)
@@ -63,3 +63,10 @@ data class ApiBlockedTime(
6363
}
6464
}
6565
}
66+
67+
private fun generateId(yearMonth: YearMonth, index: Int): Long {
68+
val eventNumber = index.toString().padStart(length = 4, padChar = '0')
69+
val year = yearMonth.year * 1_000_000
70+
val month = yearMonth.monthValue * 1_000
71+
return "$year$month$eventNumber".toLong()
72+
}

sample/src/main/java/com/alamkanak/weekview/sample/data/model/CalendarItem.kt

Lines changed: 37 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ import android.text.style.TypefaceSpan
99
import androidx.core.content.ContextCompat
1010
import com.alamkanak.weekview.WeekViewEntity
1111
import com.alamkanak.weekview.WeekViewItem
12+
import com.alamkanak.weekview.jsr310.setAllDayDuration
13+
import com.alamkanak.weekview.jsr310.setBoundedDuration
1214
import com.alamkanak.weekview.jsr310.setEndTime
1315
import com.alamkanak.weekview.jsr310.setStartTime
14-
import com.alamkanak.weekview.jsr310.toAllDayDuration
15-
import com.alamkanak.weekview.jsr310.toBoundedDurationUntil
1616
import com.alamkanak.weekview.sample.R
1717
import java.time.LocalDateTime
1818

@@ -63,40 +63,46 @@ fun CalendarItem.Event.toWeekViewItem(context: Context): WeekViewItem {
6363
}
6464
}
6565

66-
val timing = if (isAllDay) {
67-
startTime.toAllDayDuration()
68-
} else {
69-
startTime.toBoundedDurationUntil(endTime)
70-
}
71-
72-
return WeekViewItem(
73-
id = id,
74-
title = title,
75-
subtitle = subtitle,
76-
duration = timing,
77-
style = WeekViewItem.Style(
78-
textColor = textColor,
79-
backgroundColor = backgroundColor,
80-
borderWidth = borderWidth,
81-
borderColor = color,
82-
),
83-
configuration = WeekViewItem.Configuration.foreground(),
84-
data = this,
66+
val style = WeekViewItem.Style(
67+
textColor = textColor,
68+
backgroundColor = backgroundColor,
69+
borderWidth = borderWidth,
70+
borderColor = color,
8571
)
72+
73+
val config = WeekViewItem.Configuration.foreground()
74+
75+
return WeekViewItem.of(this)
76+
.setId(id)
77+
.setTitle(title)
78+
.setSubtitle(subtitle)
79+
.apply {
80+
if (isAllDay) {
81+
setAllDayDuration(startTime.toLocalDate())
82+
} else {
83+
setBoundedDuration(startTime, endTime)
84+
}
85+
}
86+
.setStyle(style)
87+
.setConfiguration(config)
88+
.build()
8689
}
8790

8891
fun CalendarItem.BlockedTimeSlot.toWeekViewItem(context: Context): WeekViewItem {
89-
return WeekViewItem(
90-
id = id,
91-
title = "Unavailable",
92-
duration = startTime.toBoundedDurationUntil(endTime),
93-
style = WeekViewItem.Style(
94-
backgroundColor = ContextCompat.getColor(context, R.color.gray_alpha10),
95-
cornerRadius = context.resources.getDimensionPixelSize(R.dimen.no_corner_radius),
96-
),
97-
configuration = WeekViewItem.Configuration.background(),
98-
data = this,
92+
val style = WeekViewItem.Style(
93+
backgroundColor = ContextCompat.getColor(context, R.color.gray_alpha10),
94+
cornerRadius = context.resources.getDimensionPixelSize(R.dimen.no_corner_radius),
9995
)
96+
97+
val config = WeekViewItem.Configuration.background()
98+
99+
return WeekViewItem.of(this)
100+
.setId(id)
101+
.setTitle("Unavailable")
102+
.setBoundedDuration(startTime, endTime)
103+
.setStyle(style)
104+
.setConfiguration(config)
105+
.build()
100106
}
101107

102108
fun CalendarItem.toWeekViewEntity(): WeekViewEntity {

sample/src/main/java/com/alamkanak/weekview/sample/ui/BasicActivity.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ class BasicActivity : AppCompatActivity() {
7171
}
7272
}
7373

74-
private class BasicActivityWeekViewAdapter(
74+
class BasicActivityWeekViewAdapter(
7575
private val dragHandler: (Long, LocalDateTime, LocalDateTime) -> Unit,
7676
private val loadMoreHandler: (List<YearMonth>) -> Unit
7777
) : WeekViewPagingAdapterJsr310<CalendarItem>() {

0 commit comments

Comments
 (0)