Skip to content
This repository has been archived by the owner on Mar 18, 2024. It is now read-only.

Commit

Permalink
Add workout duration adjuster
Browse files Browse the repository at this point in the history
  • Loading branch information
AnkitSuda committed Nov 25, 2022
1 parent de311f2 commit eb77b05
Show file tree
Hide file tree
Showing 11 changed files with 499 additions and 18 deletions.
3 changes: 3 additions & 0 deletions modules/common-ui-components-workout-editor/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ android {
}

compileOptions {
coreLibraryDesugaringEnabled true
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
Expand All @@ -56,6 +57,8 @@ dependencies {
implementation project(":modules:navigation")
implementation project(":modules:domain")

coreLibraryDesugaring Deps.Android.desugaring

implementation Deps.Dagger.hilt
kapt Deps.Dagger.hiltCompiler
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
/*
* Copyright (c) 2022 Ankit Suda.
*
* Licensed under the GNU General Public License v3
*
* This is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*/

package com.ankitsuda.rebound.ui.components.workouteditor.durationeditor

import androidx.compose.foundation.layout.*
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.material.TextButton
import androidx.compose.runtime.*
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import com.ankitsuda.base.utils.toString
import com.ankitsuda.rebound.ui.components.RButtonStyle2
import com.ankitsuda.rebound.ui.components.datetimepicker.DateTimePicker
import com.ankitsuda.rebound.ui.components.workouteditor.R
import com.ankitsuda.rebound.ui.theme.ReboundTheme
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import java.time.format.FormatStyle

@Composable
fun WorkoutDurationEditorDialog(
initialStartDateTime: LocalDateTime,
initialEndDateTime: LocalDateTime,
onDismissRequest: () -> Unit,
onSave: (startDateTime: LocalDateTime, endDateTime: LocalDateTime) -> Unit,
) {
var currentPickerActiveFor by remember {
mutableStateOf(0)
}

var startDateTime by rememberSaveable {
mutableStateOf(initialStartDateTime)
}

var endDateTime by rememberSaveable {
mutableStateOf(initialEndDateTime)
}

fun getFormattedDateString(dateTime: LocalDateTime): String =
dateTime.format(
DateTimeFormatter.ofLocalizedDateTime(
FormatStyle.MEDIUM,
FormatStyle.SHORT
)
)

fun handleSaveClick() {
onSave(
startDateTime,
endDateTime
)
onDismissRequest()
}

val formattedStartDateTime = remember(startDateTime) {
getFormattedDateString(startDateTime)
}

val formattedEndDateTime = remember(endDateTime) {
getFormattedDateString(endDateTime)
}

Dialog(
onDismissRequest = onDismissRequest,
) {
Surface(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 32.dp),
color = ReboundTheme.colors.background,
shape = ReboundTheme.shapes.large
) {
Column(
modifier = Modifier
.fillMaxWidth()
) {
Column(
modifier =
Modifier.padding(start = 16.dp, end = 16.dp, top = 16.dp, bottom = 8.dp),
verticalArrangement = Arrangement.spacedBy(12.dp)
) {
Text(
text = stringResource(R.string.adjust_duration),
style = ReboundTheme.typography.h6,
color = ReboundTheme.colors.onBackground
)

Text(
text = stringResource(R.string.start_time),
style = ReboundTheme.typography.caption,
color = ReboundTheme.colors.onBackground.copy(0.75f)
)

RButtonStyle2(
modifier = Modifier.fillMaxWidth(),
text = formattedStartDateTime,
onClick = {
currentPickerActiveFor = 1
}
)

Text(
text = stringResource(R.string.end_time),
style = ReboundTheme.typography.caption,
color = ReboundTheme.colors.onBackground.copy(0.75f)
)

RButtonStyle2(
modifier = Modifier.fillMaxWidth(),
text = formattedEndDateTime,
onClick = {
currentPickerActiveFor = 2
}
)

DialogButtonsRow(
onClickSave = ::handleSaveClick,
onClickCancel = onDismissRequest
)
}
}
}
}

if (currentPickerActiveFor == 1 || currentPickerActiveFor == 2) {
DateTimePicker(
value = when (currentPickerActiveFor) {
2 -> endDateTime
else -> startDateTime
},
onCancel = {
currentPickerActiveFor = 0
},
onValueChange = {
when (currentPickerActiveFor) {
1 -> startDateTime = it
2 -> endDateTime = it
}
currentPickerActiveFor = 0
}
)
}
}

@Composable
private fun ColumnScope.DialogButtonsRow(
onClickSave: () -> Unit,
onClickCancel: () -> Unit
) {
Row(
modifier = Modifier
.align(Alignment.End),
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
TextButton(onClick = onClickCancel) {
Text(stringResource(id = R.string.cancel))
}
TextButton(onClick = onClickSave) {
Text(stringResource(id = R.string.save))
}
}
}
4 changes: 4 additions & 0 deletions modules/common-ui-components/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ android {
}

compileOptions {
coreLibraryDesugaringEnabled true

sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
Expand All @@ -55,4 +57,6 @@ dependencies {
api project(":modules:domain")
api Deps.Android.Compose.collapsingToolbar
kapt Deps.Dagger.hiltCompiler
coreLibraryDesugaring Deps.Android.desugaring

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright (c) 2022 Ankit Suda.
*
* Licensed under the GNU General Public License v3
*
* This is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*/

package com.ankitsuda.rebound.ui.components.datetimepicker

import android.app.DatePickerDialog
import androidx.compose.runtime.*
import androidx.compose.ui.platform.LocalContext
import java.time.LocalDate

@Composable
fun DatePicker(
value: LocalDate,
onCancel: () -> Unit = {},
onValueChange: (LocalDate) -> Unit = {},
) {
val context = LocalContext.current
val dialog by remember {
mutableStateOf(
DatePickerDialog(
context,
{ _, year, month, dayOfMonth ->
onValueChange(LocalDate.of(year, month + 1, dayOfMonth))
},
value.year,
value.monthValue - 1,
value.dayOfMonth,
)
)
}

fun setupDialog() {
dialog.apply {
setOnCancelListener {
onCancel()
}
}
}

LaunchedEffect(key1 = Unit) {
setupDialog()
dialog.show()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright (c) 2022 Ankit Suda.
*
* Licensed under the GNU General Public License v3
*
* This is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*/

package com.ankitsuda.rebound.ui.components.datetimepicker

import androidx.compose.runtime.*
import java.time.LocalDateTime

@Composable
fun DateTimePicker(
value: LocalDateTime,
onCancel: () -> Unit = {},
onValueChange: (LocalDateTime) -> Unit = {},
) {
var currentView by remember {
mutableStateOf(1)
}

var pickedDate by remember(value) {
mutableStateOf(value.toLocalDate())
}

var pickedTime by remember(value) {
mutableStateOf(value.toLocalTime())
}

when (currentView) {
1 -> DatePicker(
value = pickedDate,
onCancel = onCancel,
onValueChange = {
pickedDate = it
currentView = 2
}
)
2 -> TimePicker(
value = pickedTime,
onCancel = onCancel,
onValueChange = {
pickedTime = it
currentView = 0
onValueChange(LocalDateTime.of(pickedDate, pickedTime))
}
)
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright (c) 2022 Ankit Suda.
*
* Licensed under the GNU General Public License v3
*
* This is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*/

package com.ankitsuda.rebound.ui.components.datetimepicker

import android.app.TimePickerDialog
import androidx.compose.runtime.*
import androidx.compose.ui.platform.LocalContext
import java.time.LocalTime

@Composable
fun TimePicker(
value: LocalTime,
is24HourView: Boolean = false,
onCancel: () -> Unit = {},
onValueChange: (LocalTime) -> Unit = {},
) {
val context = LocalContext.current
val dialog by remember {
mutableStateOf(
TimePickerDialog(
context,
{ _, hour, minute ->
onValueChange(LocalTime.of(hour, minute))
},
value.hour,
value.minute,
is24HourView,
)
)
}

fun setupDialog() {
dialog.apply {
setOnCancelListener {
onCancel()
}
}
}

LaunchedEffect(key1 = Unit) {
setupDialog()
dialog.show()
}
}
Loading

0 comments on commit eb77b05

Please sign in to comment.