Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move battery warning functionality to ClockPageViewModelState #25

Merged
merged 4 commits into from
Aug 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,44 @@ class ClockPageTest {
.assertTextEquals(testString)
}

@Test
fun taskNameIcon_countDownTimerAppears() {
composeTestRule.setContent {
TimeClockTheme {
ClockPage(
viewModelState = ClockPageViewModelState()
)
}
}
composeTestRule.onNodeWithTag("TaskTextField_IconButton").performClick()
composeTestRule.onNodeWithTag("TimerTextField_Hours")
.assertIsDisplayed()
.assertIsEnabled()
composeTestRule.onNodeWithTag("TimerTextField_Minutes")
.assertIsDisplayed()
.assertIsEnabled()
composeTestRule.onNodeWithTag("TimerTextField_Seconds")
.assertIsDisplayed()
.assertIsEnabled()
}

@Test
fun taskNameIcon_countDownTimerDisappearsIfAlreadyEnabled() {
composeTestRule.setContent {
TimeClockTheme {
ClockPage(
viewModelState = ClockPageViewModelState(
countDownTimerEnabled = true
)
)
}
}
composeTestRule.onNodeWithTag("TaskTextField_IconButton").performClick()
composeTestRule.onNodeWithTag("TimerTextField_Hours").assertDoesNotExist()
composeTestRule.onNodeWithTag("TimerTextField_Minutes").assertDoesNotExist()
composeTestRule.onNodeWithTag("TimerTextField_Seconds").assertDoesNotExist()
}

@Test
fun taskNameDropdown_dropdownAppearsAndTaskFillsInWhenLabelIsClicked() {
composeTestRule.setContent {
Expand Down Expand Up @@ -123,4 +161,4 @@ class ClockPageTest {
composeTestRule.onNodeWithTag("TimerTextField_Minutes").performTextInput("1")
composeTestRule.onNodeWithTag("StartTimerButton").assertIsEnabled()
}
}
}
18 changes: 14 additions & 4 deletions app/src/main/java/com/nickspatties/timeclock/ui/pages/ClockPage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ fun ClockPage(

if (viewModelState.batteryWarningDialogVisible) {
BatteryWarningDialog(
confirmFunction = viewModelState.batteryWarningConfirmFunction,
dismissFunction = viewModelState.batteryWarningDismissFunction
confirmFunction = viewModelState::confirmBatteryWarningDialog,
dismissFunction = viewModelState::dismissBatteryWarningDialog
)
}

Scaffold() {
Scaffold {
Column(
modifier = Modifier
.padding(it)
Expand Down Expand Up @@ -63,7 +63,7 @@ fun ClockPage(
},
keyboardController = keyboardController,
countdownTimerEnabled = viewModelState.countDownTimerEnabled,
onIconClick = viewModelState.onTaskNameIconClick
onIconClick = viewModelState::onTaskTextFieldIconClick
)

DropdownMenu(
Expand Down Expand Up @@ -138,4 +138,14 @@ fun ClockPage_Initial() {
ClockPage(
viewModelState = ClockPageViewModelState()
)
}

@Composable
@Preview
fun ClockPage_batteryDialogVisible() {
ClockPage(
viewModelState = ClockPageViewModelState(
batteryWarningDialogVisible = true
)
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,9 @@ class ClockPageViewModel (
// only occurs when the class is created, not when moving from view to view
init {
// state function declarations
state.batteryWarningConfirmFunction = this::goToBatterySettings
state.batteryWarningDismissFunction = this::hideBatteryWarningModal
state.onTaskNameIconClick = this::switchCountDownTimer
state.checkBatteryOptimizationSettings = this::checkBatteryOptimizationSettings
state.startBatteryManagementActivity = this::goToBatterySettings
state.saveCountDownTimerEnabledValue = this::saveCountDownTimerEnabled
state.onTimerAnimationFinish = this::resetCurrSeconds
state.onClockStart = this::startClock
state.onClockStop = this::stopClock
Expand Down Expand Up @@ -139,27 +139,20 @@ class ClockPageViewModel (
}
}

fun switchCountDownTimer() {
val shouldWarn = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
private fun checkBatteryOptimizationSettings() : Boolean {
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// can just check if the permission is set
!powerManager.isIgnoringBatteryOptimizations(getApplication<Application?>().packageName)
} else {
// is unable to change the battery permission for versions below M, so only false
false
}

if (!state.countDownTimerEnabled && shouldWarn) {
state.batteryWarningDialogVisible = true
} else {
state.countDownTimerEnabled = !state.countDownTimerEnabled
viewModelScope.launch {
userPreferencesRepository.updateCountDownEnabled(state.countDownTimerEnabled)
}
}
}

fun hideBatteryWarningModal() {
state.batteryWarningDialogVisible = false
private fun saveCountDownTimerEnabled(enabled: Boolean) {
viewModelScope.launch {
userPreferencesRepository.updateCountDownEnabled(enabled)
}
}

/**
Expand All @@ -177,7 +170,6 @@ class ClockPageViewModel (
Uri.parse("package:" + getApplication<Application?>().packageName)
startActivity(getApplication(), intentBatteryUsage, null)
}
hideBatteryWarningModal()
}

private fun timerTextFieldValuesToSeconds(): Int {
Expand Down Expand Up @@ -322,19 +314,20 @@ fun getCountDownSeconds(
* @param batteryWarningDialogVisible Determines if the battery warning dialog is visible
* @param countDownTimerEnabled Determines if the count down timer should be visible, allowing
* the user to set a time that an event will last.
* @param countDownEndTime Not sure if it'll be here in the future...
* @param currCountDownSeconds Not sure if this'll be here either...
* @param hoursTextFieldValue The text in the hours section of the EditTimerTextField
* @param minutesTextFieldValue The text in the minutes section of the EditTimerTextField. Should
* not exceed 59
* @param secondsTextFieldValue The text in the minutes section of the EditTimerTextField. Should
* not exceed 59
* @param batteryWarningConfirmFunction Fires when tapping confirm button in BatteryWarningDialog
* @param batteryWarningDismissFunction Fires when tapping outside the BatteryWarningDialog
* @param onTaskNameIconClick Fires when the icon in the TaskTextField is pushed. Changes from
* count up to count down mode.
* @param onDismissDropdown Fires when the dropdown in the TaskTextField is dismissed by tapping outside it
* @param onTimerAnimationFinish Fires when the count up timer fades in and out when starting recording
* @param checkBatteryOptimizationSettings Verifies whether or not the TimeClock has unrestricted
* battery permission. If it doesn't, then the battery warning dialog should appear.
* @param startBatteryManagementActivity Starts battery management activity
* @param saveCountDownTimerEnabledValue Saves the countDownTimerEnabled UserPreference variable, so
* the count down timer's visibility persists on activity recreation
* @param onDismissDropdown Fires when the dropdown in the TaskTextField is dismissed by
* tapping outside it
* @param onTimerAnimationFinish Fires when the count up timer fades in and out when starting
* recording
* @param onClockStart Fires when the start button is pressed
* @param onClockStop Fires when the stop button is pressed
*/
Expand All @@ -358,9 +351,9 @@ class ClockPageViewModelState(
text = "00",
selection = TextRange(0)
),
var batteryWarningConfirmFunction: () -> Unit = {},
var batteryWarningDismissFunction: () -> Unit = {},
var onTaskNameIconClick: () -> Unit = {},
var checkBatteryOptimizationSettings: () -> Boolean = {false},
var startBatteryManagementActivity: () -> Unit = {},
var saveCountDownTimerEnabledValue: (Boolean) -> Unit = {_ -> },
NicksPatties marked this conversation as resolved.
Show resolved Hide resolved
var onDismissDropdown: () -> Unit = {},
var onTimerAnimationFinish: () -> Unit = {},
var onClockStart: () -> Unit = {},
Expand Down Expand Up @@ -398,6 +391,25 @@ class ClockPageViewModelState(
// cheeky var used to prevent onTaskNameChange from being called after onDropdownMenuItemClick
var dropdownClicked = false

fun dismissBatteryWarningDialog() {
batteryWarningDialogVisible = false
}

fun confirmBatteryWarningDialog() {
startBatteryManagementActivity()
batteryWarningDialogVisible = false
}

fun onTaskTextFieldIconClick() {
val shouldWarn = checkBatteryOptimizationSettings()
if (!countDownTimerEnabled && shouldWarn) {
batteryWarningDialogVisible = true
} else {
countDownTimerEnabled = !countDownTimerEnabled
saveCountDownTimerEnabledValue(countDownTimerEnabled)
}
}

fun onTaskNameChange(tfv: TextFieldValue) {
if (dropdownClicked) {
dropdownClicked = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,4 +243,50 @@ class ClockPageViewModelStateTest {
)
)
}
}

@Test
fun confirmBatteryWarningDialog_callsStartBatteryManagementActivityFunction() {
var counter = 0
val testState = ClockPageViewModelState(
batteryWarningDialogVisible = true,
startBatteryManagementActivity = {
counter++
}
)
testState.confirmBatteryWarningDialog()
assertThat(counter).isEqualTo(1)
assertThat(testState.batteryWarningDialogVisible).isFalse()
}

@Test
fun dismissBatteryWarningDialog_dialogNotVisibleAfterDismiss() {
val testState = ClockPageViewModelState(
batteryWarningDialogVisible = true
)
testState.dismissBatteryWarningDialog()
assertThat(testState.batteryWarningDialogVisible).isFalse()
}

@Test
fun onTaskTextFieldIconClick_switchesCountDownTimerEnabled() {
var counter = 0
val testState = ClockPageViewModelState(
countDownTimerEnabled = false,
saveCountDownTimerEnabledValue = { counter++ }
)
testState.onTaskTextFieldIconClick()
assertThat(testState.countDownTimerEnabled).isTrue()
assertThat(counter).isEqualTo(1) // saveCountDownTimerEnabled has been called
}

@Test
fun onTaskTextFieldIconClick_shouldWarnIfBatterySettingsNotOptimized() {
val testState = ClockPageViewModelState(
checkBatteryOptimizationSettings = { true },
countDownTimerEnabled = false
)
testState.onTaskTextFieldIconClick()
assertThat(testState.countDownTimerEnabled).isFalse()
assertThat(testState.batteryWarningDialogVisible).isTrue()
}
}