Skip to content

Commit ee4e16b

Browse files
committed
add setting to switch between calendar and list from the records tab
1 parent 19a624a commit ee4e16b

File tree

50 files changed

+744
-71
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+744
-71
lines changed

core/src/main/java/com/example/util/simpletimetracker/core/dialog/RecordQuickActionDialogListener.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@ package com.example.util.simpletimetracker.core.dialog
22

33
interface RecordQuickActionDialogListener {
44

5-
fun onUpdate()
5+
fun onActionComplete()
66
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package com.example.util.simpletimetracker.core.mapper
2+
3+
import javax.inject.Inject
4+
import kotlin.math.ceil
5+
6+
class CalendarToListShiftMapper @Inject constructor() {
7+
8+
// TODO CAL move data edit to additonal settings
9+
fun mapCalendarToListShift(calendarShift: Int, calendarDayCount: Int): CalendarRange {
10+
if (calendarDayCount == 0) return CalendarRange(0, 0)
11+
12+
val end = calendarShift * calendarDayCount
13+
val start = end - (calendarDayCount - 1)
14+
15+
return CalendarRange(start, end)
16+
}
17+
18+
fun mapListToCalendarShift(listShift: Int, calendarDayCount: Int): Int {
19+
if (calendarDayCount == 0) return 0
20+
21+
return ceil(listShift.toFloat() / calendarDayCount).toInt()
22+
}
23+
24+
fun recalculateRangeOnCalendarViewSwitched(
25+
currentPosition: Int,
26+
lastListPosition: Int,
27+
showCalendar: Boolean,
28+
daysInCalendar: Int,
29+
): Int {
30+
return if (showCalendar) {
31+
mapListToCalendarShift(
32+
listShift = currentPosition,
33+
calendarDayCount = daysInCalendar,
34+
)
35+
} else {
36+
val calendarRange = mapCalendarToListShift(
37+
calendarShift = currentPosition,
38+
calendarDayCount = daysInCalendar,
39+
)
40+
if (lastListPosition in (calendarRange.start..calendarRange.end)) {
41+
lastListPosition
42+
} else {
43+
calendarRange.end
44+
}
45+
}
46+
}
47+
48+
fun recalculateRangeOnCalendarDaysChanged(
49+
currentPosition: Int,
50+
currentDaysInCalendar: Int,
51+
newDaysInCalendar: Int,
52+
): Int {
53+
// Find another range that contains last day of current range.
54+
val listPosition = mapCalendarToListShift(
55+
calendarShift = currentPosition,
56+
calendarDayCount = currentDaysInCalendar,
57+
).end
58+
return mapListToCalendarShift(
59+
listShift = listPosition,
60+
calendarDayCount = newDaysInCalendar,
61+
)
62+
}
63+
64+
data class CalendarRange(
65+
val start: Int,
66+
val end: Int,
67+
)
68+
}

core/src/main/java/com/example/util/simpletimetracker/core/viewData/SettingsBlock.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ enum class SettingsBlock {
4242
DisplayUntrackedRangeStart,
4343
DisplayUntrackedRangeEnd,
4444
DisplayCalendarView,
45+
DisplayCalendarButtonOnRecordsTab,
4546
DisplayReverseOrder,
4647
DisplayDaysInCalendar,
4748
DisplayShowActivityFilters,
Lines changed: 278 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,278 @@
1+
package com.example.util.simpletimetracker.core.mapper
2+
3+
import com.example.util.simpletimetracker.core.mapper.CalendarToListShiftMapper.CalendarRange
4+
import org.junit.Assert.assertEquals
5+
import org.junit.Test
6+
import org.junit.experimental.runners.Enclosed
7+
import org.junit.runner.RunWith
8+
import org.junit.runners.Parameterized
9+
10+
@RunWith(Enclosed::class)
11+
class CalendarToListShiftMapperTest {
12+
13+
@RunWith(Parameterized::class)
14+
class MapCalendarToListShift(
15+
private val input: List<Int>,
16+
private val output: CalendarRange,
17+
) {
18+
19+
@Test
20+
fun test() {
21+
val subject = CalendarToListShiftMapper()
22+
23+
assertEquals(
24+
"Test failed for params $input",
25+
output,
26+
subject.mapCalendarToListShift(
27+
calendarShift = input[0],
28+
calendarDayCount = input[1],
29+
),
30+
)
31+
}
32+
33+
companion object {
34+
@JvmStatic
35+
@Parameterized.Parameters
36+
fun data() = listOf(
37+
// calendarShift, calendarDayCount
38+
39+
// Days 0, should be impossible, check just in case.
40+
arrayOf(listOf(0, 0), CalendarRange(0, 0)),
41+
42+
// Days 1
43+
arrayOf(listOf(-13, 1), CalendarRange(-13, -13)),
44+
arrayOf(listOf(-2, 1), CalendarRange(-2, -2)),
45+
arrayOf(listOf(-1, 1), CalendarRange(-1, -1)),
46+
arrayOf(listOf(0, 1), CalendarRange(0, 0)),
47+
arrayOf(listOf(1, 1), CalendarRange(1, 1)),
48+
arrayOf(listOf(2, 1), CalendarRange(2, 2)),
49+
arrayOf(listOf(13, 1), CalendarRange(13, 13)),
50+
51+
// Days 3
52+
arrayOf(listOf(-13, 3), CalendarRange(-41, -39)),
53+
arrayOf(listOf(-2, 3), CalendarRange(-8, -6)),
54+
arrayOf(listOf(-1, 3), CalendarRange(-5, -3)),
55+
arrayOf(listOf(0, 3), CalendarRange(-2, 0)),
56+
arrayOf(listOf(1, 3), CalendarRange(1, 3)),
57+
arrayOf(listOf(2, 3), CalendarRange(4, 6)),
58+
arrayOf(listOf(13, 3), CalendarRange(37, 39)),
59+
60+
// Days 5
61+
arrayOf(listOf(-13, 5), CalendarRange(-69, -65)),
62+
arrayOf(listOf(-2, 5), CalendarRange(-14, -10)),
63+
arrayOf(listOf(-1, 5), CalendarRange(-9, -5)),
64+
arrayOf(listOf(0, 5), CalendarRange(-4, 0)),
65+
arrayOf(listOf(1, 5), CalendarRange(1, 5)),
66+
arrayOf(listOf(2, 5), CalendarRange(6, 10)),
67+
arrayOf(listOf(13, 5), CalendarRange(61, 65)),
68+
)
69+
}
70+
}
71+
72+
@RunWith(Parameterized::class)
73+
class MapListToCalendarShift(
74+
private val input: List<Int>,
75+
private val output: Int,
76+
) {
77+
78+
@Test
79+
fun test() {
80+
val subject = CalendarToListShiftMapper()
81+
82+
assertEquals(
83+
"Test failed for params $input",
84+
output,
85+
subject.mapListToCalendarShift(
86+
listShift = input[0],
87+
calendarDayCount = input[1],
88+
),
89+
)
90+
}
91+
92+
companion object {
93+
@JvmStatic
94+
@Parameterized.Parameters
95+
fun data() = listOf(
96+
// listShift, calendarDayCount
97+
98+
// Days 0, should be impossible, check just in case.
99+
arrayOf(listOf(0, 0), 0),
100+
101+
// Days 1
102+
arrayOf(listOf(-13, 1), -13),
103+
arrayOf(listOf(-2, 1), -2),
104+
arrayOf(listOf(-1, 1), -1),
105+
arrayOf(listOf(0, 1), 0),
106+
arrayOf(listOf(1, 1), 1),
107+
arrayOf(listOf(2, 1), 2),
108+
arrayOf(listOf(13, 1), 13),
109+
110+
// Days 3
111+
arrayOf(listOf(-13, 3), -4),
112+
arrayOf(listOf(-6, 3), -2),
113+
arrayOf(listOf(-5, 3), -1),
114+
arrayOf(listOf(-4, 3), -1),
115+
arrayOf(listOf(-3, 3), -1),
116+
arrayOf(listOf(-2, 3), 0),
117+
arrayOf(listOf(-1, 3), 0),
118+
arrayOf(listOf(0, 3), 0),
119+
arrayOf(listOf(1, 3), 1),
120+
arrayOf(listOf(2, 3), 1),
121+
arrayOf(listOf(3, 3), 1),
122+
arrayOf(listOf(4, 3), 2),
123+
arrayOf(listOf(13, 3), 5),
124+
125+
// Days 5
126+
arrayOf(listOf(-15, 5), -3),
127+
arrayOf(listOf(-14, 5), -2),
128+
arrayOf(listOf(-10, 5), -2),
129+
arrayOf(listOf(-9, 5), -1),
130+
arrayOf(listOf(-5, 5), -1),
131+
arrayOf(listOf(-4, 5), 0),
132+
arrayOf(listOf(-3, 5), 0),
133+
arrayOf(listOf(-2, 5), 0),
134+
arrayOf(listOf(-1, 5), 0),
135+
arrayOf(listOf(0, 5), 0),
136+
arrayOf(listOf(1, 5), 1),
137+
arrayOf(listOf(2, 5), 1),
138+
arrayOf(listOf(3, 5), 1),
139+
arrayOf(listOf(4, 5), 1),
140+
arrayOf(listOf(5, 5), 1),
141+
arrayOf(listOf(6, 5), 2),
142+
arrayOf(listOf(10, 5), 2),
143+
arrayOf(listOf(11, 5), 3),
144+
)
145+
}
146+
}
147+
148+
@RunWith(Parameterized::class)
149+
class RecalculateRangeOnCalendarViewSwitched(
150+
private val input: List<Any>,
151+
private val output: Int,
152+
) {
153+
154+
@Test
155+
fun test() {
156+
val subject = CalendarToListShiftMapper()
157+
158+
assertEquals(
159+
"Test failed for params $input",
160+
output,
161+
subject.recalculateRangeOnCalendarViewSwitched(
162+
currentPosition = input[0] as Int,
163+
lastListPosition = input[1] as Int,
164+
showCalendar = input[2] as Boolean,
165+
daysInCalendar = input[3] as Int,
166+
),
167+
)
168+
}
169+
170+
companion object {
171+
@JvmStatic
172+
@Parameterized.Parameters
173+
fun data() = listOf(
174+
// currentPosition, lastListPosition, showCalendar, daysInCalendar
175+
176+
// Days 0, should be impossible, check just in case.
177+
arrayOf(listOf(0, 0, true, 0), 0),
178+
arrayOf(listOf(0, 0, false, 0), 0),
179+
180+
// List to calendar
181+
arrayOf(listOf(-13, 0, true, 3), -4),
182+
arrayOf(listOf(0, 0, true, 3), 0),
183+
arrayOf(listOf(13, 0, true, 3), 5),
184+
arrayOf(listOf(-15, 0, true, 5), -3),
185+
arrayOf(listOf(0, 0, true, 5), 0),
186+
arrayOf(listOf(11, 0, true, 5), 3),
187+
188+
// Calendar to list, can't restore last saved position
189+
arrayOf(listOf(-13, 999, false, 3), -39),
190+
arrayOf(listOf(0, 999, false, 3), 0),
191+
arrayOf(listOf(13, 999, false, 3), 39),
192+
arrayOf(listOf(-13, 999, false, 5), -65),
193+
arrayOf(listOf(0, 999, false, 5), 0),
194+
arrayOf(listOf(13, 999, false, 5), 65),
195+
196+
// Calendar to list, can restore last saved position
197+
arrayOf(listOf(-13, -41, false, 3), -41),
198+
arrayOf(listOf(0, -1, false, 3), -1),
199+
arrayOf(listOf(13, 37, false, 3), 37),
200+
arrayOf(listOf(-13, -68, false, 5), -68),
201+
arrayOf(listOf(0, -3, false, 5), -3),
202+
arrayOf(listOf(13, 64, false, 5), 64),
203+
)
204+
}
205+
}
206+
207+
@RunWith(Parameterized::class)
208+
class RecalculateRangeOnCalendarDaysChanged(
209+
private val input: List<Int>,
210+
private val output: Int,
211+
) {
212+
213+
@Test
214+
fun test() {
215+
val subject = CalendarToListShiftMapper()
216+
217+
assertEquals(
218+
"Test failed for params $input",
219+
output,
220+
subject.recalculateRangeOnCalendarDaysChanged(
221+
currentPosition = input[0],
222+
currentDaysInCalendar = input[1],
223+
newDaysInCalendar = input[2],
224+
),
225+
)
226+
}
227+
228+
companion object {
229+
@JvmStatic
230+
@Parameterized.Parameters
231+
fun data() = listOf(
232+
// currentPosition, currentDaysInCalendar, newDaysInCalendar
233+
234+
// Days 0, should be impossible, check just in case.
235+
arrayOf(listOf(0, 0, 0), 0),
236+
237+
// From 1 to 3
238+
arrayOf(listOf(-13, 1, 3), -4),
239+
arrayOf(listOf(-3, 1, 3), -1),
240+
arrayOf(listOf(-2, 1, 3), 0),
241+
arrayOf(listOf(-1, 1, 3), 0),
242+
arrayOf(listOf(0, 1, 3), 0),
243+
arrayOf(listOf(1, 1, 3), 1),
244+
arrayOf(listOf(2, 1, 3), 1),
245+
arrayOf(listOf(3, 1, 3), 1),
246+
arrayOf(listOf(4, 1, 3), 2),
247+
arrayOf(listOf(13, 1, 3), 5),
248+
249+
// From 3 to 1
250+
arrayOf(listOf(-13, 3, 1), -39),
251+
arrayOf(listOf(-2, 3, 1), -6),
252+
arrayOf(listOf(-1, 3, 1), -3),
253+
arrayOf(listOf(0, 3, 1), 0),
254+
arrayOf(listOf(1, 3, 1), 3),
255+
arrayOf(listOf(2, 3, 1), 6),
256+
arrayOf(listOf(13, 3, 1), 39),
257+
258+
// From 3 to 7
259+
arrayOf(listOf(-13, 3, 7), -5),
260+
arrayOf(listOf(-2, 3, 7), 0),
261+
arrayOf(listOf(-1, 3, 7), 0),
262+
arrayOf(listOf(0, 3, 7), 0),
263+
arrayOf(listOf(1, 3, 7), 1),
264+
arrayOf(listOf(2, 3, 7), 1),
265+
arrayOf(listOf(13, 3, 7), 6),
266+
267+
// From 7 to 3
268+
arrayOf(listOf(-13, 7, 3), -30),
269+
arrayOf(listOf(-2, 7, 3), -4),
270+
arrayOf(listOf(-1, 7, 3), -2),
271+
arrayOf(listOf(0, 7, 3), 0),
272+
arrayOf(listOf(1, 7, 3), 3),
273+
arrayOf(listOf(2, 7, 3), 5),
274+
arrayOf(listOf(13, 7, 3), 31),
275+
)
276+
}
277+
}
278+
}

data_local/src/main/java/com/example/util/simpletimetracker/data_local/repo/PrefsRepoImpl.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@ class PrefsRepoImpl @Inject constructor(
106106
KEY_SHOW_RECORDS_CALENDAR, false,
107107
)
108108

109+
override var showCalendarButtonOnRecordsTab: Boolean by prefs.delegate(
110+
KEY_SHOW_CALENDAR_BUTTON_ON_RECORDS_TAB, false,
111+
)
112+
109113
override var reverseOrderInCalendar: Boolean by prefs.delegate(
110114
KEY_REVERSE_ORDER_IN_CALENDAR, false,
111115
)
@@ -543,6 +547,7 @@ class PrefsRepoImpl @Inject constructor(
543547
private const val KEY_SHOW_UNTRACKED_IN_RECORDS = "showUntrackedInRecords"
544548
private const val KEY_SHOW_UNTRACKED_IN_STATISTICS = "showUntrackedInStatistics"
545549
private const val KEY_SHOW_RECORDS_CALENDAR = "showRecordsCalendar"
550+
private const val KEY_SHOW_CALENDAR_BUTTON_ON_RECORDS_TAB = "showCalendarButtonOnRecordsTab"
546551
private const val KEY_REVERSE_ORDER_IN_CALENDAR = "reverseOrderInCalendar"
547552
private const val KEY_DAYS_IN_CALENDAR = "daysInCalendar"
548553
private const val KEY_SHOW_ACTIVITY_FILTERS = "showActivityFilters"

domain/src/main/java/com/example/util/simpletimetracker/domain/interactor/PrefsInteractor.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,14 @@ class PrefsInteractor @Inject constructor(
198198
prefsRepo.showRecordsCalendar = isEnabled
199199
}
200200

201+
suspend fun getShowCalendarButtonOnRecordsTab(): Boolean = withContext(Dispatchers.IO) {
202+
prefsRepo.showCalendarButtonOnRecordsTab
203+
}
204+
205+
suspend fun setShowCalendarButtonOnRecordsTab(isEnabled: Boolean) = withContext(Dispatchers.IO) {
206+
prefsRepo.showCalendarButtonOnRecordsTab = isEnabled
207+
}
208+
201209
suspend fun getReverseOrderInCalendar(): Boolean = withContext(Dispatchers.IO) {
202210
prefsRepo.reverseOrderInCalendar
203211
}

0 commit comments

Comments
 (0)