Migrate material date picker (#1277)

This commit is contained in:
Mateusz Idziejczak 2021-04-12 21:43:52 +02:00 committed by GitHub
parent 95ffb0a687
commit 13ccfda009
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 180 additions and 129 deletions

View File

@ -1,5 +1,6 @@
apply plugin: 'com.android.application' apply plugin: 'com.android.application'
apply plugin: 'kotlin-android' apply plugin: 'kotlin-android'
apply plugin: 'kotlin-parcelize'
apply plugin: 'kotlin-kapt' apply plugin: 'kotlin-kapt'
apply plugin: 'dagger.hilt.android.plugin' apply plugin: 'dagger.hilt.android.plugin'
apply plugin: 'com.google.firebase.crashlytics' apply plugin: 'com.google.firebase.crashlytics'
@ -209,7 +210,6 @@ dependencies {
implementation "at.favre.lib:slf4j-timber:1.0.1" implementation "at.favre.lib:slf4j-timber:1.0.1"
implementation "fr.bipi.treessence:treessence:0.3.2" implementation "fr.bipi.treessence:treessence:0.3.2"
implementation "com.mikepenz:aboutlibraries-core:$about_libraries" implementation "com.mikepenz:aboutlibraries-core:$about_libraries"
implementation 'com.wdullaer:materialdatetimepicker:4.2.3'
implementation "io.coil-kt:coil:1.1.1" implementation "io.coil-kt:coil:1.1.1"
implementation "io.github.wulkanowy:AppKillerManager:3.0.0" implementation "io.github.wulkanowy:AppKillerManager:3.0.0"
implementation 'me.xdrop:fuzzywuzzy:1.3.1' implementation 'me.xdrop:fuzzywuzzy:1.3.1'

View File

@ -13,7 +13,8 @@ import android.view.View.VISIBLE
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.appcompat.view.ActionMode import androidx.appcompat.view.ActionMode
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import com.wdullaer.materialdatetimepicker.date.DatePickerDialog import com.google.android.material.datepicker.CalendarConstraints
import com.google.android.material.datepicker.MaterialDatePicker
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Attendance import io.github.wulkanowy.data.db.entities.Attendance
@ -24,9 +25,12 @@ import io.github.wulkanowy.ui.modules.attendance.summary.AttendanceSummaryFragme
import io.github.wulkanowy.ui.modules.main.MainActivity import io.github.wulkanowy.ui.modules.main.MainActivity
import io.github.wulkanowy.ui.modules.main.MainView import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.ui.widgets.DividerItemDecoration import io.github.wulkanowy.ui.widgets.DividerItemDecoration
import io.github.wulkanowy.utils.SchooldaysRangeLimiter import io.github.wulkanowy.utils.SchoolDaysValidator
import io.github.wulkanowy.utils.dpToPx import io.github.wulkanowy.utils.dpToPx
import io.github.wulkanowy.utils.getThemeAttrColor import io.github.wulkanowy.utils.getThemeAttrColor
import io.github.wulkanowy.utils.schoolYearStart
import io.github.wulkanowy.utils.toLocalDateTime
import io.github.wulkanowy.utils.toTimestamp
import java.time.LocalDate import java.time.LocalDate
import javax.inject.Inject import javax.inject.Inject
@ -216,19 +220,27 @@ class AttendanceFragment : BaseFragment<FragmentAttendanceBinding>(R.layout.frag
} }
override fun showDatePickerDialog(currentDate: LocalDate) { override fun showDatePickerDialog(currentDate: LocalDate) {
val dateSetListener = DatePickerDialog.OnDateSetListener { _, year, month, dayOfMonth -> val now = LocalDate.now()
presenter.onDateSet(year, month + 1, dayOfMonth) val startOfSchoolYear = now.schoolYearStart.toTimestamp()
} val endWeek = now.plusWeeks(1).toTimestamp()
val datePickerDialog = DatePickerDialog.newInstance(dateSetListener,
currentDate.year, currentDate.monthValue - 1, currentDate.dayOfMonth)
with(datePickerDialog) { val constraintsBuilder = CalendarConstraints.Builder().apply {
setDateRangeLimiter(SchooldaysRangeLimiter()) setValidator(SchoolDaysValidator(startOfSchoolYear, endWeek))
version = DatePickerDialog.Version.VERSION_2 setStart(startOfSchoolYear)
scrollOrientation = DatePickerDialog.ScrollOrientation.VERTICAL setEnd(endWeek)
vibrate(false)
show(this@AttendanceFragment.parentFragmentManager, null)
} }
val datePicker =
MaterialDatePicker.Builder.datePicker()
.setCalendarConstraints(constraintsBuilder.build())
.setSelection(currentDate.toTimestamp())
.build()
datePicker.addOnPositiveButtonClickListener {
val date = it.toLocalDateTime()
presenter.onDateSet(date.year, date.monthValue, date.dayOfMonth)
}
datePicker.show(this@AttendanceFragment.parentFragmentManager, null)
} }
override fun showExcuseDialog() { override fun showExcuseDialog() {

View File

@ -5,7 +5,8 @@ import android.view.View
import android.view.View.GONE import android.view.View.GONE
import android.view.View.VISIBLE import android.view.View.VISIBLE
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import com.wdullaer.materialdatetimepicker.date.DatePickerDialog import com.google.android.material.datepicker.CalendarConstraints
import com.google.android.material.datepicker.MaterialDatePicker
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.LuckyNumber import io.github.wulkanowy.data.db.entities.LuckyNumber
@ -13,14 +14,18 @@ import io.github.wulkanowy.databinding.FragmentLuckyNumberHistoryBinding
import io.github.wulkanowy.ui.base.BaseFragment import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.modules.main.MainView import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.ui.widgets.DividerItemDecoration import io.github.wulkanowy.ui.widgets.DividerItemDecoration
import io.github.wulkanowy.utils.SchooldaysRangeLimiter import io.github.wulkanowy.utils.SchoolDaysValidator
import io.github.wulkanowy.utils.dpToPx import io.github.wulkanowy.utils.dpToPx
import io.github.wulkanowy.utils.schoolYearStart
import io.github.wulkanowy.utils.toLocalDateTime
import io.github.wulkanowy.utils.toTimestamp
import java.time.LocalDate import java.time.LocalDate
import javax.inject.Inject import javax.inject.Inject
@AndroidEntryPoint @AndroidEntryPoint
class LuckyNumberHistoryFragment : class LuckyNumberHistoryFragment :
BaseFragment<FragmentLuckyNumberHistoryBinding>(R.layout.fragment_lucky_number_history), LuckyNumberHistoryView, BaseFragment<FragmentLuckyNumberHistoryBinding>(R.layout.fragment_lucky_number_history),
LuckyNumberHistoryView,
MainView.TitledView { MainView.TitledView {
@Inject @Inject
@ -107,19 +112,26 @@ class LuckyNumberHistoryFragment :
} }
override fun showDatePickerDialog(currentDate: LocalDate) { override fun showDatePickerDialog(currentDate: LocalDate) {
val dateSetListener = DatePickerDialog.OnDateSetListener { _, year, month, dayOfMonth -> val now = LocalDate.now()
presenter.onDateSet(year, month + 1, dayOfMonth) val startOfSchoolYear = now.schoolYearStart.toTimestamp()
}
val datePickerDialog = DatePickerDialog.newInstance(dateSetListener,
currentDate.year, currentDate.monthValue - 1, currentDate.dayOfMonth)
with(datePickerDialog) { val constraintsBuilder = CalendarConstraints.Builder().apply {
setDateRangeLimiter(SchooldaysRangeLimiter()) setValidator(SchoolDaysValidator(startOfSchoolYear, now.toTimestamp()))
version = DatePickerDialog.Version.VERSION_2 setStart(startOfSchoolYear)
scrollOrientation = DatePickerDialog.ScrollOrientation.VERTICAL setEnd(now.toTimestamp())
vibrate(false)
show(this@LuckyNumberHistoryFragment.parentFragmentManager, null)
} }
val datePicker =
MaterialDatePicker.Builder.datePicker()
.setCalendarConstraints(constraintsBuilder.build())
.setSelection(currentDate.toTimestamp())
.build()
datePicker.addOnPositiveButtonClickListener {
val date = it.toLocalDateTime()
presenter.onDateSet(date.year, date.monthValue, date.dayOfMonth)
}
datePicker.show(this@LuckyNumberHistoryFragment.parentFragmentManager, null)
} }
override fun showContent(show: Boolean) { override fun showContent(show: Boolean) {

View File

@ -9,7 +9,8 @@ import android.view.View.GONE
import android.view.View.VISIBLE import android.view.View.VISIBLE
import androidx.core.text.HtmlCompat import androidx.core.text.HtmlCompat
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import com.wdullaer.materialdatetimepicker.date.DatePickerDialog import com.google.android.material.datepicker.CalendarConstraints
import com.google.android.material.datepicker.MaterialDatePicker
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Timetable import io.github.wulkanowy.data.db.entities.Timetable
@ -20,9 +21,13 @@ import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.ui.modules.timetable.additional.AdditionalLessonsFragment import io.github.wulkanowy.ui.modules.timetable.additional.AdditionalLessonsFragment
import io.github.wulkanowy.ui.modules.timetable.completed.CompletedLessonsFragment import io.github.wulkanowy.ui.modules.timetable.completed.CompletedLessonsFragment
import io.github.wulkanowy.ui.widgets.DividerItemDecoration import io.github.wulkanowy.ui.widgets.DividerItemDecoration
import io.github.wulkanowy.utils.SchooldaysRangeLimiter import io.github.wulkanowy.utils.SchoolDaysValidator
import io.github.wulkanowy.utils.dpToPx import io.github.wulkanowy.utils.dpToPx
import io.github.wulkanowy.utils.getThemeAttrColor import io.github.wulkanowy.utils.getThemeAttrColor
import io.github.wulkanowy.utils.schoolYearEnd
import io.github.wulkanowy.utils.schoolYearStart
import io.github.wulkanowy.utils.toLocalDateTime
import io.github.wulkanowy.utils.toTimestamp
import java.time.LocalDate import java.time.LocalDate
import javax.inject.Inject import javax.inject.Inject
@ -184,21 +189,27 @@ class TimetableFragment : BaseFragment<FragmentTimetableBinding>(R.layout.fragme
} }
override fun showDatePickerDialog(currentDate: LocalDate) { override fun showDatePickerDialog(currentDate: LocalDate) {
val dateSetListener = DatePickerDialog.OnDateSetListener { _, year, month, dayOfMonth -> val now = LocalDate.now()
presenter.onDateSet(year, month + 1, dayOfMonth) val startOfSchoolYear = now.schoolYearStart.toTimestamp()
} val endOfSchoolYear = now.schoolYearEnd.toTimestamp()
val datePickerDialog = DatePickerDialog.newInstance(
dateSetListener,
currentDate.year, currentDate.monthValue - 1, currentDate.dayOfMonth
)
with(datePickerDialog) { val constraintsBuilder = CalendarConstraints.Builder().apply {
setDateRangeLimiter(SchooldaysRangeLimiter()) setValidator(SchoolDaysValidator(startOfSchoolYear, endOfSchoolYear))
version = DatePickerDialog.Version.VERSION_2 setStart(startOfSchoolYear)
scrollOrientation = DatePickerDialog.ScrollOrientation.VERTICAL setEnd(endOfSchoolYear)
vibrate(false)
show(this@TimetableFragment.parentFragmentManager, null)
} }
val datePicker =
MaterialDatePicker.Builder.datePicker()
.setCalendarConstraints(constraintsBuilder.build())
.setSelection(currentDate.toTimestamp())
.build()
datePicker.addOnPositiveButtonClickListener {
val date = it.toLocalDateTime()
presenter.onDateSet(date.year, date.monthValue, date.dayOfMonth)
}
datePicker.show(this@TimetableFragment.parentFragmentManager, null)
} }
override fun openAdditionalLessonsView() { override fun openAdditionalLessonsView() {

View File

@ -3,7 +3,8 @@ package io.github.wulkanowy.ui.modules.timetable.additional
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import com.wdullaer.materialdatetimepicker.date.DatePickerDialog import com.google.android.material.datepicker.CalendarConstraints
import com.google.android.material.datepicker.MaterialDatePicker
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.TimetableAdditional import io.github.wulkanowy.data.db.entities.TimetableAdditional
@ -11,9 +12,13 @@ import io.github.wulkanowy.databinding.FragmentTimetableAdditionalBinding
import io.github.wulkanowy.ui.base.BaseFragment import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.modules.main.MainView import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.ui.widgets.DividerItemDecoration import io.github.wulkanowy.ui.widgets.DividerItemDecoration
import io.github.wulkanowy.utils.SchooldaysRangeLimiter import io.github.wulkanowy.utils.SchoolDaysValidator
import io.github.wulkanowy.utils.dpToPx import io.github.wulkanowy.utils.dpToPx
import io.github.wulkanowy.utils.getThemeAttrColor import io.github.wulkanowy.utils.getThemeAttrColor
import io.github.wulkanowy.utils.schoolYearEnd
import io.github.wulkanowy.utils.schoolYearStart
import io.github.wulkanowy.utils.toLocalDateTime
import io.github.wulkanowy.utils.toTimestamp
import java.time.LocalDate import java.time.LocalDate
import javax.inject.Inject import javax.inject.Inject
@ -55,7 +60,11 @@ class AdditionalLessonsFragment :
with(binding) { with(binding) {
additionalLessonsSwipe.setOnRefreshListener(presenter::onSwipeRefresh) additionalLessonsSwipe.setOnRefreshListener(presenter::onSwipeRefresh)
additionalLessonsSwipe.setColorSchemeColors(requireContext().getThemeAttrColor(R.attr.colorPrimary)) additionalLessonsSwipe.setColorSchemeColors(requireContext().getThemeAttrColor(R.attr.colorPrimary))
additionalLessonsSwipe.setProgressBackgroundColorSchemeColor(requireContext().getThemeAttrColor(R.attr.colorSwipeRefresh)) additionalLessonsSwipe.setProgressBackgroundColorSchemeColor(
requireContext().getThemeAttrColor(
R.attr.colorSwipeRefresh
)
)
additionalLessonsErrorRetry.setOnClickListener { presenter.onRetry() } additionalLessonsErrorRetry.setOnClickListener { presenter.onRetry() }
additionalLessonsErrorDetails.setOnClickListener { presenter.onDetailsClick() } additionalLessonsErrorDetails.setOnClickListener { presenter.onDetailsClick() }
@ -114,7 +123,8 @@ class AdditionalLessonsFragment :
} }
override fun showPreButton(show: Boolean) { override fun showPreButton(show: Boolean) {
binding.additionalLessonsPreviousButton.visibility = if (show) View.VISIBLE else View.INVISIBLE binding.additionalLessonsPreviousButton.visibility =
if (show) View.VISIBLE else View.INVISIBLE
} }
override fun showNextButton(show: Boolean) { override fun showNextButton(show: Boolean) {
@ -122,19 +132,27 @@ class AdditionalLessonsFragment :
} }
override fun showDatePickerDialog(currentDate: LocalDate) { override fun showDatePickerDialog(currentDate: LocalDate) {
val dateSetListener = DatePickerDialog.OnDateSetListener { _, year, month, dayOfMonth -> val now = LocalDate.now()
presenter.onDateSet(year, month + 1, dayOfMonth) val startOfSchoolYear = now.schoolYearStart.toTimestamp()
} val endOfSchoolYear = now.schoolYearEnd.toTimestamp()
val datePickerDialog = DatePickerDialog.newInstance(dateSetListener,
currentDate.year, currentDate.monthValue - 1, currentDate.dayOfMonth)
with(datePickerDialog) { val constraintsBuilder = CalendarConstraints.Builder().apply {
setDateRangeLimiter(SchooldaysRangeLimiter()) setValidator(SchoolDaysValidator(startOfSchoolYear, endOfSchoolYear))
version = DatePickerDialog.Version.VERSION_2 setStart(startOfSchoolYear)
scrollOrientation = DatePickerDialog.ScrollOrientation.VERTICAL setEnd(endOfSchoolYear)
vibrate(false)
show(this@AdditionalLessonsFragment.parentFragmentManager, null)
} }
val datePicker =
MaterialDatePicker.Builder.datePicker()
.setCalendarConstraints(constraintsBuilder.build())
.setSelection(currentDate.toTimestamp())
.build()
datePicker.addOnPositiveButtonClickListener {
val date = it.toLocalDateTime()
presenter.onDateSet(date.year, date.monthValue, date.dayOfMonth)
}
datePicker.show(this@AdditionalLessonsFragment.parentFragmentManager, null)
} }
override fun onSaveInstanceState(outState: Bundle) { override fun onSaveInstanceState(outState: Bundle) {

View File

@ -6,7 +6,8 @@ import android.view.View.GONE
import android.view.View.INVISIBLE import android.view.View.INVISIBLE
import android.view.View.VISIBLE import android.view.View.VISIBLE
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import com.wdullaer.materialdatetimepicker.date.DatePickerDialog import com.google.android.material.datepicker.CalendarConstraints
import com.google.android.material.datepicker.MaterialDatePicker
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.CompletedLesson import io.github.wulkanowy.data.db.entities.CompletedLesson
@ -15,10 +16,14 @@ import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.modules.main.MainActivity import io.github.wulkanowy.ui.modules.main.MainActivity
import io.github.wulkanowy.ui.modules.main.MainView import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.ui.widgets.DividerItemDecoration import io.github.wulkanowy.ui.widgets.DividerItemDecoration
import io.github.wulkanowy.utils.SchooldaysRangeLimiter import io.github.wulkanowy.utils.SchoolDaysValidator
import io.github.wulkanowy.utils.dpToPx import io.github.wulkanowy.utils.dpToPx
import io.github.wulkanowy.utils.getCompatDrawable import io.github.wulkanowy.utils.getCompatDrawable
import io.github.wulkanowy.utils.getThemeAttrColor import io.github.wulkanowy.utils.getThemeAttrColor
import io.github.wulkanowy.utils.schoolYearEnd
import io.github.wulkanowy.utils.schoolYearStart
import io.github.wulkanowy.utils.toLocalDateTime
import io.github.wulkanowy.utils.toTimestamp
import java.time.LocalDate import java.time.LocalDate
import javax.inject.Inject import javax.inject.Inject
@ -62,7 +67,11 @@ class CompletedLessonsFragment :
with(binding) { with(binding) {
completedLessonsSwipe.setOnRefreshListener(presenter::onSwipeRefresh) completedLessonsSwipe.setOnRefreshListener(presenter::onSwipeRefresh)
completedLessonsSwipe.setColorSchemeColors(requireContext().getThemeAttrColor(R.attr.colorPrimary)) completedLessonsSwipe.setColorSchemeColors(requireContext().getThemeAttrColor(R.attr.colorPrimary))
completedLessonsSwipe.setProgressBackgroundColorSchemeColor(requireContext().getThemeAttrColor(R.attr.colorSwipeRefresh)) completedLessonsSwipe.setProgressBackgroundColorSchemeColor(
requireContext().getThemeAttrColor(
R.attr.colorSwipeRefresh
)
)
completedLessonErrorRetry.setOnClickListener { presenter.onRetry() } completedLessonErrorRetry.setOnClickListener { presenter.onRetry() }
completedLessonErrorDetails.setOnClickListener { presenter.onDetailsClick() } completedLessonErrorDetails.setOnClickListener { presenter.onDetailsClick() }
@ -136,23 +145,35 @@ class CompletedLessonsFragment :
} }
override fun showCompletedLessonDialog(completedLesson: CompletedLesson) { override fun showCompletedLessonDialog(completedLesson: CompletedLesson) {
(activity as? MainActivity)?.showDialogFragment(CompletedLessonDialog.newInstance(completedLesson)) (activity as? MainActivity)?.showDialogFragment(
CompletedLessonDialog.newInstance(
completedLesson
)
)
} }
override fun showDatePickerDialog(currentDate: LocalDate) { override fun showDatePickerDialog(currentDate: LocalDate) {
val dateSetListener = DatePickerDialog.OnDateSetListener { _, year, month, dayOfMonth -> val now = LocalDate.now()
presenter.onDateSet(year, month + 1, dayOfMonth) val startOfSchoolYear = now.schoolYearStart.toTimestamp()
} val endOfSchoolYear = now.schoolYearEnd.toTimestamp()
val datePickerDialog = DatePickerDialog.newInstance(dateSetListener,
currentDate.year, currentDate.monthValue - 1, currentDate.dayOfMonth)
with(datePickerDialog) { val constraintsBuilder = CalendarConstraints.Builder().apply {
setDateRangeLimiter(SchooldaysRangeLimiter()) setValidator(SchoolDaysValidator(startOfSchoolYear, endOfSchoolYear))
version = DatePickerDialog.Version.VERSION_2 setStart(startOfSchoolYear)
scrollOrientation = DatePickerDialog.ScrollOrientation.VERTICAL setEnd(endOfSchoolYear)
vibrate(false)
show(this@CompletedLessonsFragment.parentFragmentManager, null)
} }
val datePicker =
MaterialDatePicker.Builder.datePicker()
.setCalendarConstraints(constraintsBuilder.build())
.setSelection(currentDate.toTimestamp())
.build()
datePicker.addOnPositiveButtonClickListener {
val date = it.toLocalDateTime()
presenter.onDateSet(date.year, date.monthValue, date.dayOfMonth)
}
datePicker.show(this@CompletedLessonsFragment.parentFragmentManager, null)
} }
override fun onSaveInstanceState(outState: Bundle) { override fun onSaveInstanceState(outState: Bundle) {

View File

@ -1,51 +0,0 @@
package io.github.wulkanowy.utils
import android.os.Parcel
import android.os.Parcelable
import com.wdullaer.materialdatetimepicker.date.DateRangeLimiter
import java.time.DayOfWeek
import java.time.LocalDate
import java.util.Calendar
@Suppress("UNUSED_PARAMETER")
class SchooldaysRangeLimiter : DateRangeLimiter {
private val now = LocalDate.now()
override fun setToNearestDate(day: Calendar): Calendar = day
override fun isOutOfRange(year: Int, month: Int, day: Int): Boolean {
val date = LocalDate.of(year, month + 1, day)
val dayOfWeek = date.dayOfWeek
return dayOfWeek == DayOfWeek.SUNDAY || date.isHolidays
}
override fun getStartDate(): Calendar {
val startYear = if (now.monthValue <= 6) now.year - 1 else now.year
val startOfSchoolYear = now.withYear(startYear).firstSchoolDay
val calendar = Calendar.getInstance()
calendar.set(startOfSchoolYear.year, startOfSchoolYear.monthValue - 1, startOfSchoolYear.dayOfMonth)
return calendar
}
override fun getEndDate(): Calendar {
val endYear = if (now.monthValue > 6) now.year + 1 else now.year
val endOfSchoolYear = now.withYear(endYear).lastSchoolDay
val calendar = Calendar.getInstance()
calendar.set(endOfSchoolYear.year, endOfSchoolYear.monthValue - 1, endOfSchoolYear.dayOfMonth)
return calendar
}
override fun writeToParcel(parcel: Parcel, flags: Int) {}
override fun describeContents() = 0
companion object CREATOR : Parcelable.Creator<SchooldaysRangeLimiter> {
override fun createFromParcel(parcel: Parcel): SchooldaysRangeLimiter = SchooldaysRangeLimiter()
override fun newArray(size: Int): Array<SchooldaysRangeLimiter?> = arrayOfNulls(size)
}
}

View File

@ -0,0 +1,18 @@
package io.github.wulkanowy.utils
import com.google.android.material.datepicker.CalendarConstraints
import kotlinx.parcelize.Parcelize
import java.time.DayOfWeek
import java.time.temporal.ChronoUnit
@Parcelize
class SchoolDaysValidator(val start: Long, val end: Long) : CalendarConstraints.DateValidator {
override fun isValid(dateLong: Long): Boolean {
val date = dateLong.toLocalDateTime()
return date.until(end.toLocalDateTime(), ChronoUnit.DAYS) >= 0 &&
date.until(start.toLocalDateTime(), ChronoUnit.DAYS) <= 0 &&
date.dayOfWeek != DayOfWeek.SUNDAY
}
}

View File

@ -11,6 +11,7 @@ import java.time.LocalDate
import java.time.LocalDateTime import java.time.LocalDateTime
import java.time.LocalDateTime.now import java.time.LocalDateTime.now
import java.time.LocalDateTime.ofInstant import java.time.LocalDateTime.ofInstant
import java.time.LocalTime
import java.time.Month import java.time.Month
import java.time.ZoneId import java.time.ZoneId
import java.time.ZoneOffset import java.time.ZoneOffset
@ -22,15 +23,20 @@ import java.util.Locale
private const val DATE_PATTERN = "dd.MM.yyyy" private const val DATE_PATTERN = "dd.MM.yyyy"
fun String.toLocalDate(format: String = DATE_PATTERN): LocalDate = LocalDate.parse(this, ofPattern(format)) fun String.toLocalDate(format: String = DATE_PATTERN): LocalDate =
LocalDate.parse(this, ofPattern(format))
fun LocalDateTime.toTimestamp() = atZone(ZoneId.systemDefault()).withZoneSameInstant(ZoneOffset.UTC).toInstant().toEpochMilli() fun LocalDateTime.toTimestamp() =
atZone(ZoneId.systemDefault()).withZoneSameInstant(ZoneOffset.UTC).toInstant().toEpochMilli()
fun Long.toLocalDateTime(): LocalDateTime = ofInstant(ofEpochMilli(this), ZoneId.systemDefault()) fun Long.toLocalDateTime(): LocalDateTime = ofInstant(ofEpochMilli(this), ZoneId.systemDefault())
fun LocalDate.toTimestamp() = atTime(LocalTime.now()).toTimestamp()
fun LocalDate.toFormattedString(format: String = DATE_PATTERN): String = format(ofPattern(format)) fun LocalDate.toFormattedString(format: String = DATE_PATTERN): String = format(ofPattern(format))
fun LocalDateTime.toFormattedString(format: String = DATE_PATTERN): String = format(ofPattern(format)) fun LocalDateTime.toFormattedString(format: String = DATE_PATTERN): String =
format(ofPattern(format))
@SuppressLint("DefaultLocale") @SuppressLint("DefaultLocale")
fun Month.getFormattedName(): String { fun Month.getFormattedName(): String {
@ -105,6 +111,12 @@ inline val LocalDate.lastSchoolDay: LocalDate
get() = LocalDate.of(year, 6, 20) get() = LocalDate.of(year, 6, 20)
.with(next(FRIDAY)) .with(next(FRIDAY))
inline val LocalDate.schoolYearStart: LocalDate
get() = withYear(if (this.monthValue <= 6) this.year - 1 else this.year).firstSchoolDay
inline val LocalDate.schoolYearEnd: LocalDate
get() = withYear(if (this.monthValue > 6) this.year + 1 else this.year).lastSchoolDay
private fun Int.getSchoolYearByMonth(monthValue: Int): Int { private fun Int.getSchoolYearByMonth(monthValue: Int): Int {
return when (monthValue) { return when (monthValue) {
in 9..12 -> this in 9..12 -> this

View File

@ -14,7 +14,6 @@
<item name="android:statusBarColor">@color/colorStatusBarLight</item> <item name="android:statusBarColor">@color/colorStatusBarLight</item>
<item name="android:windowLightNavigationBar" tools:targetApi="o_mr1">false</item> <item name="android:windowLightNavigationBar" tools:targetApi="o_mr1">false</item>
<item name="android:windowLightStatusBar" tools:targetApi="m">false</item> <item name="android:windowLightStatusBar" tools:targetApi="m">false</item>
<item name="mdtp_theme_dark">true</item>
</style> </style>
<style name="WulkanowyTheme.Black" parent="WulkanowyTheme.NoActionBar"> <style name="WulkanowyTheme.Black" parent="WulkanowyTheme.NoActionBar">

View File

@ -14,7 +14,6 @@
<item name="android:statusBarColor">@android:color/darker_gray</item> <item name="android:statusBarColor">@android:color/darker_gray</item>
<item name="android:textColor">?android:textColorPrimary</item> <item name="android:textColor">?android:textColorPrimary</item>
<item name="android:preferenceStyle">@style/PreferenceThemeOverlay</item> <item name="android:preferenceStyle">@style/PreferenceThemeOverlay</item>
<item name="mdtp_theme_dark">false</item>
</style> </style>
<style name="WulkanowyTheme.NoActionBar" parent="WulkanowyTheme"> <style name="WulkanowyTheme.NoActionBar" parent="WulkanowyTheme">