Merge branch 'release/0.9.4'

This commit is contained in:
Mikołaj Pich 2019-08-12 23:17:57 +02:00
commit ba84f2be6e
22 changed files with 535 additions and 236 deletions

114
.gitignore vendored
View File

@ -1,39 +1,90 @@
/captures
.externalNativeBuild
## https://gist.github.com/iainconnor/8605514
# Created by https://www.gitignore.io
# Built application files
/build
/*/build/
*.apk
*.ap_
*.aab
# Crashlytics configuations
com_crashlytics_export_strings.xml
# Files for the ART/Dalvik VM
*.dex
# Java class files
*.class
# Generated files
bin/
gen/
out/
# Gradle files
.gradle/
build/
# Local configuration file (sdk path, etc)
local.properties
# Gradle generated files
.gradle/
# Proguard folder generated by Eclipse
proguard/
# Signing files
.signing/
# Log Files
*.log
# User-specific configurations
.idea/copyright/profiles_settings.xml
# Android Studio Navigation editor temp files
.navigation/
# Android Studio captures folder
captures/
# IntelliJ configurations
*.iml
.idea/workspace.xml
.idea/tasks.xml
.idea/gradle.xml
.idea/assetWizardSettings.xml
.idea/dictionaries
.idea/libraries
.idea/caches
.idea/modules.xml
.idea/navEditor.xml
.idea/caches/
.idea/libraries/
.idea/inspectionProfiles/
.idea/shelf/
.idea/.name
.idea/compiler.xml
.idea/copyright/profiles_settings.xml
.idea/encodings.xml
.idea/misc.xml
.idea/modules.xml
.idea/scopes/scope_settings.xml
.idea/tasks.xml
.idea/vcs.xml
.idea/workspace.xml
.idea/caches/
*.iml
.idea/jsLibraryMappings.xml
.idea/datasources.xml
.idea/dataSources.ids
.idea/sqlDataSources.xml
.idea/dynamic.xml
.idea/uiDesigner.xml
.idea/runConfigurations.xml
# Keystore files
*.jks
*.keystore
*.p12
# External native build folder generated in Android Studio 2.2 and later
.externalNativeBuild
# Version control
vcs.xml
# lint
lint/intermediates/
lint/generated/
lint/outputs/
lint/tmp/
lint/reports/
### Android Patch ###
gen-external-apklibs
output.json
# OS-specific files
.DS_Store
@ -43,9 +94,20 @@ local.properties
.Trashes
ehthumbs.db
Thumbs.db
.idea/caches/
app/key.p12
app/upload-key.jks
*.log
.idea/assetWizardSettings.xml
.idea/uiDesigner.xml
# Legacy Eclipse project files
.classpath
.project
.cproject
.settings/
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.war
*.ear
### AndroidStudio Patch ###
!/gradle/wrapper/gradle-wrapper.jar

View File

@ -21,6 +21,9 @@
<option name="CONTINUATION_INDENT_IN_ELVIS" value="false" />
<option name="WRAP_ELVIS_EXPRESSIONS" value="0" />
</JetCodeStyleSettings>
<MarkdownNavigatorCodeStyleSettings>
<option name="RIGHT_MARGIN" value="72" />
</MarkdownNavigatorCodeStyleSettings>
<XML>
<option name="XML_KEEP_LINE_BREAKS" value="false" />
<option name="XML_ALIGN_ATTRIBUTES" value="false" />

View File

@ -1,18 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
<option name="resolveModulePerSourceSet" value="false" />
</GradleProjectSettings>
</option>
</component>
</project>

View File

@ -14,7 +14,7 @@ cache:
branches:
only:
- develop
- 0.9.2
- 0.9.4
android:
licenses:

View File

@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2017 wulkanowy
Copyright 2019 Wulkanowy
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

61
README.en.md Normal file
View File

@ -0,0 +1,61 @@
[Polska wersja README](README.md)
# Wulkanowy
[![Travis](https://img.shields.io/travis/com/wulkanowy/wulkanowy/master.svg?style=flat-square)](https://travis-ci.com/wulkanowy/wulkanowy)
[![Codecov](https://img.shields.io/codecov/c/github/wulkanowy/wulkanowy/master.svg?style=flat-square)](https://codecov.io/gh/wulkanowy/wulkanowy)
[![Discord](https://img.shields.io/discord/390889354199040011.svg?style=flat-square)](https://discord.gg/vccAQBr)
[![F-Droid](https://img.shields.io/f-droid/v/io.github.wulkanowy.svg)](https://f-droid.org/packages/io.github.wulkanowy/)
[![Last release](https://img.shields.io/github/release/wulkanowy/wulkanowy.svg?logo=github)](https://github.com/wulkanowy/wulkanowy/releases)
Unofficial android VULCAN UONET+ register client for student and parent
## Features
* logging in using the email and password
* functions from the register website:
* grades
* grade statistics
* attendance
* percentage of attendance
* exams
* timetable
* completed lessons
* messages
* homework
* notes
* lucky number
* calculation of the average
* notifications, e.g. about a new grade
* dark and black (AMOLED) theme
* offline mode
* no ads
## Download
You can download the current beta from the Google Play or Fdroid store
[<img src="https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png"
alt="Get it on Google Play"
height="80">](https://play.google.com/store/apps/details?id=io.github.wulkanowy)
[<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png"
alt="Get it on Fdroid"
height="80">](https://f-droid.org/packages/io.github.wulkanowy/)
You can also download a [development version](https://wulkanowy.github.io/#download) that includes new features prepared for the next release
## Built With
* [Wulkanowy API](https://github.com/wulkanowy/api)
* [RxJava 2](https://github.com/ReactiveX/RxJava)
* [Dagger 2](https://github.com/google/dagger)
* [Room](https://developer.android.com/topic/libraries/architecture/room)
* [WorkManager](https://developer.android.com/topic/libraries/architecture/workmanager)
## Contributing
Please contribute to the project either by creating a PR or submitting an issue on GitHub.
## License
This project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details

View File

@ -1,23 +1,62 @@
# Wulkanowy
[English version of README](README.en.md)
# Wulkanowy
[![Travis](https://img.shields.io/travis/com/wulkanowy/wulkanowy/master.svg?style=flat-square)](https://travis-ci.com/wulkanowy/wulkanowy)
[![Bitrise](https://img.shields.io/bitrise/daeff1893f3c8128/master.svg?token=Hjm1ACamk86JDeVVJHOeqQ&style=flat-square)](https://www.bitrise.io/app/daeff1893f3c8128)
[![Codecov](https://img.shields.io/codecov/c/github/wulkanowy/wulkanowy/master.svg?style=flat-square)](https://codecov.io/gh/wulkanowy/wulkanowy)
[![BCH compliance](https://bettercodehub.com/edge/badge/wulkanowy/wulkanowy?branch=master)](https://bettercodehub.com/)
[![Sonarcloud](https://sonarcloud.io/api/project_badges/measure?project=io.github.wulkanowy%3Aapp&metric=sqale_rating)](https://sonarcloud.io/dashboard?id=io.github.wulkanowy%3Aapp)
[![FOSSA Status](https://app.fossa.com/api/projects/custom%2B5644%2Fgithub.com%2Fwulkanowy%2Fwulkanowy.svg?type=shield)](https://app.fossa.com/projects/custom%2B5644%2Fgithub.com%2Fwulkanowy%2Fwulkanowy?ref=badge_shield)
[![Discord](https://img.shields.io/discord/390889354199040011.svg?style=flat-square)](https://discord.gg/vccAQBr)
[![F-Droid](https://img.shields.io/f-droid/v/io.github.wulkanowy.svg)](https://f-droid.org/packages/io.github.wulkanowy/)
[![Last release](https://img.shields.io/github/release/wulkanowy/wulkanowy.svg?logo=github)](https://github.com/wulkanowy/wulkanowy/releases)
[Pobierz wersję beta z Google Play](https://play.google.com/store/apps/details?id=io.github.wulkanowy&amp;utm_source=vcs)
Nieoficjalny klient dziennika VULCAN UONET+ dla ucznia i rodzica
[Pobierz wersję DEV](https://bitrise-redirector.herokuapp.com/v0.1/apps/f841f20d8f8b1dc8/builds/master/artifacts/0)
[(Więcej wersji DEV)](https://wulkanowy.github.io/dev.html)
## Funkcje
Androidowy klient dziennika VULCAN UONET+.
* logowanie za pomocą e-maila i hasła
* funkcje ze strony internetowej dziennika:
* oceny
* statystyki ocen
* frekwencja
* procent frekwencji
* sprawdziany
* plan lekcji
* lekcje zrealizowane
* wiadomości
* zadania domowe
* uwagi
* szczęśliwy numerek
* obliczanie średniej
* powiadomienia np. o nowej ocenie
* ciemny i czarny (AMOLED) motyw
* tryb offilne
* brak reklam
## Pobierz
Aktualną wersję beta możesz pobrać ze sklepu Google Play lub Fdroid
[<img src="https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png"
alt="Pobierz z Google Play"
height="80">](https://play.google.com/store/apps/details?id=io.github.wulkanowy)
[<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png"
alt="Pobierz z Fdroid"
height="80">](https://f-droid.org/packages/io.github.wulkanowy/)
## License
Możesz także pobrać [wersję rozwojową](https://wulkanowy.github.io/#download), która zawiera nowe funkcje przygotowywane do następnego wydania
[![FOSSA Status](https://app.fossa.com/api/projects/custom%2B5644%2Fgithub.com%2Fwulkanowy%2Fwulkanowy.svg?type=large)](https://app.fossa.com/projects/custom%2B5644%2Fgithub.com%2Fwulkanowy%2Fwulkanowy?ref=badge_large)
## Zbudowana za pomocą
* [Wulkanowy API](https://github.com/wulkanowy/api)
* [RxJava 2](https://github.com/ReactiveX/RxJava)
* [Dagger 2](https://github.com/google/dagger)
* [Room](https://developer.android.com/topic/libraries/architecture/room)
* [WorkManager](https://developer.android.com/topic/libraries/architecture/workmanager)
## Współpraca
Wnieś swój wkład w projekt, tworząc PR lub wysyłając issue na GitHub.
## Licencja
Ten projekt jest licencjonowany w ramach Apache License 2.0 - szczegóły w pliku [LICENSE](LICENSE)

1
app/.gitignore vendored
View File

@ -1 +0,0 @@
/build

View File

@ -15,10 +15,10 @@ android {
defaultConfig {
applicationId "io.github.wulkanowy"
testApplicationId "io.github.tests.wulkanowy"
minSdkVersion 15
minSdkVersion 16
targetSdkVersion 28
versionCode 41
versionName "0.9.3"
versionCode 42
versionName "0.9.4"
multiDexEnabled true
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
@ -97,8 +97,17 @@ play {
track = 'alpha'
}
ext {
work_manager = "2.1.0"
room = "2.1.0"
dagger = "2.24"
chucker = "2.0.4"
mockk = "1.9.2"
mockito_core = "3.0.4"
}
dependencies {
implementation "io.github.wulkanowy:api:0.9.3"
implementation "io.github.wulkanowy:api:0.9.4"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation "androidx.core:core:1.0.2"
@ -116,27 +125,27 @@ dependencies {
implementation "com.github.wulkanowy:MaterialChipsInput:b72fd0ee6f"
implementation "com.github.PhilJay:MPAndroidChart:v3.1.0"
implementation "androidx.work:work-runtime:2.0.1"
implementation "androidx.work:work-rxjava2:2.0.1"
implementation "androidx.work:work-runtime:$work_manager"
implementation "androidx.work:work-rxjava2:$work_manager"
implementation "androidx.room:room-runtime:2.1.0"
implementation "androidx.room:room-rxjava2:2.1.0"
kapt "androidx.room:room-compiler:2.1.0"
implementation "androidx.room:room-runtime:$room"
implementation "androidx.room:room-rxjava2:$room"
kapt "androidx.room:room-compiler:$room"
implementation "com.google.dagger:dagger-android-support:2.23.1"
kapt "com.google.dagger:dagger-compiler:2.23.1"
kapt "com.google.dagger:dagger-android-processor:2.23.1"
implementation "com.squareup.inject:assisted-inject-annotations-dagger2:0.4.0"
kapt "com.squareup.inject:assisted-inject-processor-dagger2:0.4.0"
implementation "com.google.dagger:dagger-android-support:$dagger"
kapt "com.google.dagger:dagger-compiler:$dagger"
kapt "com.google.dagger:dagger-android-processor:$dagger"
implementation "com.squareup.inject:assisted-inject-annotations-dagger2:0.5.0"
kapt "com.squareup.inject:assisted-inject-processor-dagger2:0.5.0"
implementation "eu.davidea:flexible-adapter:5.1.0"
implementation "eu.davidea:flexible-adapter-ui:1.0.0"
implementation "com.aurelhubert:ahbottomnavigation:2.3.4"
implementation "com.ncapdevi:frag-nav:3.2.0"
implementation "com.ncapdevi:frag-nav:3.3.0"
implementation "com.github.pwittchen:reactivenetwork-rx2:3.0.3"
implementation "com.github.pwittchen:reactivenetwork-rx2:3.0.4"
implementation "io.reactivex.rxjava2:rxandroid:2.1.1"
implementation "io.reactivex.rxjava2:rxjava:2.2.9"
implementation "io.reactivex.rxjava2:rxjava:2.2.11"
implementation "com.google.code.gson:gson:2.8.5"
implementation "com.jakewharton.threetenabp:threetenabp:1.2.1"
@ -147,30 +156,30 @@ dependencies {
implementation "com.mikepenz:aboutlibraries:6.2.3"
implementation "com.takisoft.preferencex:preferencex:1.0.0"
playImplementation "com.google.firebase:firebase-core:16.0.9"
playImplementation "com.google.firebase:firebase-core:17.0.1"
playImplementation "com.crashlytics.sdk.android:crashlytics:2.10.1"
releaseImplementation "fr.o80.chucker:library-no-op:2.0.4"
releaseImplementation "fr.o80.chucker:library-no-op:$chucker"
debugImplementation "fr.o80.chucker:library:2.0.4"
debugImplementation "fr.o80.chucker:library:$chucker"
debugImplementation "com.amitshekhar.android:debug-db:1.0.6"
testImplementation "junit:junit:4.12"
testImplementation "io.mockk:mockk:1.9.2"
testImplementation "io.mockk:mockk:$mockk"
testImplementation "org.threeten:threetenbp:1.4.0"
testImplementation "org.mockito:mockito-core:2.28.2"
testImplementation("org.mockito:mockito-inline:2.28.2") {
testImplementation "org.mockito:mockito-core:$mockito_core"
testImplementation("org.mockito:mockito-inline:3.0.4") {
exclude group: "org.mockito", module: "mockito-core"
}
androidTestImplementation "androidx.test:core:1.2.0"
androidTestImplementation "androidx.test:runner:1.2.0"
androidTestImplementation "androidx.test.ext:junit:1.1.1"
androidTestImplementation "io.mockk:mockk-android:1.9.2"
androidTestImplementation "androidx.room:room-testing:2.1.0"
androidTestImplementation "io.mockk:mockk-android:$mockk"
androidTestImplementation "androidx.room:room-testing:$room"
androidTestImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
androidTestImplementation "org.mockito:mockito-core:2.28.2"
androidTestImplementation("org.mockito:mockito-android:2.28.2") {
androidTestImplementation "org.mockito:mockito-core:$mockito_core"
androidTestImplementation("org.mockito:mockito-android:3.0.4") {
exclude group: 'org.mockito', module: 'mockito-core'
}
}

Binary file not shown.

View File

@ -4,8 +4,6 @@
package="io.github.wulkanowy"
android:installLocation="internalOnly">
<uses-sdk tools:overrideLibrary="com.readystatesoftware.chuck" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

View File

@ -8,22 +8,20 @@ import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
import androidx.fragment.app.Fragment
import com.google.android.material.snackbar.Snackbar
import com.google.android.material.snackbar.Snackbar.LENGTH_LONG
import dagger.android.AndroidInjection
import dagger.android.DispatchingAndroidInjector
import dagger.android.support.HasSupportFragmentInjector
import dagger.android.HasAndroidInjector
import io.github.wulkanowy.R
import io.github.wulkanowy.ui.modules.login.LoginActivity
import io.github.wulkanowy.utils.FragmentLifecycleLogger
import javax.inject.Inject
abstract class BaseActivity<T : BasePresenter<out BaseView>> : AppCompatActivity(), BaseView,
HasSupportFragmentInjector {
abstract class BaseActivity<T : BasePresenter<out BaseView>> : AppCompatActivity(), BaseView, HasAndroidInjector {
@Inject
lateinit var supportFragmentInjector: DispatchingAndroidInjector<Fragment>
lateinit var androidInjector: DispatchingAndroidInjector<Any>
@Inject
lateinit var fragmentLifecycleLogger: FragmentLifecycleLogger
@ -78,5 +76,5 @@ abstract class BaseActivity<T : BasePresenter<out BaseView>> : AppCompatActivity
presenter.onDetachView()
}
override fun supportFragmentInjector() = supportFragmentInjector
override fun androidInjector() = androidInjector
}

View File

@ -8,7 +8,13 @@ import io.github.wulkanowy.data.repositories.student.StudentRepository
import io.github.wulkanowy.ui.base.BasePresenter
import io.github.wulkanowy.ui.base.ErrorHandler
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
import io.github.wulkanowy.utils.*
import io.github.wulkanowy.utils.SchedulersProvider
import io.github.wulkanowy.utils.getLastSchoolDayIfHoliday
import io.github.wulkanowy.utils.isHolidays
import io.github.wulkanowy.utils.nextSchoolDay
import io.github.wulkanowy.utils.previousOrSameSchoolDay
import io.github.wulkanowy.utils.previousSchoolDay
import io.github.wulkanowy.utils.toFormattedString
import org.threeten.bp.LocalDate
import org.threeten.bp.LocalDate.now
import org.threeten.bp.LocalDate.ofEpochDay
@ -26,6 +32,8 @@ class AttendancePresenter @Inject constructor(
private val analytics: FirebaseAnalyticsHelper
) : BasePresenter<AttendanceView>(errorHandler, studentRepository, schedulers) {
private var baseDate: LocalDate = now().previousOrSameSchoolDay
lateinit var currentDate: LocalDate
private set
@ -33,7 +41,8 @@ class AttendancePresenter @Inject constructor(
super.onAttachView(view)
view.initView()
Timber.i("Attendance view was initialized")
loadData(ofEpochDay(date ?: now().previousOrSameSchoolDay.toEpochDay()))
loadData(ofEpochDay(date ?: baseDate.toEpochDay()))
if (currentDate.isHolidays) setBaseDateOnHolidays()
reloadView()
}
@ -56,7 +65,7 @@ class AttendancePresenter @Inject constructor(
Timber.i("Attendance view is reselected")
view?.also { view ->
if (view.currentStackSize == 1) {
now().previousOrSameSchoolDay.also {
baseDate.also {
if (currentDate != it) {
loadData(it)
reloadView()
@ -78,6 +87,20 @@ class AttendancePresenter @Inject constructor(
return true
}
private fun setBaseDateOnHolidays() {
disposable.add(studentRepository.getCurrentStudent()
.flatMap { semesterRepository.getCurrentSemester(it) }
.subscribeOn(schedulers.backgroundThread)
.observeOn(schedulers.mainThread)
.subscribe({
baseDate = baseDate.getLastSchoolDayIfHoliday(it.schoolYear)
currentDate = baseDate
reloadNavigation()
}) {
Timber.i("Loading semester result: An exception occurred")
})
}
private fun loadData(date: LocalDate, forceRefresh: Boolean = false) {
Timber.i("Loading attendance data started")
currentDate = date
@ -127,8 +150,14 @@ class AttendancePresenter @Inject constructor(
showContent(false)
showEmpty(false)
clearData()
showNextButton(!currentDate.plusDays(1).isHolidays)
reloadNavigation()
}
}
private fun reloadNavigation() {
view?.apply {
showPreButton(!currentDate.minusDays(1).isHolidays)
showNextButton(!currentDate.plusDays(1).isHolidays)
updateNavigationDay(currentDate.toFormattedString("EEEE\ndd.MM.YYYY").capitalize())
}
}

View File

@ -10,6 +10,7 @@ import io.github.wulkanowy.ui.base.ErrorHandler
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
import io.github.wulkanowy.utils.SchedulersProvider
import io.github.wulkanowy.utils.friday
import io.github.wulkanowy.utils.getLastSchoolDayIfHoliday
import io.github.wulkanowy.utils.isHolidays
import io.github.wulkanowy.utils.monday
import io.github.wulkanowy.utils.nextOrSameSchoolDay
@ -30,6 +31,8 @@ class ExamPresenter @Inject constructor(
private val analytics: FirebaseAnalyticsHelper
) : BasePresenter<ExamView>(errorHandler, studentRepository, schedulers) {
private var baseDate: LocalDate = now().nextOrSameSchoolDay
lateinit var currentDate: LocalDate
private set
@ -37,7 +40,8 @@ class ExamPresenter @Inject constructor(
super.onAttachView(view)
view.initView()
Timber.i("Exam view was initialized")
loadData(ofEpochDay(date ?: now().nextOrSameSchoolDay.toEpochDay()))
loadData(ofEpochDay(date ?: baseDate.toEpochDay()))
if (currentDate.isHolidays) setBaseDateOnHolidays()
reloadView()
}
@ -65,7 +69,7 @@ class ExamPresenter @Inject constructor(
fun onViewReselected() {
Timber.i("Exam view is reselected")
now().nextOrSameSchoolDay.also {
baseDate.also {
if (currentDate != it) {
loadData(it)
reloadView()
@ -73,6 +77,20 @@ class ExamPresenter @Inject constructor(
}
}
private fun setBaseDateOnHolidays() {
disposable.add(studentRepository.getCurrentStudent()
.flatMap { semesterRepository.getCurrentSemester(it) }
.subscribeOn(schedulers.backgroundThread)
.observeOn(schedulers.mainThread)
.subscribe({
baseDate = baseDate.getLastSchoolDayIfHoliday(it.schoolYear)
currentDate = baseDate
reloadNavigation()
}) {
Timber.i("Loading semester result: An exception occurred")
})
}
private fun loadData(date: LocalDate, forceRefresh: Boolean = false) {
Timber.i("Loading exam data started")
currentDate = date
@ -81,9 +99,8 @@ class ExamPresenter @Inject constructor(
add(studentRepository.getCurrentStudent()
.delay(200, MILLISECONDS)
.flatMap { semesterRepository.getCurrentSemester(it) }
.flatMap {
examRepository.getExams(it, currentDate.monday, currentDate.friday, forceRefresh)
}.map { it.groupBy { exam -> exam.date }.toSortedMap() }
.flatMap { examRepository.getExams(it, currentDate.monday, currentDate.friday, forceRefresh) }
.map { it.groupBy { exam -> exam.date }.toSortedMap() }
.map { createExamItems(it) }
.subscribeOn(schedulers.backgroundThread)
.observeOn(schedulers.mainThread)
@ -126,6 +143,12 @@ class ExamPresenter @Inject constructor(
showContent(false)
showEmpty(false)
clearData()
reloadNavigation()
}
}
private fun reloadNavigation() {
view?.apply {
showPreButton(!currentDate.minusDays(7).isHolidays)
showNextButton(!currentDate.plusDays(7).isHolidays)
updateNavigationWeek("${currentDate.monday.toFormattedString("dd.MM")} - " +

View File

@ -10,11 +10,13 @@ import io.github.wulkanowy.ui.base.ErrorHandler
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
import io.github.wulkanowy.utils.SchedulersProvider
import io.github.wulkanowy.utils.friday
import io.github.wulkanowy.utils.getLastSchoolDayIfHoliday
import io.github.wulkanowy.utils.isHolidays
import io.github.wulkanowy.utils.monday
import io.github.wulkanowy.utils.nextOrSameSchoolDay
import io.github.wulkanowy.utils.toFormattedString
import org.threeten.bp.LocalDate
import org.threeten.bp.LocalDate.ofEpochDay
import timber.log.Timber
import java.util.concurrent.TimeUnit
import javax.inject.Inject
@ -28,6 +30,8 @@ class HomeworkPresenter @Inject constructor(
private val analytics: FirebaseAnalyticsHelper
) : BasePresenter<HomeworkView>(errorHandler, studentRepository, schedulers) {
private var baseDate: LocalDate = LocalDate.now().nextOrSameSchoolDay
lateinit var currentDate: LocalDate
private set
@ -35,7 +39,8 @@ class HomeworkPresenter @Inject constructor(
super.onAttachView(view)
view.initView()
Timber.i("Homework view was initialized")
loadData(LocalDate.ofEpochDay(date ?: LocalDate.now().nextOrSameSchoolDay.toEpochDay()))
loadData(ofEpochDay(date ?: baseDate.toEpochDay()))
if (currentDate.isHolidays) setBaseDateOnHolidays()
reloadView()
}
@ -61,6 +66,20 @@ class HomeworkPresenter @Inject constructor(
}
}
private fun setBaseDateOnHolidays() {
disposable.add(studentRepository.getCurrentStudent()
.flatMap { semesterRepository.getCurrentSemester(it) }
.subscribeOn(schedulers.backgroundThread)
.observeOn(schedulers.mainThread)
.subscribe({
baseDate = baseDate.getLastSchoolDayIfHoliday(it.schoolYear)
currentDate = baseDate
reloadNavigation()
}) {
Timber.i("Loading semester result: An exception occurred")
})
}
private fun loadData(date: LocalDate, forceRefresh: Boolean = false) {
Timber.i("Loading homework data started")
currentDate = date
@ -113,8 +132,14 @@ class HomeworkPresenter @Inject constructor(
showContent(false)
showEmpty(false)
clearData()
showNextButton(!currentDate.plusDays(7).isHolidays)
reloadNavigation()
}
}
private fun reloadNavigation() {
view?.apply {
showPreButton(!currentDate.minusDays(7).isHolidays)
showNextButton(!currentDate.plusDays(7).isHolidays)
updateNavigationWeek("${currentDate.monday.toFormattedString("dd.MM")} - " +
currentDate.friday.toFormattedString("dd.MM"))
}

View File

@ -8,6 +8,7 @@ import io.github.wulkanowy.ui.base.BasePresenter
import io.github.wulkanowy.ui.base.ErrorHandler
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
import io.github.wulkanowy.utils.SchedulersProvider
import io.github.wulkanowy.utils.getLastSchoolDayIfHoliday
import io.github.wulkanowy.utils.isHolidays
import io.github.wulkanowy.utils.nextOrSameSchoolDay
import io.github.wulkanowy.utils.nextSchoolDay
@ -29,6 +30,8 @@ class TimetablePresenter @Inject constructor(
private val analytics: FirebaseAnalyticsHelper
) : BasePresenter<TimetableView>(errorHandler, studentRepository, schedulers) {
private var baseDate: LocalDate = now().nextOrSameSchoolDay
lateinit var currentDate: LocalDate
private set
@ -36,7 +39,8 @@ class TimetablePresenter @Inject constructor(
super.onAttachView(view)
view.initView()
Timber.i("Timetable was initialized")
loadData(ofEpochDay(date ?: now().nextOrSameSchoolDay.toEpochDay()))
loadData(ofEpochDay(date ?: baseDate.toEpochDay()))
if (currentDate.isHolidays) setBaseDateOnHolidays()
reloadView()
}
@ -59,7 +63,7 @@ class TimetablePresenter @Inject constructor(
Timber.i("Timetable view is reselected")
view?.also { view ->
if (view.currentStackSize == 1) {
now().nextOrSameSchoolDay.also {
baseDate.also {
if (currentDate != it) {
loadData(it)
reloadView()
@ -81,6 +85,20 @@ class TimetablePresenter @Inject constructor(
return true
}
private fun setBaseDateOnHolidays() {
disposable.add(studentRepository.getCurrentStudent()
.flatMap { semesterRepository.getCurrentSemester(it) }
.subscribeOn(schedulers.backgroundThread)
.observeOn(schedulers.mainThread)
.subscribe({
baseDate = baseDate.getLastSchoolDayIfHoliday(it.schoolYear)
currentDate = baseDate
reloadNavigation()
}) {
Timber.i("Loading semester result: An exception occurred")
})
}
private fun loadData(date: LocalDate, forceRefresh: Boolean = false) {
Timber.i("Loading timetable data started")
currentDate = date
@ -125,8 +143,14 @@ class TimetablePresenter @Inject constructor(
showContent(false)
showEmpty(false)
clearData()
showNextButton(!currentDate.plusDays(1).isHolidays)
reloadNavigation()
}
}
private fun reloadNavigation() {
view?.apply {
showPreButton(!currentDate.minusDays(1).isHolidays)
showNextButton(!currentDate.plusDays(1).isHolidays)
updateNavigationDay(currentDate.toFormattedString("EEEE\ndd.MM.YYYY").capitalize())
}
}

View File

@ -7,6 +7,7 @@ import io.github.wulkanowy.data.repositories.student.StudentRepository
import io.github.wulkanowy.ui.base.BasePresenter
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
import io.github.wulkanowy.utils.SchedulersProvider
import io.github.wulkanowy.utils.getLastSchoolDayIfHoliday
import io.github.wulkanowy.utils.isHolidays
import io.github.wulkanowy.utils.nextOrSameSchoolDay
import io.github.wulkanowy.utils.nextSchoolDay
@ -28,6 +29,8 @@ class CompletedLessonsPresenter @Inject constructor(
private val analytics: FirebaseAnalyticsHelper
) : BasePresenter<CompletedLessonsView>(completedLessonsErrorHandler, studentRepository, schedulers) {
private var baseDate: LocalDate = now().nextOrSameSchoolDay
lateinit var currentDate: LocalDate
private set
@ -35,7 +38,8 @@ class CompletedLessonsPresenter @Inject constructor(
super.onAttachView(view)
Timber.i("Completed lessons is attached")
view.initView()
loadData(ofEpochDay(date ?: now().nextOrSameSchoolDay.toEpochDay()))
loadData(ofEpochDay(date ?: baseDate.toEpochDay()))
if (currentDate.isHolidays) setBaseDateOnHolidays()
reloadView()
completedLessonsErrorHandler.onFeatureDisabled = {
this.view?.showFeatureDisabled()
@ -65,6 +69,20 @@ class CompletedLessonsPresenter @Inject constructor(
}
}
private fun setBaseDateOnHolidays() {
disposable.add(studentRepository.getCurrentStudent()
.flatMap { semesterRepository.getCurrentSemester(it) }
.subscribeOn(schedulers.backgroundThread)
.observeOn(schedulers.mainThread)
.subscribe({
baseDate = baseDate.getLastSchoolDayIfHoliday(it.schoolYear)
currentDate = baseDate
reloadNavigation()
}) {
Timber.i("Loading semester result: An exception occurred")
})
}
private fun loadData(date: LocalDate, forceRefresh: Boolean = false) {
Timber.i("Loading completed lessons data started")
currentDate = date
@ -109,8 +127,14 @@ class CompletedLessonsPresenter @Inject constructor(
showContent(false)
showEmpty(false)
clearData()
showNextButton(!currentDate.plusDays(1).isHolidays)
reloadNavigation()
}
}
private fun reloadNavigation() {
view?.apply {
showPreButton(!currentDate.minusDays(1).isHolidays)
showNextButton(!currentDate.plusDays(1).isHolidays)
updateNavigationDay(currentDate.toFormattedString("EEEE\ndd.MM.YYYY").capitalize())
}
}

View File

@ -6,11 +6,11 @@ import org.threeten.bp.DayOfWeek.MONDAY
import org.threeten.bp.DayOfWeek.SATURDAY
import org.threeten.bp.DayOfWeek.SUNDAY
import org.threeten.bp.Instant
import org.threeten.bp.Instant.ofEpochMilli
import org.threeten.bp.LocalDate
import org.threeten.bp.LocalDateTime
import org.threeten.bp.Month
import org.threeten.bp.ZoneId
import org.threeten.bp.format.DateTimeFormatter
import org.threeten.bp.format.DateTimeFormatter.ofPattern
import org.threeten.bp.format.TextStyle.FULL_STANDALONE
import org.threeten.bp.temporal.TemporalAdjusters.firstInMonth
@ -21,21 +21,15 @@ import java.util.Locale
private const val DATE_PATTERN = "dd.MM.yyyy"
fun Date.toLocalDate(): LocalDate {
return Instant.ofEpochMilli(this.time).atZone(ZoneId.systemDefault()).toLocalDate()
}
fun Date.toLocalDate(): LocalDate = Instant.ofEpochMilli(time).atZone(ZoneId.systemDefault()).toLocalDate()
fun Date.toLocalDateTime(): LocalDateTime {
return Instant.ofEpochMilli(this.time).atZone(ZoneId.systemDefault()).toLocalDateTime()
}
fun Date.toLocalDateTime(): LocalDateTime = ofEpochMilli(time).atZone(ZoneId.systemDefault()).toLocalDateTime()
fun String.toLocalDate(format: String = DATE_PATTERN): LocalDate {
return LocalDate.parse(this, DateTimeFormatter.ofPattern(format))
}
fun String.toLocalDate(format: String = DATE_PATTERN): LocalDate = LocalDate.parse(this, ofPattern(format))
fun LocalDate.toFormattedString(format: String = DATE_PATTERN): String = this.format(ofPattern(format))
fun LocalDate.toFormattedString(format: String = DATE_PATTERN): String = format(ofPattern(format))
fun LocalDateTime.toFormattedString(format: String = DATE_PATTERN): String = this.format(ofPattern(format))
fun LocalDateTime.toFormattedString(format: String = DATE_PATTERN): String = format(ofPattern(format))
fun LocalDateTime.toDate(): Date = DateTimeUtils.toDate(atZone(ZoneId.systemDefault()).toInstant())
@ -66,62 +60,81 @@ fun Month.getFormattedName(): String {
inline val LocalDate.nextSchoolDay: LocalDate
get() {
return when (this.dayOfWeek) {
FRIDAY, SATURDAY, SUNDAY -> this.with(next(MONDAY))
else -> this.plusDays(1)
return when (dayOfWeek) {
FRIDAY, SATURDAY, SUNDAY -> with(next(MONDAY))
else -> plusDays(1)
}
}
inline val LocalDate.previousSchoolDay: LocalDate
get() {
return when (this.dayOfWeek) {
SATURDAY, SUNDAY, MONDAY -> this.with(previous(FRIDAY))
else -> this.minusDays(1)
return when (dayOfWeek) {
SATURDAY, SUNDAY, MONDAY -> with(previous(FRIDAY))
else -> minusDays(1)
}
}
inline val LocalDate.nextOrSameSchoolDay: LocalDate
get() {
return when (this.dayOfWeek) {
SATURDAY, SUNDAY -> this.with(next(MONDAY))
return when (dayOfWeek) {
SATURDAY, SUNDAY -> with(next(MONDAY))
else -> this
}
}
inline val LocalDate.previousOrSameSchoolDay: LocalDate
get() {
return when (this.dayOfWeek) {
SATURDAY, SUNDAY -> this.with(previous(FRIDAY))
return when (dayOfWeek) {
SATURDAY, SUNDAY -> with(previous(FRIDAY))
else -> this
}
}
inline val LocalDate.weekDayName: String
get() = this.format(ofPattern("EEEE", Locale.getDefault()))
get() = format(ofPattern("EEEE", Locale.getDefault()))
inline val LocalDate.shortcutWeekDayName: String
get() = this.format(ofPattern("EEE", Locale.getDefault()))
get() = format(ofPattern("EEE", Locale.getDefault()))
inline val LocalDate.monday: LocalDate
get() = this.with(MONDAY)
get() = with(MONDAY)
inline val LocalDate.friday: LocalDate
get() = this.with(FRIDAY)
get() = with(FRIDAY)
/**
* [Dz.U. 2016 poz. 1335](http://prawo.sejm.gov.pl/isap.nsf/DocDetails.xsp?id=WDU20160001335)
*/
inline val LocalDate.isHolidays: Boolean
get() {
return LocalDate.of(this.year, 9, 1).run {
when (dayOfWeek) {
FRIDAY, SATURDAY, SUNDAY -> with(firstInMonth(MONDAY))
else -> this
}
}.let { firstSchoolDay ->
LocalDate.of(this.year, 6, 20)
.with(next(FRIDAY))
.let { lastSchoolDay -> this.isBefore(firstSchoolDay) && this.isAfter(lastSchoolDay) }
get() = isBefore(firstSchoolDay) && isAfter(lastSchoolDay)
inline val LocalDate.firstSchoolDay: LocalDate
get() = LocalDate.of(year, 9, 1).run {
when (dayOfWeek) {
FRIDAY, SATURDAY, SUNDAY -> with(firstInMonth(MONDAY))
else -> this
}
}
inline val LocalDate.lastSchoolDay: LocalDate
get() = LocalDate.of(year, 6, 20)
.with(next(FRIDAY))
private fun Int.getSchoolYearByMonth(monthValue: Int): Int {
return when (monthValue) {
in 9..12 -> this
else -> this + 1
}
}
fun LocalDate.getLastSchoolDayIfHoliday(schoolYear: Int): LocalDate {
val date = LocalDate.of(schoolYear.getSchoolYearByMonth(monthValue), monthValue, dayOfMonth)
if (date.isHolidays) {
return date.lastSchoolDay
}
return date
}

View File

@ -1,8 +1,6 @@
Wersja 0.9.3
Wersja 0.9.4
Naprawiliśmy:
- problemy z logowaniem jeśli symbol zawierał cyfry
- bardzo rzadkie problemy z ładowaniem ocen
- jeszcze rzadsze problemy ze stabilnością podczas logowania
- naprawienie nawigacji we frekwencji, sprawdzianach, planie lekcji na wakacjach
- wyświetlanie szczęśliwego numerka po ostatniej aktualizacji dziennika VULCAN (19.06)
Pełna lista zmian: https://github.com/wulkanowy/wulkanowy/releases

View File

@ -4,7 +4,7 @@ import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Test
import org.threeten.bp.LocalDate
import org.threeten.bp.LocalDate.of
import org.threeten.bp.LocalDateTime
import org.threeten.bp.Month.JANUARY
import java.util.Locale
@ -13,13 +13,13 @@ class TimeExtensionTest {
@Test
fun toLocalDateTest() {
assertEquals(LocalDate.of(1970, 1, 1), "1970-01-01".toLocalDate("yyyy-MM-dd"))
assertEquals(of(1970, 1, 1), "1970-01-01".toLocalDate("yyyy-MM-dd"))
}
@Test
fun toFormattedStringLocalDateTest() {
assertEquals("01.10.2018", LocalDate.of(2018, 10, 1).toFormattedString())
assertEquals("2018-10.01", LocalDate.of(2018, 10, 1).toFormattedString("yyyy-MM.dd"))
assertEquals("01.10.2018", of(2018, 10, 1).toFormattedString())
assertEquals("2018-10.01", of(2018, 10, 1).toFormattedString("yyyy-MM.dd"))
}
@Test
@ -30,20 +30,20 @@ class TimeExtensionTest {
@Test
fun mondayTest() {
assertEquals(LocalDate.of(2018, 10, 1), LocalDate.of(2018, 10, 2).monday)
assertEquals(LocalDate.of(2018, 10, 1), LocalDate.of(2018, 10, 5).monday)
assertEquals(LocalDate.of(2018, 10, 1), LocalDate.of(2018, 10, 6).monday)
assertEquals(LocalDate.of(2018, 10, 1), LocalDate.of(2018, 10, 7).monday)
assertEquals(LocalDate.of(2018, 10, 8), LocalDate.of(2018, 10, 8).monday)
assertEquals(of(2018, 10, 1), of(2018, 10, 2).monday)
assertEquals(of(2018, 10, 1), of(2018, 10, 5).monday)
assertEquals(of(2018, 10, 1), of(2018, 10, 6).monday)
assertEquals(of(2018, 10, 1), of(2018, 10, 7).monday)
assertEquals(of(2018, 10, 8), of(2018, 10, 8).monday)
}
@Test
fun fridayTest() {
assertEquals(LocalDate.of(2018, 10, 5), LocalDate.of(2018, 10, 2).friday)
assertEquals(LocalDate.of(2018, 10, 5), LocalDate.of(2018, 10, 5).friday)
assertEquals(LocalDate.of(2018, 10, 5), LocalDate.of(2018, 10, 6).friday)
assertEquals(LocalDate.of(2018, 10, 5), LocalDate.of(2018, 10, 7).friday)
assertEquals(LocalDate.of(2018, 10, 12), LocalDate.of(2018, 10, 8).friday)
assertEquals(of(2018, 10, 5), of(2018, 10, 2).friday)
assertEquals(of(2018, 10, 5), of(2018, 10, 5).friday)
assertEquals(of(2018, 10, 5), of(2018, 10, 6).friday)
assertEquals(of(2018, 10, 5), of(2018, 10, 7).friday)
assertEquals(of(2018, 10, 12), of(2018, 10, 8).friday)
}
@Test
@ -57,106 +57,118 @@ class TimeExtensionTest {
@Test
fun weekDayNameTest() {
Locale.setDefault(Locale.forLanguageTag("PL"))
assertEquals("poniedziałek", LocalDate.of(2018, 10, 1).weekDayName)
assertEquals("poniedziałek", of(2018, 10, 1).weekDayName)
Locale.setDefault(Locale.forLanguageTag("US"))
assertEquals("Monday", LocalDate.of(2018, 10, 1).weekDayName)
assertEquals("Monday", of(2018, 10, 1).weekDayName)
}
@Test
fun nextSchoolDayTest() {
assertEquals(LocalDate.of(2018, 10, 2), LocalDate.of(2018, 10, 1).nextSchoolDay)
assertEquals(LocalDate.of(2018, 10, 3), LocalDate.of(2018, 10, 2).nextSchoolDay)
assertEquals(LocalDate.of(2018, 10, 4), LocalDate.of(2018, 10, 3).nextSchoolDay)
assertEquals(LocalDate.of(2018, 10, 5), LocalDate.of(2018, 10, 4).nextSchoolDay)
assertEquals(LocalDate.of(2018, 10, 8), LocalDate.of(2018, 10, 5).nextSchoolDay)
assertEquals(LocalDate.of(2018, 10, 8), LocalDate.of(2018, 10, 6).nextSchoolDay)
assertEquals(LocalDate.of(2018, 10, 8), LocalDate.of(2018, 10, 7).nextSchoolDay)
assertEquals(LocalDate.of(2018, 10, 9), LocalDate.of(2018, 10, 8).nextSchoolDay)
assertEquals(of(2018, 10, 2), of(2018, 10, 1).nextSchoolDay)
assertEquals(of(2018, 10, 3), of(2018, 10, 2).nextSchoolDay)
assertEquals(of(2018, 10, 4), of(2018, 10, 3).nextSchoolDay)
assertEquals(of(2018, 10, 5), of(2018, 10, 4).nextSchoolDay)
assertEquals(of(2018, 10, 8), of(2018, 10, 5).nextSchoolDay)
assertEquals(of(2018, 10, 8), of(2018, 10, 6).nextSchoolDay)
assertEquals(of(2018, 10, 8), of(2018, 10, 7).nextSchoolDay)
assertEquals(of(2018, 10, 9), of(2018, 10, 8).nextSchoolDay)
}
@Test
fun previousSchoolDayTest() {
assertEquals(LocalDate.of(2018, 10, 9), LocalDate.of(2018, 10, 10).previousSchoolDay)
assertEquals(LocalDate.of(2018, 10, 8), LocalDate.of(2018, 10, 9).previousSchoolDay)
assertEquals(LocalDate.of(2018, 10, 5), LocalDate.of(2018, 10, 8).previousSchoolDay)
assertEquals(LocalDate.of(2018, 10, 5), LocalDate.of(2018, 10, 7).previousSchoolDay)
assertEquals(LocalDate.of(2018, 10, 5), LocalDate.of(2018, 10, 6).previousSchoolDay)
assertEquals(LocalDate.of(2018, 10, 4), LocalDate.of(2018, 10, 5).previousSchoolDay)
assertEquals(LocalDate.of(2018, 10, 3), LocalDate.of(2018, 10, 4).previousSchoolDay)
assertEquals(of(2018, 10, 9), of(2018, 10, 10).previousSchoolDay)
assertEquals(of(2018, 10, 8), of(2018, 10, 9).previousSchoolDay)
assertEquals(of(2018, 10, 5), of(2018, 10, 8).previousSchoolDay)
assertEquals(of(2018, 10, 5), of(2018, 10, 7).previousSchoolDay)
assertEquals(of(2018, 10, 5), of(2018, 10, 6).previousSchoolDay)
assertEquals(of(2018, 10, 4), of(2018, 10, 5).previousSchoolDay)
assertEquals(of(2018, 10, 3), of(2018, 10, 4).previousSchoolDay)
}
@Test
fun nextOrSameSchoolDayTest() {
assertEquals(LocalDate.of(2018, 9, 28), LocalDate.of(2018, 9, 28).nextOrSameSchoolDay)
assertEquals(LocalDate.of(2018, 10, 1), LocalDate.of(2018, 9, 29).nextOrSameSchoolDay)
assertEquals(LocalDate.of(2018, 10, 1), LocalDate.of(2018, 9, 30).nextOrSameSchoolDay)
assertEquals(LocalDate.of(2018, 10, 1), LocalDate.of(2018, 10, 1).nextOrSameSchoolDay)
assertEquals(LocalDate.of(2018, 10, 2), LocalDate.of(2018, 10, 2).nextOrSameSchoolDay)
assertEquals(of(2018, 9, 28), of(2018, 9, 28).nextOrSameSchoolDay)
assertEquals(of(2018, 10, 1), of(2018, 9, 29).nextOrSameSchoolDay)
assertEquals(of(2018, 10, 1), of(2018, 9, 30).nextOrSameSchoolDay)
assertEquals(of(2018, 10, 1), of(2018, 10, 1).nextOrSameSchoolDay)
assertEquals(of(2018, 10, 2), of(2018, 10, 2).nextOrSameSchoolDay)
}
@Test
fun previousOrSameSchoolDayTest() {
assertEquals(LocalDate.of(2018, 9, 28), LocalDate.of(2018, 9, 28).previousOrSameSchoolDay)
assertEquals(LocalDate.of(2018, 9, 28), LocalDate.of(2018, 9, 29).previousOrSameSchoolDay)
assertEquals(LocalDate.of(2018, 9, 28), LocalDate.of(2018, 9, 30).previousOrSameSchoolDay)
assertEquals(LocalDate.of(2018, 10, 1), LocalDate.of(2018, 10, 1).previousOrSameSchoolDay)
assertEquals(LocalDate.of(2018, 10, 2), LocalDate.of(2018, 10, 2).previousOrSameSchoolDay)
assertEquals(of(2018, 9, 28), of(2018, 9, 28).previousOrSameSchoolDay)
assertEquals(of(2018, 9, 28), of(2018, 9, 29).previousOrSameSchoolDay)
assertEquals(of(2018, 9, 28), of(2018, 9, 30).previousOrSameSchoolDay)
assertEquals(of(2018, 10, 1), of(2018, 10, 1).previousOrSameSchoolDay)
assertEquals(of(2018, 10, 2), of(2018, 10, 2).previousOrSameSchoolDay)
}
@Test
fun isHolidays_schoolEndTest() {
assertFalse(LocalDate.of(2017, 6, 23).isHolidays)
assertFalse(LocalDate.of(2018, 6, 22).isHolidays)
assertFalse(LocalDate.of(2019, 6, 21).isHolidays)
assertFalse(LocalDate.of(2020, 6, 26).isHolidays)
assertFalse(LocalDate.of(2021, 6, 25).isHolidays)
assertFalse(LocalDate.of(2022, 6, 24).isHolidays)
assertFalse(LocalDate.of(2023, 6, 23).isHolidays)
assertFalse(LocalDate.of(2024, 6, 21).isHolidays)
assertFalse(LocalDate.of(2025, 6, 27).isHolidays)
assertFalse(of(2017, 6, 23).isHolidays)
assertFalse(of(2018, 6, 22).isHolidays)
assertFalse(of(2019, 6, 21).isHolidays)
assertFalse(of(2020, 6, 26).isHolidays)
assertFalse(of(2021, 6, 25).isHolidays)
assertFalse(of(2022, 6, 24).isHolidays)
assertFalse(of(2023, 6, 23).isHolidays)
assertFalse(of(2024, 6, 21).isHolidays)
assertFalse(of(2025, 6, 27).isHolidays)
}
@Test
fun isHolidays_holidaysStartTest() {
assertTrue(LocalDate.of(2017, 6, 24).isHolidays)
assertTrue(LocalDate.of(2018, 6, 23).isHolidays)
assertTrue(LocalDate.of(2019, 6, 22).isHolidays)
assertTrue(LocalDate.of(2020, 6, 27).isHolidays)
assertTrue(LocalDate.of(2021, 6, 26).isHolidays)
assertTrue(LocalDate.of(2022, 6, 25).isHolidays)
assertTrue(LocalDate.of(2023, 6, 24).isHolidays)
assertTrue(LocalDate.of(2024, 6, 22).isHolidays)
assertTrue(LocalDate.of(2025, 6, 28).isHolidays)
assertTrue(of(2017, 6, 24).isHolidays)
assertTrue(of(2018, 6, 23).isHolidays)
assertTrue(of(2019, 6, 22).isHolidays)
assertTrue(of(2020, 6, 27).isHolidays)
assertTrue(of(2021, 6, 26).isHolidays)
assertTrue(of(2022, 6, 25).isHolidays)
assertTrue(of(2023, 6, 24).isHolidays)
assertTrue(of(2024, 6, 22).isHolidays)
assertTrue(of(2025, 6, 28).isHolidays)
}
@Test
fun isHolidays_holidaysEndTest() {
assertTrue(LocalDate.of(2017, 9, 1).isHolidays) // friday
assertTrue(LocalDate.of(2017, 9, 2).isHolidays) // saturday
assertTrue(LocalDate.of(2017, 9, 3).isHolidays) // sunday
assertTrue(LocalDate.of(2018, 9, 1).isHolidays) // saturday
assertTrue(LocalDate.of(2018, 9, 2).isHolidays) // sunday
assertTrue(LocalDate.of(2019, 9, 1).isHolidays) // sunday
assertTrue(LocalDate.of(2020, 8, 31).isHolidays) // monday
assertTrue(LocalDate.of(2021, 8, 31).isHolidays) // tuesday
assertTrue(LocalDate.of(2022, 8, 31).isHolidays) // wednesday
assertTrue(LocalDate.of(2023, 9, 1).isHolidays) // friday
assertTrue(LocalDate.of(2023, 9, 2).isHolidays) // saturday
assertTrue(LocalDate.of(2023, 9, 3).isHolidays) // sunday
assertTrue(LocalDate.of(2024, 9, 1).isHolidays) // sunday
assertTrue(LocalDate.of(2025, 8, 31).isHolidays) // sunday
assertTrue(of(2017, 9, 1).isHolidays) // friday
assertTrue(of(2017, 9, 2).isHolidays) // saturday
assertTrue(of(2017, 9, 3).isHolidays) // sunday
assertTrue(of(2018, 9, 1).isHolidays) // saturday
assertTrue(of(2018, 9, 2).isHolidays) // sunday
assertTrue(of(2019, 9, 1).isHolidays) // sunday
assertTrue(of(2020, 8, 31).isHolidays) // monday
assertTrue(of(2021, 8, 31).isHolidays) // tuesday
assertTrue(of(2022, 8, 31).isHolidays) // wednesday
assertTrue(of(2023, 9, 1).isHolidays) // friday
assertTrue(of(2023, 9, 2).isHolidays) // saturday
assertTrue(of(2023, 9, 3).isHolidays) // sunday
assertTrue(of(2024, 9, 1).isHolidays) // sunday
assertTrue(of(2025, 8, 31).isHolidays) // sunday
}
@Test
fun isHolidays_schoolStartTest() {
assertFalse(LocalDate.of(2017, 9, 4).isHolidays) // monday
assertFalse(LocalDate.of(2018, 9, 3).isHolidays) // monday
assertFalse(LocalDate.of(2019, 9, 2).isHolidays) // monday
assertFalse(LocalDate.of(2020, 9, 1).isHolidays) // tuesday
assertFalse(LocalDate.of(2021, 9, 1).isHolidays) // wednesday
assertFalse(LocalDate.of(2022, 9, 1).isHolidays) // thursday
assertFalse(LocalDate.of(2023, 9, 4).isHolidays) // monday
assertFalse(LocalDate.of(2024, 9, 2).isHolidays) // monday
assertFalse(LocalDate.of(2025, 9, 1).isHolidays) // monday
assertFalse(of(2017, 9, 4).isHolidays) // monday
assertFalse(of(2018, 9, 3).isHolidays) // monday
assertFalse(of(2019, 9, 2).isHolidays) // monday
assertFalse(of(2020, 9, 1).isHolidays) // tuesday
assertFalse(of(2021, 9, 1).isHolidays) // wednesday
assertFalse(of(2022, 9, 1).isHolidays) // thursday
assertFalse(of(2023, 9, 4).isHolidays) // monday
assertFalse(of(2024, 9, 2).isHolidays) // monday
assertFalse(of(2025, 9, 1).isHolidays) // monday
}
@Test
fun getCorrectedDate_holidays() {
assertEquals(of(2019, 6, 21), of(2019, 8, 9).getLastSchoolDayIfHoliday(2018))
assertEquals(of(2018, 6, 22), of(2019, 8, 9).getLastSchoolDayIfHoliday(2017))
}
@Test
fun getCorrectedDate_schoolYear() {
assertEquals(of(2019, 5, 1), of(2019, 5, 1).getLastSchoolDayIfHoliday(2018))
assertEquals(of(2018, 5, 1), of(2019, 5, 1).getLastSchoolDayIfHoliday(2017))
}
}

Binary file not shown.

View File

@ -1,5 +1,5 @@
buildscript {
ext.kotlin_version = '1.3.31'
ext.kotlin_version = '1.3.41'
repositories {
mavenCentral()
google()
@ -9,9 +9,9 @@ buildscript {
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.android.tools.build:gradle:3.4.1'
classpath 'com.google.gms:google-services:4.2.0'
classpath "io.fabric.tools:gradle:1.29.0"
classpath 'com.android.tools.build:gradle:3.4.2'
classpath 'com.google.gms:google-services:4.3.0'
classpath "io.fabric.tools:gradle:1.31.0"
classpath "com.github.triplet.gradle:play-publisher:2.2.1"
classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.7.1"
classpath "gradle.plugin.com.star-zero.gradle:githook:1.1.0"