1
0
mirror of https://github.com/wulkanowy/wulkanowy.git synced 2024-09-20 08:19:09 -05:00

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 # Created by https://www.gitignore.io
.externalNativeBuild
## https://gist.github.com/iainconnor/8605514
# Built application files # Built application files
/build *.apk
/*/build/ *.ap_
*.aab
# Crashlytics configuations # Files for the ART/Dalvik VM
com_crashlytics_export_strings.xml *.dex
# Java class files
*.class
# Generated files
bin/
gen/
out/
# Gradle files
.gradle/
build/
# Local configuration file (sdk path, etc) # Local configuration file (sdk path, etc)
local.properties local.properties
# Gradle generated files # Proguard folder generated by Eclipse
.gradle/ proguard/
# Signing files # Log Files
.signing/ *.log
# User-specific configurations # Android Studio Navigation editor temp files
.idea/copyright/profiles_settings.xml .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/libraries/
.idea/inspectionProfiles/ .idea/shelf/
.idea/.name .idea/.name
.idea/compiler.xml .idea/compiler.xml
.idea/copyright/profiles_settings.xml
.idea/encodings.xml .idea/encodings.xml
.idea/misc.xml .idea/misc.xml
.idea/modules.xml
.idea/scopes/scope_settings.xml .idea/scopes/scope_settings.xml
.idea/tasks.xml
.idea/vcs.xml .idea/vcs.xml
.idea/workspace.xml .idea/jsLibraryMappings.xml
.idea/caches/ .idea/datasources.xml
*.iml .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 # OS-specific files
.DS_Store .DS_Store
@ -43,9 +94,20 @@ local.properties
.Trashes .Trashes
ehthumbs.db ehthumbs.db
Thumbs.db Thumbs.db
.idea/caches/
app/key.p12 # Legacy Eclipse project files
app/upload-key.jks .classpath
*.log .project
.idea/assetWizardSettings.xml .cproject
.idea/uiDesigner.xml .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="CONTINUATION_INDENT_IN_ELVIS" value="false" />
<option name="WRAP_ELVIS_EXPRESSIONS" value="0" /> <option name="WRAP_ELVIS_EXPRESSIONS" value="0" />
</JetCodeStyleSettings> </JetCodeStyleSettings>
<MarkdownNavigatorCodeStyleSettings>
<option name="RIGHT_MARGIN" value="72" />
</MarkdownNavigatorCodeStyleSettings>
<XML> <XML>
<option name="XML_KEEP_LINE_BREAKS" value="false" /> <option name="XML_KEEP_LINE_BREAKS" value="false" />
<option name="XML_ALIGN_ATTRIBUTES" 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: branches:
only: only:
- develop - develop
- 0.9.2 - 0.9.4
android: android:
licenses: licenses:

View File

@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier same "printed page" as the copyright notice for easier
identification within third-party archives. identification within third-party archives.
Copyright 2017 wulkanowy Copyright 2019 Wulkanowy
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with 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) [![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) [![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) [![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/) [![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) [![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) ## Funkcje
[(Więcej wersji DEV)](https://wulkanowy.github.io/dev.html)
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 { defaultConfig {
applicationId "io.github.wulkanowy" applicationId "io.github.wulkanowy"
testApplicationId "io.github.tests.wulkanowy" testApplicationId "io.github.tests.wulkanowy"
minSdkVersion 15 minSdkVersion 16
targetSdkVersion 28 targetSdkVersion 28
versionCode 41 versionCode 42
versionName "0.9.3" versionName "0.9.4"
multiDexEnabled true multiDexEnabled true
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true vectorDrawables.useSupportLibrary = true
@ -97,8 +97,17 @@ play {
track = 'alpha' 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 { 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 "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation "androidx.core:core:1.0.2" implementation "androidx.core:core:1.0.2"
@ -116,27 +125,27 @@ dependencies {
implementation "com.github.wulkanowy:MaterialChipsInput:b72fd0ee6f" implementation "com.github.wulkanowy:MaterialChipsInput:b72fd0ee6f"
implementation "com.github.PhilJay:MPAndroidChart:v3.1.0" implementation "com.github.PhilJay:MPAndroidChart:v3.1.0"
implementation "androidx.work:work-runtime:2.0.1" implementation "androidx.work:work-runtime:$work_manager"
implementation "androidx.work:work-rxjava2:2.0.1" implementation "androidx.work:work-rxjava2:$work_manager"
implementation "androidx.room:room-runtime:2.1.0" implementation "androidx.room:room-runtime:$room"
implementation "androidx.room:room-rxjava2:2.1.0" implementation "androidx.room:room-rxjava2:$room"
kapt "androidx.room:room-compiler:2.1.0" kapt "androidx.room:room-compiler:$room"
implementation "com.google.dagger:dagger-android-support:2.23.1" implementation "com.google.dagger:dagger-android-support:$dagger"
kapt "com.google.dagger:dagger-compiler:2.23.1" kapt "com.google.dagger:dagger-compiler:$dagger"
kapt "com.google.dagger:dagger-android-processor:2.23.1" kapt "com.google.dagger:dagger-android-processor:$dagger"
implementation "com.squareup.inject:assisted-inject-annotations-dagger2:0.4.0" implementation "com.squareup.inject:assisted-inject-annotations-dagger2:0.5.0"
kapt "com.squareup.inject:assisted-inject-processor-dagger2:0.4.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:5.1.0"
implementation "eu.davidea:flexible-adapter-ui:1.0.0" implementation "eu.davidea:flexible-adapter-ui:1.0.0"
implementation "com.aurelhubert:ahbottomnavigation:2.3.4" 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: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.google.code.gson:gson:2.8.5"
implementation "com.jakewharton.threetenabp:threetenabp:1.2.1" implementation "com.jakewharton.threetenabp:threetenabp:1.2.1"
@ -147,30 +156,30 @@ dependencies {
implementation "com.mikepenz:aboutlibraries:6.2.3" implementation "com.mikepenz:aboutlibraries:6.2.3"
implementation "com.takisoft.preferencex:preferencex:1.0.0" 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" 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" debugImplementation "com.amitshekhar.android:debug-db:1.0.6"
testImplementation "junit:junit:4.12" 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.threeten:threetenbp:1.4.0"
testImplementation "org.mockito:mockito-core:2.28.2" testImplementation "org.mockito:mockito-core:$mockito_core"
testImplementation("org.mockito:mockito-inline:2.28.2") { testImplementation("org.mockito:mockito-inline:3.0.4") {
exclude group: "org.mockito", module: "mockito-core" exclude group: "org.mockito", module: "mockito-core"
} }
androidTestImplementation "androidx.test:core:1.2.0" androidTestImplementation "androidx.test:core:1.2.0"
androidTestImplementation "androidx.test:runner:1.2.0" androidTestImplementation "androidx.test:runner:1.2.0"
androidTestImplementation "androidx.test.ext:junit:1.1.1" androidTestImplementation "androidx.test.ext:junit:1.1.1"
androidTestImplementation "io.mockk:mockk-android:1.9.2" androidTestImplementation "io.mockk:mockk-android:$mockk"
androidTestImplementation "androidx.room:room-testing:2.1.0" androidTestImplementation "androidx.room:room-testing:$room"
androidTestImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin_version" androidTestImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
androidTestImplementation "org.mockito:mockito-core:2.28.2" androidTestImplementation "org.mockito:mockito-core:$mockito_core"
androidTestImplementation("org.mockito:mockito-android:2.28.2") { androidTestImplementation("org.mockito:mockito-android:3.0.4") {
exclude group: 'org.mockito', module: 'mockito-core' exclude group: 'org.mockito', module: 'mockito-core'
} }
} }

Binary file not shown.

View File

@ -4,8 +4,6 @@
package="io.github.wulkanowy" package="io.github.wulkanowy"
android:installLocation="internalOnly"> android:installLocation="internalOnly">
<uses-sdk tools:overrideLibrary="com.readystatesoftware.chuck" />
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <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.AlertDialog
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate import androidx.appcompat.app.AppCompatDelegate
import androidx.fragment.app.Fragment
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import com.google.android.material.snackbar.Snackbar.LENGTH_LONG import com.google.android.material.snackbar.Snackbar.LENGTH_LONG
import dagger.android.AndroidInjection import dagger.android.AndroidInjection
import dagger.android.DispatchingAndroidInjector import dagger.android.DispatchingAndroidInjector
import dagger.android.support.HasSupportFragmentInjector import dagger.android.HasAndroidInjector
import io.github.wulkanowy.R import io.github.wulkanowy.R
import io.github.wulkanowy.ui.modules.login.LoginActivity import io.github.wulkanowy.ui.modules.login.LoginActivity
import io.github.wulkanowy.utils.FragmentLifecycleLogger import io.github.wulkanowy.utils.FragmentLifecycleLogger
import javax.inject.Inject import javax.inject.Inject
abstract class BaseActivity<T : BasePresenter<out BaseView>> : AppCompatActivity(), BaseView, abstract class BaseActivity<T : BasePresenter<out BaseView>> : AppCompatActivity(), BaseView, HasAndroidInjector {
HasSupportFragmentInjector {
@Inject @Inject
lateinit var supportFragmentInjector: DispatchingAndroidInjector<Fragment> lateinit var androidInjector: DispatchingAndroidInjector<Any>
@Inject @Inject
lateinit var fragmentLifecycleLogger: FragmentLifecycleLogger lateinit var fragmentLifecycleLogger: FragmentLifecycleLogger
@ -78,5 +76,5 @@ abstract class BaseActivity<T : BasePresenter<out BaseView>> : AppCompatActivity
presenter.onDetachView() 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.BasePresenter
import io.github.wulkanowy.ui.base.ErrorHandler import io.github.wulkanowy.ui.base.ErrorHandler
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper 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
import org.threeten.bp.LocalDate.now import org.threeten.bp.LocalDate.now
import org.threeten.bp.LocalDate.ofEpochDay import org.threeten.bp.LocalDate.ofEpochDay
@ -26,6 +32,8 @@ class AttendancePresenter @Inject constructor(
private val analytics: FirebaseAnalyticsHelper private val analytics: FirebaseAnalyticsHelper
) : BasePresenter<AttendanceView>(errorHandler, studentRepository, schedulers) { ) : BasePresenter<AttendanceView>(errorHandler, studentRepository, schedulers) {
private var baseDate: LocalDate = now().previousOrSameSchoolDay
lateinit var currentDate: LocalDate lateinit var currentDate: LocalDate
private set private set
@ -33,7 +41,8 @@ class AttendancePresenter @Inject constructor(
super.onAttachView(view) super.onAttachView(view)
view.initView() view.initView()
Timber.i("Attendance view was initialized") Timber.i("Attendance view was initialized")
loadData(ofEpochDay(date ?: now().previousOrSameSchoolDay.toEpochDay())) loadData(ofEpochDay(date ?: baseDate.toEpochDay()))
if (currentDate.isHolidays) setBaseDateOnHolidays()
reloadView() reloadView()
} }
@ -56,7 +65,7 @@ class AttendancePresenter @Inject constructor(
Timber.i("Attendance view is reselected") Timber.i("Attendance view is reselected")
view?.also { view -> view?.also { view ->
if (view.currentStackSize == 1) { if (view.currentStackSize == 1) {
now().previousOrSameSchoolDay.also { baseDate.also {
if (currentDate != it) { if (currentDate != it) {
loadData(it) loadData(it)
reloadView() reloadView()
@ -78,6 +87,20 @@ class AttendancePresenter @Inject constructor(
return true 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) { private fun loadData(date: LocalDate, forceRefresh: Boolean = false) {
Timber.i("Loading attendance data started") Timber.i("Loading attendance data started")
currentDate = date currentDate = date
@ -127,8 +150,14 @@ class AttendancePresenter @Inject constructor(
showContent(false) showContent(false)
showEmpty(false) showEmpty(false)
clearData() clearData()
showNextButton(!currentDate.plusDays(1).isHolidays) reloadNavigation()
}
}
private fun reloadNavigation() {
view?.apply {
showPreButton(!currentDate.minusDays(1).isHolidays) showPreButton(!currentDate.minusDays(1).isHolidays)
showNextButton(!currentDate.plusDays(1).isHolidays)
updateNavigationDay(currentDate.toFormattedString("EEEE\ndd.MM.YYYY").capitalize()) 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.FirebaseAnalyticsHelper
import io.github.wulkanowy.utils.SchedulersProvider import io.github.wulkanowy.utils.SchedulersProvider
import io.github.wulkanowy.utils.friday import io.github.wulkanowy.utils.friday
import io.github.wulkanowy.utils.getLastSchoolDayIfHoliday
import io.github.wulkanowy.utils.isHolidays import io.github.wulkanowy.utils.isHolidays
import io.github.wulkanowy.utils.monday import io.github.wulkanowy.utils.monday
import io.github.wulkanowy.utils.nextOrSameSchoolDay import io.github.wulkanowy.utils.nextOrSameSchoolDay
@ -30,6 +31,8 @@ class ExamPresenter @Inject constructor(
private val analytics: FirebaseAnalyticsHelper private val analytics: FirebaseAnalyticsHelper
) : BasePresenter<ExamView>(errorHandler, studentRepository, schedulers) { ) : BasePresenter<ExamView>(errorHandler, studentRepository, schedulers) {
private var baseDate: LocalDate = now().nextOrSameSchoolDay
lateinit var currentDate: LocalDate lateinit var currentDate: LocalDate
private set private set
@ -37,7 +40,8 @@ class ExamPresenter @Inject constructor(
super.onAttachView(view) super.onAttachView(view)
view.initView() view.initView()
Timber.i("Exam view was initialized") Timber.i("Exam view was initialized")
loadData(ofEpochDay(date ?: now().nextOrSameSchoolDay.toEpochDay())) loadData(ofEpochDay(date ?: baseDate.toEpochDay()))
if (currentDate.isHolidays) setBaseDateOnHolidays()
reloadView() reloadView()
} }
@ -65,7 +69,7 @@ class ExamPresenter @Inject constructor(
fun onViewReselected() { fun onViewReselected() {
Timber.i("Exam view is reselected") Timber.i("Exam view is reselected")
now().nextOrSameSchoolDay.also { baseDate.also {
if (currentDate != it) { if (currentDate != it) {
loadData(it) loadData(it)
reloadView() 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) { private fun loadData(date: LocalDate, forceRefresh: Boolean = false) {
Timber.i("Loading exam data started") Timber.i("Loading exam data started")
currentDate = date currentDate = date
@ -81,9 +99,8 @@ class ExamPresenter @Inject constructor(
add(studentRepository.getCurrentStudent() add(studentRepository.getCurrentStudent()
.delay(200, MILLISECONDS) .delay(200, MILLISECONDS)
.flatMap { semesterRepository.getCurrentSemester(it) } .flatMap { semesterRepository.getCurrentSemester(it) }
.flatMap { .flatMap { examRepository.getExams(it, currentDate.monday, currentDate.friday, forceRefresh) }
examRepository.getExams(it, currentDate.monday, currentDate.friday, forceRefresh) .map { it.groupBy { exam -> exam.date }.toSortedMap() }
}.map { it.groupBy { exam -> exam.date }.toSortedMap() }
.map { createExamItems(it) } .map { createExamItems(it) }
.subscribeOn(schedulers.backgroundThread) .subscribeOn(schedulers.backgroundThread)
.observeOn(schedulers.mainThread) .observeOn(schedulers.mainThread)
@ -126,6 +143,12 @@ class ExamPresenter @Inject constructor(
showContent(false) showContent(false)
showEmpty(false) showEmpty(false)
clearData() clearData()
reloadNavigation()
}
}
private fun reloadNavigation() {
view?.apply {
showPreButton(!currentDate.minusDays(7).isHolidays) showPreButton(!currentDate.minusDays(7).isHolidays)
showNextButton(!currentDate.plusDays(7).isHolidays) showNextButton(!currentDate.plusDays(7).isHolidays)
updateNavigationWeek("${currentDate.monday.toFormattedString("dd.MM")} - " + 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.FirebaseAnalyticsHelper
import io.github.wulkanowy.utils.SchedulersProvider import io.github.wulkanowy.utils.SchedulersProvider
import io.github.wulkanowy.utils.friday import io.github.wulkanowy.utils.friday
import io.github.wulkanowy.utils.getLastSchoolDayIfHoliday
import io.github.wulkanowy.utils.isHolidays import io.github.wulkanowy.utils.isHolidays
import io.github.wulkanowy.utils.monday import io.github.wulkanowy.utils.monday
import io.github.wulkanowy.utils.nextOrSameSchoolDay import io.github.wulkanowy.utils.nextOrSameSchoolDay
import io.github.wulkanowy.utils.toFormattedString import io.github.wulkanowy.utils.toFormattedString
import org.threeten.bp.LocalDate import org.threeten.bp.LocalDate
import org.threeten.bp.LocalDate.ofEpochDay
import timber.log.Timber import timber.log.Timber
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import javax.inject.Inject import javax.inject.Inject
@ -28,6 +30,8 @@ class HomeworkPresenter @Inject constructor(
private val analytics: FirebaseAnalyticsHelper private val analytics: FirebaseAnalyticsHelper
) : BasePresenter<HomeworkView>(errorHandler, studentRepository, schedulers) { ) : BasePresenter<HomeworkView>(errorHandler, studentRepository, schedulers) {
private var baseDate: LocalDate = LocalDate.now().nextOrSameSchoolDay
lateinit var currentDate: LocalDate lateinit var currentDate: LocalDate
private set private set
@ -35,7 +39,8 @@ class HomeworkPresenter @Inject constructor(
super.onAttachView(view) super.onAttachView(view)
view.initView() view.initView()
Timber.i("Homework view was initialized") Timber.i("Homework view was initialized")
loadData(LocalDate.ofEpochDay(date ?: LocalDate.now().nextOrSameSchoolDay.toEpochDay())) loadData(ofEpochDay(date ?: baseDate.toEpochDay()))
if (currentDate.isHolidays) setBaseDateOnHolidays()
reloadView() 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) { private fun loadData(date: LocalDate, forceRefresh: Boolean = false) {
Timber.i("Loading homework data started") Timber.i("Loading homework data started")
currentDate = date currentDate = date
@ -113,8 +132,14 @@ class HomeworkPresenter @Inject constructor(
showContent(false) showContent(false)
showEmpty(false) showEmpty(false)
clearData() clearData()
showNextButton(!currentDate.plusDays(7).isHolidays) reloadNavigation()
}
}
private fun reloadNavigation() {
view?.apply {
showPreButton(!currentDate.minusDays(7).isHolidays) showPreButton(!currentDate.minusDays(7).isHolidays)
showNextButton(!currentDate.plusDays(7).isHolidays)
updateNavigationWeek("${currentDate.monday.toFormattedString("dd.MM")} - " + updateNavigationWeek("${currentDate.monday.toFormattedString("dd.MM")} - " +
currentDate.friday.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.ui.base.ErrorHandler
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
import io.github.wulkanowy.utils.SchedulersProvider import io.github.wulkanowy.utils.SchedulersProvider
import io.github.wulkanowy.utils.getLastSchoolDayIfHoliday
import io.github.wulkanowy.utils.isHolidays import io.github.wulkanowy.utils.isHolidays
import io.github.wulkanowy.utils.nextOrSameSchoolDay import io.github.wulkanowy.utils.nextOrSameSchoolDay
import io.github.wulkanowy.utils.nextSchoolDay import io.github.wulkanowy.utils.nextSchoolDay
@ -29,6 +30,8 @@ class TimetablePresenter @Inject constructor(
private val analytics: FirebaseAnalyticsHelper private val analytics: FirebaseAnalyticsHelper
) : BasePresenter<TimetableView>(errorHandler, studentRepository, schedulers) { ) : BasePresenter<TimetableView>(errorHandler, studentRepository, schedulers) {
private var baseDate: LocalDate = now().nextOrSameSchoolDay
lateinit var currentDate: LocalDate lateinit var currentDate: LocalDate
private set private set
@ -36,7 +39,8 @@ class TimetablePresenter @Inject constructor(
super.onAttachView(view) super.onAttachView(view)
view.initView() view.initView()
Timber.i("Timetable was initialized") Timber.i("Timetable was initialized")
loadData(ofEpochDay(date ?: now().nextOrSameSchoolDay.toEpochDay())) loadData(ofEpochDay(date ?: baseDate.toEpochDay()))
if (currentDate.isHolidays) setBaseDateOnHolidays()
reloadView() reloadView()
} }
@ -59,7 +63,7 @@ class TimetablePresenter @Inject constructor(
Timber.i("Timetable view is reselected") Timber.i("Timetable view is reselected")
view?.also { view -> view?.also { view ->
if (view.currentStackSize == 1) { if (view.currentStackSize == 1) {
now().nextOrSameSchoolDay.also { baseDate.also {
if (currentDate != it) { if (currentDate != it) {
loadData(it) loadData(it)
reloadView() reloadView()
@ -81,6 +85,20 @@ class TimetablePresenter @Inject constructor(
return true 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) { private fun loadData(date: LocalDate, forceRefresh: Boolean = false) {
Timber.i("Loading timetable data started") Timber.i("Loading timetable data started")
currentDate = date currentDate = date
@ -125,8 +143,14 @@ class TimetablePresenter @Inject constructor(
showContent(false) showContent(false)
showEmpty(false) showEmpty(false)
clearData() clearData()
showNextButton(!currentDate.plusDays(1).isHolidays) reloadNavigation()
}
}
private fun reloadNavigation() {
view?.apply {
showPreButton(!currentDate.minusDays(1).isHolidays) showPreButton(!currentDate.minusDays(1).isHolidays)
showNextButton(!currentDate.plusDays(1).isHolidays)
updateNavigationDay(currentDate.toFormattedString("EEEE\ndd.MM.YYYY").capitalize()) 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.ui.base.BasePresenter
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
import io.github.wulkanowy.utils.SchedulersProvider import io.github.wulkanowy.utils.SchedulersProvider
import io.github.wulkanowy.utils.getLastSchoolDayIfHoliday
import io.github.wulkanowy.utils.isHolidays import io.github.wulkanowy.utils.isHolidays
import io.github.wulkanowy.utils.nextOrSameSchoolDay import io.github.wulkanowy.utils.nextOrSameSchoolDay
import io.github.wulkanowy.utils.nextSchoolDay import io.github.wulkanowy.utils.nextSchoolDay
@ -28,6 +29,8 @@ class CompletedLessonsPresenter @Inject constructor(
private val analytics: FirebaseAnalyticsHelper private val analytics: FirebaseAnalyticsHelper
) : BasePresenter<CompletedLessonsView>(completedLessonsErrorHandler, studentRepository, schedulers) { ) : BasePresenter<CompletedLessonsView>(completedLessonsErrorHandler, studentRepository, schedulers) {
private var baseDate: LocalDate = now().nextOrSameSchoolDay
lateinit var currentDate: LocalDate lateinit var currentDate: LocalDate
private set private set
@ -35,7 +38,8 @@ class CompletedLessonsPresenter @Inject constructor(
super.onAttachView(view) super.onAttachView(view)
Timber.i("Completed lessons is attached") Timber.i("Completed lessons is attached")
view.initView() view.initView()
loadData(ofEpochDay(date ?: now().nextOrSameSchoolDay.toEpochDay())) loadData(ofEpochDay(date ?: baseDate.toEpochDay()))
if (currentDate.isHolidays) setBaseDateOnHolidays()
reloadView() reloadView()
completedLessonsErrorHandler.onFeatureDisabled = { completedLessonsErrorHandler.onFeatureDisabled = {
this.view?.showFeatureDisabled() 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) { private fun loadData(date: LocalDate, forceRefresh: Boolean = false) {
Timber.i("Loading completed lessons data started") Timber.i("Loading completed lessons data started")
currentDate = date currentDate = date
@ -109,8 +127,14 @@ class CompletedLessonsPresenter @Inject constructor(
showContent(false) showContent(false)
showEmpty(false) showEmpty(false)
clearData() clearData()
showNextButton(!currentDate.plusDays(1).isHolidays) reloadNavigation()
}
}
private fun reloadNavigation() {
view?.apply {
showPreButton(!currentDate.minusDays(1).isHolidays) showPreButton(!currentDate.minusDays(1).isHolidays)
showNextButton(!currentDate.plusDays(1).isHolidays)
updateNavigationDay(currentDate.toFormattedString("EEEE\ndd.MM.YYYY").capitalize()) 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.SATURDAY
import org.threeten.bp.DayOfWeek.SUNDAY import org.threeten.bp.DayOfWeek.SUNDAY
import org.threeten.bp.Instant import org.threeten.bp.Instant
import org.threeten.bp.Instant.ofEpochMilli
import org.threeten.bp.LocalDate import org.threeten.bp.LocalDate
import org.threeten.bp.LocalDateTime import org.threeten.bp.LocalDateTime
import org.threeten.bp.Month import org.threeten.bp.Month
import org.threeten.bp.ZoneId import org.threeten.bp.ZoneId
import org.threeten.bp.format.DateTimeFormatter
import org.threeten.bp.format.DateTimeFormatter.ofPattern import org.threeten.bp.format.DateTimeFormatter.ofPattern
import org.threeten.bp.format.TextStyle.FULL_STANDALONE import org.threeten.bp.format.TextStyle.FULL_STANDALONE
import org.threeten.bp.temporal.TemporalAdjusters.firstInMonth import org.threeten.bp.temporal.TemporalAdjusters.firstInMonth
@ -21,21 +21,15 @@ import java.util.Locale
private const val DATE_PATTERN = "dd.MM.yyyy" private const val DATE_PATTERN = "dd.MM.yyyy"
fun Date.toLocalDate(): LocalDate { fun Date.toLocalDate(): LocalDate = Instant.ofEpochMilli(time).atZone(ZoneId.systemDefault()).toLocalDate()
return Instant.ofEpochMilli(this.time).atZone(ZoneId.systemDefault()).toLocalDate()
}
fun Date.toLocalDateTime(): LocalDateTime { fun Date.toLocalDateTime(): LocalDateTime = ofEpochMilli(time).atZone(ZoneId.systemDefault()).toLocalDateTime()
return Instant.ofEpochMilli(this.time).atZone(ZoneId.systemDefault()).toLocalDateTime()
}
fun String.toLocalDate(format: String = DATE_PATTERN): LocalDate { fun String.toLocalDate(format: String = DATE_PATTERN): LocalDate = LocalDate.parse(this, ofPattern(format))
return LocalDate.parse(this, DateTimeFormatter.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()) fun LocalDateTime.toDate(): Date = DateTimeUtils.toDate(atZone(ZoneId.systemDefault()).toInstant())
@ -66,62 +60,81 @@ fun Month.getFormattedName(): String {
inline val LocalDate.nextSchoolDay: LocalDate inline val LocalDate.nextSchoolDay: LocalDate
get() { get() {
return when (this.dayOfWeek) { return when (dayOfWeek) {
FRIDAY, SATURDAY, SUNDAY -> this.with(next(MONDAY)) FRIDAY, SATURDAY, SUNDAY -> with(next(MONDAY))
else -> this.plusDays(1) else -> plusDays(1)
} }
} }
inline val LocalDate.previousSchoolDay: LocalDate inline val LocalDate.previousSchoolDay: LocalDate
get() { get() {
return when (this.dayOfWeek) { return when (dayOfWeek) {
SATURDAY, SUNDAY, MONDAY -> this.with(previous(FRIDAY)) SATURDAY, SUNDAY, MONDAY -> with(previous(FRIDAY))
else -> this.minusDays(1) else -> minusDays(1)
} }
} }
inline val LocalDate.nextOrSameSchoolDay: LocalDate inline val LocalDate.nextOrSameSchoolDay: LocalDate
get() { get() {
return when (this.dayOfWeek) { return when (dayOfWeek) {
SATURDAY, SUNDAY -> this.with(next(MONDAY)) SATURDAY, SUNDAY -> with(next(MONDAY))
else -> this else -> this
} }
} }
inline val LocalDate.previousOrSameSchoolDay: LocalDate inline val LocalDate.previousOrSameSchoolDay: LocalDate
get() { get() {
return when (this.dayOfWeek) { return when (dayOfWeek) {
SATURDAY, SUNDAY -> this.with(previous(FRIDAY)) SATURDAY, SUNDAY -> with(previous(FRIDAY))
else -> this else -> this
} }
} }
inline val LocalDate.weekDayName: String inline val LocalDate.weekDayName: String
get() = this.format(ofPattern("EEEE", Locale.getDefault())) get() = format(ofPattern("EEEE", Locale.getDefault()))
inline val LocalDate.shortcutWeekDayName: String inline val LocalDate.shortcutWeekDayName: String
get() = this.format(ofPattern("EEE", Locale.getDefault())) get() = format(ofPattern("EEE", Locale.getDefault()))
inline val LocalDate.monday: LocalDate inline val LocalDate.monday: LocalDate
get() = this.with(MONDAY) get() = with(MONDAY)
inline val LocalDate.friday: LocalDate 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) * [Dz.U. 2016 poz. 1335](http://prawo.sejm.gov.pl/isap.nsf/DocDetails.xsp?id=WDU20160001335)
*/ */
inline val LocalDate.isHolidays: Boolean inline val LocalDate.isHolidays: Boolean
get() { get() = isBefore(firstSchoolDay) && isAfter(lastSchoolDay)
return LocalDate.of(this.year, 9, 1).run {
inline val LocalDate.firstSchoolDay: LocalDate
get() = LocalDate.of(year, 9, 1).run {
when (dayOfWeek) { when (dayOfWeek) {
FRIDAY, SATURDAY, SUNDAY -> with(firstInMonth(MONDAY)) FRIDAY, SATURDAY, SUNDAY -> with(firstInMonth(MONDAY))
else -> this else -> this
} }
}.let { firstSchoolDay -> }
LocalDate.of(this.year, 6, 20)
inline val LocalDate.lastSchoolDay: LocalDate
get() = LocalDate.of(year, 6, 20)
.with(next(FRIDAY)) .with(next(FRIDAY))
.let { lastSchoolDay -> this.isBefore(firstSchoolDay) && this.isAfter(lastSchoolDay) }
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: - naprawienie nawigacji we frekwencji, sprawdzianach, planie lekcji na wakacjach
- problemy z logowaniem jeśli symbol zawierał cyfry - wyświetlanie szczęśliwego numerka po ostatniej aktualizacji dziennika VULCAN (19.06)
- bardzo rzadkie problemy z ładowaniem ocen
- jeszcze rzadsze problemy ze stabilnością podczas logowania
Pełna lista zmian: https://github.com/wulkanowy/wulkanowy/releases 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.assertFalse
import org.junit.Assert.assertTrue import org.junit.Assert.assertTrue
import org.junit.Test import org.junit.Test
import org.threeten.bp.LocalDate import org.threeten.bp.LocalDate.of
import org.threeten.bp.LocalDateTime import org.threeten.bp.LocalDateTime
import org.threeten.bp.Month.JANUARY import org.threeten.bp.Month.JANUARY
import java.util.Locale import java.util.Locale
@ -13,13 +13,13 @@ class TimeExtensionTest {
@Test @Test
fun toLocalDateTest() { 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 @Test
fun toFormattedStringLocalDateTest() { fun toFormattedStringLocalDateTest() {
assertEquals("01.10.2018", LocalDate.of(2018, 10, 1).toFormattedString()) assertEquals("01.10.2018", of(2018, 10, 1).toFormattedString())
assertEquals("2018-10.01", LocalDate.of(2018, 10, 1).toFormattedString("yyyy-MM.dd")) assertEquals("2018-10.01", of(2018, 10, 1).toFormattedString("yyyy-MM.dd"))
} }
@Test @Test
@ -30,20 +30,20 @@ class TimeExtensionTest {
@Test @Test
fun mondayTest() { fun mondayTest() {
assertEquals(LocalDate.of(2018, 10, 1), LocalDate.of(2018, 10, 2).monday) assertEquals(of(2018, 10, 1), of(2018, 10, 2).monday)
assertEquals(LocalDate.of(2018, 10, 1), LocalDate.of(2018, 10, 5).monday) assertEquals(of(2018, 10, 1), of(2018, 10, 5).monday)
assertEquals(LocalDate.of(2018, 10, 1), LocalDate.of(2018, 10, 6).monday) assertEquals(of(2018, 10, 1), of(2018, 10, 6).monday)
assertEquals(LocalDate.of(2018, 10, 1), LocalDate.of(2018, 10, 7).monday) assertEquals(of(2018, 10, 1), of(2018, 10, 7).monday)
assertEquals(LocalDate.of(2018, 10, 8), LocalDate.of(2018, 10, 8).monday) assertEquals(of(2018, 10, 8), of(2018, 10, 8).monday)
} }
@Test @Test
fun fridayTest() { fun fridayTest() {
assertEquals(LocalDate.of(2018, 10, 5), LocalDate.of(2018, 10, 2).friday) assertEquals(of(2018, 10, 5), of(2018, 10, 2).friday)
assertEquals(LocalDate.of(2018, 10, 5), LocalDate.of(2018, 10, 5).friday) assertEquals(of(2018, 10, 5), of(2018, 10, 5).friday)
assertEquals(LocalDate.of(2018, 10, 5), LocalDate.of(2018, 10, 6).friday) assertEquals(of(2018, 10, 5), of(2018, 10, 6).friday)
assertEquals(LocalDate.of(2018, 10, 5), LocalDate.of(2018, 10, 7).friday) assertEquals(of(2018, 10, 5), of(2018, 10, 7).friday)
assertEquals(LocalDate.of(2018, 10, 12), LocalDate.of(2018, 10, 8).friday) assertEquals(of(2018, 10, 12), of(2018, 10, 8).friday)
} }
@Test @Test
@ -57,106 +57,118 @@ class TimeExtensionTest {
@Test @Test
fun weekDayNameTest() { fun weekDayNameTest() {
Locale.setDefault(Locale.forLanguageTag("PL")) 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")) Locale.setDefault(Locale.forLanguageTag("US"))
assertEquals("Monday", LocalDate.of(2018, 10, 1).weekDayName) assertEquals("Monday", of(2018, 10, 1).weekDayName)
} }
@Test @Test
fun nextSchoolDayTest() { fun nextSchoolDayTest() {
assertEquals(LocalDate.of(2018, 10, 2), LocalDate.of(2018, 10, 1).nextSchoolDay) assertEquals(of(2018, 10, 2), of(2018, 10, 1).nextSchoolDay)
assertEquals(LocalDate.of(2018, 10, 3), LocalDate.of(2018, 10, 2).nextSchoolDay) assertEquals(of(2018, 10, 3), of(2018, 10, 2).nextSchoolDay)
assertEquals(LocalDate.of(2018, 10, 4), LocalDate.of(2018, 10, 3).nextSchoolDay) assertEquals(of(2018, 10, 4), of(2018, 10, 3).nextSchoolDay)
assertEquals(LocalDate.of(2018, 10, 5), LocalDate.of(2018, 10, 4).nextSchoolDay) assertEquals(of(2018, 10, 5), of(2018, 10, 4).nextSchoolDay)
assertEquals(LocalDate.of(2018, 10, 8), LocalDate.of(2018, 10, 5).nextSchoolDay) assertEquals(of(2018, 10, 8), of(2018, 10, 5).nextSchoolDay)
assertEquals(LocalDate.of(2018, 10, 8), LocalDate.of(2018, 10, 6).nextSchoolDay) assertEquals(of(2018, 10, 8), of(2018, 10, 6).nextSchoolDay)
assertEquals(LocalDate.of(2018, 10, 8), LocalDate.of(2018, 10, 7).nextSchoolDay) assertEquals(of(2018, 10, 8), of(2018, 10, 7).nextSchoolDay)
assertEquals(LocalDate.of(2018, 10, 9), LocalDate.of(2018, 10, 8).nextSchoolDay) assertEquals(of(2018, 10, 9), of(2018, 10, 8).nextSchoolDay)
} }
@Test @Test
fun previousSchoolDayTest() { fun previousSchoolDayTest() {
assertEquals(LocalDate.of(2018, 10, 9), LocalDate.of(2018, 10, 10).previousSchoolDay) assertEquals(of(2018, 10, 9), of(2018, 10, 10).previousSchoolDay)
assertEquals(LocalDate.of(2018, 10, 8), LocalDate.of(2018, 10, 9).previousSchoolDay) assertEquals(of(2018, 10, 8), of(2018, 10, 9).previousSchoolDay)
assertEquals(LocalDate.of(2018, 10, 5), LocalDate.of(2018, 10, 8).previousSchoolDay) assertEquals(of(2018, 10, 5), of(2018, 10, 8).previousSchoolDay)
assertEquals(LocalDate.of(2018, 10, 5), LocalDate.of(2018, 10, 7).previousSchoolDay) assertEquals(of(2018, 10, 5), of(2018, 10, 7).previousSchoolDay)
assertEquals(LocalDate.of(2018, 10, 5), LocalDate.of(2018, 10, 6).previousSchoolDay) assertEquals(of(2018, 10, 5), of(2018, 10, 6).previousSchoolDay)
assertEquals(LocalDate.of(2018, 10, 4), LocalDate.of(2018, 10, 5).previousSchoolDay) assertEquals(of(2018, 10, 4), of(2018, 10, 5).previousSchoolDay)
assertEquals(LocalDate.of(2018, 10, 3), LocalDate.of(2018, 10, 4).previousSchoolDay) assertEquals(of(2018, 10, 3), of(2018, 10, 4).previousSchoolDay)
} }
@Test @Test
fun nextOrSameSchoolDayTest() { fun nextOrSameSchoolDayTest() {
assertEquals(LocalDate.of(2018, 9, 28), LocalDate.of(2018, 9, 28).nextOrSameSchoolDay) assertEquals(of(2018, 9, 28), of(2018, 9, 28).nextOrSameSchoolDay)
assertEquals(LocalDate.of(2018, 10, 1), LocalDate.of(2018, 9, 29).nextOrSameSchoolDay) assertEquals(of(2018, 10, 1), of(2018, 9, 29).nextOrSameSchoolDay)
assertEquals(LocalDate.of(2018, 10, 1), LocalDate.of(2018, 9, 30).nextOrSameSchoolDay) assertEquals(of(2018, 10, 1), of(2018, 9, 30).nextOrSameSchoolDay)
assertEquals(LocalDate.of(2018, 10, 1), LocalDate.of(2018, 10, 1).nextOrSameSchoolDay) assertEquals(of(2018, 10, 1), of(2018, 10, 1).nextOrSameSchoolDay)
assertEquals(LocalDate.of(2018, 10, 2), LocalDate.of(2018, 10, 2).nextOrSameSchoolDay) assertEquals(of(2018, 10, 2), of(2018, 10, 2).nextOrSameSchoolDay)
} }
@Test @Test
fun previousOrSameSchoolDayTest() { fun previousOrSameSchoolDayTest() {
assertEquals(LocalDate.of(2018, 9, 28), LocalDate.of(2018, 9, 28).previousOrSameSchoolDay) assertEquals(of(2018, 9, 28), of(2018, 9, 28).previousOrSameSchoolDay)
assertEquals(LocalDate.of(2018, 9, 28), LocalDate.of(2018, 9, 29).previousOrSameSchoolDay) assertEquals(of(2018, 9, 28), of(2018, 9, 29).previousOrSameSchoolDay)
assertEquals(LocalDate.of(2018, 9, 28), LocalDate.of(2018, 9, 30).previousOrSameSchoolDay) assertEquals(of(2018, 9, 28), of(2018, 9, 30).previousOrSameSchoolDay)
assertEquals(LocalDate.of(2018, 10, 1), LocalDate.of(2018, 10, 1).previousOrSameSchoolDay) assertEquals(of(2018, 10, 1), of(2018, 10, 1).previousOrSameSchoolDay)
assertEquals(LocalDate.of(2018, 10, 2), LocalDate.of(2018, 10, 2).previousOrSameSchoolDay) assertEquals(of(2018, 10, 2), of(2018, 10, 2).previousOrSameSchoolDay)
} }
@Test @Test
fun isHolidays_schoolEndTest() { fun isHolidays_schoolEndTest() {
assertFalse(LocalDate.of(2017, 6, 23).isHolidays) assertFalse(of(2017, 6, 23).isHolidays)
assertFalse(LocalDate.of(2018, 6, 22).isHolidays) assertFalse(of(2018, 6, 22).isHolidays)
assertFalse(LocalDate.of(2019, 6, 21).isHolidays) assertFalse(of(2019, 6, 21).isHolidays)
assertFalse(LocalDate.of(2020, 6, 26).isHolidays) assertFalse(of(2020, 6, 26).isHolidays)
assertFalse(LocalDate.of(2021, 6, 25).isHolidays) assertFalse(of(2021, 6, 25).isHolidays)
assertFalse(LocalDate.of(2022, 6, 24).isHolidays) assertFalse(of(2022, 6, 24).isHolidays)
assertFalse(LocalDate.of(2023, 6, 23).isHolidays) assertFalse(of(2023, 6, 23).isHolidays)
assertFalse(LocalDate.of(2024, 6, 21).isHolidays) assertFalse(of(2024, 6, 21).isHolidays)
assertFalse(LocalDate.of(2025, 6, 27).isHolidays) assertFalse(of(2025, 6, 27).isHolidays)
} }
@Test @Test
fun isHolidays_holidaysStartTest() { fun isHolidays_holidaysStartTest() {
assertTrue(LocalDate.of(2017, 6, 24).isHolidays) assertTrue(of(2017, 6, 24).isHolidays)
assertTrue(LocalDate.of(2018, 6, 23).isHolidays) assertTrue(of(2018, 6, 23).isHolidays)
assertTrue(LocalDate.of(2019, 6, 22).isHolidays) assertTrue(of(2019, 6, 22).isHolidays)
assertTrue(LocalDate.of(2020, 6, 27).isHolidays) assertTrue(of(2020, 6, 27).isHolidays)
assertTrue(LocalDate.of(2021, 6, 26).isHolidays) assertTrue(of(2021, 6, 26).isHolidays)
assertTrue(LocalDate.of(2022, 6, 25).isHolidays) assertTrue(of(2022, 6, 25).isHolidays)
assertTrue(LocalDate.of(2023, 6, 24).isHolidays) assertTrue(of(2023, 6, 24).isHolidays)
assertTrue(LocalDate.of(2024, 6, 22).isHolidays) assertTrue(of(2024, 6, 22).isHolidays)
assertTrue(LocalDate.of(2025, 6, 28).isHolidays) assertTrue(of(2025, 6, 28).isHolidays)
} }
@Test @Test
fun isHolidays_holidaysEndTest() { fun isHolidays_holidaysEndTest() {
assertTrue(LocalDate.of(2017, 9, 1).isHolidays) // friday assertTrue(of(2017, 9, 1).isHolidays) // friday
assertTrue(LocalDate.of(2017, 9, 2).isHolidays) // saturday assertTrue(of(2017, 9, 2).isHolidays) // saturday
assertTrue(LocalDate.of(2017, 9, 3).isHolidays) // sunday assertTrue(of(2017, 9, 3).isHolidays) // sunday
assertTrue(LocalDate.of(2018, 9, 1).isHolidays) // saturday assertTrue(of(2018, 9, 1).isHolidays) // saturday
assertTrue(LocalDate.of(2018, 9, 2).isHolidays) // sunday assertTrue(of(2018, 9, 2).isHolidays) // sunday
assertTrue(LocalDate.of(2019, 9, 1).isHolidays) // sunday assertTrue(of(2019, 9, 1).isHolidays) // sunday
assertTrue(LocalDate.of(2020, 8, 31).isHolidays) // monday assertTrue(of(2020, 8, 31).isHolidays) // monday
assertTrue(LocalDate.of(2021, 8, 31).isHolidays) // tuesday assertTrue(of(2021, 8, 31).isHolidays) // tuesday
assertTrue(LocalDate.of(2022, 8, 31).isHolidays) // wednesday assertTrue(of(2022, 8, 31).isHolidays) // wednesday
assertTrue(LocalDate.of(2023, 9, 1).isHolidays) // friday assertTrue(of(2023, 9, 1).isHolidays) // friday
assertTrue(LocalDate.of(2023, 9, 2).isHolidays) // saturday assertTrue(of(2023, 9, 2).isHolidays) // saturday
assertTrue(LocalDate.of(2023, 9, 3).isHolidays) // sunday assertTrue(of(2023, 9, 3).isHolidays) // sunday
assertTrue(LocalDate.of(2024, 9, 1).isHolidays) // sunday assertTrue(of(2024, 9, 1).isHolidays) // sunday
assertTrue(LocalDate.of(2025, 8, 31).isHolidays) // sunday assertTrue(of(2025, 8, 31).isHolidays) // sunday
} }
@Test @Test
fun isHolidays_schoolStartTest() { fun isHolidays_schoolStartTest() {
assertFalse(LocalDate.of(2017, 9, 4).isHolidays) // monday assertFalse(of(2017, 9, 4).isHolidays) // monday
assertFalse(LocalDate.of(2018, 9, 3).isHolidays) // monday assertFalse(of(2018, 9, 3).isHolidays) // monday
assertFalse(LocalDate.of(2019, 9, 2).isHolidays) // monday assertFalse(of(2019, 9, 2).isHolidays) // monday
assertFalse(LocalDate.of(2020, 9, 1).isHolidays) // tuesday assertFalse(of(2020, 9, 1).isHolidays) // tuesday
assertFalse(LocalDate.of(2021, 9, 1).isHolidays) // wednesday assertFalse(of(2021, 9, 1).isHolidays) // wednesday
assertFalse(LocalDate.of(2022, 9, 1).isHolidays) // thursday assertFalse(of(2022, 9, 1).isHolidays) // thursday
assertFalse(LocalDate.of(2023, 9, 4).isHolidays) // monday assertFalse(of(2023, 9, 4).isHolidays) // monday
assertFalse(LocalDate.of(2024, 9, 2).isHolidays) // monday assertFalse(of(2024, 9, 2).isHolidays) // monday
assertFalse(LocalDate.of(2025, 9, 1).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 { buildscript {
ext.kotlin_version = '1.3.31' ext.kotlin_version = '1.3.41'
repositories { repositories {
mavenCentral() mavenCentral()
google() google()
@ -9,9 +9,9 @@ buildscript {
} }
dependencies { dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.android.tools.build:gradle:3.4.1' classpath 'com.android.tools.build:gradle:3.4.2'
classpath 'com.google.gms:google-services:4.2.0' classpath 'com.google.gms:google-services:4.3.0'
classpath "io.fabric.tools:gradle:1.29.0" classpath "io.fabric.tools:gradle:1.31.0"
classpath "com.github.triplet.gradle:play-publisher:2.2.1" classpath "com.github.triplet.gradle:play-publisher:2.2.1"
classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.7.1" classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.7.1"
classpath "gradle.plugin.com.star-zero.gradle:githook:1.1.0" classpath "gradle.plugin.com.star-zero.gradle:githook:1.1.0"