From b17356591a657428febc8ca5a2407a94d9fa9a3e Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 1 Nov 2019 19:50:28 +0000 Subject: [PATCH 001/217] Bump assisted-inject-processor-dagger2 from 0.5.0 to 0.5.1 (#575) --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 090a643da..bacfc9d21 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -158,7 +158,7 @@ dependencies { 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" + kapt "com.squareup.inject:assisted-inject-processor-dagger2:0.5.1" implementation "eu.davidea:flexible-adapter:5.1.0" implementation "eu.davidea:flexible-adapter-ui:1.0.0" From 323bc188b135b4c60d27951f2f7e7c50e6a4be4b Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Fri, 1 Nov 2019 20:20:09 +0000 Subject: [PATCH 002/217] Bump assisted-inject-annotations-dagger2 from 0.5.0 to 0.5.1 (#576) --- app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index bacfc9d21..eaf0cae36 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -157,7 +157,7 @@ dependencies { 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" + implementation "com.squareup.inject:assisted-inject-annotations-dagger2:0.5.1" kapt "com.squareup.inject:assisted-inject-processor-dagger2:0.5.1" implementation "eu.davidea:flexible-adapter:5.1.0" From 38370d647d0c6233f933b0240602715999e35dc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Borcz?= Date: Sun, 3 Nov 2019 12:37:03 +0100 Subject: [PATCH 003/217] Add language change settings (#577) --- app/build.gradle | 1 + .../main/java/io/github/wulkanowy/WulkanowyApp.kt | 2 ++ .../preferences/PreferencesRepository.kt | 4 ++++ .../main/java/io/github/wulkanowy/di/AppModule.kt | 5 +++++ .../ui/modules/login/form/LoginFormFragment.kt | 4 ++-- .../studentselect/LoginStudentSelectFragment.kt | 4 ++-- .../ui/modules/login/symbol/LoginSymbolFragment.kt | 4 ++-- .../schoolandteachers/school/SchoolFragment.kt | 8 ++++---- .../ui/modules/settings/SettingsFragment.kt | 11 ++++++++++- .../ui/modules/settings/SettingsPresenter.kt | 8 +++++++- .../wulkanowy/ui/modules/settings/SettingsView.kt | 2 ++ .../main/java/io/github/wulkanowy/utils/AppInfo.kt | 5 +++++ .../io/github/wulkanowy/utils/ContextExtension.kt | 6 +++--- app/src/main/res/values-pl/preferences_values.xml | 6 ++++++ app/src/main/res/values-pl/strings.xml | 1 + app/src/main/res/values/preferences_defaults.xml | 1 + app/src/main/res/values/preferences_keys.xml | 1 + app/src/main/res/values/preferences_values.xml | 11 +++++++++++ app/src/main/res/values/strings.xml | 1 + app/src/main/res/xml/scheme_preferences.xml | 12 ++++++++++-- 20 files changed, 80 insertions(+), 17 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index eaf0cae36..c64eec875 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -164,6 +164,7 @@ dependencies { implementation "eu.davidea:flexible-adapter-ui:1.0.0" implementation "com.aurelhubert:ahbottomnavigation:2.3.4" implementation "com.ncapdevi:frag-nav:3.3.0" + implementation "com.github.YarikSOffice:lingver:1.1.0" implementation "com.github.pwittchen:reactivenetwork-rx2:3.0.6" implementation "io.reactivex.rxjava2:rxandroid:2.1.1" diff --git a/app/src/main/java/io/github/wulkanowy/WulkanowyApp.kt b/app/src/main/java/io/github/wulkanowy/WulkanowyApp.kt index 72969059b..90b3581c8 100644 --- a/app/src/main/java/io/github/wulkanowy/WulkanowyApp.kt +++ b/app/src/main/java/io/github/wulkanowy/WulkanowyApp.kt @@ -6,6 +6,7 @@ import android.util.Log.VERBOSE import androidx.multidex.MultiDex import androidx.work.Configuration import com.jakewharton.threetenabp.AndroidThreeTen +import com.yariksoffice.lingver.Lingver import dagger.android.AndroidInjector import dagger.android.support.DaggerApplication import eu.davidea.flexibleadapter.FlexibleAdapter @@ -44,6 +45,7 @@ class WulkanowyApp : DaggerApplication(), Configuration.Provider { super.onCreate() AndroidThreeTen.init(this) RxJavaPlugins.setErrorHandler(::onError) + Lingver.init(this) themeManager.applyDefaultTheme() initLogging() diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/preferences/PreferencesRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/preferences/PreferencesRepository.kt index e1caf9202..07a3654ac 100644 --- a/app/src/main/java/io/github/wulkanowy/data/repositories/preferences/PreferencesRepository.kt +++ b/app/src/main/java/io/github/wulkanowy/data/repositories/preferences/PreferencesRepository.kt @@ -33,6 +33,10 @@ class PreferencesRepository @Inject constructor( val gradeColorTheme: String get() = getString(R.string.pref_key_grade_color_scheme, R.string.pref_default_grade_color_scheme) + val appLanguageKey = context.getString(R.string.pref_key_app_language) + val appLanguage + get() = getString(appLanguageKey, R.string.pref_default_app_language) + val serviceEnableKey = context.getString(R.string.pref_key_services_enable) val isServiceEnabled: Boolean get() = getBoolean(serviceEnableKey, R.bool.pref_default_services_enable) diff --git a/app/src/main/java/io/github/wulkanowy/di/AppModule.kt b/app/src/main/java/io/github/wulkanowy/di/AppModule.kt index 42e50fa4e..4f5683850 100644 --- a/app/src/main/java/io/github/wulkanowy/di/AppModule.kt +++ b/app/src/main/java/io/github/wulkanowy/di/AppModule.kt @@ -2,6 +2,7 @@ package io.github.wulkanowy.di import android.appwidget.AppWidgetManager import android.content.Context +import com.yariksoffice.lingver.Lingver import dagger.Module import dagger.Provides import eu.davidea.flexibleadapter.FlexibleAdapter @@ -32,4 +33,8 @@ internal class AppModule { @Singleton @Provides fun provideAppInfo() = AppInfo() + + @Singleton + @Provides + fun provideLingver() = Lingver.getInstance() } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormFragment.kt index 1288e2991..8c7b52ead 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormFragment.kt @@ -16,7 +16,7 @@ import io.github.wulkanowy.ui.base.BaseFragment import io.github.wulkanowy.ui.modules.login.LoginActivity import io.github.wulkanowy.utils.AppInfo import io.github.wulkanowy.utils.hideSoftInput -import io.github.wulkanowy.utils.openEmail +import io.github.wulkanowy.utils.openEmailClient import io.github.wulkanowy.utils.openInternetBrowser import io.github.wulkanowy.utils.showSoftInput import kotlinx.android.synthetic.main.fragment_login_form.* @@ -166,7 +166,7 @@ class LoginFormFragment : BaseFragment(), LoginFormView { } override fun openEmail() { - context?.openEmail( + context?.openEmailClient( requireContext().getString(R.string.login_email_intent_title), "wulkanowyinc@gmail.com", requireContext().getString(R.string.login_email_subject), diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectFragment.kt index dba0c951a..8478f7ccf 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectFragment.kt @@ -14,7 +14,7 @@ import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.ui.base.BaseFragment import io.github.wulkanowy.ui.modules.main.MainActivity import io.github.wulkanowy.utils.AppInfo -import io.github.wulkanowy.utils.openEmail +import io.github.wulkanowy.utils.openEmailClient import io.github.wulkanowy.utils.openInternetBrowser import io.github.wulkanowy.utils.setOnItemClickListener import kotlinx.android.synthetic.main.fragment_login_student_select.* @@ -102,7 +102,7 @@ class LoginStudentSelectFragment : BaseFragment(), LoginStudentSelectView { } override fun openEmail() { - context?.openEmail( + context?.openEmailClient( requireContext().getString(R.string.login_email_intent_title), "wulkanowyinc@gmail.com", requireContext().getString(R.string.login_email_subject), diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolFragment.kt index 724e3fbb9..b7ae39a7f 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolFragment.kt @@ -16,7 +16,7 @@ import io.github.wulkanowy.ui.base.BaseFragment import io.github.wulkanowy.ui.modules.login.LoginActivity import io.github.wulkanowy.utils.AppInfo import io.github.wulkanowy.utils.hideSoftInput -import io.github.wulkanowy.utils.openEmail +import io.github.wulkanowy.utils.openEmailClient import io.github.wulkanowy.utils.openInternetBrowser import io.github.wulkanowy.utils.showSoftInput import kotlinx.android.synthetic.main.fragment_login_symbol.* @@ -131,7 +131,7 @@ class LoginSymbolFragment : BaseFragment(), LoginSymbolView { } override fun openEmail() { - context?.openEmail( + context?.openEmailClient( requireContext().getString(R.string.login_email_intent_title), "wulkanowyinc@gmail.com", requireContext().getString(R.string.login_email_subject), diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/school/SchoolFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/school/SchoolFragment.kt index 92f74ca89..4e944d387 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/school/SchoolFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/schoolandteachers/school/SchoolFragment.kt @@ -10,8 +10,8 @@ import io.github.wulkanowy.ui.base.BaseFragment import io.github.wulkanowy.ui.modules.main.MainView import io.github.wulkanowy.ui.modules.schoolandteachers.SchoolAndTeachersChildView import io.github.wulkanowy.ui.modules.schoolandteachers.SchoolAndTeachersFragment -import io.github.wulkanowy.utils.dialPhone -import io.github.wulkanowy.utils.openMapLocation +import io.github.wulkanowy.utils.openDialer +import io.github.wulkanowy.utils.openNavigation import kotlinx.android.synthetic.main.fragment_school.* import javax.inject.Inject @@ -86,10 +86,10 @@ class SchoolFragment : BaseFragment(), SchoolView, MainView.TitledView, SchoolAn } override fun openMapsLocation(location: String) { - context?.openMapLocation(location) + context?.openNavigation(location) } override fun dialPhone(phone: String) { - context?.dialPhone(phone) + context?.openDialer(phone) } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/SettingsFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/SettingsFragment.kt index cb172b98b..172749809 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/SettingsFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/SettingsFragment.kt @@ -5,6 +5,7 @@ import android.content.SharedPreferences import android.os.Bundle import androidx.preference.Preference import androidx.preference.PreferenceFragmentCompat +import com.yariksoffice.lingver.Lingver import dagger.android.support.AndroidSupportInjection import io.github.wulkanowy.R import io.github.wulkanowy.ui.base.BaseActivity @@ -12,7 +13,8 @@ import io.github.wulkanowy.ui.modules.main.MainView import io.github.wulkanowy.utils.AppInfo import javax.inject.Inject -class SettingsFragment : PreferenceFragmentCompat(), SharedPreferences.OnSharedPreferenceChangeListener, +class SettingsFragment : PreferenceFragmentCompat(), + SharedPreferences.OnSharedPreferenceChangeListener, MainView.TitledView, SettingsView { @Inject @@ -21,6 +23,9 @@ class SettingsFragment : PreferenceFragmentCompat(), SharedPreferences.OnSharedP @Inject lateinit var appInfo: AppInfo + @Inject + lateinit var lingver: Lingver + companion object { fun newInstance() = SettingsFragment() } @@ -50,6 +55,10 @@ class SettingsFragment : PreferenceFragmentCompat(), SharedPreferences.OnSharedP activity?.recreate() } + override fun updateLanguage(langCode: String) { + lingver.setLocale(requireContext(), langCode) + } + override fun setServicesSuspended(serviceEnablesKey: String, isHolidays: Boolean) { findPreference(serviceEnablesKey)?.apply { summary = if (isHolidays) getString(R.string.pref_services_suspended) else "" diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/SettingsPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/SettingsPresenter.kt index 88d38e0d2..89ba0ee5e 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/SettingsPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/SettingsPresenter.kt @@ -6,6 +6,7 @@ import io.github.wulkanowy.data.repositories.student.StudentRepository import io.github.wulkanowy.services.sync.SyncManager import io.github.wulkanowy.ui.base.BasePresenter import io.github.wulkanowy.ui.base.ErrorHandler +import io.github.wulkanowy.utils.AppInfo import io.github.wulkanowy.utils.FirebaseAnalyticsHelper import io.github.wulkanowy.utils.SchedulersProvider import io.github.wulkanowy.utils.isHolidays @@ -20,7 +21,8 @@ class SettingsPresenter @Inject constructor( private val preferencesRepository: PreferencesRepository, private val analytics: FirebaseAnalyticsHelper, private val syncManager: SyncManager, - private val chuckCollector: ChuckCollector + private val chuckCollector: ChuckCollector, + private val appInfo: AppInfo ) : BasePresenter(errorHandler, studentRepository, schedulers) { override fun onAttachView(view: SettingsView) { @@ -38,6 +40,10 @@ class SettingsPresenter @Inject constructor( servicesIntervalKey, servicesOnlyWifiKey -> syncManager.startSyncWorker(true) isDebugNotificationEnableKey -> chuckCollector.showNotification(isDebugNotificationEnable) appThemeKey -> view?.recreateView() + appLanguageKey -> view?.run { + updateLanguage(if (appLanguage == "system") appInfo.systemLanguage else appLanguage) + recreateView() + } else -> Unit } } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/SettingsView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/SettingsView.kt index 1c4bf3b0b..e50eb47b3 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/SettingsView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/SettingsView.kt @@ -6,5 +6,7 @@ interface SettingsView : BaseView { fun recreateView() + fun updateLanguage(langCode: String) + fun setServicesSuspended(serviceEnablesKey: String, isHolidays: Boolean) } diff --git a/app/src/main/java/io/github/wulkanowy/utils/AppInfo.kt b/app/src/main/java/io/github/wulkanowy/utils/AppInfo.kt index 3fa83a043..a444da6fe 100644 --- a/app/src/main/java/io/github/wulkanowy/utils/AppInfo.kt +++ b/app/src/main/java/io/github/wulkanowy/utils/AppInfo.kt @@ -1,5 +1,6 @@ package io.github.wulkanowy.utils +import android.content.res.Resources import android.os.Build.MANUFACTURER import android.os.Build.MODEL import android.os.Build.VERSION.SDK_INT @@ -25,4 +26,8 @@ open class AppInfo { open val systemManufacturer: String get() = MANUFACTURER open val systemModel: String get() = MODEL + + @Suppress("DEPRECATION") + open val systemLanguage: String + get() = Resources.getSystem().configuration.locale.language } diff --git a/app/src/main/java/io/github/wulkanowy/utils/ContextExtension.kt b/app/src/main/java/io/github/wulkanowy/utils/ContextExtension.kt index 5110b0674..a265378e2 100644 --- a/app/src/main/java/io/github/wulkanowy/utils/ContextExtension.kt +++ b/app/src/main/java/io/github/wulkanowy/utils/ContextExtension.kt @@ -32,7 +32,7 @@ fun Context.openInternetBrowser(uri: String, onActivityNotFound: (uri: String) - } } -fun Context.openEmail(chooserTitle: String, email: String, subject: String?, body: String?) { +fun Context.openEmailClient(chooserTitle: String, email: String, subject: String?, body: String?) { val emailIntent = Intent(Intent.ACTION_SENDTO, Uri.fromParts("mailto", email, null)) emailIntent.putExtra(Intent.EXTRA_EMAIL, arrayOf(email)) if (subject != null) emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject) @@ -40,7 +40,7 @@ fun Context.openEmail(chooserTitle: String, email: String, subject: String?, bod startActivity(Intent.createChooser(emailIntent, chooserTitle)) } -fun Context.openMapLocation(location: String) { +fun Context.openNavigation(location: String) { val intentUri = Uri.parse("geo:0,0?q=${Uri.encode(location)}") val intent = Intent(Intent.ACTION_VIEW, intentUri) if (intent.resolveActivity(packageManager) != null) { @@ -48,7 +48,7 @@ fun Context.openMapLocation(location: String) { } } -fun Context.dialPhone(phone: String) { +fun Context.openDialer(phone: String) { val intentUri = Uri.parse("tel:$phone") val intent = Intent(Intent.ACTION_DIAL, intentUri) startActivity(intent) diff --git a/app/src/main/res/values-pl/preferences_values.xml b/app/src/main/res/values-pl/preferences_values.xml index e4c30eb05..facec3f0b 100644 --- a/app/src/main/res/values-pl/preferences_values.xml +++ b/app/src/main/res/values-pl/preferences_values.xml @@ -16,6 +16,12 @@ Czarny (AMOLED) + + Język systemu + Polski + English + + Domyślna 0,25 diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 8ff4d3079..2ceff8a03 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -300,6 +300,7 @@ Motyw aplikacji Rozwiń oceny Schemat kolorów ocen + Język aplikacji Powiadomienia Pokazuj powiadomienia diff --git a/app/src/main/res/values/preferences_defaults.xml b/app/src/main/res/values/preferences_defaults.xml index 53b5c2ab3..733d71b0c 100644 --- a/app/src/main/res/values/preferences_defaults.xml +++ b/app/src/main/res/values/preferences_defaults.xml @@ -7,6 +7,7 @@ false light vulcan + system true 60 false diff --git a/app/src/main/res/values/preferences_keys.xml b/app/src/main/res/values/preferences_keys.xml index 730fea591..a2172db96 100644 --- a/app/src/main/res/values/preferences_keys.xml +++ b/app/src/main/res/values/preferences_keys.xml @@ -7,6 +7,7 @@ expand_grade grade_average_mode grade_average_always_calc + app_language services_enable services_interval services_disable_wifi_only diff --git a/app/src/main/res/values/preferences_values.xml b/app/src/main/res/values/preferences_values.xml index 289f14f34..52de39e1b 100644 --- a/app/src/main/res/values/preferences_values.xml +++ b/app/src/main/res/values/preferences_values.xml @@ -24,6 +24,17 @@ black + + System language + Polski + English + + + system + pl + en + + 15 minutes 30 minutes diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4660f9fe0..d5149a1da 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -286,6 +286,7 @@ Application theme Expand grades Grades color scheme + App language Notifications Show notifications diff --git a/app/src/main/res/xml/scheme_preferences.xml b/app/src/main/res/xml/scheme_preferences.xml index 28229f417..d9e6c5333 100644 --- a/app/src/main/res/xml/scheme_preferences.xml +++ b/app/src/main/res/xml/scheme_preferences.xml @@ -37,6 +37,14 @@ app:key="@string/pref_key_grade_color_scheme" app:title="@string/pref_view_grade_color_scheme" app:useSimpleSummaryProvider="true" /> + + app:title="@string/pref_view_grade_average_force_calc" /> Date: Sun, 3 Nov 2019 14:52:35 +0100 Subject: [PATCH 004/217] Add DatePicker to Timetable and Attendance modules. (#522) --- app/build.gradle | 1 + .../modules/attendance/AttendanceFragment.kt | 19 +++++++ .../modules/attendance/AttendancePresenter.kt | 9 ++++ .../ui/modules/attendance/AttendanceView.kt | 3 ++ .../ui/modules/timetable/TimetableFragment.kt | 19 +++++++ .../modules/timetable/TimetablePresenter.kt | 10 ++++ .../ui/modules/timetable/TimetableView.kt | 3 ++ .../completed/CompletedLessonsFragment.kt | 19 +++++++ .../completed/CompletedLessonsPresenter.kt | 9 ++++ .../completed/CompletedLessonsView.kt | 3 ++ .../wulkanowy/utils/SchooldaysRangeLimiter.kt | 51 +++++++++++++++++++ .../main/res/layout/fragment_attendance.xml | 11 ++-- .../main/res/layout/fragment_timetable.xml | 12 +++-- .../layout/fragment_timetable_completed.xml | 1 + app/src/main/res/values-night/styles.xml | 1 + app/src/main/res/values/styles.xml | 2 + 16 files changed, 163 insertions(+), 10 deletions(-) create mode 100644 app/src/main/java/io/github/wulkanowy/utils/SchooldaysRangeLimiter.kt diff --git a/app/build.gradle b/app/build.gradle index c64eec875..bb4f94769 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -176,6 +176,7 @@ dependencies { implementation "at.favre.lib:slf4j-timber:1.0.1" implementation "com.squareup.okhttp3:logging-interceptor:3.12.6" implementation "com.mikepenz:aboutlibraries:7.0.4" + implementation 'com.wdullaer:materialdatetimepicker:4.2.3' playImplementation "com.google.firebase:firebase-core:17.2.1" playImplementation "com.crashlytics.sdk.android:crashlytics:2.10.1" diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceFragment.kt index fb6309f7e..b57bf7d06 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceFragment.kt @@ -7,6 +7,7 @@ import android.view.MenuInflater import android.view.MenuItem import android.view.View import android.view.ViewGroup +import com.wdullaer.materialdatetimepicker.date.DatePickerDialog import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.common.FlexibleItemDecoration import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager @@ -17,9 +18,11 @@ import io.github.wulkanowy.ui.base.BaseFragment import io.github.wulkanowy.ui.modules.attendance.summary.AttendanceSummaryFragment import io.github.wulkanowy.ui.modules.main.MainActivity import io.github.wulkanowy.ui.modules.main.MainView +import io.github.wulkanowy.utils.SchooldaysRangeLimiter import io.github.wulkanowy.utils.dpToPx import io.github.wulkanowy.utils.setOnItemClickListener import kotlinx.android.synthetic.main.fragment_attendance.* +import org.threeten.bp.LocalDate import javax.inject.Inject class AttendanceFragment : BaseFragment(), AttendanceView, MainView.MainChildView, @@ -71,6 +74,7 @@ class AttendanceFragment : BaseFragment(), AttendanceView, MainView.MainChildVie attendanceSwipe.setOnRefreshListener(presenter::onSwipeRefresh) attendancePreviousButton.setOnClickListener { presenter.onPreviousDay() } + attendanceNavDate.setOnClickListener { presenter.onPickDate() } attendanceNextButton.setOnClickListener { presenter.onNextDay() } attendanceNavContainer.setElevationCompat(requireContext().dpToPx(8f)) @@ -141,6 +145,21 @@ class AttendanceFragment : BaseFragment(), AttendanceView, MainView.MainChildVie (activity as? MainActivity)?.showDialogFragment(AttendanceDialog.newInstance(lesson)) } + override fun showDatePickerDialog(currentDate: LocalDate) { + val dateSetListener = DatePickerDialog.OnDateSetListener { _, year, month, dayOfMonth -> + presenter.onDateSet(year, month + 1, dayOfMonth) + } + val datePickerDialog = DatePickerDialog.newInstance(dateSetListener, + currentDate.year, currentDate.monthValue - 1, currentDate.dayOfMonth) + + with(datePickerDialog) { + setDateRangeLimiter(SchooldaysRangeLimiter()) + version = DatePickerDialog.Version.VERSION_2 + scrollOrientation = DatePickerDialog.ScrollOrientation.VERTICAL + show(this@AttendanceFragment.parentFragmentManager, null) + } + } + override fun openSummaryView() { (activity as? MainActivity)?.pushView(AttendanceSummaryFragment.newInstance()) } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendancePresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendancePresenter.kt index b8114208a..0e1f50403 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendancePresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendancePresenter.kt @@ -56,6 +56,15 @@ class AttendancePresenter @Inject constructor( reloadView() } + fun onPickDate() { + view?.showDatePickerDialog(currentDate) + } + + fun onDateSet(year: Int, month: Int, day: Int) { + loadData(LocalDate.of(year, month, day)) + reloadView() + } + fun onSwipeRefresh() { Timber.i("Force refreshing the attendance") loadData(currentDate, true) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceView.kt index 04fe94a48..20b3cd9e8 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceView.kt @@ -2,6 +2,7 @@ package io.github.wulkanowy.ui.modules.attendance import io.github.wulkanowy.data.db.entities.Attendance import io.github.wulkanowy.ui.base.BaseView +import org.threeten.bp.LocalDate interface AttendanceView : BaseView { @@ -35,6 +36,8 @@ interface AttendanceView : BaseView { fun showAttendanceDialog(lesson: Attendance) + fun showDatePickerDialog(currentDate: LocalDate) + fun openSummaryView() fun popView() diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableFragment.kt index a64dee8d8..e1d7db8d6 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableFragment.kt @@ -7,6 +7,7 @@ import android.view.MenuInflater import android.view.MenuItem import android.view.View import android.view.ViewGroup +import com.wdullaer.materialdatetimepicker.date.DatePickerDialog import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.common.FlexibleItemDecoration import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager @@ -17,9 +18,11 @@ import io.github.wulkanowy.ui.base.BaseFragment import io.github.wulkanowy.ui.modules.main.MainActivity import io.github.wulkanowy.ui.modules.main.MainView import io.github.wulkanowy.ui.modules.timetable.completed.CompletedLessonsFragment +import io.github.wulkanowy.utils.SchooldaysRangeLimiter import io.github.wulkanowy.utils.dpToPx import io.github.wulkanowy.utils.setOnItemClickListener import kotlinx.android.synthetic.main.fragment_timetable.* +import org.threeten.bp.LocalDate import javax.inject.Inject class TimetableFragment : BaseFragment(), TimetableView, MainView.MainChildView, @@ -72,6 +75,7 @@ class TimetableFragment : BaseFragment(), TimetableView, MainView.MainChildView, timetableSwipe.setOnRefreshListener(presenter::onSwipeRefresh) timetablePreviousButton.setOnClickListener { presenter.onPreviousDay() } + timetableNavDate.setOnClickListener {presenter.onPickDate() } timetableNextButton.setOnClickListener { presenter.onNextDay() } timetableNavContainer.setElevationCompat(requireContext().dpToPx(8f)) @@ -142,6 +146,21 @@ class TimetableFragment : BaseFragment(), TimetableView, MainView.MainChildView, (activity as? MainActivity)?.showDialogFragment(TimetableDialog.newInstance(lesson)) } + override fun showDatePickerDialog(currentDate: LocalDate) { + val dateSetListener = DatePickerDialog.OnDateSetListener { _, year, month, dayOfMonth -> + presenter.onDateSet(year, month + 1, dayOfMonth) + } + val datePickerDialog = DatePickerDialog.newInstance(dateSetListener, + currentDate.year, currentDate.monthValue - 1, currentDate.dayOfMonth) + + with(datePickerDialog) { + setDateRangeLimiter(SchooldaysRangeLimiter()) + version = DatePickerDialog.Version.VERSION_2 + scrollOrientation = DatePickerDialog.ScrollOrientation.VERTICAL + show(this@TimetableFragment.parentFragmentManager, null) + } + } + override fun openCompletedLessonsView() { (activity as? MainActivity)?.pushView(CompletedLessonsFragment.newInstance()) } diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetablePresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetablePresenter.kt index cea5bf2f5..be80fbd4a 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetablePresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetablePresenter.kt @@ -17,6 +17,7 @@ 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.of import org.threeten.bp.LocalDate.ofEpochDay import timber.log.Timber import java.util.concurrent.TimeUnit.MILLISECONDS @@ -55,6 +56,15 @@ class TimetablePresenter @Inject constructor( reloadView() } + fun onPickDate() { + view?.showDatePickerDialog(currentDate) + } + + fun onDateSet(year: Int, month: Int, day: Int) { + loadData(of(year, month, day)) + reloadView() + } + fun onSwipeRefresh() { Timber.i("Force refreshing the timetable") loadData(currentDate, true) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableView.kt index 84f28974f..749f11e0b 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableView.kt @@ -2,6 +2,7 @@ package io.github.wulkanowy.ui.modules.timetable import io.github.wulkanowy.data.db.entities.Timetable import io.github.wulkanowy.ui.base.BaseView +import org.threeten.bp.LocalDate interface TimetableView : BaseView { @@ -35,6 +36,8 @@ interface TimetableView : BaseView { fun showTimetableDialog(lesson: Timetable) + fun showDatePickerDialog(currentDate: LocalDate) + fun popView() fun openCompletedLessonsView() diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/completed/CompletedLessonsFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/completed/CompletedLessonsFragment.kt index c7b5c6ca1..67d358247 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/completed/CompletedLessonsFragment.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/completed/CompletedLessonsFragment.kt @@ -4,6 +4,7 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import com.wdullaer.materialdatetimepicker.date.DatePickerDialog import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager import eu.davidea.flexibleadapter.items.AbstractFlexibleItem @@ -12,10 +13,12 @@ import io.github.wulkanowy.data.db.entities.CompletedLesson import io.github.wulkanowy.ui.base.BaseFragment import io.github.wulkanowy.ui.modules.main.MainActivity import io.github.wulkanowy.ui.modules.main.MainView +import io.github.wulkanowy.utils.SchooldaysRangeLimiter import io.github.wulkanowy.utils.dpToPx import io.github.wulkanowy.utils.getCompatDrawable import io.github.wulkanowy.utils.setOnItemClickListener import kotlinx.android.synthetic.main.fragment_timetable_completed.* +import org.threeten.bp.LocalDate import javax.inject.Inject class CompletedLessonsFragment : BaseFragment(), CompletedLessonsView, MainView.TitledView { @@ -56,6 +59,7 @@ class CompletedLessonsFragment : BaseFragment(), CompletedLessonsView, MainView. completedLessonsSwipe.setOnRefreshListener(presenter::onSwipeRefresh) completedLessonsPreviousButton.setOnClickListener { presenter.onPreviousDay() } + completedLessonsNavDate.setOnClickListener { presenter.onPickDate() } completedLessonsNextButton.setOnClickListener { presenter.onNextDay() } completedLessonsNavContainer.setElevationCompat(requireContext().dpToPx(8f)) @@ -110,6 +114,21 @@ class CompletedLessonsFragment : BaseFragment(), CompletedLessonsView, MainView. (activity as? MainActivity)?.showDialogFragment(CompletedLessonDialog.newInstance(completedLesson)) } + override fun showDatePickerDialog(currentDate: LocalDate) { + val dateSetListener = DatePickerDialog.OnDateSetListener { _, year, month, dayOfMonth -> + presenter.onDateSet(year, month + 1, dayOfMonth) + } + val datePickerDialog = DatePickerDialog.newInstance(dateSetListener, + currentDate.year, currentDate.monthValue - 1, currentDate.dayOfMonth) + + with(datePickerDialog) { + setDateRangeLimiter(SchooldaysRangeLimiter()) + version = DatePickerDialog.Version.VERSION_2 + scrollOrientation = DatePickerDialog.ScrollOrientation.VERTICAL + show(this@CompletedLessonsFragment.parentFragmentManager, null) + } + } + override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) outState.putLong(SAVED_DATE_KEY, presenter.currentDate.toEpochDay()) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/completed/CompletedLessonsPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/completed/CompletedLessonsPresenter.kt index b936c6576..3a439e1ab 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/completed/CompletedLessonsPresenter.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/completed/CompletedLessonsPresenter.kt @@ -57,6 +57,15 @@ class CompletedLessonsPresenter @Inject constructor( reloadView() } + fun onPickDate() { + view?.showDatePickerDialog(currentDate) + } + + fun onDateSet(year: Int, month: Int, day: Int) { + loadData(LocalDate.of(year, month, day)) + reloadView() + } + fun onSwipeRefresh() { Timber.i("Force refreshing the completed lessons") loadData(currentDate, true) diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/completed/CompletedLessonsView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/completed/CompletedLessonsView.kt index a8bef66f1..e1e167cda 100644 --- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/completed/CompletedLessonsView.kt +++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/completed/CompletedLessonsView.kt @@ -2,6 +2,7 @@ package io.github.wulkanowy.ui.modules.timetable.completed import io.github.wulkanowy.data.db.entities.CompletedLesson import io.github.wulkanowy.ui.base.BaseView +import org.threeten.bp.LocalDate interface CompletedLessonsView : BaseView { @@ -32,4 +33,6 @@ interface CompletedLessonsView : BaseView { fun showNextButton(show: Boolean) fun showCompletedLessonDialog(completedLesson: CompletedLesson) + + fun showDatePickerDialog(currentDate: LocalDate) } diff --git a/app/src/main/java/io/github/wulkanowy/utils/SchooldaysRangeLimiter.kt b/app/src/main/java/io/github/wulkanowy/utils/SchooldaysRangeLimiter.kt new file mode 100644 index 000000000..922aafbd8 --- /dev/null +++ b/app/src/main/java/io/github/wulkanowy/utils/SchooldaysRangeLimiter.kt @@ -0,0 +1,51 @@ +package io.github.wulkanowy.utils + +import android.os.Parcel +import android.os.Parcelable +import com.wdullaer.materialdatetimepicker.date.DateRangeLimiter +import org.threeten.bp.DayOfWeek +import org.threeten.bp.LocalDate +import java.util.Calendar + +@Suppress("UNUSED_PARAMETER") +class SchooldaysRangeLimiter : DateRangeLimiter { + + private val now = LocalDate.now() + + override fun setToNearestDate(day: Calendar): Calendar = day + + override fun isOutOfRange(year: Int, month: Int, day: Int): Boolean { + val date = LocalDate.of(year, month + 1, day) + val dayOfWeek = date.dayOfWeek + return dayOfWeek == DayOfWeek.SUNDAY || dayOfWeek == DayOfWeek.SATURDAY || date.isHolidays + } + + override fun getStartDate(): Calendar { + val startYear = if (now.monthValue <= 6) now.year - 1 else now.year + val startOfSchoolYear = now.withYear(startYear).firstSchoolDay + + val calendar = Calendar.getInstance() + calendar.set(startOfSchoolYear.year, startOfSchoolYear.monthValue - 1, startOfSchoolYear.dayOfMonth) + return calendar + } + + override fun getEndDate(): Calendar { + val endYear = if (now.monthValue > 6) now.year + 1 else now.year + val endOfSchoolYear = now.withYear(endYear).lastSchoolDay + + val calendar = Calendar.getInstance() + calendar.set(endOfSchoolYear.year, endOfSchoolYear.monthValue - 1, endOfSchoolYear.dayOfMonth) + return calendar + } + + override fun writeToParcel(parcel: Parcel, flags: Int) {} + + override fun describeContents() = 0 + + companion object CREATOR : Parcelable.Creator { + + override fun createFromParcel(parcel: Parcel): SchooldaysRangeLimiter = SchooldaysRangeLimiter() + + override fun newArray(size: Int): Array = arrayOfNulls(size) + } +} diff --git a/app/src/main/res/layout/fragment_attendance.xml b/app/src/main/res/layout/fragment_attendance.xml index 4877103ef..b88066e53 100644 --- a/app/src/main/res/layout/fragment_attendance.xml +++ b/app/src/main/res/layout/fragment_attendance.xml @@ -60,8 +60,8 @@ android:layout_width="match_parent" android:layout_height="48dp" android:layout_gravity="bottom" - android:orientation="horizontal" android:gravity="center" + android:orientation="horizontal" tools:ignore="UnusedAttribute"> + app:srcCompat="@drawable/ic_chevron_left" /> + app:srcCompat="@drawable/ic_chevron_right" /> diff --git a/app/src/main/res/layout/fragment_timetable.xml b/app/src/main/res/layout/fragment_timetable.xml index db5c6fc23..27c5c4c1c 100644 --- a/app/src/main/res/layout/fragment_timetable.xml +++ b/app/src/main/res/layout/fragment_timetable.xml @@ -60,28 +60,30 @@ android:layout_width="match_parent" android:layout_height="48dp" android:layout_gravity="bottom" - android:orientation="horizontal" android:gravity="center" + android:orientation="horizontal" tools:ignore="UnusedAttribute"> + + app:srcCompat="@drawable/ic_chevron_left" /> + app:srcCompat="@drawable/ic_chevron_right" /> diff --git a/app/src/main/res/layout/fragment_timetable_completed.xml b/app/src/main/res/layout/fragment_timetable_completed.xml index 7c093a4a7..7c40063e8 100644 --- a/app/src/main/res/layout/fragment_timetable_completed.xml +++ b/app/src/main/res/layout/fragment_timetable_completed.xml @@ -88,6 +88,7 @@ android:layout_width="wrap_content" android:layout_height="match_parent" android:fontFamily="sans-serif" + android:background="?selectableItemBackgroundBorderless" android:gravity="center" android:text="@string/app_name" android:textSize="16sp" /> diff --git a/app/src/main/res/values-night/styles.xml b/app/src/main/res/values-night/styles.xml index 3e4a2466f..492645381 100644 --- a/app/src/main/res/values-night/styles.xml +++ b/app/src/main/res/values-night/styles.xml @@ -10,6 +10,7 @@ ?android:textColorPrimary @android:color/black false + true + +