Skip to content

Commit 8c0e1b1

Browse files
committed
change first tab on date time selection in csv export settings
1 parent 94c551f commit 8c0e1b1

File tree

9 files changed

+145
-70
lines changed

9 files changed

+145
-70
lines changed

app/src/androidTest/java/com/example/util/simpletimetracker/SettingsTest.kt

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,28 @@
11
package com.example.util.simpletimetracker
22

33
import android.view.View
4+
import android.widget.DatePicker
5+
import android.widget.TimePicker
46
import androidx.test.espresso.Espresso.onView
57
import androidx.test.espresso.Espresso.pressBack
68
import androidx.test.espresso.ViewAssertion
9+
import androidx.test.espresso.action.ViewActions.click
710
import androidx.test.espresso.assertion.PositionAssertions.isCompletelyAbove
811
import androidx.test.espresso.assertion.PositionAssertions.isCompletelyBelow
912
import androidx.test.espresso.assertion.PositionAssertions.isCompletelyLeftOf
1013
import androidx.test.espresso.assertion.PositionAssertions.isCompletelyRightOf
1114
import androidx.test.espresso.assertion.PositionAssertions.isLeftAlignedWith
1215
import androidx.test.espresso.assertion.PositionAssertions.isTopAlignedWith
1316
import androidx.test.espresso.assertion.ViewAssertions.matches
17+
import androidx.test.espresso.contrib.PickerActions.setDate
18+
import androidx.test.espresso.contrib.PickerActions.setTime
1419
import androidx.test.espresso.matcher.ViewMatchers
1520
import androidx.test.espresso.matcher.ViewMatchers.hasDescendant
1621
import androidx.test.espresso.matcher.ViewMatchers.isChecked
1722
import androidx.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed
1823
import androidx.test.espresso.matcher.ViewMatchers.isDescendantOfA
1924
import androidx.test.espresso.matcher.ViewMatchers.isNotChecked
25+
import androidx.test.espresso.matcher.ViewMatchers.withClassName
2026
import androidx.test.espresso.matcher.ViewMatchers.withId
2127
import androidx.test.espresso.matcher.ViewMatchers.withSubstring
2228
import androidx.test.espresso.matcher.ViewMatchers.withText
@@ -42,6 +48,7 @@ import com.example.util.simpletimetracker.utils.unconstrainedClickOnView
4248
import com.example.util.simpletimetracker.utils.withPluralText
4349
import dagger.hilt.android.testing.HiltAndroidTest
4450
import org.hamcrest.CoreMatchers.allOf
51+
import org.hamcrest.CoreMatchers.equalTo
4552
import org.hamcrest.Matcher
4653
import org.junit.Test
4754
import org.junit.runner.RunWith
@@ -795,6 +802,76 @@ class SettingsTest : BaseUiTest() {
795802
tryAction { clickOnView(allOf(isDescendantOfA(withId(R.id.viewRunningRecordItem)), withText(name))) }
796803
}
797804

805+
@Test
806+
fun csvExportSettings() {
807+
NavUtils.openSettingsScreen()
808+
onView(withId(R.id.layoutSettingsExportCsv)).perform(nestedScrollTo(), click())
809+
810+
// View is set up
811+
val currentTime = System.currentTimeMillis()
812+
var timeStarted = timeMapper.formatDateTime(currentTime - TimeUnit.DAYS.toMillis(7), true)
813+
var timeEnded = timeMapper.formatDateTime(currentTime, true)
814+
checkViewIsDisplayed(allOf(withId(R.id.tvCsvExportSettingsTimeStarted), withText(timeStarted)))
815+
checkViewIsDisplayed(allOf(withId(R.id.tvCsvExportSettingsTimeEnded), withText(timeEnded)))
816+
817+
val calendar = Calendar.getInstance().apply {
818+
add(Calendar.DATE, -1)
819+
}
820+
val hourStarted = 15
821+
val minutesStarted = 16
822+
val hourEnded = 17
823+
val minutesEnded = 19
824+
val year = calendar.get(Calendar.YEAR)
825+
val month = calendar.get(Calendar.MONTH)
826+
val day = calendar.get(Calendar.DAY_OF_MONTH)
827+
828+
// Set time started
829+
clickOnViewWithId(R.id.tvCsvExportSettingsTimeStarted)
830+
onView(withClassName(equalTo(DatePicker::class.java.name)))
831+
.perform(setDate(year, month + 1, day))
832+
clickOnView(allOf(isDescendantOfA(withId(R.id.tabsDateTimeDialog)), withText(R.string.date_time_dialog_time)))
833+
onView(withClassName(equalTo(TimePicker::class.java.name)))
834+
.perform(setTime(hourStarted, minutesStarted))
835+
clickOnViewWithId(R.id.btnDateTimeDialogPositive)
836+
837+
// Check time set
838+
val timeStartedTimestamp = Calendar.getInstance().run {
839+
set(Calendar.YEAR, year)
840+
set(Calendar.MONTH, month)
841+
set(Calendar.DAY_OF_MONTH, day)
842+
set(Calendar.HOUR_OF_DAY, hourStarted)
843+
set(Calendar.MINUTE, minutesStarted)
844+
timeInMillis
845+
}
846+
timeStarted = timeStartedTimestamp
847+
.let { timeMapper.formatDateTime(it, true) }
848+
849+
checkViewIsDisplayed(allOf(withId(R.id.tvCsvExportSettingsTimeStarted), withText(timeStarted)))
850+
851+
// Set time ended
852+
clickOnViewWithId(R.id.tvCsvExportSettingsTimeEnded)
853+
onView(withClassName(equalTo(DatePicker::class.java.name)))
854+
.perform(setDate(year, month + 1, day))
855+
clickOnView(allOf(isDescendantOfA(withId(R.id.tabsDateTimeDialog)), withText(R.string.date_time_dialog_time)))
856+
onView(withClassName(equalTo(TimePicker::class.java.name)))
857+
.perform(setTime(hourEnded, minutesEnded))
858+
clickOnViewWithId(R.id.btnDateTimeDialogPositive)
859+
860+
// Check time set
861+
val timeEndedTimestamp = Calendar.getInstance().run {
862+
set(Calendar.YEAR, year)
863+
set(Calendar.MONTH, month)
864+
set(Calendar.DAY_OF_MONTH, day)
865+
set(Calendar.HOUR_OF_DAY, hourEnded)
866+
set(Calendar.MINUTE, minutesEnded)
867+
timeInMillis
868+
}
869+
timeEnded = timeEndedTimestamp
870+
.let { timeMapper.formatDateTime(it, true) }
871+
872+
checkViewIsDisplayed(allOf(withId(R.id.tvCsvExportSettingsTimeEnded), withText(timeEnded)))
873+
}
874+
798875
private fun clearDuration() {
799876
repeat(6) { clickOnViewWithId(R.id.ivDurationPickerDelete) }
800877
}

feature_change_record/src/main/java/com/example/util/simpletimetracker/feature_change_record/viewModel/ChangeRecordViewModel.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ class ChangeRecordViewModel @Inject constructor(
110110
DateTimeDialogParams(
111111
tag = TIME_STARTED_TAG,
112112
timestamp = newTimeStarted,
113-
type = DateTimeDialogType.DATETIME,
113+
type = DateTimeDialogType.DATETIME(),
114114
useMilitaryTime = useMilitaryTime,
115115
firstDayOfWeek = firstDayOfWeek
116116
)
@@ -128,7 +128,7 @@ class ChangeRecordViewModel @Inject constructor(
128128
DateTimeDialogParams(
129129
tag = TIME_ENDED_TAG,
130130
timestamp = newTimeEnded,
131-
type = DateTimeDialogType.DATETIME,
131+
type = DateTimeDialogType.DATETIME(),
132132
useMilitaryTime = useMilitaryTime,
133133
firstDayOfWeek = firstDayOfWeek
134134
)

feature_change_running_record/src/main/java/com/example/util/simpletimetracker/feature_change_running_record/viewModel/ChangeRunningRecordViewModel.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ class ChangeRunningRecordViewModel @Inject constructor(
115115
DateTimeDialogParams(
116116
tag = TIME_STARTED_TAG,
117117
timestamp = newTimeStarted,
118-
type = DateTimeDialogType.DATETIME,
118+
type = DateTimeDialogType.DATETIME(),
119119
useMilitaryTime = useMilitaryTime,
120120
firstDayOfWeek = firstDayOfWeek
121121
)

feature_dialogs/src/main/java/com/example/util/simpletimetracker/feature_dialogs/csvExportSettings/viewModel/CsvExportSettingsViewModel.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class CsvExportSettingsViewModel @Inject constructor(
4747
DateTimeDialogParams(
4848
tag = TIME_STARTED_TAG,
4949
timestamp = rangeStart,
50-
type = DateTimeDialogType.DATETIME,
50+
type = DateTimeDialogType.DATETIME(initialTab = DateTimeDialogType.Tab.DATE),
5151
useMilitaryTime = useMilitaryTime,
5252
firstDayOfWeek = firstDayOfWeek
5353
)
@@ -65,7 +65,7 @@ class CsvExportSettingsViewModel @Inject constructor(
6565
DateTimeDialogParams(
6666
tag = TIME_ENDED_TAG,
6767
timestamp = rangeEnd,
68-
type = DateTimeDialogType.DATETIME,
68+
type = DateTimeDialogType.DATETIME(initialTab = DateTimeDialogType.Tab.DATE),
6969
useMilitaryTime = useMilitaryTime,
7070
firstDayOfWeek = firstDayOfWeek
7171
)

feature_dialogs/src/main/java/com/example/util/simpletimetracker/feature_dialogs/dateTime/DateTimeDialogFragment.kt

Lines changed: 38 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,11 @@ import com.example.util.simpletimetracker.core.extension.getAllFragments
1313
import com.example.util.simpletimetracker.core.extension.onTabSelected
1414
import com.example.util.simpletimetracker.core.extension.visible
1515
import com.example.util.simpletimetracker.core.mapper.TimeMapper
16-
import com.example.util.simpletimetracker.domain.extension.orFalse
17-
import com.example.util.simpletimetracker.domain.extension.orZero
18-
import com.example.util.simpletimetracker.domain.model.DayOfWeek
1916
import com.example.util.simpletimetracker.feature_dialogs.R
2017
import com.example.util.simpletimetracker.feature_dialogs.databinding.DateTimeDialogFragmentBinding
2118
import com.example.util.simpletimetracker.navigation.params.DateTimeDialogParams
2219
import com.example.util.simpletimetracker.navigation.params.DateTimeDialogType
20+
import com.google.android.material.tabs.TabLayout
2321
import dagger.hilt.android.AndroidEntryPoint
2422
import java.util.Calendar
2523
import javax.inject.Inject
@@ -39,22 +37,8 @@ class DateTimeDialogFragment :
3937
private var timeDialogFragment: TimeDialogFragment? = null
4038
private var dateDialogFragment: DateDialogFragment? = null
4139
private var dateTimeDialogListeners: MutableList<DateTimeDialogListener> = mutableListOf()
42-
private val dialogTag: String? by lazy {
43-
arguments?.getString(ARGS_TAG)
44-
}
45-
private val type: DateTimeDialogType by lazy {
46-
arguments?.getSerializable(ARGS_TYPE) as? DateTimeDialogType
47-
?: DateTimeDialogType.DATETIME
48-
}
49-
private val useMilitary: Boolean by lazy {
50-
arguments?.getBoolean(ARGS_MILITARY).orFalse()
51-
}
52-
private val timestamp: Long by lazy {
53-
arguments?.getLong(ARGS_TIMESTAMP).orZero()
54-
}
55-
private val firstDayOfWeek: DayOfWeek by lazy {
56-
arguments?.getSerializable(ARGS_FIRST_DAY_OF_WEEK) as? DayOfWeek
57-
?: DayOfWeek.MONDAY
40+
private val params: DateTimeDialogParams by lazy {
41+
arguments?.getParcelable(ARGS_PARAMS) ?: DateTimeDialogParams()
5842
}
5943
private var newTimestamp: Long = 0
6044
private val calendar = Calendar.getInstance()
@@ -77,15 +61,15 @@ class DateTimeDialogFragment :
7761
override fun onCreateView(
7862
inflater: LayoutInflater,
7963
container: ViewGroup?,
80-
savedInstanceState: Bundle?
64+
savedInstanceState: Bundle?,
8165
): View {
8266
_binding = DateTimeDialogFragmentBinding.inflate(inflater, container, false)
8367
return binding.root
8468
}
8569

8670
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
8771
super.onViewCreated(view, savedInstanceState)
88-
newTimestamp = timestamp
72+
newTimestamp = params.timestamp
8973
initUi()
9074
initUx()
9175
}
@@ -127,27 +111,27 @@ class DateTimeDialogFragment :
127111
dateDialogFragment?.getSelectedDate()?.let { (year, month, day) ->
128112
onDateSet(year, month, day)
129113
}
130-
dateTimeDialogListeners.forEach { it.onDateTimeSet(newTimestamp, dialogTag) }
114+
dateTimeDialogListeners.forEach { it.onDateTimeSet(newTimestamp, params.tag) }
131115
dismiss()
132116
}
133117
}
134118

135119
private fun initFragments() {
136-
val dayOfWeek = timeMapper.toCalendarDayOfWeek(firstDayOfWeek)
120+
val dayOfWeek = timeMapper.toCalendarDayOfWeek(params.firstDayOfWeek)
137121
childFragmentManager.commit {
138122
replace(
139123
R.id.datePickerContainer,
140-
DateDialogFragment.newInstance(timestamp, dayOfWeek)
124+
DateDialogFragment.newInstance(params.timestamp, dayOfWeek)
141125
.apply { listener = this@DateTimeDialogFragment }
142126
.also { dateDialogFragment = it }
143127
)
144128
}
145129

146-
if (type == DateTimeDialogType.DATETIME) {
130+
if (params.type is DateTimeDialogType.DATETIME) {
147131
childFragmentManager.commit {
148132
replace(
149133
R.id.timePickerContainer,
150-
TimeDialogFragment.newInstance(timestamp, useMilitary)
134+
TimeDialogFragment.newInstance(params.timestamp, params.useMilitaryTime)
151135
.apply { listener = this@DateTimeDialogFragment }
152136
.also { timeDialogFragment = it }
153137
)
@@ -156,46 +140,45 @@ class DateTimeDialogFragment :
156140
}
157141

158142
private fun initTabs() = with(binding) {
159-
when (type) {
160-
DateTimeDialogType.DATE -> {
161-
tabsDateTimeDialog.visible = false
143+
when (val type = params.type) {
144+
is DateTimeDialogType.DATE -> {
145+
setDateTabOnly()
146+
}
147+
is DateTimeDialogType.DATETIME -> {
148+
tabsDateTimeDialog.onTabSelected(::changeTabsVisibility)
149+
when (type.initialTab) {
150+
DateTimeDialogType.Tab.DATE -> tabsDateTimeDialog.getTabAt(0)?.select()
151+
DateTimeDialogType.Tab.TIME -> tabsDateTimeDialog.getTabAt(1)?.select()
152+
}
153+
}
154+
}
155+
}
156+
157+
private fun setDateTabOnly() = with(binding) {
158+
tabsDateTimeDialog.visible = false
159+
datePickerContainer.visible = true
160+
timePickerContainer.visible = false
161+
}
162+
163+
private fun changeTabsVisibility(tab: TabLayout.Tab) = with(binding) {
164+
when (tab.position) {
165+
0 -> {
162166
datePickerContainer.visible = true
163167
timePickerContainer.visible = false
164168
}
165-
DateTimeDialogType.DATETIME -> {
166-
tabsDateTimeDialog.getTabAt(1)?.select()
167-
tabsDateTimeDialog.onTabSelected { tab ->
168-
when (tab.position) {
169-
0 -> {
170-
datePickerContainer.visible = true
171-
timePickerContainer.visible = false
172-
}
173-
1 -> {
174-
datePickerContainer.visible = false
175-
timePickerContainer.visible = true
176-
}
177-
}
178-
}
169+
1 -> {
170+
datePickerContainer.visible = false
171+
timePickerContainer.visible = true
179172
}
180173
}
181174
}
182175

183176
companion object {
184-
private const val ARGS_TAG = "tag"
185-
private const val ARGS_TYPE = "type"
186-
private const val ARGS_MILITARY = "military"
187-
private const val ARGS_TIMESTAMP = "timestamp"
188-
private const val ARGS_FIRST_DAY_OF_WEEK = "firstDayOfWeek"
177+
private const val ARGS_PARAMS = "params"
189178

190179
fun createBundle(data: Any?): Bundle = Bundle().apply {
191180
when (data) {
192-
is DateTimeDialogParams -> {
193-
putString(ARGS_TAG, data.tag)
194-
putSerializable(ARGS_TYPE, data.type)
195-
putBoolean(ARGS_MILITARY, data.useMilitaryTime)
196-
putLong(ARGS_TIMESTAMP, data.timestamp)
197-
putSerializable(ARGS_FIRST_DAY_OF_WEEK, data.firstDayOfWeek)
198-
}
181+
is DateTimeDialogParams -> putParcelable(ARGS_PARAMS, data)
199182
}
200183
}
201184
}

feature_dialogs/src/main/res/layout/date_time_dialog_fragment.xml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,14 @@
3131
android:id="@+id/datePickerContainer"
3232
android:layout_width="wrap_content"
3333
android:layout_height="wrap_content"
34-
android:visibility="gone" />
34+
tools:layout_height="200dp"
35+
tools:layout_width="200dp" />
3536

3637
<FrameLayout
3738
android:id="@+id/timePickerContainer"
3839
android:layout_width="wrap_content"
3940
android:layout_height="wrap_content"
40-
android:visibility="visible"
41+
android:visibility="gone"
4142
tools:layout_height="200dp"
4243
tools:layout_width="200dp" />
4344

feature_settings/src/main/java/com/example/util/simpletimetracker/feature_settings/viewModel/SettingsViewModel.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import com.example.util.simpletimetracker.navigation.Notification
1919
import com.example.util.simpletimetracker.navigation.Router
2020
import com.example.util.simpletimetracker.navigation.Screen
2121
import com.example.util.simpletimetracker.navigation.params.CardOrderDialogParams
22-
import com.example.util.simpletimetracker.navigation.params.CsvExportSettingsParams
2322
import com.example.util.simpletimetracker.navigation.params.DurationDialogParams
2423
import com.example.util.simpletimetracker.navigation.params.FileChooserParams
2524
import com.example.util.simpletimetracker.navigation.params.OpenMarketParams
Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
package com.example.util.simpletimetracker.navigation.params
22

3+
import android.os.Parcelable
34
import com.example.util.simpletimetracker.domain.model.DayOfWeek
5+
import kotlinx.parcelize.Parcelize
46

7+
@Parcelize
58
data class DateTimeDialogParams(
69
val tag: String? = null,
7-
val useMilitaryTime: Boolean,
8-
val type: DateTimeDialogType,
9-
val timestamp: Long,
10-
val firstDayOfWeek: DayOfWeek
11-
)
10+
val useMilitaryTime: Boolean = false,
11+
val type: DateTimeDialogType = DateTimeDialogType.DATETIME(),
12+
val timestamp: Long = 0,
13+
val firstDayOfWeek: DayOfWeek = DayOfWeek.MONDAY,
14+
) : Parcelable
Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
11
package com.example.util.simpletimetracker.navigation.params
22

3-
enum class DateTimeDialogType {
4-
DATE, DATETIME
3+
import android.os.Parcelable
4+
import kotlinx.parcelize.Parcelize
5+
6+
sealed class DateTimeDialogType : Parcelable {
7+
8+
@Parcelize
9+
object DATE : DateTimeDialogType()
10+
11+
@Parcelize
12+
data class DATETIME(val initialTab: Tab = Tab.TIME) : DateTimeDialogType()
13+
14+
enum class Tab {
15+
DATE, TIME
16+
}
517
}

0 commit comments

Comments
 (0)