Skip to content

Commit

Permalink
Merge pull request #85 from Wottrich/issues-84
Browse files Browse the repository at this point in the history
Selecting a date less than today crashes the application - issue #84
  • Loading branch information
waseefakhtar authored Oct 18, 2023
2 parents ea3e77c + 6f64bb7 commit 112d98d
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 31 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package com.waseefakhtar.doseapp.feature.addmedication

import android.app.DatePickerDialog
import android.content.Context
import android.widget.DatePicker
import android.widget.Toast
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.interaction.collectIsPressedAsState
Expand Down Expand Up @@ -59,14 +57,14 @@ import com.waseefakhtar.doseapp.R
import com.waseefakhtar.doseapp.analytics.AnalyticsEvents
import com.waseefakhtar.doseapp.analytics.AnalyticsHelper
import com.waseefakhtar.doseapp.domain.model.Medication
import com.waseefakhtar.doseapp.extension.toFormattedString
import com.waseefakhtar.doseapp.feature.addmedication.model.CalendarInformation
import com.waseefakhtar.doseapp.feature.addmedication.viewmodel.AddMedicationViewModel
import com.waseefakhtar.doseapp.util.MONTH_NAME_DAY_YEAR_DATE_FORMAT
import com.waseefakhtar.doseapp.util.Recurrence
import com.waseefakhtar.doseapp.util.TimesOfDay
import com.waseefakhtar.doseapp.util.getRecurrenceList
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import java.text.DateFormatSymbols
import java.util.Calendar
import java.util.Date

Expand Down Expand Up @@ -528,39 +526,26 @@ fun EndDateTextField(endDate: (Long) -> Unit) {
val interactionSource = remember { MutableInteractionSource() }
val isPressed: Boolean by interactionSource.collectIsPressedAsState()

val currentDate = Date().toFormattedString()
var selectedDate by rememberSaveable { mutableStateOf(currentDate) }

val context = LocalContext.current

val calendar = Calendar.getInstance()
val year: Int = calendar[Calendar.YEAR]
val month: Int = calendar[Calendar.MONTH]
val day: Int = calendar[Calendar.DAY_OF_MONTH]
calendar.time = Date()

val datePickerDialog =
DatePickerDialog(context, { _: DatePicker, year: Int, month: Int, dayOfMonth: Int ->
val newDate = Calendar.getInstance()
newDate.set(year, month, dayOfMonth)
selectedDate = "${month.toMonthName()} $dayOfMonth, $year"
endDate(newDate.timeInMillis)
}, year, month, day)
val currentDate = CalendarInformation(Calendar.getInstance())
var selectedDate by rememberSaveable(
stateSaver = CalendarInformation.getStateSaver()
) { mutableStateOf(currentDate) }

DatePickerDialogComponent(
isPressed,
selectedDate,
onSelectedDate = {
selectedDate = it
endDate(it.getTimeInMillis())
}
)

TextField(
modifier = Modifier.fillMaxWidth(),
readOnly = true,
value = selectedDate,
value = selectedDate.getDateFormatted(MONTH_NAME_DAY_YEAR_DATE_FORMAT),
onValueChange = {},
trailingIcon = { Icons.Default.DateRange },
interactionSource = interactionSource
)

if (isPressed) {
datePickerDialog.show()
}
}

fun Int.toMonthName(): String {
return DateFormatSymbols().months[this]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.waseefakhtar.doseapp.feature.addmedication

import android.app.DatePickerDialog
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalContext
import com.waseefakhtar.doseapp.feature.addmedication.model.CalendarInformation
import java.util.Calendar

@Composable
fun DatePickerDialogComponent(
showDialog: Boolean,
selectedDate: CalendarInformation,
onSelectedDate: (selectedDate: CalendarInformation) -> Unit
) {
val listener = setUpOnDateSetListener(onSelectedDate)
val datePickerDialog = getDatePickerDialog(selectedDate, listener)
if (showDialog) {
datePickerDialog.datePicker.minDate = Calendar.getInstance().timeInMillis
datePickerDialog.show()
}
}

private fun setUpOnDateSetListener(
onSelectedDate: (selectedDate: CalendarInformation) -> Unit
): DatePickerDialog.OnDateSetListener {
return DatePickerDialog.OnDateSetListener { _, selectedYear, selectedMonth, selectedDay ->
val newDate = Calendar.getInstance().apply { set(selectedYear, selectedMonth, selectedDay) }
onSelectedDate(CalendarInformation(newDate))
}
}

@Composable
private fun getDatePickerDialog(
selectedDate: CalendarInformation,
listener: DatePickerDialog.OnDateSetListener
): DatePickerDialog {
val context = LocalContext.current
val (year, month, day) = selectedDate.dateInformation
return DatePickerDialog(
context,
listener,
year,
month,
day
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.waseefakhtar.doseapp.feature.addmedication.model

import androidx.compose.runtime.saveable.Saver
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Locale
import java.util.MissingFormatArgumentException

class CalendarInformation(private val calendar: Calendar) {

val dateInformation = DateInformation(
year = calendar.get(Calendar.YEAR),
month = calendar.get(Calendar.MONTH),
dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH)
)

fun getTimeInMillis() = calendar.timeInMillis

fun getDateFormatted(pattern: String): String {
return try {
SimpleDateFormat(pattern, Locale.getDefault()).format(calendar.time)
} catch (ex: MissingFormatArgumentException) {
throw ex
}
}

inner class DateInformation(
val year: Int,
val month: Int,
val dayOfMonth: Int
) {
operator fun component1(): Int = year
operator fun component2(): Int = month
operator fun component3(): Int = dayOfMonth
}

companion object {
fun getStateSaver() = Saver<CalendarInformation, Calendar>(
save = { state ->
state.calendar
},
restore = {
CalendarInformation(it)
}
)
}
}
2 changes: 2 additions & 0 deletions app/src/main/java/com/waseefakhtar/doseapp/util/TimeUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import java.util.Calendar
import java.util.concurrent.TimeUnit
import kotlin.math.abs

const val MONTH_NAME_DAY_YEAR_DATE_FORMAT = "MMMM dd, yyyy"

@Composable
fun getTimeRemaining(medication: Medication): String {
val currentTime = Calendar.getInstance().time
Expand Down

0 comments on commit 112d98d

Please sign in to comment.