From 2ff031005e3d542e1033f16f814771b22a8d41ec Mon Sep 17 00:00:00 2001
From: Piotr Romanowski
Date: Sat, 30 May 2020 13:15:28 +0200
Subject: [PATCH 001/100] Fix displaying the feature disabled message in
completed lessons (#849)
---
.../ui/modules/timetable/completed/CompletedLessonsPresenter.kt | 1 +
1 file changed, 1 insertion(+)
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 7243061d6..92aeb5814 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
@@ -43,6 +43,7 @@ class CompletedLessonsPresenter @Inject constructor(
completedLessonsErrorHandler.showErrorMessage = ::showErrorViewOnError
completedLessonsErrorHandler.onFeatureDisabled = {
this.view?.showFeatureDisabled()
+ this.view?.showEmpty(true);
Timber.i("Completed lessons feature disabled by school")
}
loadData(ofEpochDay(date ?: baseDate.toEpochDay()))
From df57d16d21dc053bd837c43bbea493192b669d93 Mon Sep 17 00:00:00 2001
From: "dependabot-preview[bot]"
<27856297+dependabot-preview[bot]@users.noreply.github.com>
Date: Sat, 30 May 2020 11:16:58 +0000
Subject: [PATCH 002/100] Bump dagger from 2.27 to 2.28 (#850)
---
app/build.gradle | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/build.gradle b/app/build.gradle
index 31cada744..2521a10ed 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -114,7 +114,7 @@ play {
ext {
work_manager = "2.3.4"
room = "2.2.5"
- dagger = "2.27"
+ dagger = "2.28"
chucker = "3.2.0"
mockk = "1.9.2"
}
From 2149a4db9f7cf77e7d2cdb0592b9625613763acf Mon Sep 17 00:00:00 2001
From: "dependabot-preview[bot]"
<27856297+dependabot-preview[bot]@users.noreply.github.com>
Date: Sat, 30 May 2020 11:17:22 +0000
Subject: [PATCH 003/100] Bump about_libraries from 8.1.3 to 8.1.4 (#851)
---
build.gradle | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/build.gradle b/build.gradle
index 696e778f5..ad2eddaac 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,6 +1,6 @@
buildscript {
ext.kotlin_version = '1.3.72'
- ext.about_libraries = '8.1.3'
+ ext.about_libraries = '8.1.4'
repositories {
mavenCentral()
google()
From 1cfa1f15c0853da971ed7d6e3a49946a044ba9ac Mon Sep 17 00:00:00 2001
From: "dependabot-preview[bot]"
<27856297+dependabot-preview[bot]@users.noreply.github.com>
Date: Sat, 30 May 2020 11:33:43 +0000
Subject: [PATCH 004/100] Bump gradle from 3.6.3 to 4.0.0 (#852)
---
build.gradle | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/build.gradle b/build.gradle
index ad2eddaac..7b4d04770 100644
--- a/build.gradle
+++ b/build.gradle
@@ -9,7 +9,7 @@ buildscript {
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
- classpath 'com.android.tools.build:gradle:3.6.3'
+ classpath 'com.android.tools.build:gradle:4.0.0'
classpath 'com.google.gms:google-services:4.3.3'
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.1.1'
classpath "com.github.triplet.gradle:play-publisher:2.7.5"
From ab7d30c9950c9f0eab5581494b8197425cb12394 Mon Sep 17 00:00:00 2001
From: "dependabot-preview[bot]"
<27856297+dependabot-preview[bot]@users.noreply.github.com>
Date: Sat, 30 May 2020 12:19:52 +0000
Subject: [PATCH 005/100] Bump sonarqube-gradle-plugin from 2.8 to 3.0 (#853)
---
build.gradle | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/build.gradle b/build.gradle
index 7b4d04770..069c62b24 100644
--- a/build.gradle
+++ b/build.gradle
@@ -13,7 +13,7 @@ buildscript {
classpath 'com.google.gms:google-services:4.3.3'
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.1.1'
classpath "com.github.triplet.gradle:play-publisher:2.7.5"
- classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.8"
+ classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:3.0"
classpath "gradle.plugin.com.star-zero.gradle:githook:1.2.0"
classpath "com.mikepenz.aboutlibraries.plugin:aboutlibraries-plugin:${about_libraries}"
}
From 5c0160a24d2bc3e9e1f9205b2bccec2b2b2138a4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miko=C5=82aj=20Pich?=
Date: Tue, 2 Jun 2020 00:57:22 +0200
Subject: [PATCH 006/100] Don't capture click on login student select checkbox
(#862)
---
.../login/studentselect/LoginStudentSelectAdapter.kt | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectAdapter.kt
index 7383a5ecb..f59260b43 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectAdapter.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectAdapter.kt
@@ -31,9 +31,14 @@ class LoginStudentSelectAdapter @Inject constructor() :
loginItemSchool.text = student.schoolName
loginItemName.isEnabled = !alreadySaved
loginItemSchool.isEnabled = !alreadySaved
- loginItemCheck.isEnabled = !alreadySaved
loginItemSignedIn.visibility = if (alreadySaved) View.VISIBLE else View.GONE
+ with(loginItemCheck) {
+ isEnabled = !alreadySaved
+ keyListener = null
+ isChecked = false
+ }
+
root.setOnClickListener {
onClickListener(student, alreadySaved)
From d8d13c73fb249326a6bd717ed9ed78c020c1c998 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miko=C5=82aj=20Pich?=
Date: Tue, 2 Jun 2020 01:01:02 +0200
Subject: [PATCH 007/100] Filter out empty items in grade summary (#857)
---
.../ui/modules/grade/summary/GradeSummaryPresenter.kt | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/summary/GradeSummaryPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/summary/GradeSummaryPresenter.kt
index 9b88689db..a61ad4af9 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/summary/GradeSummaryPresenter.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/summary/GradeSummaryPresenter.kt
@@ -109,7 +109,17 @@ class GradeSummaryPresenter @Inject constructor(
private fun createGradeSummaryItems(items: List): List {
return items
+ .filter { !checkEmpty(it) }
.sortedBy { it.subject }
.map { it.summary.copy(average = it.average) }
}
+
+ private fun checkEmpty(gradeSummary: GradeDetailsWithAverage): Boolean {
+ return gradeSummary.run {
+ summary.finalGrade.isBlank()
+ && summary.predictedGrade.isBlank()
+ && average == .0
+ && points == "-"
+ }
+ }
}
From fb554a4a3b3fed614ce11cf66e8ed0572b26593b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miko=C5=82aj=20Pich?=
Date: Tue, 2 Jun 2020 01:01:58 +0200
Subject: [PATCH 008/100] Fix capitalization in new message activity (#860)
---
app/src/main/res/layout/activity_send_message.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/src/main/res/layout/activity_send_message.xml b/app/src/main/res/layout/activity_send_message.xml
index f59dcabdf..e0ec52bb6 100644
--- a/app/src/main/res/layout/activity_send_message.xml
+++ b/app/src/main/res/layout/activity_send_message.xml
@@ -148,7 +148,7 @@
android:hint="@string/message_content"
android:imeOptions="flagNoExtractUi"
android:importantForAutofill="no"
- android:inputType="textMultiLine"
+ android:inputType="textMultiLine|textCapSentences"
android:minHeight="58dp"
android:paddingStart="16dp"
android:paddingLeft="16dp"
From 1db42210e8492a707cea4aaaffd6835e6a93130d Mon Sep 17 00:00:00 2001
From: "dependabot-preview[bot]"
<27856297+dependabot-preview[bot]@users.noreply.github.com>
Date: Tue, 2 Jun 2020 01:02:16 +0200
Subject: [PATCH 009/100] Bump about_libraries from 8.1.4 to 8.1.6 (#861)
Bumps `about_libraries` from 8.1.4 to 8.1.6.
Updates `aboutlibraries-plugin` from 8.1.4 to 8.1.6
- [Release notes](https://github.com/mikepenz/AboutLibraries/releases)
- [Changelog](https://github.com/mikepenz/AboutLibraries/blob/develop/gradle-release.gradle)
- [Commits](https://github.com/mikepenz/AboutLibraries/compare/v8.1.4...v8.1.6)
Updates `aboutlibraries-core` from 8.1.4 to 8.1.6
- [Release notes](https://github.com/mikepenz/AboutLibraries/releases)
- [Changelog](https://github.com/mikepenz/AboutLibraries/blob/develop/gradle-release.gradle)
- [Commits](https://github.com/mikepenz/AboutLibraries/compare/v8.1.4...v8.1.6)
Signed-off-by: dependabot-preview[bot]
Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
---
build.gradle | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/build.gradle b/build.gradle
index 069c62b24..98cc971e0 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,6 +1,6 @@
buildscript {
ext.kotlin_version = '1.3.72'
- ext.about_libraries = '8.1.4'
+ ext.about_libraries = '8.1.6'
repositories {
mavenCentral()
google()
From 54f41aaa6387da74a559707146d37b746b8603a4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miko=C5=82aj=20Pich?=
Date: Tue, 2 Jun 2020 01:04:02 +0200
Subject: [PATCH 010/100] Fix too many alarms on samsung devices (#859)
---
.../services/alarm/TimetableNotificationSchedulerHelper.kt | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/app/src/main/java/io/github/wulkanowy/services/alarm/TimetableNotificationSchedulerHelper.kt b/app/src/main/java/io/github/wulkanowy/services/alarm/TimetableNotificationSchedulerHelper.kt
index 5374c4767..54b245ddb 100644
--- a/app/src/main/java/io/github/wulkanowy/services/alarm/TimetableNotificationSchedulerHelper.kt
+++ b/app/src/main/java/io/github/wulkanowy/services/alarm/TimetableNotificationSchedulerHelper.kt
@@ -3,7 +3,7 @@ package io.github.wulkanowy.services.alarm
import android.app.AlarmManager
import android.app.AlarmManager.RTC_WAKEUP
import android.app.PendingIntent
-import android.app.PendingIntent.FLAG_CANCEL_CURRENT
+import android.app.PendingIntent.FLAG_UPDATE_CURRENT
import android.content.Context
import android.content.Intent
import androidx.core.app.AlarmManagerCompat
@@ -55,7 +55,7 @@ class TimetableNotificationSchedulerHelper @Inject constructor(
private fun cancelScheduledTo(range: ClosedRange, requestCode: Int) {
if (now() in range) cancelNotification()
- alarmManager.cancel(PendingIntent.getBroadcast(context, requestCode, Intent(), FLAG_CANCEL_CURRENT))
+ alarmManager.cancel(PendingIntent.getBroadcast(context, requestCode, Intent(), FLAG_UPDATE_CURRENT))
}
fun cancelNotification() = NotificationManagerCompat.from(context).cancel(MainView.Section.TIMETABLE.id)
@@ -102,7 +102,7 @@ class TimetableNotificationSchedulerHelper @Inject constructor(
PendingIntent.getBroadcast(context, getRequestCode(time, studentId), intent.also {
it.putExtra(NOTIFICATION_ID, MainView.Section.TIMETABLE.id)
it.putExtra(LESSON_TYPE, notificationType)
- }, FLAG_CANCEL_CURRENT)
+ }, FLAG_UPDATE_CURRENT)
)
Timber.d("TimetableNotification scheduled: type: $notificationType, subject: ${intent.getStringExtra(LESSON_TITLE)}, start: $time, student: $studentId")
}
From ba5dbf90d82719c11dbf3e94816bcbd702373f72 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miko=C5=82aj=20Pich?=
Date: Tue, 2 Jun 2020 01:04:41 +0200
Subject: [PATCH 011/100] Fixes in updating adapter items (#854)
---
.../grade/details/GradeDetailsAdapter.kt | 59 +++++++++++--------
.../modules/message/tab/MessageTabAdapter.kt | 5 +-
2 files changed, 37 insertions(+), 27 deletions(-)
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsAdapter.kt
index d5e05f3b9..c129d9485 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsAdapter.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsAdapter.kt
@@ -7,6 +7,7 @@ import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
+import androidx.recyclerview.widget.RecyclerView.NO_POSITION
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Grade
import io.github.wulkanowy.databinding.HeaderGradeDetailsBinding
@@ -23,7 +24,7 @@ class GradeDetailsAdapter @Inject constructor() : BaseExpandableAdapter()
- private var expandedPosition = RecyclerView.NO_POSITION
+ private var expandedPosition = NO_POSITION
private var isExpandable = false
@@ -35,7 +36,7 @@ class GradeDetailsAdapter @Inject constructor() : BaseExpandableAdapter 1) {
- Timber.e("Header with subject $subject found ${candidates.size} times! Items: $candidates, expanded: $expandedPosition")
+ Timber.e("Header with subject $subject found ${candidates.size} times! Expanded: $expandedPosition. Items: $candidates")
}
return candidates.first()
}
fun updateHeaderItem(item: GradeDetailsItem) {
- headers[headers.indexOf(item)] = item
- items[items.indexOf(item)] = item
- notifyItemChanged(items.indexOf(item))
+ val headerPosition = headers.indexOf(item)
+ val itemPosition = items.indexOf(item)
+
+ if (headerPosition == NO_POSITION || itemPosition == NO_POSITION) {
+ Timber.e("Invalid update header positions! Header: $headerPosition, item: $itemPosition")
+ }
+
+ headers[headerPosition] = item
+ items[itemPosition] = item
+ notifyItemChanged(itemPosition)
}
fun collapseAll() {
if (expandedPosition != -1) {
refreshList(headers)
- expandedPosition = RecyclerView.NO_POSITION
+ expandedPosition = NO_POSITION
}
}
@Synchronized
- private fun refreshList(newItems: List) {
+ private fun refreshList(newItems: MutableList) {
val diffCallback = GradeDetailsDiffUtil(items, newItems)
val diffResult = DiffUtil.calculateDiff(diffCallback)
- items = newItems.toMutableList()
+ items = newItems
diffResult.dispatchUpdatesTo(this)
}
@@ -99,23 +103,24 @@ class GradeDetailsAdapter @Inject constructor() : BaseExpandableAdapter bindHeaderViewHolder(
- binding = holder.binding,
+ holder = holder,
header = items[position].value as GradeDetailsHeader,
- headerPosition = headers.indexOf(items[position]),
- adapterPosition = position
+ position = position
)
is ItemViewHolder -> bindItemViewHolder(
- binding = holder.binding,
- grade = items[position].value as Grade,
- position = holder.adapterPosition
+ holder = holder,
+ grade = items[position].value as Grade
)
}
}
- private fun bindHeaderViewHolder(binding: HeaderGradeDetailsBinding, header: GradeDetailsHeader, headerPosition: Int, adapterPosition: Int) {
- with(binding) {
+ private fun bindHeaderViewHolder(holder: HeaderViewHolder, header: GradeDetailsHeader, position: Int) {
+ val headerPosition = headers.indexOf(items[position])
+ val adapterPosition = holder.adapterPosition
+
+ with(holder.binding) {
gradeHeaderDivider.visibility = if (adapterPosition == 0) View.GONE else View.VISIBLE
- gradeHeaderSubject.apply {
+ with(gradeHeaderSubject) {
text = header.subject
maxLines = if (headerPosition == expandedPosition) 2 else 1
}
@@ -130,7 +135,7 @@ class GradeDetailsAdapter @Inject constructor() : BaseExpandableAdapter
Date: Tue, 2 Jun 2020 15:13:41 +0200
Subject: [PATCH 012/100] Revert "Bump sonarqube-gradle-plugin from 2.8 to 3.0"
(#864)
This reverts commit ab7d30c9950c9f0eab5581494b8197425cb12394.
---
build.gradle | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/build.gradle b/build.gradle
index 98cc971e0..7e5759d12 100644
--- a/build.gradle
+++ b/build.gradle
@@ -13,7 +13,7 @@ buildscript {
classpath 'com.google.gms:google-services:4.3.3'
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.1.1'
classpath "com.github.triplet.gradle:play-publisher:2.7.5"
- classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:3.0"
+ classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.8"
classpath "gradle.plugin.com.star-zero.gradle:githook:1.2.0"
classpath "com.mikepenz.aboutlibraries.plugin:aboutlibraries-plugin:${about_libraries}"
}
From ff5a47b0dfceddce73067448736da7c0cf3713ff Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafa=C5=82=20Borcz?=
Date: Tue, 2 Jun 2020 15:18:41 +0200
Subject: [PATCH 013/100] New Crowdin translations (#856)
---
app/src/main/res/values-ru/strings.xml | 4 +--
app/src/main/res/values-uk/strings.xml | 38 +++++++++++++-------------
2 files changed, 21 insertions(+), 21 deletions(-)
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index c0c751960..6eb8f7741 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -290,8 +290,8 @@
Поделиться логами
Обновить
- Check for updates
- Before reporting a bug, check first if an update with the bug fix is available
+ Проверить наличие обновлений
+ Прежде чем сообщать об ошибке, проверьте наличие обновлений
Содержание
Повторить
diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml
index a63e5682a..ec4dbc155 100644
--- a/app/src/main/res/values-uk/strings.xml
+++ b/app/src/main/res/values-uk/strings.xml
@@ -120,14 +120,14 @@
Години
Зміни
Брак уроків у цей день
- %s min
- %s sec
- %1$s left
- in %1$s
- Finished
- Now: %s
- Next: %s
- Later: %s
+ %s хвилин
+ %s сек
+ %1$s лишилося
+ через %1$s
+ Завершено
+ Зараз: %s
+ Наступний: %s
+ Пізніше: %s
Уроки, що відбулися
Показати уроки, що відбулися
@@ -290,8 +290,8 @@
Поділитися логами
Оновити
- Check for updates
- Before reporting a bug, check first if an update with the bug fix is available
+ Провірити наявність оновлень
+ Перед тим, як повідомлювати о помілці, перевірте наявність оновлень
Зміст
Повторити
@@ -308,8 +308,8 @@
Предмет
Попередній
Наступний
- Search
- Search...
+ Пошук
+ Пошук...
Брак уроків
Увібрати тему
@@ -324,17 +324,17 @@
Показувати присутність у відвідуваності
Тема додатку
Більше оцінок
- Mark current lesson in timetable
- Show chart list in class grades
+ Позначити поточний урок у розкладі
+ Показувати діаграми в оцінках класу
Показати уроки всього класу
Схема кольорів оцінок
Мова додатку
Повідомлення
Показувати повідомлення
- Show upcoming lesson notifications
- Fix synchronization & notifications issues
- Your device may have data synchronization issues and with notifications.\n\nTo fix them, you need to add Wulkanowy to the autostart and turn off battery optimization/saving in the phone settings.
- Go to settings
+ Показувати повідомлення о наступних уроках
+ Виправити помилки з синхронізацією і повідомленнями
+ На вашому пристрої можуть бути помилки з синхронізацією і повідомленнями\n\nЩоб виправити іх, вам необхідно додати Wulkanowy в авто-старт и вимкнути оптимізацію/экономію батареї в налаштуваннях пристрою.
+ Перейти до налаштувань
Показувати дебаг-повідомлення
Синхронізація
Автоматична синхронізація
@@ -360,7 +360,7 @@
Нові повідомлення
Нові нотатки
Показувати push-повідомлення
- Upcoming lessons
+ Наступні уроки
Дебаг
Чорний
From 792e44a9d0b263832e5cf70d15cbaf21e723f820 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miko=C5=82aj=20Pich?=
Date: Tue, 2 Jun 2020 15:50:32 +0200
Subject: [PATCH 014/100] Fix login button state in student select login
fragment (#863)
---
.../LoginStudentSelectAdapter.kt | 9 ++++++-
.../LoginStudentSelectPresenter.kt | 8 +++++-
.../layout/fragment_login_student_select.xml | 25 ++++++++++---------
3 files changed, 28 insertions(+), 14 deletions(-)
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectAdapter.kt
index f59260b43..3332f2be8 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectAdapter.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectAdapter.kt
@@ -12,7 +12,13 @@ import javax.inject.Inject
class LoginStudentSelectAdapter @Inject constructor() :
RecyclerView.Adapter() {
+ private val checkedList = mutableMapOf()
+
var items = emptyList>()
+ set(value) {
+ field = value
+ checkedList.clear()
+ }
var onClickListener: (Student, alreadySaved: Boolean) -> Unit = { _, _ -> }
@@ -36,7 +42,7 @@ class LoginStudentSelectAdapter @Inject constructor() :
with(loginItemCheck) {
isEnabled = !alreadySaved
keyListener = null
- isChecked = false
+ isChecked = checkedList[position] ?: false
}
root.setOnClickListener {
@@ -45,6 +51,7 @@ class LoginStudentSelectAdapter @Inject constructor() :
with(loginItemCheck) {
if (isEnabled) {
isChecked = !isChecked
+ checkedList[position] = isChecked
}
}
}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectPresenter.kt
index b2d0aed91..db25c0da3 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectPresenter.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectPresenter.kt
@@ -22,7 +22,7 @@ class LoginStudentSelectPresenter @Inject constructor(
var students = emptyList()
- private var selectedStudents = mutableListOf()
+ private val selectedStudents = mutableListOf()
fun onAttachView(view: LoginStudentSelectView, students: Serializable?) {
super.onAttachView(view)
@@ -69,6 +69,7 @@ class LoginStudentSelectPresenter @Inject constructor(
}
private fun loadData(students: List) {
+ resetSelectedState()
this.students = students
disposable.add(studentRepository.getSavedStudents()
.map { savedStudents ->
@@ -88,6 +89,11 @@ class LoginStudentSelectPresenter @Inject constructor(
)
}
+ private fun resetSelectedState() {
+ selectedStudents.clear()
+ view?.enableSignIn(false)
+ }
+
private fun registerStudents(students: List) {
disposable.add(studentRepository.saveStudents(students)
.map { students.first().apply { id = it.first() } }
diff --git a/app/src/main/res/layout/fragment_login_student_select.xml b/app/src/main/res/layout/fragment_login_student_select.xml
index 64e06cbd5..f9c6c1572 100644
--- a/app/src/main/res/layout/fragment_login_student_select.xml
+++ b/app/src/main/res/layout/fragment_login_student_select.xml
@@ -24,10 +24,10 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
+ android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
- android:visibility="gone"
tools:visibility="visible">
+ android:layout_marginRight="16dp"
+ android:orientation="horizontal">
+
@@ -95,9 +96,9 @@
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginLeft="32dp"
+ android:layout_marginTop="32dp"
android:layout_marginEnd="32dp"
android:layout_marginRight="32dp"
- android:layout_marginTop="32dp"
android:layout_marginBottom="32dp"
android:gravity="center_horizontal"
android:text="@string/login_select_student"
@@ -129,8 +130,8 @@
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:layout_marginEnd="24dp"
- android:layout_marginRight="24dp"
android:layout_marginBottom="32dp"
+ android:enabled="false"
android:text="@string/login_sign_in"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
From 191b1ad022e19c02bb53231e88e38aba21b63a4d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miko=C5=82aj=20Pich?=
Date: Tue, 2 Jun 2020 15:51:15 +0200
Subject: [PATCH 015/100] Emulate summaries from grade list when summaries are
empty (#855)
---
app/build.gradle | 2 +-
.../ui/modules/grade/GradeAverageProvider.kt | 33 ++-
.../grade/summary/GradeSummaryPresenter.kt | 2 +-
.../modules/grade/GradeAverageProviderTest.kt | 269 ++++++++++++------
4 files changed, 215 insertions(+), 91 deletions(-)
diff --git a/app/build.gradle b/app/build.gradle
index 2521a10ed..f29af84fa 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -124,7 +124,7 @@ configurations.all {
}
dependencies {
- implementation "io.github.wulkanowy:sdk:0.18.1"
+ implementation "io.github.wulkanowy:sdk:d0081b4"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation "androidx.core:core-ktx:1.2.0"
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeAverageProvider.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeAverageProvider.kt
index 954b57566..9582a5db3 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeAverageProvider.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeAverageProvider.kt
@@ -1,5 +1,7 @@
package io.github.wulkanowy.ui.modules.grade
+import io.github.wulkanowy.data.db.entities.Grade
+import io.github.wulkanowy.data.db.entities.GradeSummary
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.repositories.grade.GradeRepository
@@ -58,15 +60,14 @@ class GradeAverageProvider @Inject constructor(
val isAnyAverage = summaries.any { it.average != .0 }
val allGrades = details.groupBy { it.subject }
- summaries.map { summary ->
+ summaries.emulateEmptySummaries(student, semester, allGrades.toList(), isAnyAverage).map { summary ->
val grades = allGrades[summary.subject].orEmpty()
GradeDetailsWithAverage(
subject = summary.subject,
average = if (!isAnyAverage || preferencesRepository.gradeAverageForceCalc) {
- grades.map {
- if (student.loginMode == Sdk.Mode.SCRAPPER.name) it.changeModifier(plusModifier, minusModifier)
- else it
- }.calcAverage()
+ (if (student.loginMode == Sdk.Mode.SCRAPPER.name)
+ grades.map { it.changeModifier(plusModifier, minusModifier) }
+ else grades).calcAverage()
} else summary.average,
points = summary.pointsSum,
summary = summary,
@@ -75,4 +76,26 @@ class GradeAverageProvider @Inject constructor(
}
}
}
+
+ private fun List.emulateEmptySummaries(student: Student, semester: Semester, grades: List>>, calcAverage: Boolean): List {
+ if (isNotEmpty() && size == grades.size) return this
+
+ return grades.mapIndexed { i, (subject, details) ->
+ singleOrNull { it.subject == subject }?.let { return@mapIndexed it }
+ GradeSummary(
+ studentId = student.studentId,
+ semesterId = semester.semesterId,
+ position = i,
+ subject = subject,
+ predictedGrade = "",
+ finalGrade = "",
+ proposedPoints = "",
+ finalPoints = "",
+ pointsSum = "",
+ average = if (calcAverage) (if (student.loginMode == Sdk.Mode.SCRAPPER.name) {
+ details.map { it.changeModifier(plusModifier, minusModifier) }
+ } else details).calcAverage() else .0
+ )
+ }
+ }
}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/summary/GradeSummaryPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/summary/GradeSummaryPresenter.kt
index a61ad4af9..229a0107d 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/summary/GradeSummaryPresenter.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/summary/GradeSummaryPresenter.kt
@@ -119,7 +119,7 @@ class GradeSummaryPresenter @Inject constructor(
summary.finalGrade.isBlank()
&& summary.predictedGrade.isBlank()
&& average == .0
- && points == "-"
+ && points.isBlank()
}
}
}
diff --git a/app/src/test/java/io/github/wulkanowy/ui/modules/grade/GradeAverageProviderTest.kt b/app/src/test/java/io/github/wulkanowy/ui/modules/grade/GradeAverageProviderTest.kt
index fcc30593f..ee8634ca8 100644
--- a/app/src/test/java/io/github/wulkanowy/ui/modules/grade/GradeAverageProviderTest.kt
+++ b/app/src/test/java/io/github/wulkanowy/ui/modules/grade/GradeAverageProviderTest.kt
@@ -1,11 +1,11 @@
package io.github.wulkanowy.ui.modules.grade
+import io.github.wulkanowy.createSemesterEntity
import io.github.wulkanowy.data.db.entities.Grade
import io.github.wulkanowy.data.db.entities.GradeSummary
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.repositories.grade.GradeRepository
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
-import io.github.wulkanowy.createSemesterEntity
import io.github.wulkanowy.data.repositories.semester.SemesterRepository
import io.github.wulkanowy.sdk.Sdk
import io.reactivex.Single
@@ -84,8 +84,6 @@ class GradeAverageProviderTest {
fun setUp() {
MockitoAnnotations.initMocks(this)
- `when`(preferencesRepository.gradeMinusModifier).thenReturn(.33)
- `when`(preferencesRepository.gradePlusModifier).thenReturn(.33)
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(false)
`when`(semesterRepository.getSemesters(student)).thenReturn(Single.just(semesters))
@@ -93,7 +91,83 @@ class GradeAverageProviderTest {
}
@Test
- fun onlyOneSemesterTest() {
+ fun `force calc current semester average with default modifiers in scraper mode`() {
+ `when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true)
+ `when`(preferencesRepository.gradeAverageMode).thenReturn("only_one_semester")
+ `when`(semesterRepository.getSemesters(student)).thenReturn(Single.just(semesters))
+ `when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGradeWithModifier to secondSummariesWithModifier))
+
+ val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
+
+ assertEquals(3.5, items.single { it.subject == "Język polski" }.average, .0) // from details and after set custom plus/minus
+ }
+
+ @Test
+ fun `force calc current semester average with custom modifiers in scraper mode`() {
+ val student = student.copy(loginMode = Sdk.Mode.SCRAPPER.name)
+
+ `when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true)
+ `when`(preferencesRepository.gradeMinusModifier).thenReturn(.33)
+ `when`(preferencesRepository.gradePlusModifier).thenReturn(.33)
+
+ `when`(preferencesRepository.gradeAverageMode).thenReturn("only_one_semester")
+ `when`(semesterRepository.getSemesters(student)).thenReturn(Single.just(semesters))
+ `when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGradeWithModifier to secondSummariesWithModifier))
+
+ val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
+
+ assertEquals(3.5, items.single { it.subject == "Język polski" }.average, .0) // from details and after set custom plus/minus
+ }
+
+ @Test
+ fun `force calc current semester average with custom modifiers in api mode`() {
+ val student = student.copy(loginMode = Sdk.Mode.API.name)
+
+ `when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true)
+ `when`(preferencesRepository.gradeMinusModifier).thenReturn(.33) // useless in this mode
+ `when`(preferencesRepository.gradePlusModifier).thenReturn(.33)
+
+ `when`(preferencesRepository.gradeAverageMode).thenReturn("only_one_semester")
+ `when`(semesterRepository.getSemesters(student)).thenReturn(Single.just(semesters))
+ `when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGradeWithModifier to secondSummariesWithModifier))
+
+ val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
+
+ assertEquals(3.375, items.single { it.subject == "Język polski" }.average, .0) // (from details): 3.375
+ }
+
+ @Test
+ fun `force calc current semester average with custom modifiers in hybrid mode`() {
+ val student = student.copy(loginMode = Sdk.Mode.HYBRID.name)
+
+ `when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true)
+ `when`(preferencesRepository.gradeMinusModifier).thenReturn(.33) // useless in this mode
+ `when`(preferencesRepository.gradePlusModifier).thenReturn(.33)
+
+ `when`(preferencesRepository.gradeAverageMode).thenReturn("only_one_semester")
+ `when`(semesterRepository.getSemesters(student)).thenReturn(Single.just(semesters))
+ `when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGradeWithModifier to secondSummariesWithModifier))
+
+ val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
+
+ assertEquals(3.375, items.single { it.subject == "Język polski" }.average, .0) // (from details): 3.375
+ }
+
+ @Test
+ fun `calc current semester average`() {
+ `when`(preferencesRepository.gradeAverageForceCalc).thenReturn(false)
+ `when`(preferencesRepository.gradeAverageMode).thenReturn("only_one_semester")
+ `when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGrades to secondSummaries))
+
+ val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
+
+ assertEquals(2, items.size)
+ assertEquals(2.9, items.single { it.subject == "Matematyka" }.average, .0) // from summary: 2,9
+ assertEquals(3.4, items.single { it.subject == "Fizyka" }.average, .0) // from details: 3,4
+ }
+
+ @Test
+ fun `force calc current semester average`() {
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true)
`when`(preferencesRepository.gradeAverageMode).thenReturn("only_one_semester")
`when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGrades to secondSummaries))
@@ -101,65 +175,12 @@ class GradeAverageProviderTest {
val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
assertEquals(2, items.size)
- assertEquals(2.5, items.single { it.subject == "Matematyka" }.average, .0)
- assertEquals(3.0, items.single { it.subject == "Fizyka" }.average, .0)
+ assertEquals(2.5, items.single { it.subject == "Matematyka" }.average, .0) // from details: 2,5
+ assertEquals(3.0, items.single { it.subject == "Fizyka" }.average, .0) // from details: 3,0
}
@Test
- fun onlyOneSemester_gradesWithModifiers_default() {
- `when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true)
- `when`(preferencesRepository.gradeAverageMode).thenReturn("only_one_semester")
- `when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGradeWithModifier to secondSummariesWithModifier))
-
- val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
-
- assertEquals(3.5, items.single { it.subject == "Język polski" }.average, .0)
- }
-
- @Test
- fun onlyOneSemester_gradesWithModifiers_api() {
- val student = student.copy(loginMode = Sdk.Mode.API.name)
-
- `when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true)
- `when`(preferencesRepository.gradeAverageMode).thenReturn("only_one_semester")
- `when`(semesterRepository.getSemesters(student)).thenReturn(Single.just(semesters))
- `when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGradeWithModifier to secondSummariesWithModifier))
-
- val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
-
- assertEquals(3.375, items.single { it.subject == "Język polski" }.average, .0)
- }
-
- @Test
- fun onlyOneSemester_gradesWithModifiers_scrapper() {
- val student = student.copy(loginMode = Sdk.Mode.SCRAPPER.name)
-
- `when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true)
- `when`(preferencesRepository.gradeAverageMode).thenReturn("only_one_semester")
- `when`(semesterRepository.getSemesters(student)).thenReturn(Single.just(semesters))
- `when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGradeWithModifier to secondSummariesWithModifier))
-
- val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
-
- assertEquals(3.5, items.single { it.subject == "Język polski" }.average, .0)
- }
-
- @Test
- fun onlyOneSemester_gradesWithModifiers_hybrid() {
- val student = student.copy(loginMode = Sdk.Mode.HYBRID.name)
-
- `when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true)
- `when`(preferencesRepository.gradeAverageMode).thenReturn("only_one_semester")
- `when`(semesterRepository.getSemesters(student)).thenReturn(Single.just(semesters))
- `when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGradeWithModifier to secondSummariesWithModifier))
-
- val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
-
- assertEquals(3.375, items.single { it.subject == "Język polski" }.average, .0)
- }
-
- @Test
- fun allYearFirstSemesterTest() {
+ fun `force calc full year average when current is first`() {
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true)
`when`(preferencesRepository.gradeAverageMode).thenReturn("all_year")
`when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(firstGrades to firstSummaries))
@@ -167,33 +188,19 @@ class GradeAverageProviderTest {
val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[1].semesterId).blockingGet()
assertEquals(2, items.size)
- assertEquals(3.5, items.single { it.subject == "Matematyka" }.average, .0)
- assertEquals(3.5, items.single { it.subject == "Fizyka" }.average, .0)
- }
-
- @Test
- fun allYearSecondSemesterTest() {
- `when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true)
- `when`(preferencesRepository.gradeAverageMode).thenReturn("all_year")
- `when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(firstGrades to firstSummaries))
- `when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGrades to secondSummaries))
-
- val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
-
- assertEquals(2, items.size)
- assertEquals(3.0, items.single { it.subject == "Matematyka" }.average, .0)
- assertEquals(3.25, items.single { it.subject == "Fizyka" }.average, .0)
+ assertEquals(3.5, items.single { it.subject == "Matematyka" }.average, .0) // (from summary): 3,5
+ assertEquals(3.5, items.single { it.subject == "Fizyka" }.average, .0) // (from summary): 3,5
}
@Test(expected = IllegalArgumentException::class)
- fun incorrectAverageModeTest() {
+ fun `calc average on invalid mode`() {
`when`(preferencesRepository.gradeAverageMode).thenReturn("test_mode")
gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId, true).blockingGet()
}
@Test
- fun allYearSemester_averageFromSummary() {
+ fun `calc full year average`() {
`when`(preferencesRepository.gradeAverageMode).thenReturn("all_year")
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(false)
`when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(firstGrades to listOf(
@@ -208,14 +215,14 @@ class GradeAverageProviderTest {
val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
assertEquals(2, items.size)
- assertEquals(3.25, items.single { it.subject == "Matematyka" }.average, .0)
- assertEquals(3.75, items.single { it.subject == "Fizyka" }.average, .0)
+ assertEquals(3.25, items.single { it.subject == "Matematyka" }.average, .0) // (from summaries ↑): 3,0 + 3,5 → 3,25
+ assertEquals(3.75, items.single { it.subject == "Fizyka" }.average, .0) // (from summaries ↑): 3,5 + 4,0 → 3,75
}
@Test
- fun onlyOneSemester_averageFromSummary_forceCalc() {
- `when`(preferencesRepository.gradeAverageMode).thenReturn("all_year")
+ fun `force calc full year average`() {
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true)
+ `when`(preferencesRepository.gradeAverageMode).thenReturn("all_year")
`when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(firstGrades to firstSummaries))
`when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGrades to listOf(
getSummary(22, "Matematyka", 1.1),
@@ -225,8 +232,102 @@ class GradeAverageProviderTest {
val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
assertEquals(2, items.size)
- assertEquals(3.0, items.single { it.subject == "Matematyka" }.average, .0)
- assertEquals(3.25, items.single { it.subject == "Fizyka" }.average, .0)
+ assertEquals(3.0, items.single { it.subject == "Matematyka" }.average, .0) // (from details): 3,5 + 2,5 → 3,0
+ assertEquals(3.25, items.single { it.subject == "Fizyka" }.average, .0) // (from details): 3,5 + 3,0 → 3,25
+ }
+
+ @Test
+ fun `calc full year average when no summaries`() {
+ `when`(preferencesRepository.gradeAverageForceCalc).thenReturn(false)
+ `when`(preferencesRepository.gradeAverageMode).thenReturn("all_year")
+
+ `when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(firstGrades to emptyList()))
+ `when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGrades to emptyList()))
+
+ val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
+
+ assertEquals(2, items.size)
+ assertEquals(3.0, items.single { it.subject == "Matematyka" }.average, .0) // (from details): 2,5 + 3,5 → 3,0
+ assertEquals(3.25, items.single { it.subject == "Fizyka" }.average, .0) // (from details): 3,5 + 3,0 → 3,25
+ }
+
+ @Test
+ fun `force calc full year average when no summaries`() {
+ `when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true)
+ `when`(preferencesRepository.gradeAverageMode).thenReturn("all_year")
+
+ `when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(firstGrades to emptyList()))
+ `when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGrades to emptyList()))
+
+ val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
+
+ assertEquals(2, items.size)
+ assertEquals(3.0, items.single { it.subject == "Matematyka" }.average, .0) // (from details): 3,5 + 2,5 → 3,0
+ assertEquals(3.25, items.single { it.subject == "Fizyka" }.average, .0) // (from details): 3,5 + 3,0 → 3,25
+ }
+
+ @Test
+ fun `calc full year average when missing summaries in both semesters`() {
+ `when`(preferencesRepository.gradeAverageForceCalc).thenReturn(false)
+ `when`(preferencesRepository.gradeAverageMode).thenReturn("all_year")
+
+ `when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(firstGrades to listOf(
+ getSummary(22, "Matematyka", 4.0)
+ )))
+ `when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGrades to listOf(
+ getSummary(23, "Matematyka", 3.0)
+ )))
+
+ val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
+
+ assertEquals(2, items.size)
+ assertEquals(3.5, items.single { it.subject == "Matematyka" }.average, .0) // (from summaries ↑): 4,0 + 3,0 → 3,5
+ assertEquals(3.25, items.single { it.subject == "Fizyka" }.average, .0) // (from details): 3,5 + 3,0 → 3,25
+ }
+
+ @Test
+ fun `calc full year average when missing summary in second semester`() {
+ `when`(preferencesRepository.gradeAverageForceCalc).thenReturn(false)
+ `when`(preferencesRepository.gradeAverageMode).thenReturn("all_year")
+
+ `when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(firstGrades to firstSummaries))
+ `when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGrades to secondSummaries.dropLast(1)))
+
+ val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
+
+ assertEquals(2, items.size)
+ assertEquals(3.4, items.single { it.subject == "Matematyka" }.average, .0) // (from summaries): 3,9 + 2,9 → 3,4
+ assertEquals(3.05, items.single { it.subject == "Fizyka" }.average, .0) // 3,1 (from summary) + 3,0 (from details) → 3,05
+ }
+
+ @Test
+ fun `calc full year average when missing summary in first semester`() {
+ `when`(preferencesRepository.gradeAverageForceCalc).thenReturn(false)
+ `when`(preferencesRepository.gradeAverageMode).thenReturn("all_year")
+
+ `when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(firstGrades to firstSummaries.dropLast(1)))
+ `when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGrades to secondSummaries))
+
+ val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
+
+ assertEquals(2, items.size)
+ assertEquals(3.4, items.single { it.subject == "Matematyka" }.average, .0) // (from summaries): 3,9 + 2,9 → 3,4
+ assertEquals(3.45, items.single { it.subject == "Fizyka" }.average, .0) // 3,5 (from details) + 3,4 (from summary) → 3,45
+ }
+
+ @Test
+ fun `force calc full year average when missing summary in first semester`() {
+ `when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true)
+ `when`(preferencesRepository.gradeAverageMode).thenReturn("all_year")
+
+ `when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(firstGrades to firstSummaries.dropLast(1)))
+ `when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGrades to secondSummaries))
+
+ val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
+
+ assertEquals(2, items.size)
+ assertEquals(3.0, items.single { it.subject == "Matematyka" }.average, .0) // (from details): 3,5 + 2,5 → 3,0
+ assertEquals(3.25, items.single { it.subject == "Fizyka" }.average, .0) // (from details): 3,5 + 3,0 → 3,25
}
private fun getGrade(semesterId: Int, subject: String, value: Double, modifier: Double = 0.0): Grade {
From 419675066f516786fc78095273c78f142be15b2d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miko=C5=82aj=20Pich?=
Date: Tue, 2 Jun 2020 17:07:52 +0200
Subject: [PATCH 016/100] Version 0.18.2
---
.travis.yml | 2 +-
app/build.gradle | 6 +++---
app/src/main/play/release-notes/pl-PL/default.txt | 13 +++++++------
3 files changed, 11 insertions(+), 10 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index d858cf3e0..4bb842821 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -14,7 +14,7 @@ cache:
branches:
only:
- develop
- - 0.18.1
+ - 0.18.2
android:
licenses:
diff --git a/app/build.gradle b/app/build.gradle
index f29af84fa..e2aab017d 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -17,8 +17,8 @@ android {
testApplicationId "io.github.tests.wulkanowy"
minSdkVersion 17
targetSdkVersion 29
- versionCode 60
- versionName "0.18.1"
+ versionCode 61
+ versionName "0.18.2"
multiDexEnabled true
resValue "string", "app_name", "Wulkanowy"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@@ -124,7 +124,7 @@ configurations.all {
}
dependencies {
- implementation "io.github.wulkanowy:sdk:d0081b4"
+ implementation "io.github.wulkanowy:sdk:0.18.2"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation "androidx.core:core-ktx:1.2.0"
diff --git a/app/src/main/play/release-notes/pl-PL/default.txt b/app/src/main/play/release-notes/pl-PL/default.txt
index d61f1b97b..1908d2e26 100644
--- a/app/src/main/play/release-notes/pl-PL/default.txt
+++ b/app/src/main/play/release-notes/pl-PL/default.txt
@@ -1,8 +1,9 @@
-Wersja 0.18.1
-- naprawiliśmy sortowanie w ocenach
-- naprawilismy wiele problemów ze stabilnością
-- nazwy opcji w ustawieniach nie są już ucięte
-- w zadaniach domowych wyświetlają się teraz pozycje na weekend
-- wyłączyliśmy logowanie przez token (bo nie działa i nie wiadomo kiedy będzie działać)
+Wersja 0.18.2
+- naprawiliśmy zaznaczanie uczniów przy logowaniu
+- naprawiliśmy odświeżanie planu lekcji na samsungach
+- naprawiliśmy wysyłanie wiadomości
+- poprawiliśmy oznaczanie nowych wiadomości jako przeczytanych
+- w podsumowaniu ocen nie będą się już pokazywać „puste” przedmioty
+- w polu pisania wiadomości pierwsza litera w zdaniu będzie teraz domyślnie duża
Pełna lista zmian: https://github.com/wulkanowy/wulkanowy/releases
From 522a36d67027dc775f69c773a6272438fa04bd1e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miko=C5=82aj=20Pich?=
Date: Wed, 10 Jun 2020 16:26:45 +0200
Subject: [PATCH 017/100] Fix message deleting (#875)
---
.../github/wulkanowy/data/repositories/message/MessageRemote.kt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/message/MessageRemote.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/message/MessageRemote.kt
index 1808c048b..2df2e20a3 100644
--- a/app/src/main/java/io/github/wulkanowy/data/repositories/message/MessageRemote.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/repositories/message/MessageRemote.kt
@@ -75,6 +75,6 @@ class MessageRemote @Inject constructor(private val sdk: Sdk) {
}
fun deleteMessage(student: Student, message: Message): Single {
- return sdk.init(student).deleteMessages(listOf(Pair(message.realId, message.folderId)))
+ return sdk.init(student).deleteMessages(listOf(message.messageId to message.folderId))
}
}
From 5c84c8d5b175a219bc8db987acfcae893641dc8a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miko=C5=82aj=20Pich?=
Date: Wed, 10 Jun 2020 17:28:49 +0200
Subject: [PATCH 018/100] Fix force average calc from two semesters (#870)
---
app/build.gradle | 2 +-
.../preferences/PreferencesRepository.kt | 5 +-
.../ui/modules/grade/GradeAverageMode.kt | 11 ++
.../ui/modules/grade/GradeAverageProvider.kt | 58 ++++--
.../main/res/values-de/preferences_values.xml | 1 +
.../main/res/values-pl/preferences_values.xml | 5 +-
.../main/res/values-ru/preferences_values.xml | 1 +
.../main/res/values-uk/preferences_values.xml | 1 +
.../main/res/values/preferences_values.xml | 2 +
.../modules/grade/GradeAverageProviderTest.kt | 173 ++++++++++++++----
10 files changed, 206 insertions(+), 53 deletions(-)
create mode 100644 app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeAverageMode.kt
diff --git a/app/build.gradle b/app/build.gradle
index e2aab017d..cb735b3b4 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -124,7 +124,7 @@ configurations.all {
}
dependencies {
- implementation "io.github.wulkanowy:sdk:0.18.2"
+ implementation "io.github.wulkanowy:sdk:a57afdb"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation "androidx.core:core-ktx:1.2.0"
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 6b13563a4..7715cde0d 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
@@ -3,6 +3,7 @@ package io.github.wulkanowy.data.repositories.preferences
import android.content.Context
import android.content.SharedPreferences
import io.github.wulkanowy.R
+import io.github.wulkanowy.ui.modules.grade.GradeAverageMode
import javax.inject.Inject
import javax.inject.Singleton
@@ -17,8 +18,8 @@ class PreferencesRepository @Inject constructor(
val isShowPresent: Boolean
get() = getBoolean(R.string.pref_key_attendance_present, R.bool.pref_default_attendance_present)
- val gradeAverageMode: String
- get() = getString(R.string.pref_key_grade_average_mode, R.string.pref_default_grade_average_mode)
+ val gradeAverageMode: GradeAverageMode
+ get() = GradeAverageMode.getByValue(getString(R.string.pref_key_grade_average_mode, R.string.pref_default_grade_average_mode))
val gradeAverageForceCalc: Boolean
get() = getBoolean(R.string.pref_key_grade_average_force_calc, R.bool.pref_default_grade_average_force_calc)
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeAverageMode.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeAverageMode.kt
new file mode 100644
index 000000000..1960c3df7
--- /dev/null
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeAverageMode.kt
@@ -0,0 +1,11 @@
+package io.github.wulkanowy.ui.modules.grade
+
+enum class GradeAverageMode(val value: String) {
+ ALL_YEAR("all_year"),
+ ONE_SEMESTER("only_one_semester"),
+ BOTH_SEMESTERS("both_semesters");
+
+ companion object {
+ fun getByValue(value: String) = values().firstOrNull { it.value == value } ?: ONE_SEMESTER
+ }
+}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeAverageProvider.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeAverageProvider.kt
index 9582a5db3..bda098f47 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeAverageProvider.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeAverageProvider.kt
@@ -8,6 +8,9 @@ import io.github.wulkanowy.data.repositories.grade.GradeRepository
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
import io.github.wulkanowy.data.repositories.semester.SemesterRepository
import io.github.wulkanowy.sdk.Sdk
+import io.github.wulkanowy.ui.modules.grade.GradeAverageMode.ALL_YEAR
+import io.github.wulkanowy.ui.modules.grade.GradeAverageMode.BOTH_SEMESTERS
+import io.github.wulkanowy.ui.modules.grade.GradeAverageMode.ONE_SEMESTER
import io.github.wulkanowy.utils.calcAverage
import io.github.wulkanowy.utils.changeModifier
import io.reactivex.Single
@@ -19,21 +22,21 @@ class GradeAverageProvider @Inject constructor(
private val preferencesRepository: PreferencesRepository
) {
- private val plusModifier = preferencesRepository.gradePlusModifier
+ private val plusModifier get() = preferencesRepository.gradePlusModifier
- private val minusModifier = preferencesRepository.gradeMinusModifier
+ private val minusModifier get() = preferencesRepository.gradeMinusModifier
fun getGradesDetailsWithAverage(student: Student, semesterId: Int, forceRefresh: Boolean = false): Single> {
return semesterRepository.getSemesters(student).flatMap { semesters ->
when (preferencesRepository.gradeAverageMode) {
- "only_one_semester" -> getSemesterDetailsWithAverage(student, semesters.single { it.semesterId == semesterId }, forceRefresh)
- "all_year" -> calculateWholeYearAverage(student, semesters, semesterId, forceRefresh)
- else -> throw IllegalArgumentException("Incorrect grade average mode: ${preferencesRepository.gradeAverageMode} ")
+ ONE_SEMESTER -> getSemesterDetailsWithAverage(student, semesters.single { it.semesterId == semesterId }, forceRefresh)
+ BOTH_SEMESTERS -> calculateBothSemestersAverage(student, semesters, semesterId, forceRefresh)
+ ALL_YEAR -> calculateAllYearAverage(student, semesters, semesterId, forceRefresh)
}
}
}
- private fun calculateWholeYearAverage(student: Student, semesters: List, semesterId: Int, forceRefresh: Boolean): Single> {
+ private fun calculateBothSemestersAverage(student: Student, semesters: List, semesterId: Int, forceRefresh: Boolean): Single> {
val selectedSemester = semesters.single { it.semesterId == semesterId }
val firstSemester = semesters.single { it.diaryId == selectedSemester.diaryId && it.semesterName == 1 }
@@ -44,11 +47,30 @@ class GradeAverageProvider @Inject constructor(
getSemesterDetailsWithAverage(student, firstSemester, forceRefresh).map { secondDetails ->
selectedDetails.map { selected ->
val second = secondDetails.singleOrNull { it.subject == selected.subject }
- selected.copy(
- average = if (!isAnyAverage || preferencesRepository.gradeAverageForceCalc) {
- (selected.grades + second?.grades.orEmpty()).calcAverage()
- } else (selected.average + (second?.average ?: selected.average)) / 2
- )
+ selected.copy(average = if (!isAnyAverage || preferencesRepository.gradeAverageForceCalc) {
+ val selectedGrades = selected.grades.updateModifiers(student).calcAverage()
+ (selectedGrades + (second?.grades?.updateModifiers(student)?.calcAverage() ?: selectedGrades)) / 2
+ } else (selected.average + (second?.average ?: selected.average)) / 2)
+ }
+ }
+ } else Single.just(selectedDetails)
+ }
+ }
+
+ private fun calculateAllYearAverage(student: Student, semesters: List, semesterId: Int, forceRefresh: Boolean): Single> {
+ val selectedSemester = semesters.single { it.semesterId == semesterId }
+ val firstSemester = semesters.single { it.diaryId == selectedSemester.diaryId && it.semesterName == 1 }
+
+ return getSemesterDetailsWithAverage(student, selectedSemester, forceRefresh).flatMap { selectedDetails ->
+ val isAnyAverage = selectedDetails.any { it.average != .0 }
+
+ if (selectedSemester != firstSemester) {
+ getSemesterDetailsWithAverage(student, firstSemester, forceRefresh).map { secondDetails ->
+ selectedDetails.map { selected ->
+ val second = secondDetails.singleOrNull { it.subject == selected.subject }
+ selected.copy(average = if (!isAnyAverage || preferencesRepository.gradeAverageForceCalc) {
+ (selected.grades.updateModifiers(student) + second?.grades?.updateModifiers(student).orEmpty()).calcAverage()
+ } else selected.average)
}
}
} else Single.just(selectedDetails)
@@ -65,9 +87,7 @@ class GradeAverageProvider @Inject constructor(
GradeDetailsWithAverage(
subject = summary.subject,
average = if (!isAnyAverage || preferencesRepository.gradeAverageForceCalc) {
- (if (student.loginMode == Sdk.Mode.SCRAPPER.name)
- grades.map { it.changeModifier(plusModifier, minusModifier) }
- else grades).calcAverage()
+ grades.updateModifiers(student).calcAverage()
} else summary.average,
points = summary.pointsSum,
summary = summary,
@@ -92,10 +112,14 @@ class GradeAverageProvider @Inject constructor(
proposedPoints = "",
finalPoints = "",
pointsSum = "",
- average = if (calcAverage) (if (student.loginMode == Sdk.Mode.SCRAPPER.name) {
- details.map { it.changeModifier(plusModifier, minusModifier) }
- } else details).calcAverage() else .0
+ average = if (calcAverage) details.updateModifiers(student).calcAverage() else .0
)
}
}
+
+ private fun List.updateModifiers(student: Student): List {
+ return if (student.loginMode == Sdk.Mode.SCRAPPER.name) {
+ map { it.changeModifier(plusModifier, minusModifier) }
+ } else this
+ }
}
diff --git a/app/src/main/res/values-de/preferences_values.xml b/app/src/main/res/values-de/preferences_values.xml
index 28ad08bc2..496287984 100644
--- a/app/src/main/res/values-de/preferences_values.xml
+++ b/app/src/main/res/values-de/preferences_values.xml
@@ -36,6 +36,7 @@
- Durchschnittsnote für das 2. Semester
+ - Average of grades from both semesters
- Durchschnitt der Bewertungen für das ganze Jahr
diff --git a/app/src/main/res/values-pl/preferences_values.xml b/app/src/main/res/values-pl/preferences_values.xml
index 475f7327f..1d81fb586 100644
--- a/app/src/main/res/values-pl/preferences_values.xml
+++ b/app/src/main/res/values-pl/preferences_values.xml
@@ -35,8 +35,9 @@
- Kolory ocen w dzienniku
- - Średnia ocen z 2 semestru
- - Średnia ocen z całego roku
+ - Średnia ocen z drugiego semestru
+ - Średnia średnich z obu semestrów
+ - Średnia wszystkich ocen z całego roku
- Nie pokazuj
diff --git a/app/src/main/res/values-ru/preferences_values.xml b/app/src/main/res/values-ru/preferences_values.xml
index 6c1522682..bd8bb844f 100644
--- a/app/src/main/res/values-ru/preferences_values.xml
+++ b/app/src/main/res/values-ru/preferences_values.xml
@@ -36,6 +36,7 @@
- Средняя оценка со 2 семестра
+ - Average of grades from both semesters
- Средняя оценка с целого года
diff --git a/app/src/main/res/values-uk/preferences_values.xml b/app/src/main/res/values-uk/preferences_values.xml
index 3c70c9d09..be2179c3e 100644
--- a/app/src/main/res/values-uk/preferences_values.xml
+++ b/app/src/main/res/values-uk/preferences_values.xml
@@ -36,6 +36,7 @@
- Середня оцінка з 2 семестру
+ - Average of grades from both semesters
- Середня оцінка за весь рік
diff --git a/app/src/main/res/values/preferences_values.xml b/app/src/main/res/values/preferences_values.xml
index 76427a487..5824658c4 100644
--- a/app/src/main/res/values/preferences_values.xml
+++ b/app/src/main/res/values/preferences_values.xml
@@ -88,10 +88,12 @@
- Average of grades only from the 2nd semester
+ - Average of grades from both semesters
- Average of grades from the whole year
- only_one_semester
+ - both_semesters
- all_year
diff --git a/app/src/test/java/io/github/wulkanowy/ui/modules/grade/GradeAverageProviderTest.kt b/app/src/test/java/io/github/wulkanowy/ui/modules/grade/GradeAverageProviderTest.kt
index ee8634ca8..984bbbcf8 100644
--- a/app/src/test/java/io/github/wulkanowy/ui/modules/grade/GradeAverageProviderTest.kt
+++ b/app/src/test/java/io/github/wulkanowy/ui/modules/grade/GradeAverageProviderTest.kt
@@ -86,6 +86,8 @@ class GradeAverageProviderTest {
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(false)
`when`(semesterRepository.getSemesters(student)).thenReturn(Single.just(semesters))
+ `when`(preferencesRepository.gradeMinusModifier).thenReturn(.33)
+ `when`(preferencesRepository.gradePlusModifier).thenReturn(.33)
gradeAverageProvider = GradeAverageProvider(semesterRepository, gradeRepository, preferencesRepository)
}
@@ -93,7 +95,7 @@ class GradeAverageProviderTest {
@Test
fun `force calc current semester average with default modifiers in scraper mode`() {
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true)
- `when`(preferencesRepository.gradeAverageMode).thenReturn("only_one_semester")
+ `when`(preferencesRepository.gradeAverageMode).thenReturn(GradeAverageMode.ONE_SEMESTER)
`when`(semesterRepository.getSemesters(student)).thenReturn(Single.just(semesters))
`when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGradeWithModifier to secondSummariesWithModifier))
@@ -110,7 +112,7 @@ class GradeAverageProviderTest {
`when`(preferencesRepository.gradeMinusModifier).thenReturn(.33)
`when`(preferencesRepository.gradePlusModifier).thenReturn(.33)
- `when`(preferencesRepository.gradeAverageMode).thenReturn("only_one_semester")
+ `when`(preferencesRepository.gradeAverageMode).thenReturn(GradeAverageMode.ONE_SEMESTER)
`when`(semesterRepository.getSemesters(student)).thenReturn(Single.just(semesters))
`when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGradeWithModifier to secondSummariesWithModifier))
@@ -127,7 +129,7 @@ class GradeAverageProviderTest {
`when`(preferencesRepository.gradeMinusModifier).thenReturn(.33) // useless in this mode
`when`(preferencesRepository.gradePlusModifier).thenReturn(.33)
- `when`(preferencesRepository.gradeAverageMode).thenReturn("only_one_semester")
+ `when`(preferencesRepository.gradeAverageMode).thenReturn(GradeAverageMode.ONE_SEMESTER)
`when`(semesterRepository.getSemesters(student)).thenReturn(Single.just(semesters))
`when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGradeWithModifier to secondSummariesWithModifier))
@@ -144,7 +146,7 @@ class GradeAverageProviderTest {
`when`(preferencesRepository.gradeMinusModifier).thenReturn(.33) // useless in this mode
`when`(preferencesRepository.gradePlusModifier).thenReturn(.33)
- `when`(preferencesRepository.gradeAverageMode).thenReturn("only_one_semester")
+ `when`(preferencesRepository.gradeAverageMode).thenReturn(GradeAverageMode.ONE_SEMESTER)
`when`(semesterRepository.getSemesters(student)).thenReturn(Single.just(semesters))
`when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGradeWithModifier to secondSummariesWithModifier))
@@ -156,7 +158,7 @@ class GradeAverageProviderTest {
@Test
fun `calc current semester average`() {
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(false)
- `when`(preferencesRepository.gradeAverageMode).thenReturn("only_one_semester")
+ `when`(preferencesRepository.gradeAverageMode).thenReturn(GradeAverageMode.ONE_SEMESTER)
`when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGrades to secondSummaries))
val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
@@ -169,7 +171,7 @@ class GradeAverageProviderTest {
@Test
fun `force calc current semester average`() {
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true)
- `when`(preferencesRepository.gradeAverageMode).thenReturn("only_one_semester")
+ `when`(preferencesRepository.gradeAverageMode).thenReturn(GradeAverageMode.ONE_SEMESTER)
`when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGrades to secondSummaries))
val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
@@ -182,7 +184,7 @@ class GradeAverageProviderTest {
@Test
fun `force calc full year average when current is first`() {
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true)
- `when`(preferencesRepository.gradeAverageMode).thenReturn("all_year")
+ `when`(preferencesRepository.gradeAverageMode).thenReturn(GradeAverageMode.ALL_YEAR)
`when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(firstGrades to firstSummaries))
val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[1].semesterId).blockingGet()
@@ -192,16 +194,9 @@ class GradeAverageProviderTest {
assertEquals(3.5, items.single { it.subject == "Fizyka" }.average, .0) // (from summary): 3,5
}
- @Test(expected = IllegalArgumentException::class)
- fun `calc average on invalid mode`() {
- `when`(preferencesRepository.gradeAverageMode).thenReturn("test_mode")
-
- gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId, true).blockingGet()
- }
-
@Test
- fun `calc full year average`() {
- `when`(preferencesRepository.gradeAverageMode).thenReturn("all_year")
+ fun `calc both semesters average`() {
+ `when`(preferencesRepository.gradeAverageMode).thenReturn(GradeAverageMode.BOTH_SEMESTERS)
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(false)
`when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(firstGrades to listOf(
getSummary(22, "Matematyka", 3.0),
@@ -222,7 +217,7 @@ class GradeAverageProviderTest {
@Test
fun `force calc full year average`() {
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true)
- `when`(preferencesRepository.gradeAverageMode).thenReturn("all_year")
+ `when`(preferencesRepository.gradeAverageMode).thenReturn(GradeAverageMode.ALL_YEAR)
`when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(firstGrades to firstSummaries))
`when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGrades to listOf(
getSummary(22, "Matematyka", 1.1),
@@ -237,9 +232,9 @@ class GradeAverageProviderTest {
}
@Test
- fun `calc full year average when no summaries`() {
+ fun `calc both semesters average when no summaries`() {
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(false)
- `when`(preferencesRepository.gradeAverageMode).thenReturn("all_year")
+ `when`(preferencesRepository.gradeAverageMode).thenReturn(GradeAverageMode.BOTH_SEMESTERS)
`when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(firstGrades to emptyList()))
`when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGrades to emptyList()))
@@ -247,14 +242,14 @@ class GradeAverageProviderTest {
val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
assertEquals(2, items.size)
- assertEquals(3.0, items.single { it.subject == "Matematyka" }.average, .0) // (from details): 2,5 + 3,5 → 3,0
- assertEquals(3.25, items.single { it.subject == "Fizyka" }.average, .0) // (from details): 3,5 + 3,0 → 3,25
+ assertEquals(3.0, items.single { it.subject == "Matematyka" }.average, .0) // (from details): 3,5 + 2,5 → 3,0
+ assertEquals(3.25, items.single { it.subject == "Fizyka" }.average, .0) // (from details): 3,5 + 3,0 → 3,25
}
@Test
fun `force calc full year average when no summaries`() {
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true)
- `when`(preferencesRepository.gradeAverageMode).thenReturn("all_year")
+ `when`(preferencesRepository.gradeAverageMode).thenReturn(GradeAverageMode.ALL_YEAR)
`when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(firstGrades to emptyList()))
`when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGrades to emptyList()))
@@ -267,9 +262,9 @@ class GradeAverageProviderTest {
}
@Test
- fun `calc full year average when missing summaries in both semesters`() {
+ fun `calc both semesters average when missing summaries in both semesters`() {
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(false)
- `when`(preferencesRepository.gradeAverageMode).thenReturn("all_year")
+ `when`(preferencesRepository.gradeAverageMode).thenReturn(GradeAverageMode.BOTH_SEMESTERS)
`when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(firstGrades to listOf(
getSummary(22, "Matematyka", 4.0)
@@ -286,9 +281,9 @@ class GradeAverageProviderTest {
}
@Test
- fun `calc full year average when missing summary in second semester`() {
+ fun `calc both semesters average when missing summary in second semester`() {
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(false)
- `when`(preferencesRepository.gradeAverageMode).thenReturn("all_year")
+ `when`(preferencesRepository.gradeAverageMode).thenReturn(GradeAverageMode.BOTH_SEMESTERS)
`when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(firstGrades to firstSummaries))
`when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGrades to secondSummaries.dropLast(1)))
@@ -301,9 +296,9 @@ class GradeAverageProviderTest {
}
@Test
- fun `calc full year average when missing summary in first semester`() {
+ fun `calc both semesters average when missing summary in first semester`() {
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(false)
- `when`(preferencesRepository.gradeAverageMode).thenReturn("all_year")
+ `when`(preferencesRepository.gradeAverageMode).thenReturn(GradeAverageMode.BOTH_SEMESTERS)
`when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(firstGrades to firstSummaries.dropLast(1)))
`when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGrades to secondSummaries))
@@ -318,7 +313,7 @@ class GradeAverageProviderTest {
@Test
fun `force calc full year average when missing summary in first semester`() {
`when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true)
- `when`(preferencesRepository.gradeAverageMode).thenReturn("all_year")
+ `when`(preferencesRepository.gradeAverageMode).thenReturn(GradeAverageMode.ALL_YEAR)
`when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(firstGrades to firstSummaries.dropLast(1)))
`when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(secondGrades to secondSummaries))
@@ -330,14 +325,130 @@ class GradeAverageProviderTest {
assertEquals(3.25, items.single { it.subject == "Fizyka" }.average, .0) // (from details): 3,5 + 3,0 → 3,25
}
- private fun getGrade(semesterId: Int, subject: String, value: Double, modifier: Double = 0.0): Grade {
+ @Test
+ fun `force calc both semesters average with different average from all grades and from two semesters`() {
+ `when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true)
+ `when`(preferencesRepository.gradeAverageMode).thenReturn(GradeAverageMode.BOTH_SEMESTERS)
+
+ `when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(listOf(
+ getGrade(22, "Fizyka", 5.0, weight = 2.0),
+ getGrade(22, "Fizyka", 6.0, weight = 2.0),
+ getGrade(22, "Fizyka", 5.0, weight = 4.0),
+ getGrade(22, "Fizyka", 6.0, weight = 2.0),
+ getGrade(22, "Fizyka", 6.0, weight = 2.0),
+ getGrade(22, "Fizyka", 6.0, weight = 4.0),
+ getGrade(22, "Fizyka", 6.0, weight = 4.0),
+ getGrade(22, "Fizyka", 6.0, weight = 2.0)
+ ) to listOf(getSummary(semesterId = 22, subject = "Fizyka", average = .0))))
+ `when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(listOf(
+ getGrade(23, "Fizyka", 5.0, weight = 1.0),
+ getGrade(23, "Fizyka", 5.0, weight = 2.0),
+ getGrade(23, "Fizyka", 4.0, modifier = 0.3, weight = 2.0)
+ ) to listOf(getSummary(semesterId = 23, subject = "Fizyka", average = .0))))
+
+ val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
+
+ assertEquals(5.2296, items.single { it.subject == "Fizyka" }.average, .0001) // (from details): 5.72727272 + 4,732 → 5.229636363636364
+ }
+
+ @Test
+ fun `force calc full year average with different average from all grades and from two semesters`() {
+ `when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true)
+ `when`(preferencesRepository.gradeAverageMode).thenReturn(GradeAverageMode.ALL_YEAR)
+
+ `when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(listOf(
+ getGrade(22, "Fizyka", 5.0, weight = 2.0),
+ getGrade(22, "Fizyka", 6.0, weight = 2.0),
+ getGrade(22, "Fizyka", 5.0, weight = 4.0),
+ getGrade(22, "Fizyka", 6.0, weight = 2.0),
+ getGrade(22, "Fizyka", 6.0, weight = 2.0),
+ getGrade(22, "Fizyka", 6.0, weight = 4.0),
+ getGrade(22, "Fizyka", 6.0, weight = 4.0),
+ getGrade(22, "Fizyka", 6.0, weight = 2.0)
+ ) to listOf(getSummary(semesterId = 22, subject = "Fizyka", average = .0))))
+ `when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(listOf(
+ getGrade(23, "Fizyka", 5.0, weight = 1.0),
+ getGrade(23, "Fizyka", 5.0, weight = 2.0),
+ getGrade(23, "Fizyka", 4.0, modifier = 0.3, weight = 2.0)
+ ) to listOf(getSummary(semesterId = 23, subject = "Fizyka", average = .0))))
+
+ val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
+
+ assertEquals(5.5429, items.single { it.subject == "Fizyka" }.average, .0001) // (from details): 5.72727272 + 4,732 → .average()
+ }
+
+ @Test
+ fun `force calc both semesters average with different average from all grades and from two semesters with custom modifiers`() {
+ val student = student.copy(loginMode = Sdk.Mode.SCRAPPER.name)
+
+ `when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true)
+ `when`(preferencesRepository.gradeMinusModifier).thenReturn(.33)
+ `when`(preferencesRepository.gradePlusModifier).thenReturn(.5)
+
+ `when`(preferencesRepository.gradeAverageMode).thenReturn(GradeAverageMode.BOTH_SEMESTERS)
+ `when`(semesterRepository.getSemesters(student)).thenReturn(Single.just(semesters))
+
+ `when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(listOf(
+ getGrade(22, "Fizyka", 5.0, weight = 2.0),
+ getGrade(22, "Fizyka", 6.0, weight = 2.0),
+ getGrade(22, "Fizyka", 5.0, weight = 4.0),
+ getGrade(22, "Fizyka", 6.0, weight = 2.0),
+ getGrade(22, "Fizyka", 6.0, weight = 2.0),
+ getGrade(22, "Fizyka", 6.0, weight = 4.0),
+ getGrade(22, "Fizyka", 6.0, weight = 4.0),
+ getGrade(22, "Fizyka", 6.0, weight = 2.0)
+ ) to listOf(getSummary(semesterId = 22, subject = "Fizyka", average = .0))))
+ `when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(listOf(
+ getGrade(23, "Fizyka", 5.0, weight = 1.0),
+ getGrade(23, "Fizyka", 5.0, weight = 2.0),
+ getGrade(23, "Fizyka", 4.0, modifier = 0.33, weight = 2.0)
+ ) to listOf(getSummary(semesterId = 23, subject = "Fizyka", average = .0))))
+
+ val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
+
+ assertEquals(5.2636, items.single { it.subject == "Fizyka" }.average, .0001) // (from details): 5.72727272 + 4,8 → 5.26363636
+ }
+
+ @Test
+ fun `force calc full year average with different average from all grades and from two semesters with custom modifiers`() {
+ val student = student.copy(loginMode = Sdk.Mode.SCRAPPER.name)
+
+ `when`(preferencesRepository.gradeAverageForceCalc).thenReturn(true)
+ `when`(preferencesRepository.gradeMinusModifier).thenReturn(.33)
+ `when`(preferencesRepository.gradePlusModifier).thenReturn(.5)
+
+ `when`(preferencesRepository.gradeAverageMode).thenReturn(GradeAverageMode.ALL_YEAR)
+ `when`(semesterRepository.getSemesters(student)).thenReturn(Single.just(semesters))
+
+ `when`(gradeRepository.getGrades(student, semesters[1])).thenReturn(Single.just(listOf(
+ getGrade(22, "Fizyka", 5.0, weight = 2.0),
+ getGrade(22, "Fizyka", 6.0, weight = 2.0),
+ getGrade(22, "Fizyka", 5.0, weight = 4.0),
+ getGrade(22, "Fizyka", 6.0, weight = 2.0),
+ getGrade(22, "Fizyka", 6.0, weight = 2.0),
+ getGrade(22, "Fizyka", 6.0, weight = 4.0),
+ getGrade(22, "Fizyka", 6.0, weight = 4.0),
+ getGrade(22, "Fizyka", 6.0, weight = 2.0)
+ ) to listOf(getSummary(semesterId = 22, subject = "Fizyka", average = .0))))
+ `when`(gradeRepository.getGrades(student, semesters[2])).thenReturn(Single.just(listOf(
+ getGrade(23, "Fizyka", 5.0, weight = 1.0),
+ getGrade(23, "Fizyka", 5.0, weight = 2.0),
+ getGrade(23, "Fizyka", 4.0, modifier = 0.33, weight = 2.0)
+ ) to listOf(getSummary(semesterId = 23, subject = "Fizyka", average = .0))))
+
+ val items = gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId).blockingGet()
+
+ assertEquals(5.5555, items.single { it.subject == "Fizyka" }.average, .0001) // (from details): 5.72727272 + 4,8 → .average()
+ }
+
+ private fun getGrade(semesterId: Int, subject: String, value: Double, modifier: Double = 0.0, weight: Double = 1.0): Grade {
return Grade(
studentId = 101,
semesterId = semesterId,
subject = subject,
value = value,
modifier = modifier,
- weightValue = 1.0,
+ weightValue = weight,
teacher = "",
date = now(),
weight = "",
From 674a78b6619a2d94957d874a14f19e540a16c746 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miko=C5=82aj=20Pich?=
Date: Wed, 10 Jun 2020 19:18:09 +0200
Subject: [PATCH 019/100] Version 0.18.3
---
.travis.yml | 2 +-
app/build.gradle | 6 +++---
app/src/main/play/release-notes/pl-PL/default.txt | 11 ++++-------
3 files changed, 8 insertions(+), 11 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index 4bb842821..788aeffa7 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -14,7 +14,7 @@ cache:
branches:
only:
- develop
- - 0.18.2
+ - 0.18.3
android:
licenses:
diff --git a/app/build.gradle b/app/build.gradle
index cb735b3b4..498c7a376 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -17,8 +17,8 @@ android {
testApplicationId "io.github.tests.wulkanowy"
minSdkVersion 17
targetSdkVersion 29
- versionCode 61
- versionName "0.18.2"
+ versionCode 62
+ versionName "0.18.3"
multiDexEnabled true
resValue "string", "app_name", "Wulkanowy"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@@ -124,7 +124,7 @@ configurations.all {
}
dependencies {
- implementation "io.github.wulkanowy:sdk:a57afdb"
+ implementation "io.github.wulkanowy:sdk:0.18.3"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation "androidx.core:core-ktx:1.2.0"
diff --git a/app/src/main/play/release-notes/pl-PL/default.txt b/app/src/main/play/release-notes/pl-PL/default.txt
index 1908d2e26..db9e9a9a3 100644
--- a/app/src/main/play/release-notes/pl-PL/default.txt
+++ b/app/src/main/play/release-notes/pl-PL/default.txt
@@ -1,9 +1,6 @@
-Wersja 0.18.2
-- naprawiliśmy zaznaczanie uczniów przy logowaniu
-- naprawiliśmy odświeżanie planu lekcji na samsungach
-- naprawiliśmy wysyłanie wiadomości
-- poprawiliśmy oznaczanie nowych wiadomości jako przeczytanych
-- w podsumowaniu ocen nie będą się już pokazywać „puste” przedmioty
-- w polu pisania wiadomości pierwsza litera w zdaniu będzie teraz domyślnie duża
+Wersja 0.18.3
+- poprawiliśmy liczenie średniej i dodaliśmy nowy sposób jej liczenia w ustawieniach
+- naprawiliśmy usuwanie wiadomości
+- naprawiliśmy wysyłanie wiadomości na Lubelskim Portalu Oświatowym
Pełna lista zmian: https://github.com/wulkanowy/wulkanowy/releases
From 5529ffcf73712532e8bef74bbf9ed2cfa532fe5e Mon Sep 17 00:00:00 2001
From: "dependabot-preview[bot]"
<27856297+dependabot-preview[bot]@users.noreply.github.com>
Date: Thu, 11 Jun 2020 12:01:52 +0000
Subject: [PATCH 020/100] Bump fragment-ktx from 1.2.4 to 1.2.5 (#878)
---
app/build.gradle | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/build.gradle b/app/build.gradle
index 498c7a376..1f616e6fc 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -131,7 +131,7 @@ dependencies {
implementation "androidx.activity:activity-ktx:1.1.0"
implementation "androidx.appcompat:appcompat:1.2.0-rc01"
implementation "androidx.appcompat:appcompat-resources:1.1.0"
- implementation "androidx.fragment:fragment-ktx:1.2.4"
+ implementation "androidx.fragment:fragment-ktx:1.2.5"
implementation "androidx.annotation:annotation:1.1.0"
implementation "androidx.multidex:multidex:2.0.1"
From 8cce81585aec9fafc1c5a0131952aa35219edb7b Mon Sep 17 00:00:00 2001
From: "dependabot-preview[bot]"
<27856297+dependabot-preview[bot]@users.noreply.github.com>
Date: Thu, 11 Jun 2020 12:02:10 +0000
Subject: [PATCH 021/100] Bump firebase-analytics from 17.4.2 to 17.4.3 (#881)
---
app/build.gradle | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/build.gradle b/app/build.gradle
index 1f616e6fc..0abc9295e 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -181,7 +181,7 @@ dependencies {
implementation "io.coil-kt:coil:0.11.0"
implementation "io.github.wulkanowy:AppKillerManager:3.0.0"
- playImplementation 'com.google.firebase:firebase-analytics:17.4.2'
+ playImplementation 'com.google.firebase:firebase-analytics:17.4.3'
playImplementation 'com.google.firebase:firebase-inappmessaging-display-ktx:19.0.7'
playImplementation "com.google.firebase:firebase-inappmessaging-ktx:19.0.7"
playImplementation 'com.google.firebase:firebase-messaging:20.2.0'
From 00943717a2bdf5ce6fa060c32fb9a2c83cdc0cef Mon Sep 17 00:00:00 2001
From: "dependabot-preview[bot]"
<27856297+dependabot-preview[bot]@users.noreply.github.com>
Date: Thu, 11 Jun 2020 12:02:38 +0000
Subject: [PATCH 022/100] Bump firebase-crashlytics from 17.0.0 to 17.0.1
(#880)
---
app/build.gradle | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/app/build.gradle b/app/build.gradle
index 0abc9295e..86ee94c37 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -185,7 +185,7 @@ dependencies {
playImplementation 'com.google.firebase:firebase-inappmessaging-display-ktx:19.0.7'
playImplementation "com.google.firebase:firebase-inappmessaging-ktx:19.0.7"
playImplementation 'com.google.firebase:firebase-messaging:20.2.0'
- playImplementation 'com.google.firebase:firebase-crashlytics:17.0.0'
+ playImplementation 'com.google.firebase:firebase-crashlytics:17.0.1'
playImplementation 'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava'
releaseImplementation "com.github.ChuckerTeam.Chucker:library-no-op:$chucker"
From f151f7bd62aac50f71a5387c4dd819bf4ba8e164 Mon Sep 17 00:00:00 2001
From: "dependabot-preview[bot]"
<27856297+dependabot-preview[bot]@users.noreply.github.com>
Date: Thu, 11 Jun 2020 12:05:30 +0000
Subject: [PATCH 023/100] Bump about_libraries from 8.1.6 to 8.2.0 (#879)
---
build.gradle | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/build.gradle b/build.gradle
index 7e5759d12..6b0859822 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,6 +1,6 @@
buildscript {
ext.kotlin_version = '1.3.72'
- ext.about_libraries = '8.1.6'
+ ext.about_libraries = '8.2.0'
repositories {
mavenCentral()
google()
From eedaa637716752ec3250a61da735551dd99a383d Mon Sep 17 00:00:00 2001
From: "dependabot-preview[bot]"
<27856297+dependabot-preview[bot]@users.noreply.github.com>
Date: Thu, 11 Jun 2020 12:05:54 +0000
Subject: [PATCH 024/100] Bump sonarqube-gradle-plugin from 2.8 to 3.0 (#882)
---
build.gradle | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/build.gradle b/build.gradle
index 6b0859822..4de7310b5 100644
--- a/build.gradle
+++ b/build.gradle
@@ -13,7 +13,7 @@ buildscript {
classpath 'com.google.gms:google-services:4.3.3'
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.1.1'
classpath "com.github.triplet.gradle:play-publisher:2.7.5"
- classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.8"
+ classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:3.0"
classpath "gradle.plugin.com.star-zero.gradle:githook:1.2.0"
classpath "com.mikepenz.aboutlibraries.plugin:aboutlibraries-plugin:${about_libraries}"
}
From 30af77614e4b222ab8eee896fd33cc847c7c0c17 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miko=C5=82aj=20Pich?=
Date: Thu, 11 Jun 2020 14:38:04 +0200
Subject: [PATCH 025/100] Fix showing summary summary for subjects without
partial grades (#877)
---
app/build.gradle | 6 +++---
.../wulkanowy/ui/modules/grade/GradeAverageProvider.kt | 2 +-
app/src/main/java/io/github/wulkanowy/utils/SdkExtension.kt | 2 ++
3 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/app/build.gradle b/app/build.gradle
index 86ee94c37..44896664a 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -77,8 +77,8 @@ android {
}
}
- viewBinding {
- enabled = true
+ buildFeatures {
+ viewBinding = true
}
lintOptions {
@@ -124,7 +124,7 @@ configurations.all {
}
dependencies {
- implementation "io.github.wulkanowy:sdk:0.18.3"
+ implementation "io.github.wulkanowy:sdk:7dc0761"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation "androidx.core:core-ktx:1.2.0"
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeAverageProvider.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeAverageProvider.kt
index bda098f47..af1699323 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeAverageProvider.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeAverageProvider.kt
@@ -98,7 +98,7 @@ class GradeAverageProvider @Inject constructor(
}
private fun List.emulateEmptySummaries(student: Student, semester: Semester, grades: List>>, calcAverage: Boolean): List {
- if (isNotEmpty() && size == grades.size) return this
+ if (isNotEmpty() && size > grades.size) return this
return grades.mapIndexed { i, (subject, details) ->
singleOrNull { it.subject == subject }?.let { return@mapIndexed it }
diff --git a/app/src/main/java/io/github/wulkanowy/utils/SdkExtension.kt b/app/src/main/java/io/github/wulkanowy/utils/SdkExtension.kt
index e4d4163b4..63a30db8c 100644
--- a/app/src/main/java/io/github/wulkanowy/utils/SdkExtension.kt
+++ b/app/src/main/java/io/github/wulkanowy/utils/SdkExtension.kt
@@ -23,6 +23,8 @@ fun Sdk.init(student: Student): Sdk {
certKey = student.certificateKey
privateKey = student.privateKey
+ emptyCookieJarInterceptor = true
+
Timber.d("Sdk in ${student.loginMode} mode reinitialized")
return this
From a05da2656a3960848e2baef1ce9545e316b6f116 Mon Sep 17 00:00:00 2001
From: Dominik Korsa
Date: Fri, 12 Jun 2020 21:35:51 +0200
Subject: [PATCH 026/100] Add account headers in student picker (#871)
---
.../repositories/student/StudentRemote.kt | 2 +-
.../wulkanowy/ui/modules/account/Account.kt | 3 +
.../ui/modules/account/AccountAdapter.kt | 60 +++++++++++--
.../ui/modules/account/AccountDialog.kt | 3 +-
.../ui/modules/account/AccountItem.kt | 9 ++
.../ui/modules/account/AccountPresenter.kt | 9 ++
.../ui/modules/account/AccountView.kt | 3 +-
app/src/main/res/layout/dialog_account.xml | 89 +++++++++++--------
app/src/main/res/layout/header_account.xml | 28 ++++++
app/src/main/res/layout/item_account.xml | 30 +++++--
app/src/main/res/values-pl/strings.xml | 4 +
app/src/main/res/values/strings.xml | 4 +
12 files changed, 185 insertions(+), 59 deletions(-)
create mode 100644 app/src/main/java/io/github/wulkanowy/ui/modules/account/Account.kt
create mode 100644 app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountItem.kt
create mode 100644 app/src/main/res/layout/header_account.xml
diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/student/StudentRemote.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/student/StudentRemote.kt
index 15c336505..4c0ffd820 100644
--- a/app/src/main/java/io/github/wulkanowy/data/repositories/student/StudentRemote.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/repositories/student/StudentRemote.kt
@@ -14,7 +14,7 @@ class StudentRemote @Inject constructor(private val sdk: Sdk) {
private fun mapStudents(students: List, email: String, password: String): List {
return students.map { student ->
Student(
- email = email,
+ email = email.ifBlank { student.email },
password = password,
isParent = student.isParent,
symbol = student.symbol,
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/account/Account.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/account/Account.kt
new file mode 100644
index 000000000..dbcb499e8
--- /dev/null
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/account/Account.kt
@@ -0,0 +1,3 @@
+package io.github.wulkanowy.ui.modules.account
+
+data class Account(val email: String, val isParent: Boolean)
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountAdapter.kt
index 7df0ca378..27915a710 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountAdapter.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountAdapter.kt
@@ -3,33 +3,72 @@ package io.github.wulkanowy.ui.modules.account
import android.annotation.SuppressLint
import android.graphics.PorterDuff
import android.view.LayoutInflater
+import android.view.View.GONE
+import android.view.View.VISIBLE
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Student
+import io.github.wulkanowy.databinding.HeaderAccountBinding
import io.github.wulkanowy.databinding.ItemAccountBinding
+import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.utils.getThemeAttrColor
import javax.inject.Inject
-class AccountAdapter @Inject constructor() : RecyclerView.Adapter() {
+class AccountAdapter @Inject constructor() : RecyclerView.Adapter() {
- var items = emptyList()
+ var items = emptyList>()
var onClickListener: (Student) -> Unit = {}
override fun getItemCount() = items.size
- override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder(
- ItemAccountBinding.inflate(LayoutInflater.from(parent.context), parent, false)
- )
+ override fun getItemViewType(position: Int) = items[position].viewType.id
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
+ val inflater = LayoutInflater.from(parent.context)
+
+ return when (viewType) {
+ AccountItem.ViewType.HEADER.id -> HeaderViewHolder(HeaderAccountBinding.inflate(inflater, parent, false))
+ AccountItem.ViewType.ITEM.id -> ItemViewHolder(ItemAccountBinding.inflate(inflater, parent, false))
+ else -> throw IllegalStateException()
+ }
+ }
+
+ override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
+ when (holder) {
+ is HeaderViewHolder -> bindHeaderViewHolder(holder.binding, items[position].value as Account)
+ is ItemViewHolder -> bindItemViewHolder(holder.binding, items[position].value as Student)
+ }
+ }
+
+ private fun bindHeaderViewHolder(binding: HeaderAccountBinding, account: Account) {
+ with(binding) {
+ accountHeaderEmail.text = account.email
+ accountHeaderType.setText(if (account.isParent) R.string.account_type_parent else R.string.account_type_student)
+ }
+ }
@SuppressLint("SetTextI18n")
- override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
- val student = items[position]
-
- with(holder.binding) {
+ private fun bindItemViewHolder(binding: ItemAccountBinding, student: Student) {
+ with(binding) {
accountItemName.text = "${student.studentName} ${student.className}"
accountItemSchool.text = student.schoolName
+ with(accountItemLoginMode) {
+ visibility = when (Sdk.Mode.valueOf(student.loginMode)) {
+ Sdk.Mode.API -> {
+ setText(R.string.account_login_mobile_api)
+ VISIBLE
+ }
+ Sdk.Mode.HYBRID -> {
+ setText(R.string.account_login_hybrid)
+ VISIBLE
+ }
+ Sdk.Mode.SCRAPPER -> {
+ GONE
+ }
+ }
+ }
with(accountItemImage) {
val colorImage = if (student.isCurrent) context.getThemeAttrColor(R.attr.colorPrimary)
@@ -42,5 +81,8 @@ class AccountAdapter @Inject constructor() : RecyclerView.Adapter(), AccountView {
}
}
- override fun updateData(data: List) {
+ override fun updateData(data: List>) {
with(accountAdapter) {
items = data
notifyDataSetChanged()
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountItem.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountItem.kt
new file mode 100644
index 000000000..05a4a69ce
--- /dev/null
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountItem.kt
@@ -0,0 +1,9 @@
+package io.github.wulkanowy.ui.modules.account
+
+data class AccountItem(val value: T, val viewType: ViewType) {
+
+ enum class ViewType(val id: Int) {
+ HEADER(1),
+ ITEM(2)
+ }
+}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountPresenter.kt
index 3416a043f..b5fbcdb63 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountPresenter.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountPresenter.kt
@@ -83,11 +83,20 @@ class AccountPresenter @Inject constructor(
}
}
+ private fun createAccountItems(items: List): List> {
+ return items.groupBy { Account(it.email, it.isParent) }.map { (account, students) ->
+ listOf(AccountItem(account, AccountItem.ViewType.HEADER)) + students.map { student ->
+ AccountItem(student, AccountItem.ViewType.ITEM)
+ }
+ }.flatten()
+ }
+
private fun loadData() {
Timber.i("Loading account data started")
disposable.add(studentRepository.getSavedStudents(false)
.subscribeOn(schedulers.backgroundThread)
.observeOn(schedulers.mainThread)
+ .map { createAccountItems(it) }
.subscribe({
Timber.i("Loading account result: Success")
view?.updateData(it)
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountView.kt
index abb9e1d27..a1f8086cd 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountView.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountView.kt
@@ -1,13 +1,12 @@
package io.github.wulkanowy.ui.modules.account
-import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.ui.base.BaseView
interface AccountView : BaseView {
fun initView()
- fun updateData(data: List)
+ fun updateData(data: List>)
fun dismissView()
diff --git a/app/src/main/res/layout/dialog_account.xml b/app/src/main/res/layout/dialog_account.xml
index 6e975c80d..d56de3a2e 100644
--- a/app/src/main/res/layout/dialog_account.xml
+++ b/app/src/main/res/layout/dialog_account.xml
@@ -5,45 +5,60 @@
android:layout_width="300dp"
android:layout_height="wrap_content">
-
-
-
+ android:orientation="vertical">
-
+
-
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/header_account.xml b/app/src/main/res/layout/header_account.xml
new file mode 100644
index 000000000..6219c26db
--- /dev/null
+++ b/app/src/main/res/layout/header_account.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/item_account.xml b/app/src/main/res/layout/item_account.xml
index 614e4d2df..9568b345a 100644
--- a/app/src/main/res/layout/item_account.xml
+++ b/app/src/main/res/layout/item_account.xml
@@ -3,20 +3,17 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
- android:layout_height="56dp"
+ android:layout_height="wrap_content"
android:background="?selectableItemBackground"
android:orientation="horizontal"
- android:paddingStart="24dp"
- android:paddingLeft="24dp"
- android:paddingEnd="24dp"
- android:paddingRight="24dp"
+ android:paddingVertical="8dp"
+ android:paddingHorizontal="16dp"
tools:context=".ui.modules.account.AccountAdapter">
+
+
diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml
index 7f25d8a67..4cb8997cf 100644
--- a/app/src/main/res/values-pl/strings.xml
+++ b/app/src/main/res/values-pl/strings.xml
@@ -265,6 +265,10 @@
Wyloguj
Czy chcesz wylogować aktualnego ucznia?
Wylogowanie ucznia
+ Konto ucznia
+ Konto rodzica
+ Tryb API mobilne
+ Tryb hybrydowy
Wersja aplikacji
Twórcy
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 7793cd9c2..29e3460b4 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -282,6 +282,10 @@
Logout
Do you want to log out of an active student?
Student logout
+ Student account
+ Parent account
+ Mobile API mode
+ Hybrid mode
From a52983693722869b56e6afddfb29ddd6f469e3a9 Mon Sep 17 00:00:00 2001
From: Dominik Korsa
Date: Sat, 13 Jun 2020 14:12:01 +0200
Subject: [PATCH 027/100] Fix lint errors (#873)
---
.../data/db/migrations/Migration13Test.kt | 30 +++++++--------
.../attendance/AttendanceLocalTest.kt | 37 +++++++++++++++++--
.../luckynumber/LuckyNumberLocalTest.kt | 1 -
.../wulkanowy/utils/CrashlyticsUtils.kt | 1 -
.../github/wulkanowy/data/RepositoryModule.kt | 6 +--
.../appcreator/AppCreatorRepository.kt | 2 +-
.../data/repositories/exam/ExamLocal.kt | 2 +-
.../repositories/recipient/RecipientLocal.kt | 2 +-
.../reportingunit/ReportingUnitLocal.kt | 2 +-
.../sync/works/GradeStatisticsWork.kt | 2 +-
.../about/logviewer/LogViewerPresenter.kt | 6 +--
.../modules/attendance/AttendancePresenter.kt | 1 -
.../completed/CompletedLessonsPresenter.kt | 2 +-
.../wulkanowy/utils/LifecycleAwareVariable.kt | 2 +-
app/src/main/res/values/strings.xml | 2 +-
.../io/github/wulkanowy/TestEnityCreator.kt | 23 ++++++++++++
.../message/MessageRepositoryTest.kt | 13 +++----
17 files changed, 91 insertions(+), 43 deletions(-)
diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/db/migrations/Migration13Test.kt b/app/src/androidTest/java/io/github/wulkanowy/data/db/migrations/Migration13Test.kt
index 6f9406f6d..da4284b02 100644
--- a/app/src/androidTest/java/io/github/wulkanowy/data/db/migrations/Migration13Test.kt
+++ b/app/src/androidTest/java/io/github/wulkanowy/data/db/migrations/Migration13Test.kt
@@ -120,23 +120,23 @@ class Migration13Test : AbstractMigrationTest() {
assertEquals(2, first.diaryId)
}
- getSemesters(db, "SELECT * FROM Semesters WHERE student_id = 2 AND class_id = 5").let {
- assertTrue { it.single { it.second }.second }
- assertEquals(1970, it[0].first.schoolYear)
- assertEquals(of(1970, 1, 1), it[0].first.end)
- assertEquals(of(1970, 1, 1), it[0].first.start)
- assertFalse(it[0].second)
- assertFalse(it[1].second)
- assertFalse(it[2].second)
- assertTrue(it[3].second)
+ getSemesters(db, "SELECT * FROM Semesters WHERE student_id = 2 AND class_id = 5").let { semesters ->
+ assertTrue { semesters.single { it.second }.second }
+ assertEquals(1970, semesters[0].first.schoolYear)
+ assertEquals(of(1970, 1, 1), semesters[0].first.end)
+ assertEquals(of(1970, 1, 1), semesters[0].first.start)
+ assertFalse(semesters[0].second)
+ assertFalse(semesters[1].second)
+ assertFalse(semesters[2].second)
+ assertTrue(semesters[3].second)
}
- getSemesters(db, "SELECT * FROM Semesters WHERE student_id = 2 AND class_id = 5").let {
- assertTrue { it.single { it.second }.second }
- assertFalse(it[0].second)
- assertFalse(it[1].second)
- assertFalse(it[2].second)
- assertTrue(it[3].second)
+ getSemesters(db, "SELECT * FROM Semesters WHERE student_id = 2 AND class_id = 5").let { semesters ->
+ assertTrue { semesters.single { it.second }.second }
+ assertFalse(semesters[0].second)
+ assertFalse(semesters[1].second)
+ assertFalse(semesters[2].second)
+ assertTrue(semesters[3].second)
}
}
diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/attendance/AttendanceLocalTest.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/attendance/AttendanceLocalTest.kt
index c7ede6ae5..cdfc524ad 100644
--- a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/attendance/AttendanceLocalTest.kt
+++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/attendance/AttendanceLocalTest.kt
@@ -10,6 +10,7 @@ import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
+import org.threeten.bp.LocalDate
import org.threeten.bp.LocalDate.now
import org.threeten.bp.LocalDate.of
import kotlin.test.assertEquals
@@ -35,9 +36,18 @@ class AttendanceLocalTest {
@Test
fun saveAndReadTest() {
attendanceLocal.saveAttendance(listOf(
- Attendance(1, 2, 3, of(2018, 9, 10), 0, "", "", false, false, false, false, false, false, false, SentExcuseStatus.ACCEPTED.name),
- Attendance(1, 2, 3, of(2018, 9, 14), 0, "", "", false, false, false, false, false, false, false, SentExcuseStatus.WAITING.name),
- Attendance(1, 2, 3, of(2018, 9, 17), 0, "", "", false, false, false, false, false, false, false, SentExcuseStatus.ACCEPTED.name)
+ getAttendanceEntity(
+ of(2018, 9, 10),
+ SentExcuseStatus.ACCEPTED
+ ),
+ getAttendanceEntity(
+ of(2018, 9, 14),
+ SentExcuseStatus.WAITING
+ ),
+ getAttendanceEntity(
+ of(2018, 9, 17),
+ SentExcuseStatus.ACCEPTED
+ )
))
val attendance = attendanceLocal
@@ -50,4 +60,25 @@ class AttendanceLocalTest {
assertEquals(attendance[0].date, of(2018, 9, 10))
assertEquals(attendance[1].date, of(2018, 9, 14))
}
+
+ private fun getAttendanceEntity(
+ date: LocalDate,
+ excuseStatus: SentExcuseStatus
+ ) = Attendance(
+ studentId = 1,
+ diaryId = 2,
+ timeId = 3,
+ date = date,
+ number = 0,
+ subject = "",
+ name = "",
+ presence = false,
+ absence = false,
+ exemption = false,
+ lateness = false,
+ excused = false,
+ deleted = false,
+ excusable = false,
+ excuseStatus = excuseStatus.name
+ )
}
diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/luckynumber/LuckyNumberLocalTest.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/luckynumber/LuckyNumberLocalTest.kt
index 65ef1fcbf..efad0d4d5 100644
--- a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/luckynumber/LuckyNumberLocalTest.kt
+++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/luckynumber/LuckyNumberLocalTest.kt
@@ -5,7 +5,6 @@ import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import io.github.wulkanowy.data.db.AppDatabase
import io.github.wulkanowy.data.db.entities.LuckyNumber
-import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import org.junit.After
import org.junit.Before
diff --git a/app/src/fdroid/java/io/github/wulkanowy/utils/CrashlyticsUtils.kt b/app/src/fdroid/java/io/github/wulkanowy/utils/CrashlyticsUtils.kt
index 6351997d0..d03a319a2 100644
--- a/app/src/fdroid/java/io/github/wulkanowy/utils/CrashlyticsUtils.kt
+++ b/app/src/fdroid/java/io/github/wulkanowy/utils/CrashlyticsUtils.kt
@@ -2,7 +2,6 @@
package io.github.wulkanowy.utils
-import android.content.Context
import timber.log.Timber
open class TimberTreeNoOp : Timber.Tree() {
diff --git a/app/src/main/java/io/github/wulkanowy/data/RepositoryModule.kt b/app/src/main/java/io/github/wulkanowy/data/RepositoryModule.kt
index 9540372fc..19af1b2f8 100644
--- a/app/src/main/java/io/github/wulkanowy/data/RepositoryModule.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/RepositoryModule.kt
@@ -1,17 +1,15 @@
package io.github.wulkanowy.data
-import android.app.AlarmManager
import android.content.Context
import android.content.SharedPreferences
import android.content.res.AssetManager
import android.content.res.Resources
-import androidx.core.content.getSystemService
import androidx.preference.PreferenceManager
-import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
-import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.strategy.WalledGardenInternetObservingStrategy
import com.chuckerteam.chucker.api.ChuckerCollector
import com.chuckerteam.chucker.api.ChuckerInterceptor
import com.chuckerteam.chucker.api.RetentionManager
+import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
+import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.strategy.WalledGardenInternetObservingStrategy
import dagger.Module
import dagger.Provides
import io.github.wulkanowy.data.db.AppDatabase
diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/appcreator/AppCreatorRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/appcreator/AppCreatorRepository.kt
index 6a0b2d32e..76cf698c9 100644
--- a/app/src/main/java/io/github/wulkanowy/data/repositories/appcreator/AppCreatorRepository.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/repositories/appcreator/AppCreatorRepository.kt
@@ -10,7 +10,7 @@ import javax.inject.Singleton
@Singleton
class AppCreatorRepository @Inject constructor(private val assets: AssetManager) {
fun getAppCreators(): Single> {
- return Single.fromCallable> {
+ return Single.fromCallable {
Gson().fromJson(
assets.open("contributors.json").bufferedReader().use { it.readText() },
Array::class.java
diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/exam/ExamLocal.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/exam/ExamLocal.kt
index 0f484d323..389eb5835 100644
--- a/app/src/main/java/io/github/wulkanowy/data/repositories/exam/ExamLocal.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/repositories/exam/ExamLocal.kt
@@ -13,7 +13,7 @@ class ExamLocal @Inject constructor(private val examDb: ExamDao) {
fun getExams(semester: Semester, startDate: LocalDate, endDate: LocalDate): Maybe> {
return examDb.loadAll(semester.diaryId, semester.studentId, startDate, endDate)
- .filter { !it.isEmpty() }
+ .filter { it.isNotEmpty() }
}
fun saveExams(exams: List) {
diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/recipient/RecipientLocal.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/recipient/RecipientLocal.kt
index 9b1d4ac2f..ff8175440 100644
--- a/app/src/main/java/io/github/wulkanowy/data/repositories/recipient/RecipientLocal.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/repositories/recipient/RecipientLocal.kt
@@ -12,7 +12,7 @@ import javax.inject.Singleton
class RecipientLocal @Inject constructor(private val recipientDb: RecipientDao) {
fun getRecipients(student: Student, role: Int, unit: ReportingUnit): Maybe> {
- return recipientDb.load(student.studentId, role, unit.realId).filter { !it.isEmpty() }
+ return recipientDb.load(student.studentId, role, unit.realId).filter { it.isNotEmpty() }
}
fun saveRecipients(recipients: List): List {
diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/reportingunit/ReportingUnitLocal.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/reportingunit/ReportingUnitLocal.kt
index 6f9eec3fc..0631c668c 100644
--- a/app/src/main/java/io/github/wulkanowy/data/repositories/reportingunit/ReportingUnitLocal.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/repositories/reportingunit/ReportingUnitLocal.kt
@@ -11,7 +11,7 @@ import javax.inject.Singleton
class ReportingUnitLocal @Inject constructor(private val reportingUnitDb: ReportingUnitDao) {
fun getReportingUnits(student: Student): Maybe> {
- return reportingUnitDb.load(student.studentId).filter { !it.isEmpty() }
+ return reportingUnitDb.load(student.studentId).filter { it.isNotEmpty() }
}
fun getReportingUnit(student: Student, unitId: Int): Maybe {
diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/works/GradeStatisticsWork.kt b/app/src/main/java/io/github/wulkanowy/services/sync/works/GradeStatisticsWork.kt
index 327c71740..c4681fb8f 100644
--- a/app/src/main/java/io/github/wulkanowy/services/sync/works/GradeStatisticsWork.kt
+++ b/app/src/main/java/io/github/wulkanowy/services/sync/works/GradeStatisticsWork.kt
@@ -9,7 +9,7 @@ import javax.inject.Inject
class GradeStatisticsWork @Inject constructor(private val gradeStatisticsRepository: GradeStatisticsRepository) : Work {
override fun create(student: Student, semester: Semester): Completable {
- return gradeStatisticsRepository.getGradesStatistics(student, semester, "Wszystkie", false, true)
+ return gradeStatisticsRepository.getGradesStatistics(student, semester, "Wszystkie", false, forceRefresh = true)
.ignoreElement()
}
}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/about/logviewer/LogViewerPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/about/logviewer/LogViewerPresenter.kt
index 4485cb3eb..33eb1122d 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/about/logviewer/LogViewerPresenter.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/about/logviewer/LogViewerPresenter.kt
@@ -25,9 +25,9 @@ class LogViewerPresenter @Inject constructor(
disposable.add(loggerRepository.getLogFiles()
.subscribeOn(schedulers.backgroundThread)
.observeOn(schedulers.mainThread)
- .subscribe({
- Timber.i("Loading logs files result: ${it.joinToString { it.name }}")
- view?.shareLogs(it)
+ .subscribe({ files ->
+ Timber.i("Loading logs files result: ${files.joinToString { it.name }}")
+ view?.shareLogs(files)
}, {
Timber.i("Loading logs files result: An exception occurred")
errorHandler.dispatch(it)
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 437e06c92..f58d0617f 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
@@ -20,7 +20,6 @@ import org.threeten.bp.LocalDate
import org.threeten.bp.LocalDate.now
import org.threeten.bp.LocalDate.ofEpochDay
import timber.log.Timber
-import java.util.concurrent.TimeUnit.MILLISECONDS
import javax.inject.Inject
class AttendancePresenter @Inject constructor(
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 92aeb5814..f72d753a9 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
@@ -43,7 +43,7 @@ class CompletedLessonsPresenter @Inject constructor(
completedLessonsErrorHandler.showErrorMessage = ::showErrorViewOnError
completedLessonsErrorHandler.onFeatureDisabled = {
this.view?.showFeatureDisabled()
- this.view?.showEmpty(true);
+ this.view?.showEmpty(true)
Timber.i("Completed lessons feature disabled by school")
}
loadData(ofEpochDay(date ?: baseDate.toEpochDay()))
diff --git a/app/src/main/java/io/github/wulkanowy/utils/LifecycleAwareVariable.kt b/app/src/main/java/io/github/wulkanowy/utils/LifecycleAwareVariable.kt
index 2c49ee97c..b96faeb21 100644
--- a/app/src/main/java/io/github/wulkanowy/utils/LifecycleAwareVariable.kt
+++ b/app/src/main/java/io/github/wulkanowy/utils/LifecycleAwareVariable.kt
@@ -52,4 +52,4 @@ class LifecycleAwareVariableActivity : ReadWriteProperty Fragment.lifecycleAwareVariable() = LifecycleAwareVariable()
-fun AppCompatActivity.lifecycleAwareVariable() = LifecycleAwareVariableActivity()
+fun lifecycleAwareVariable() = LifecycleAwareVariableActivity()
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 29e3460b4..bec752cf2 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -343,7 +343,7 @@
Prev
Next
Search
- Search...
+ Search…
diff --git a/app/src/test/java/io/github/wulkanowy/TestEnityCreator.kt b/app/src/test/java/io/github/wulkanowy/TestEnityCreator.kt
index 5d003f273..f7d29220f 100644
--- a/app/src/test/java/io/github/wulkanowy/TestEnityCreator.kt
+++ b/app/src/test/java/io/github/wulkanowy/TestEnityCreator.kt
@@ -1,5 +1,6 @@
package io.github.wulkanowy
+import io.github.wulkanowy.data.db.entities.Message
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.db.entities.Timetable
@@ -72,3 +73,25 @@ fun getTimetableEntity(
teacher = "",
teacherOld = ""
)
+
+fun getMessageEntity(
+ messageId: Int,
+ content: String,
+ unread: Boolean
+) = Message(
+ studentId = 1,
+ realId = 1,
+ messageId = messageId,
+ sender = "",
+ senderId = 1,
+ recipient = "",
+ subject = "",
+ content = content,
+ date = now(),
+ folderId = 1,
+ unread = unread,
+ unreadBy = 1,
+ readBy = 1,
+ removed = false,
+ hasAttachments = false
+)
diff --git a/app/src/test/java/io/github/wulkanowy/data/repositories/message/MessageRepositoryTest.kt b/app/src/test/java/io/github/wulkanowy/data/repositories/message/MessageRepositoryTest.kt
index b7963d430..fcc4188a6 100644
--- a/app/src/test/java/io/github/wulkanowy/data/repositories/message/MessageRepositoryTest.kt
+++ b/app/src/test/java/io/github/wulkanowy/data/repositories/message/MessageRepositoryTest.kt
@@ -2,10 +2,10 @@ package io.github.wulkanowy.data.repositories.message
import androidx.room.EmptyResultSetException
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
-import io.github.wulkanowy.data.db.entities.Message
import io.github.wulkanowy.data.db.entities.MessageWithAttachment
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.repositories.UnitTestInternetObservingStrategy
+import io.github.wulkanowy.getMessageEntity
import io.reactivex.Single
import io.reactivex.observers.TestObserver
import org.junit.Assert.assertEquals
@@ -15,7 +15,6 @@ import org.mockito.Mock
import org.mockito.Mockito.`when`
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
-import org.threeten.bp.LocalDateTime.now
import java.net.UnknownHostException
class MessageRepositoryTest {
@@ -44,7 +43,7 @@ class MessageRepositoryTest {
@Test
fun `throw error when message is not in the db`() {
- val testMessage = Message(1, 1, 1, "", 1, "", "", "", now(), 1, false, 1, 1, false, false)
+ val testMessage = getMessageEntity(1, "", false)
`when`(local.getMessageWithAttachment(student, testMessage)).thenReturn(Single.error(EmptyResultSetException("No message in database")))
val message = repo.getMessage(student, testMessage)
@@ -55,7 +54,7 @@ class MessageRepositoryTest {
@Test
fun `get message when content already in db`() {
- val testMessage = Message(1, 1, 123, "", 1, "", "", "Test", now(), 1, false, 1, 1, false, false)
+ val testMessage = getMessageEntity(123, "Test", false)
val messageWithAttachment = MessageWithAttachment(testMessage, emptyList())
`when`(local.getMessageWithAttachment(student, testMessage)).thenReturn(Single.just(messageWithAttachment))
@@ -67,7 +66,7 @@ class MessageRepositoryTest {
@Test
fun `get message when content in db is empty`() {
- val testMessage = Message(1, 1, 123, "", 1, "", "", "", now(), 1, true, 1, 1, false, false)
+ val testMessage = getMessageEntity(123, "", true)
val testMessageWithContent = testMessage.copy(content = "Test")
val mWa = MessageWithAttachment(testMessage, emptyList())
@@ -86,7 +85,7 @@ class MessageRepositoryTest {
@Test
fun `get message when content in db is empty and there is no internet connection`() {
- val testMessage = Message(1, 1, 123, "", 1, "", "", "", now(), 1, false, 1, 1, false, false)
+ val testMessage = getMessageEntity(123, "", false)
val messageWithAttachment = MessageWithAttachment(testMessage, emptyList())
testObservingStrategy.isInternetConnection = false
@@ -100,7 +99,7 @@ class MessageRepositoryTest {
@Test
fun `get message when content in db is empty, unread and there is no internet connection`() {
- val testMessage = Message(1, 1, 123, "", 1, "", "", "", now(), 1, true, 1, 1, false, false)
+ val testMessage = getMessageEntity(123, "", true)
val messageWithAttachment = MessageWithAttachment(testMessage, emptyList())
testObservingStrategy.isInternetConnection = false
From a6682c9b73d525133e32accbc2aae89636fad9b2 Mon Sep 17 00:00:00 2001
From: Dominik Korsa
Date: Sat, 13 Jun 2020 17:11:18 +0200
Subject: [PATCH 028/100] Add predicted and final grade notifications (#872)
---
.../25.json | 2 +-
.../26.json | 1768 +++++++++++++++++
.../github/wulkanowy/data/db/AppDatabase.kt | 6 +-
.../data/db/entities/GradeSummary.kt | 13 +
.../data/db/migrations/Migration26.kt | 14 +
.../data/repositories/grade/GradeLocal.kt | 4 +
.../repositories/grade/GradeRepository.kt | 39 +-
.../services/sync/works/GradeWork.kt | 53 +-
app/src/main/res/values-pl/strings.xml | 24 +
app/src/main/res/values/strings.xml | 16 +
10 files changed, 1927 insertions(+), 12 deletions(-)
create mode 100644 app/schemas/io.github.wulkanowy.data.db.AppDatabase/26.json
create mode 100644 app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration26.kt
diff --git a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/25.json b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/25.json
index e99a11d4a..474824df6 100644
--- a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/25.json
+++ b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/25.json
@@ -1741,4 +1741,4 @@
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'd101f5a26a024f62e6fee161e421b882')"
]
}
-}
\ No newline at end of file
+}
diff --git a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/26.json b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/26.json
new file mode 100644
index 000000000..21005f9c6
--- /dev/null
+++ b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/26.json
@@ -0,0 +1,1768 @@
+{
+ "formatVersion": 1,
+ "database": {
+ "version": 26,
+ "identityHash": "43f8777ffe95a5a2850ee981db3dbe2e",
+ "entities": [
+ {
+ "tableName": "Students",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `scrapper_base_url` TEXT NOT NULL, `mobile_base_url` TEXT NOT NULL, `login_type` TEXT NOT NULL, `login_mode` TEXT NOT NULL, `certificate_key` TEXT NOT NULL, `private_key` TEXT NOT NULL, `is_parent` INTEGER NOT NULL, `email` TEXT NOT NULL, `password` TEXT NOT NULL, `symbol` TEXT NOT NULL, `student_id` INTEGER NOT NULL, `user_login_id` INTEGER NOT NULL, `student_name` TEXT NOT NULL, `school_id` TEXT NOT NULL, `school_short` TEXT NOT NULL, `school_name` TEXT NOT NULL, `class_name` TEXT NOT NULL, `class_id` INTEGER NOT NULL, `is_current` INTEGER NOT NULL, `registration_date` INTEGER NOT NULL)",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "scrapperBaseUrl",
+ "columnName": "scrapper_base_url",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "mobileBaseUrl",
+ "columnName": "mobile_base_url",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "loginType",
+ "columnName": "login_type",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "loginMode",
+ "columnName": "login_mode",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "certificateKey",
+ "columnName": "certificate_key",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "privateKey",
+ "columnName": "private_key",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "isParent",
+ "columnName": "is_parent",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "email",
+ "columnName": "email",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "password",
+ "columnName": "password",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "symbol",
+ "columnName": "symbol",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "studentId",
+ "columnName": "student_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "userLoginId",
+ "columnName": "user_login_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "studentName",
+ "columnName": "student_name",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "schoolSymbol",
+ "columnName": "school_id",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "schoolShortName",
+ "columnName": "school_short",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "schoolName",
+ "columnName": "school_name",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "className",
+ "columnName": "class_name",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "classId",
+ "columnName": "class_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "isCurrent",
+ "columnName": "is_current",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "registrationDate",
+ "columnName": "registration_date",
+ "affinity": "INTEGER",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "id"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [
+ {
+ "name": "index_Students_email_symbol_student_id_school_id_class_id",
+ "unique": true,
+ "columnNames": [
+ "email",
+ "symbol",
+ "student_id",
+ "school_id",
+ "class_id"
+ ],
+ "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Students_email_symbol_student_id_school_id_class_id` ON `${TABLE_NAME}` (`email`, `symbol`, `student_id`, `school_id`, `class_id`)"
+ }
+ ],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "Semesters",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_current` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `diary_name` TEXT NOT NULL, `school_year` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `semester_name` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL)",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "current",
+ "columnName": "is_current",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "studentId",
+ "columnName": "student_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "diaryId",
+ "columnName": "diary_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "diaryName",
+ "columnName": "diary_name",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "schoolYear",
+ "columnName": "school_year",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "semesterId",
+ "columnName": "semester_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "semesterName",
+ "columnName": "semester_name",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "start",
+ "columnName": "start",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "end",
+ "columnName": "end",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "classId",
+ "columnName": "class_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "unitId",
+ "columnName": "unit_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "id"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [
+ {
+ "name": "index_Semesters_student_id_diary_id_semester_id",
+ "unique": true,
+ "columnNames": [
+ "student_id",
+ "diary_id",
+ "semester_id"
+ ],
+ "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Semesters_student_id_diary_id_semester_id` ON `${TABLE_NAME}` (`student_id`, `diary_id`, `semester_id`)"
+ }
+ ],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "Exams",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `group` TEXT NOT NULL, `type` TEXT NOT NULL, `description` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL)",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "studentId",
+ "columnName": "student_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "diaryId",
+ "columnName": "diary_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "date",
+ "columnName": "date",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "entryDate",
+ "columnName": "entry_date",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "subject",
+ "columnName": "subject",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "group",
+ "columnName": "group",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "type",
+ "columnName": "type",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "description",
+ "columnName": "description",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "teacher",
+ "columnName": "teacher",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "teacherSymbol",
+ "columnName": "teacher_symbol",
+ "affinity": "TEXT",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "id"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "Timetable",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `number` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `subjectOld` TEXT NOT NULL, `group` TEXT NOT NULL, `room` TEXT NOT NULL, `roomOld` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacherOld` TEXT NOT NULL, `info` TEXT NOT NULL, `student_plan` INTEGER NOT NULL, `changes` INTEGER NOT NULL, `canceled` INTEGER NOT NULL)",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "studentId",
+ "columnName": "student_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "diaryId",
+ "columnName": "diary_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "number",
+ "columnName": "number",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "start",
+ "columnName": "start",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "end",
+ "columnName": "end",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "date",
+ "columnName": "date",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "subject",
+ "columnName": "subject",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "subjectOld",
+ "columnName": "subjectOld",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "group",
+ "columnName": "group",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "room",
+ "columnName": "room",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "roomOld",
+ "columnName": "roomOld",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "teacher",
+ "columnName": "teacher",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "teacherOld",
+ "columnName": "teacherOld",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "info",
+ "columnName": "info",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "isStudentPlan",
+ "columnName": "student_plan",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "changes",
+ "columnName": "changes",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "canceled",
+ "columnName": "canceled",
+ "affinity": "INTEGER",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "id"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "Attendance",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `time_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `exemption` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `excused` INTEGER NOT NULL, `deleted` INTEGER NOT NULL, `excusable` INTEGER NOT NULL, `excuse_status` TEXT)",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "studentId",
+ "columnName": "student_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "diaryId",
+ "columnName": "diary_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "timeId",
+ "columnName": "time_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "date",
+ "columnName": "date",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "number",
+ "columnName": "number",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "subject",
+ "columnName": "subject",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "presence",
+ "columnName": "presence",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "absence",
+ "columnName": "absence",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "exemption",
+ "columnName": "exemption",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "lateness",
+ "columnName": "lateness",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "excused",
+ "columnName": "excused",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "deleted",
+ "columnName": "deleted",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "excusable",
+ "columnName": "excusable",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "excuseStatus",
+ "columnName": "excuse_status",
+ "affinity": "TEXT",
+ "notNull": false
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "id"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "AttendanceSummary",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `subject_id` INTEGER NOT NULL, `month` INTEGER NOT NULL, `presence` INTEGER NOT NULL, `absence` INTEGER NOT NULL, `absence_excused` INTEGER NOT NULL, `absence_for_school_reasons` INTEGER NOT NULL, `lateness` INTEGER NOT NULL, `lateness_excused` INTEGER NOT NULL, `exemption` INTEGER NOT NULL)",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "studentId",
+ "columnName": "student_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "diaryId",
+ "columnName": "diary_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "subjectId",
+ "columnName": "subject_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "month",
+ "columnName": "month",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "presence",
+ "columnName": "presence",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "absence",
+ "columnName": "absence",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "absenceExcused",
+ "columnName": "absence_excused",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "absenceForSchoolReasons",
+ "columnName": "absence_for_school_reasons",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "lateness",
+ "columnName": "lateness",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "latenessExcused",
+ "columnName": "lateness_excused",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "exemption",
+ "columnName": "exemption",
+ "affinity": "INTEGER",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "id"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "Grades",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `entry` TEXT NOT NULL, `value` REAL NOT NULL, `modifier` REAL NOT NULL, `comment` TEXT NOT NULL, `color` TEXT NOT NULL, `grade_symbol` TEXT NOT NULL, `description` TEXT NOT NULL, `weight` TEXT NOT NULL, `weightValue` REAL NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL)",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "isRead",
+ "columnName": "is_read",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "isNotified",
+ "columnName": "is_notified",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "semesterId",
+ "columnName": "semester_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "studentId",
+ "columnName": "student_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "subject",
+ "columnName": "subject",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "entry",
+ "columnName": "entry",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "value",
+ "columnName": "value",
+ "affinity": "REAL",
+ "notNull": true
+ },
+ {
+ "fieldPath": "modifier",
+ "columnName": "modifier",
+ "affinity": "REAL",
+ "notNull": true
+ },
+ {
+ "fieldPath": "comment",
+ "columnName": "comment",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "color",
+ "columnName": "color",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "gradeSymbol",
+ "columnName": "grade_symbol",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "description",
+ "columnName": "description",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "weight",
+ "columnName": "weight",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "weightValue",
+ "columnName": "weightValue",
+ "affinity": "REAL",
+ "notNull": true
+ },
+ {
+ "fieldPath": "date",
+ "columnName": "date",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "teacher",
+ "columnName": "teacher",
+ "affinity": "TEXT",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "id"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "GradesSummary",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_predicted_grade_notified` INTEGER NOT NULL, `is_final_grade_notified` INTEGER NOT NULL, `predicted_grade_last_change` INTEGER NOT NULL, `final_grade_last_change` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `position` INTEGER NOT NULL, `subject` TEXT NOT NULL, `predicted_grade` TEXT NOT NULL, `final_grade` TEXT NOT NULL, `proposed_points` TEXT NOT NULL, `final_points` TEXT NOT NULL, `points_sum` TEXT NOT NULL, `average` REAL NOT NULL)",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "isPredictedGradeNotified",
+ "columnName": "is_predicted_grade_notified",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "isFinalGradeNotified",
+ "columnName": "is_final_grade_notified",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "predictedGradeLastChange",
+ "columnName": "predicted_grade_last_change",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "finalGradeLastChange",
+ "columnName": "final_grade_last_change",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "semesterId",
+ "columnName": "semester_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "studentId",
+ "columnName": "student_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "position",
+ "columnName": "position",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "subject",
+ "columnName": "subject",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "predictedGrade",
+ "columnName": "predicted_grade",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "finalGrade",
+ "columnName": "final_grade",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "proposedPoints",
+ "columnName": "proposed_points",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "finalPoints",
+ "columnName": "final_points",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "pointsSum",
+ "columnName": "points_sum",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "average",
+ "columnName": "average",
+ "affinity": "REAL",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "id"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "GradesStatistics",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `grade` INTEGER NOT NULL, `amount` INTEGER NOT NULL, `is_semester` INTEGER NOT NULL)",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "studentId",
+ "columnName": "student_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "semesterId",
+ "columnName": "semester_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "subject",
+ "columnName": "subject",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "grade",
+ "columnName": "grade",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "amount",
+ "columnName": "amount",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "semester",
+ "columnName": "is_semester",
+ "affinity": "INTEGER",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "id"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "GradesPointsStatistics",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `others` REAL NOT NULL, `student` REAL NOT NULL)",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "studentId",
+ "columnName": "student_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "semesterId",
+ "columnName": "semester_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "subject",
+ "columnName": "subject",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "others",
+ "columnName": "others",
+ "affinity": "REAL",
+ "notNull": true
+ },
+ {
+ "fieldPath": "student",
+ "columnName": "student",
+ "affinity": "REAL",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "id"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "Messages",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `message_id` INTEGER NOT NULL, `sender_name` TEXT NOT NULL, `sender_id` INTEGER NOT NULL, `recipient_name` TEXT NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `date` INTEGER NOT NULL, `folder_id` INTEGER NOT NULL, `unread` INTEGER NOT NULL, `unread_by` INTEGER NOT NULL, `read_by` INTEGER NOT NULL, `removed` INTEGER NOT NULL, `has_attachments` INTEGER NOT NULL)",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "isNotified",
+ "columnName": "is_notified",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "studentId",
+ "columnName": "student_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "realId",
+ "columnName": "real_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "messageId",
+ "columnName": "message_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "sender",
+ "columnName": "sender_name",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "senderId",
+ "columnName": "sender_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "recipient",
+ "columnName": "recipient_name",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "subject",
+ "columnName": "subject",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "content",
+ "columnName": "content",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "date",
+ "columnName": "date",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "folderId",
+ "columnName": "folder_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "unread",
+ "columnName": "unread",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "unreadBy",
+ "columnName": "unread_by",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "readBy",
+ "columnName": "read_by",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "removed",
+ "columnName": "removed",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "hasAttachments",
+ "columnName": "has_attachments",
+ "affinity": "INTEGER",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "id"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "MessageAttachments",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`real_id` INTEGER NOT NULL, `message_id` INTEGER NOT NULL, `one_drive_id` TEXT NOT NULL, `url` TEXT NOT NULL, `filename` TEXT NOT NULL, PRIMARY KEY(`real_id`))",
+ "fields": [
+ {
+ "fieldPath": "realId",
+ "columnName": "real_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "messageId",
+ "columnName": "message_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "oneDriveId",
+ "columnName": "one_drive_id",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "url",
+ "columnName": "url",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "filename",
+ "columnName": "filename",
+ "affinity": "TEXT",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "real_id"
+ ],
+ "autoGenerate": false
+ },
+ "indices": [],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "Notes",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `category` TEXT NOT NULL, `category_type` INTEGER NOT NULL, `is_points_show` INTEGER NOT NULL, `points` INTEGER NOT NULL, `content` TEXT NOT NULL)",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "isRead",
+ "columnName": "is_read",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "isNotified",
+ "columnName": "is_notified",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "studentId",
+ "columnName": "student_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "date",
+ "columnName": "date",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "teacher",
+ "columnName": "teacher",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "teacherSymbol",
+ "columnName": "teacher_symbol",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "category",
+ "columnName": "category",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "categoryType",
+ "columnName": "category_type",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "isPointsShow",
+ "columnName": "is_points_show",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "points",
+ "columnName": "points",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "content",
+ "columnName": "content",
+ "affinity": "TEXT",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "id"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "Homework",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_done` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `entry_date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `attachments` TEXT NOT NULL)",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "isDone",
+ "columnName": "is_done",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "semesterId",
+ "columnName": "semester_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "studentId",
+ "columnName": "student_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "date",
+ "columnName": "date",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "entryDate",
+ "columnName": "entry_date",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "subject",
+ "columnName": "subject",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "content",
+ "columnName": "content",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "teacher",
+ "columnName": "teacher",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "teacherSymbol",
+ "columnName": "teacher_symbol",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "attachments",
+ "columnName": "attachments",
+ "affinity": "TEXT",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "id"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "Subjects",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `name` TEXT NOT NULL)",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "studentId",
+ "columnName": "student_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "diaryId",
+ "columnName": "diary_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "realId",
+ "columnName": "real_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "id"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "LuckyNumbers",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `lucky_number` INTEGER NOT NULL)",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "isNotified",
+ "columnName": "is_notified",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "studentId",
+ "columnName": "student_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "date",
+ "columnName": "date",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "luckyNumber",
+ "columnName": "lucky_number",
+ "affinity": "INTEGER",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "id"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "CompletedLesson",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `number` INTEGER NOT NULL, `subject` TEXT NOT NULL, `topic` TEXT NOT NULL, `teacher` TEXT NOT NULL, `teacher_symbol` TEXT NOT NULL, `substitution` TEXT NOT NULL, `absence` TEXT NOT NULL, `resources` TEXT NOT NULL)",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "studentId",
+ "columnName": "student_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "diaryId",
+ "columnName": "diary_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "date",
+ "columnName": "date",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "number",
+ "columnName": "number",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "subject",
+ "columnName": "subject",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "topic",
+ "columnName": "topic",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "teacher",
+ "columnName": "teacher",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "teacherSymbol",
+ "columnName": "teacher_symbol",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "substitution",
+ "columnName": "substitution",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "absence",
+ "columnName": "absence",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "resources",
+ "columnName": "resources",
+ "affinity": "TEXT",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "id"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "ReportingUnits",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `short` TEXT NOT NULL, `sender_id` INTEGER NOT NULL, `sender_name` TEXT NOT NULL, `roles` TEXT NOT NULL)",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "studentId",
+ "columnName": "student_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "realId",
+ "columnName": "real_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "shortName",
+ "columnName": "short",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "senderId",
+ "columnName": "sender_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "senderName",
+ "columnName": "sender_name",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "roles",
+ "columnName": "roles",
+ "affinity": "TEXT",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "id"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "Recipients",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `real_id` TEXT NOT NULL, `name` TEXT NOT NULL, `real_name` TEXT NOT NULL, `login_id` INTEGER NOT NULL, `unit_id` INTEGER NOT NULL, `role` INTEGER NOT NULL, `hash` TEXT NOT NULL)",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "studentId",
+ "columnName": "student_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "realId",
+ "columnName": "real_id",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "realName",
+ "columnName": "real_name",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "loginId",
+ "columnName": "login_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "unitId",
+ "columnName": "unit_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "role",
+ "columnName": "role",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "hash",
+ "columnName": "hash",
+ "affinity": "TEXT",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "id"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "MobileDevices",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `device_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `date` INTEGER NOT NULL)",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "studentId",
+ "columnName": "student_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "deviceId",
+ "columnName": "device_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "date",
+ "columnName": "date",
+ "affinity": "INTEGER",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "id"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "Teachers",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `short_name` TEXT NOT NULL)",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "studentId",
+ "columnName": "student_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "classId",
+ "columnName": "class_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "subject",
+ "columnName": "subject",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "shortName",
+ "columnName": "short_name",
+ "affinity": "TEXT",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "id"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [],
+ "foreignKeys": []
+ },
+ {
+ "tableName": "School",
+ "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `address` TEXT NOT NULL, `contact` TEXT NOT NULL, `headmaster` TEXT NOT NULL, `pedagogue` TEXT NOT NULL)",
+ "fields": [
+ {
+ "fieldPath": "id",
+ "columnName": "id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "studentId",
+ "columnName": "student_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "classId",
+ "columnName": "class_id",
+ "affinity": "INTEGER",
+ "notNull": true
+ },
+ {
+ "fieldPath": "name",
+ "columnName": "name",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "address",
+ "columnName": "address",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "contact",
+ "columnName": "contact",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "headmaster",
+ "columnName": "headmaster",
+ "affinity": "TEXT",
+ "notNull": true
+ },
+ {
+ "fieldPath": "pedagogue",
+ "columnName": "pedagogue",
+ "affinity": "TEXT",
+ "notNull": true
+ }
+ ],
+ "primaryKey": {
+ "columnNames": [
+ "id"
+ ],
+ "autoGenerate": true
+ },
+ "indices": [],
+ "foreignKeys": []
+ }
+ ],
+ "views": [],
+ "setupQueries": [
+ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
+ "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '43f8777ffe95a5a2850ee981db3dbe2e')"
+ ]
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/io/github/wulkanowy/data/db/AppDatabase.kt b/app/src/main/java/io/github/wulkanowy/data/db/AppDatabase.kt
index 762c52f8f..a31b68c0d 100644
--- a/app/src/main/java/io/github/wulkanowy/data/db/AppDatabase.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/db/AppDatabase.kt
@@ -68,6 +68,7 @@ import io.github.wulkanowy.data.db.migrations.Migration22
import io.github.wulkanowy.data.db.migrations.Migration23
import io.github.wulkanowy.data.db.migrations.Migration24
import io.github.wulkanowy.data.db.migrations.Migration25
+import io.github.wulkanowy.data.db.migrations.Migration26
import io.github.wulkanowy.data.db.migrations.Migration3
import io.github.wulkanowy.data.db.migrations.Migration4
import io.github.wulkanowy.data.db.migrations.Migration5
@@ -110,7 +111,7 @@ import javax.inject.Singleton
abstract class AppDatabase : RoomDatabase() {
companion object {
- const val VERSION_SCHEMA = 25
+ const val VERSION_SCHEMA = 26
fun getMigrations(sharedPrefProvider: SharedPrefProvider): Array {
return arrayOf(
@@ -137,7 +138,8 @@ abstract class AppDatabase : RoomDatabase() {
Migration22(),
Migration23(),
Migration24(),
- Migration25()
+ Migration25(),
+ Migration26()
)
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/db/entities/GradeSummary.kt b/app/src/main/java/io/github/wulkanowy/data/db/entities/GradeSummary.kt
index 6e29112b2..dd3126d4d 100644
--- a/app/src/main/java/io/github/wulkanowy/data/db/entities/GradeSummary.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/db/entities/GradeSummary.kt
@@ -3,6 +3,7 @@ package io.github.wulkanowy.data.db.entities
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
+import org.threeten.bp.LocalDateTime
@Entity(tableName = "GradesSummary")
data class GradeSummary(
@@ -36,4 +37,16 @@ data class GradeSummary(
) {
@PrimaryKey(autoGenerate = true)
var id: Long = 0
+
+ @ColumnInfo(name = "is_predicted_grade_notified")
+ var isPredictedGradeNotified: Boolean = true
+
+ @ColumnInfo(name = "is_final_grade_notified")
+ var isFinalGradeNotified: Boolean = true
+
+ @ColumnInfo(name = "predicted_grade_last_change")
+ var predictedGradeLastChange: LocalDateTime = LocalDateTime.now()
+
+ @ColumnInfo(name = "final_grade_last_change")
+ var finalGradeLastChange: LocalDateTime = LocalDateTime.now()
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration26.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration26.kt
new file mode 100644
index 000000000..7130d86d8
--- /dev/null
+++ b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration26.kt
@@ -0,0 +1,14 @@
+package io.github.wulkanowy.data.db.migrations
+
+import androidx.room.migration.Migration
+import androidx.sqlite.db.SupportSQLiteDatabase
+
+class Migration26 : Migration(25, 26) {
+
+ override fun migrate(database: SupportSQLiteDatabase) {
+ database.execSQL("ALTER TABLE GradesSummary ADD COLUMN is_predicted_grade_notified INTEGER NOT NULL DEFAULT 1")
+ database.execSQL("ALTER TABLE GradesSummary ADD COLUMN is_final_grade_notified INTEGER NOT NULL DEFAULT 1")
+ database.execSQL("ALTER TABLE GradesSummary ADD COLUMN predicted_grade_last_change INTEGER NOT NULL DEFAULT 0")
+ database.execSQL("ALTER TABLE GradesSummary ADD COLUMN final_grade_last_change INTEGER NOT NULL DEFAULT 0")
+ }
+}
diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/grade/GradeLocal.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/grade/GradeLocal.kt
index 944ed34ae..52ab60178 100644
--- a/app/src/main/java/io/github/wulkanowy/data/repositories/grade/GradeLocal.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/repositories/grade/GradeLocal.kt
@@ -27,6 +27,10 @@ class GradeLocal @Inject constructor(
gradeDb.updateAll(grades)
}
+ fun updateGradesSummary(gradesSummary: List) {
+ gradeSummaryDb.updateAll(gradesSummary)
+ }
+
fun getGradesDetails(semester: Semester): Maybe> {
return gradeDb.loadAll(semester.semesterId, semester.studentId).filter { it.isNotEmpty() }
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/grade/GradeRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/grade/GradeRepository.kt
index e28350a51..2ba68b967 100644
--- a/app/src/main/java/io/github/wulkanowy/data/repositories/grade/GradeRepository.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/repositories/grade/GradeRepository.kt
@@ -9,6 +9,7 @@ import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.utils.uniqueSubtract
import io.reactivex.Completable
import io.reactivex.Single
+import org.threeten.bp.LocalDateTime
import java.net.UnknownHostException
import javax.inject.Inject
import javax.inject.Singleton
@@ -43,7 +44,31 @@ class GradeRepository @Inject constructor(
local.getGradesSummary(semester).toSingle(emptyList())
.doOnSuccess { old ->
local.deleteGradesSummary(old.uniqueSubtract(newSummary))
- local.saveGradesSummary(newSummary.uniqueSubtract(old))
+ local.saveGradesSummary(newSummary.uniqueSubtract(old)
+ .onEach { summary ->
+ val oldSummary = old.find { oldSummary -> oldSummary.subject == summary.subject }
+ summary.isPredictedGradeNotified = when {
+ summary.predictedGrade.isEmpty() -> true
+ notify && oldSummary?.predictedGrade != summary.predictedGrade -> false
+ else -> true
+ }
+ summary.isFinalGradeNotified = when {
+ summary.finalGrade.isEmpty() -> true
+ notify && oldSummary?.finalGrade != summary.finalGrade -> false
+ else -> true
+ }
+
+ summary.predictedGradeLastChange = when {
+ oldSummary == null -> LocalDateTime.now()
+ summary.predictedGrade != oldSummary.predictedGrade -> LocalDateTime.now()
+ else -> oldSummary.predictedGradeLastChange
+ }
+ summary.finalGradeLastChange = when {
+ oldSummary == null -> LocalDateTime.now()
+ summary.finalGrade != oldSummary.finalGrade -> LocalDateTime.now()
+ else -> oldSummary.finalGradeLastChange
+ }
+ })
}
}
}.flatMap {
@@ -63,6 +88,14 @@ class GradeRepository @Inject constructor(
return local.getGradesDetails(semester).map { it.filter { grade -> !grade.isNotified } }.toSingle(emptyList())
}
+ fun getNotNotifiedPredictedGrades(semester: Semester): Single> {
+ return local.getGradesSummary(semester).map { it.filter { gradeSummary -> !gradeSummary.isPredictedGradeNotified } }.toSingle(emptyList())
+ }
+
+ fun getNotNotifiedFinalGrades(semester: Semester): Single> {
+ return local.getGradesSummary(semester).map { it.filter { gradeSummary -> !gradeSummary.isFinalGradeNotified } }.toSingle(emptyList())
+ }
+
fun updateGrade(grade: Grade): Completable {
return Completable.fromCallable { local.updateGrades(listOf(grade)) }
}
@@ -70,4 +103,8 @@ class GradeRepository @Inject constructor(
fun updateGrades(grades: List): Completable {
return Completable.fromCallable { local.updateGrades(grades) }
}
+
+ fun updateGradesSummary(gradesSummary: List): Completable {
+ return Completable.fromCallable { local.updateGradesSummary(gradesSummary) }
+ }
}
diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/works/GradeWork.kt b/app/src/main/java/io/github/wulkanowy/services/sync/works/GradeWork.kt
index 6e90826ad..fcdaad6e6 100644
--- a/app/src/main/java/io/github/wulkanowy/services/sync/works/GradeWork.kt
+++ b/app/src/main/java/io/github/wulkanowy/services/sync/works/GradeWork.kt
@@ -9,6 +9,7 @@ import androidx.core.app.NotificationCompat.PRIORITY_HIGH
import androidx.core.app.NotificationManagerCompat
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Grade
+import io.github.wulkanowy.data.db.entities.GradeSummary
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.repositories.grade.GradeRepository
@@ -30,17 +31,21 @@ class GradeWork @Inject constructor(
override fun create(student: Student, semester: Semester): Completable {
return gradeRepository.getGrades(student, semester, true, preferencesRepository.isNotificationsEnable)
- .flatMap { gradeRepository.getNotNotifiedGrades(semester) }
- .flatMapCompletable {
- if (it.isNotEmpty()) notify(it)
+ .ignoreElement()
+ .concatWith(Completable.concatArray(gradeRepository.getNotNotifiedGrades(semester).flatMapCompletable {
+ if (it.isNotEmpty()) notifyDetails(it)
gradeRepository.updateGrades(it.onEach { grade -> grade.isNotified = true })
- }
+ }, gradeRepository.getNotNotifiedPredictedGrades(semester).flatMapCompletable {
+ if (it.isNotEmpty()) notifyPredicted(it)
+ gradeRepository.updateGradesSummary(it.onEach { grade -> grade.isPredictedGradeNotified = true })
+ }, gradeRepository.getNotNotifiedFinalGrades(semester).flatMapCompletable {
+ if (it.isNotEmpty()) notifyFinal(it)
+ gradeRepository.updateGradesSummary(it.onEach { grade -> grade.isFinalGradeNotified = true })
+ }))
}
- private fun notify(grades: List) {
- notificationManager.notify(Random.nextInt(Int.MAX_VALUE), NotificationCompat.Builder(context, NewGradesChannel.CHANNEL_ID)
- .setContentTitle(context.resources.getQuantityString(R.plurals.grade_new_items, grades.size, grades.size))
- .setContentText(context.resources.getQuantityString(R.plurals.grade_notify_new_items, grades.size, grades.size))
+ private fun getNotificationBuilder(): NotificationCompat.Builder {
+ return NotificationCompat.Builder(context, NewGradesChannel.CHANNEL_ID)
.setSmallIcon(R.drawable.ic_stat_grade)
.setAutoCancel(true)
.setPriority(PRIORITY_HIGH)
@@ -49,6 +54,12 @@ class GradeWork @Inject constructor(
.setContentIntent(
PendingIntent.getActivity(context, MainView.Section.GRADE.id,
MainActivity.getStartIntent(context, MainView.Section.GRADE, true), FLAG_UPDATE_CURRENT))
+ }
+
+ private fun notifyDetails(grades: List) {
+ notificationManager.notify(Random.nextInt(Int.MAX_VALUE), getNotificationBuilder()
+ .setContentTitle(context.resources.getQuantityString(R.plurals.grade_new_items, grades.size, grades.size))
+ .setContentText(context.resources.getQuantityString(R.plurals.grade_notify_new_items, grades.size, grades.size))
.setStyle(NotificationCompat.InboxStyle().run {
setSummaryText(context.resources.getQuantityString(R.plurals.grade_number_item, grades.size, grades.size))
grades.forEach { addLine("${it.subject}: ${it.entry}") }
@@ -57,4 +68,30 @@ class GradeWork @Inject constructor(
.build()
)
}
+
+ private fun notifyPredicted(gradesSummary: List) {
+ notificationManager.notify(Random.nextInt(Int.MAX_VALUE), getNotificationBuilder()
+ .setContentTitle(context.resources.getQuantityString(R.plurals.grade_new_items_predicted, gradesSummary.size, gradesSummary.size))
+ .setContentText(context.resources.getQuantityString(R.plurals.grade_notify_new_items_predicted, gradesSummary.size, gradesSummary.size))
+ .setStyle(NotificationCompat.InboxStyle().run {
+ setSummaryText(context.resources.getQuantityString(R.plurals.grade_number_item, gradesSummary.size, gradesSummary.size))
+ gradesSummary.forEach { addLine("${it.subject}: ${it.predictedGrade}") }
+ this
+ })
+ .build()
+ )
+ }
+
+ private fun notifyFinal(gradesSummary: List) {
+ notificationManager.notify(Random.nextInt(Int.MAX_VALUE), getNotificationBuilder()
+ .setContentTitle(context.resources.getQuantityString(R.plurals.grade_new_items_final, gradesSummary.size, gradesSummary.size))
+ .setContentText(context.resources.getQuantityString(R.plurals.grade_notify_new_items_final, gradesSummary.size, gradesSummary.size))
+ .setStyle(NotificationCompat.InboxStyle().run {
+ setSummaryText(context.resources.getQuantityString(R.plurals.grade_number_item, gradesSummary.size, gradesSummary.size))
+ gradesSummary.forEach { addLine("${it.subject}: ${it.finalGrade}") }
+ this
+ })
+ .build()
+ )
+ }
}
diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml
index 4cb8997cf..2bba1640b 100644
--- a/app/src/main/res/values-pl/strings.xml
+++ b/app/src/main/res/values-pl/strings.xml
@@ -107,12 +107,36 @@
- Nowe oceny
- Nowe oceny
+
+ - Nowa ocena przewidywana
+ - Nowe oceny przewidywane
+ - Nowe oceny przewidywane
+ - Nowe oceny przewidywane
+
+
+ - Nowa ocena końcowa
+ - Nowe oceny końcowe
+ - Nowe oceny końcowe
+ - Nowe oceny końcowe
+
- Masz %1$d nową ocenę
- Masz %1$d nowe oceny
- Masz %1$d nowych ocen
- Masz %1$d nowych ocen
+
+ - Masz %1$d nową przewidywaną ocenę
+ - Masz %1$d nowe przewidywane oceny
+ - Masz %1$d nowych przewidywanych ocen
+ - Masz %1$d nowych przewidywanych ocen
+
+
+ - Masz %1$d nową końcową ocenę
+ - Masz %1$d nowe końcowe oceny
+ - Masz %1$d nowych końcowych ocen
+ - Masz %1$d nowych końcowych ocen
+
Lekcja
Sala
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index bec752cf2..3efb53cb2 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -113,10 +113,26 @@
- New grade
- New grades
+
+ - New predicted grade
+ - New predicted grades
+
+
+ - New final grade
+ - New final grades
+
- You received %1$d grade
- You received %1$d grades
+
+ - You received %1$d predicted grade
+ - You received %1$d predicted grades
+
+
+ - You received %1$d final grade
+ - You received %1$d final grades
+
From 924bcb0d647b1664de83427a669f721bf5594d86 Mon Sep 17 00:00:00 2001
From: Dominik Korsa
Date: Sun, 14 Jun 2020 00:50:09 +0200
Subject: [PATCH 029/100] Message sharing and printing (#866)
---
app/src/main/assets/message-print-page.html | 94 +++++++++++++++++++
app/src/main/assets/wulkanowy-logo-black.svg | 74 +++++++++++++++
.../message/preview/MessagePreviewAdapter.kt | 2 +-
.../message/preview/MessagePreviewFragment.kt | 61 ++++++++++++
.../preview/MessagePreviewPresenter.kt | 65 ++++++++++++-
.../message/preview/MessagePreviewView.kt | 11 +++
.../wulkanowy/utils/ContextExtension.kt | 13 +++
.../res/drawable/ic_menu_message_print.xml | 13 +++
.../res/drawable/ic_menu_message_share.xml | 10 ++
.../res/menu/action_menu_message_preview.xml | 14 +++
app/src/main/res/values-pl/strings.xml | 2 +
app/src/main/res/values/strings.xml | 2 +
12 files changed, 359 insertions(+), 2 deletions(-)
create mode 100644 app/src/main/assets/message-print-page.html
create mode 100644 app/src/main/assets/wulkanowy-logo-black.svg
create mode 100644 app/src/main/res/drawable/ic_menu_message_print.xml
create mode 100644 app/src/main/res/drawable/ic_menu_message_share.xml
diff --git a/app/src/main/assets/message-print-page.html b/app/src/main/assets/message-print-page.html
new file mode 100644
index 000000000..8da7dec6e
--- /dev/null
+++ b/app/src/main/assets/message-print-page.html
@@ -0,0 +1,94 @@
+
+
+
+
+ %SUBJECT% | Wulkanowy
+
+
+
+%SUBJECT%
+
+
+ %INFO%
+
+
+
+
+
Treść wiadomości
+ %CONTENT%
+
+
+
diff --git a/app/src/main/assets/wulkanowy-logo-black.svg b/app/src/main/assets/wulkanowy-logo-black.svg
new file mode 100644
index 000000000..9bfbe2c02
--- /dev/null
+++ b/app/src/main/assets/wulkanowy-logo-black.svg
@@ -0,0 +1,74 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewAdapter.kt
index 436dee53f..a94d2cfc8 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewAdapter.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewAdapter.kt
@@ -63,7 +63,7 @@ class MessagePreviewAdapter @Inject constructor() :
@SuppressLint("SetTextI18n")
private fun bindMessage(holder: MessageViewHolder, message: Message) {
with(holder.binding) {
- messagePreviewSubject.text = if (message.subject.isNotBlank()) message.subject else root.context.getString(R.string.message_no_subject)
+ messagePreviewSubject.text = message.subject.ifBlank { root.context.getString(R.string.message_no_subject) }
messagePreviewDate.text = root.context.getString(R.string.message_date, message.date.toFormattedString("yyyy-MM-dd HH:mm:ss"))
messagePreviewContent.text = message.content
messagePreviewAuthor.text = if (message.folderId == MessageFolder.SENT.id) "${root.context.getString(R.string.message_to)} ${message.recipient}"
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewFragment.kt
index 99eede15a..575db75b9 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewFragment.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewFragment.kt
@@ -1,12 +1,20 @@
package io.github.wulkanowy.ui.modules.message.preview
+import android.os.Build
import android.os.Bundle
+import android.print.PrintAttributes
+import android.print.PrintManager
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.view.View.GONE
import android.view.View.VISIBLE
+import android.webkit.WebResourceRequest
+import android.webkit.WebView
+import android.webkit.WebViewClient
+import androidx.annotation.RequiresApi
+import androidx.core.content.getSystemService
import androidx.recyclerview.widget.LinearLayoutManager
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Message
@@ -17,6 +25,8 @@ import io.github.wulkanowy.ui.modules.main.MainActivity
import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.ui.modules.message.MessageFragment
import io.github.wulkanowy.ui.modules.message.send.SendMessageActivity
+import io.github.wulkanowy.utils.AppInfo
+import io.github.wulkanowy.utils.shareText
import javax.inject.Inject
class MessagePreviewFragment :
@@ -29,18 +39,31 @@ class MessagePreviewFragment :
@Inject
lateinit var previewAdapter: MessagePreviewAdapter
+ @Inject
+ lateinit var appInfo: AppInfo
+
private var menuReplyButton: MenuItem? = null
private var menuForwardButton: MenuItem? = null
private var menuDeleteButton: MenuItem? = null
+ private var menuShareButton: MenuItem? = null
+
+ private var menuPrintButton: MenuItem? = null
+
override val titleStringId: Int
get() = R.string.message_title
override val deleteMessageSuccessString: String
get() = getString(R.string.message_delete_success)
+ override val messageNoSubjectString: String
+ get() = getString(R.string.message_no_subject)
+
+ override val printHTML: String
+ get() = requireContext().assets.open("message-print-page.html").bufferedReader().use { it.readText() }
+
companion object {
const val MESSAGE_ID_KEY = "message_id"
@@ -77,6 +100,8 @@ class MessagePreviewFragment :
menuReplyButton = menu.findItem(R.id.messagePreviewMenuReply)
menuForwardButton = menu.findItem(R.id.messagePreviewMenuForward)
menuDeleteButton = menu.findItem(R.id.messagePreviewMenuDelete)
+ menuShareButton = menu.findItem(R.id.messagePreviewMenuShare)
+ menuPrintButton = menu.findItem(R.id.messagePreviewMenuPrint)
presenter.onCreateOptionsMenu()
}
@@ -85,6 +110,8 @@ class MessagePreviewFragment :
R.id.messagePreviewMenuReply -> presenter.onReply()
R.id.messagePreviewMenuForward -> presenter.onForward()
R.id.messagePreviewMenuDelete -> presenter.onMessageDelete()
+ R.id.messagePreviewMenuShare -> presenter.onShare()
+ R.id.messagePreviewMenuPrint -> presenter.onPrint()
else -> false
}
}
@@ -108,6 +135,8 @@ class MessagePreviewFragment :
menuReplyButton?.isVisible = show
menuForwardButton?.isVisible = show
menuDeleteButton?.isVisible = show
+ menuShareButton?.isVisible = show
+ menuPrintButton?.isVisible = show && appInfo.systemVersion >= Build.VERSION_CODES.LOLLIPOP
}
override fun setDeletedOptionsLabels() {
@@ -138,6 +167,38 @@ class MessagePreviewFragment :
context?.let { it.startActivity(SendMessageActivity.getStartIntent(it, message)) }
}
+ override fun shareText(text: String, subject: String) {
+ context?.shareText(text, subject)
+ }
+
+ @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
+ override fun printDocument(html: String, jobName: String) {
+ val webView = WebView(activity)
+ webView.webViewClient = object : WebViewClient() {
+
+ override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest) = false
+
+ override fun onPageFinished(view: WebView, url: String) {
+ createWebPrintJob(view, jobName)
+ }
+ }
+
+ webView.loadDataWithBaseURL("file:///android_asset/", html, "text/HTML", "UTF-8", null)
+ }
+
+ @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
+ private fun createWebPrintJob(webView: WebView, jobName: String) {
+ activity?.getSystemService()?.let { printManager ->
+ val printAdapter = webView.createPrintDocumentAdapter(jobName)
+
+ printManager.print(
+ jobName,
+ printAdapter,
+ PrintAttributes.Builder().build()
+ )
+ }
+ }
+
override fun popView() {
(activity as MainActivity).popView()
}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewPresenter.kt
index 24678c70e..db7996bca 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewPresenter.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewPresenter.kt
@@ -1,12 +1,17 @@
package io.github.wulkanowy.ui.modules.message.preview
+import android.annotation.SuppressLint
+import android.os.Build
import io.github.wulkanowy.data.db.entities.Message
+import io.github.wulkanowy.data.db.entities.MessageAttachment
import io.github.wulkanowy.data.repositories.message.MessageRepository
import io.github.wulkanowy.data.repositories.student.StudentRepository
import io.github.wulkanowy.ui.base.BasePresenter
import io.github.wulkanowy.ui.base.ErrorHandler
+import io.github.wulkanowy.utils.AppInfo
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
import io.github.wulkanowy.utils.SchedulersProvider
+import io.github.wulkanowy.utils.toFormattedString
import timber.log.Timber
import javax.inject.Inject
@@ -15,11 +20,14 @@ class MessagePreviewPresenter @Inject constructor(
errorHandler: ErrorHandler,
studentRepository: StudentRepository,
private val messageRepository: MessageRepository,
- private val analytics: FirebaseAnalyticsHelper
+ private val analytics: FirebaseAnalyticsHelper,
+ private var appInfo: AppInfo
) : BasePresenter(errorHandler, studentRepository, schedulers) {
var message: Message? = null
+ var attachments: List? = null
+
private lateinit var lastError: Throwable
private var retryCallback: () -> Unit = {}
@@ -56,6 +64,7 @@ class MessagePreviewPresenter @Inject constructor(
.subscribe({ message ->
Timber.i("Loading message ${message.message.messageId} preview result: Success ")
this@MessagePreviewPresenter.message = message.message
+ this@MessagePreviewPresenter.attachments = message.attachments
view?.apply {
setMessageWithAttachment(message)
initOptions()
@@ -87,6 +96,60 @@ class MessagePreviewPresenter @Inject constructor(
} else false
}
+ fun onShare(): Boolean {
+ message?.let {
+ var text = "Temat: ${it.subject.ifBlank { view?.messageNoSubjectString.orEmpty() }}\n" + when (it.sender.isNotEmpty()) {
+ true -> "Od: ${it.sender}\n"
+ false -> "Do: ${it.recipient}\n"
+ } + "Data: ${it.date.toFormattedString("yyyy-MM-dd HH:mm:ss")}\n\n${it.content}"
+
+ attachments?.let { attachments ->
+ if (attachments.isNotEmpty()) {
+ text += "\n\nZałączniki:"
+
+ attachments.forEach { attachment ->
+ text += "\n${attachment.filename}: ${attachment.url}"
+ }
+ }
+ }
+
+ view?.shareText(text, "FW: ${it.subject.ifBlank { view?.messageNoSubjectString.orEmpty() }}")
+ return true
+ }
+ return false
+ }
+
+ @SuppressLint("NewApi")
+ fun onPrint(): Boolean {
+ if (appInfo.systemVersion < Build.VERSION_CODES.LOLLIPOP) return false
+ message?.let {
+ val dateString = it.date.toFormattedString("yyyy-MM-dd HH:mm:ss")
+ val infoContent = "Data wysłania
$dateString" + when {
+ it.sender.isNotEmpty() -> "Od
${it.sender}"
+ else -> "Do
${it.recipient}"
+ }
+
+ val messageContent = "${it.content}
"
+ .replace(Regex("[\\n\\r]{2,}"), "")
+ .replace(Regex("[\\n\\r]"), "
")
+
+ val jobName = "Wiadomość " + when {
+ it.sender.isNotEmpty() -> "od ${it.sender}"
+ else -> "do ${it.recipient}"
+ } + " $dateString: ${it.subject.ifBlank { view?.messageNoSubjectString.orEmpty() }} | Wulkanowy"
+
+ view?.apply {
+ val html = printHTML
+ .replace("%SUBJECT%", it.subject.ifBlank { view?.messageNoSubjectString.orEmpty() })
+ .replace("%CONTENT%", messageContent)
+ .replace("%INFO%", infoContent)
+ printDocument(html, jobName)
+ }
+ return true
+ }
+ return false
+ }
+
private fun deleteMessage() {
message?.let { message ->
disposable.add(studentRepository.getCurrentStudent()
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewView.kt
index 3d620459c..0fdb4bda3 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewView.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/preview/MessagePreviewView.kt
@@ -1,5 +1,7 @@
package io.github.wulkanowy.ui.modules.message.preview
+import android.os.Build
+import androidx.annotation.RequiresApi
import io.github.wulkanowy.data.db.entities.Message
import io.github.wulkanowy.data.db.entities.MessageWithAttachment
import io.github.wulkanowy.ui.base.BaseView
@@ -8,6 +10,10 @@ interface MessagePreviewView : BaseView {
val deleteMessageSuccessString: String
+ val messageNoSubjectString: String
+
+ val printHTML: String
+
fun initView()
fun setMessageWithAttachment(item: MessageWithAttachment)
@@ -34,5 +40,10 @@ interface MessagePreviewView : BaseView {
fun openMessageForward(message: Message?)
+ fun shareText(text: String, subject: String)
+
+ @RequiresApi(Build.VERSION_CODES.LOLLIPOP)
+ fun printDocument(html: String, jobName: String)
+
fun popView()
}
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 2b40cb476..cf715e657 100644
--- a/app/src/main/java/io/github/wulkanowy/utils/ContextExtension.kt
+++ b/app/src/main/java/io/github/wulkanowy/utils/ContextExtension.kt
@@ -71,4 +71,17 @@ fun Context.openDialer(phone: String) {
startActivity(intent)
}
+fun Context.shareText(text: String, subject: String?) {
+ val sendIntent: Intent = Intent().apply {
+ action = Intent.ACTION_SEND
+ putExtra(Intent.EXTRA_TEXT, text)
+ if (subject != null) {
+ putExtra(Intent.EXTRA_SUBJECT, subject)
+ }
+ type = "text/plain"
+ }
+ val shareIntent = Intent.createChooser(sendIntent, null)
+ startActivity(shareIntent)
+}
+
fun Context.dpToPx(dp: Float) = dp * resources.displayMetrics.densityDpi / DENSITY_DEFAULT
diff --git a/app/src/main/res/drawable/ic_menu_message_print.xml b/app/src/main/res/drawable/ic_menu_message_print.xml
new file mode 100644
index 000000000..204b0f6e3
--- /dev/null
+++ b/app/src/main/res/drawable/ic_menu_message_print.xml
@@ -0,0 +1,13 @@
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_menu_message_share.xml b/app/src/main/res/drawable/ic_menu_message_share.xml
new file mode 100644
index 000000000..67a8ee494
--- /dev/null
+++ b/app/src/main/res/drawable/ic_menu_message_share.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/src/main/res/menu/action_menu_message_preview.xml b/app/src/main/res/menu/action_menu_message_preview.xml
index dfc12e234..4c1332e10 100644
--- a/app/src/main/res/menu/action_menu_message_preview.xml
+++ b/app/src/main/res/menu/action_menu_message_preview.xml
@@ -22,4 +22,18 @@
android:title="@string/message_delete"
app:iconTint="@color/material_on_surface_emphasis_medium"
app:showAsAction="ifRoom" />
+
+
diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml
index 2bba1640b..a8eccabf0 100644
--- a/app/src/main/res/values-pl/strings.xml
+++ b/app/src/main/res/values-pl/strings.xml
@@ -204,6 +204,8 @@
Przenieś do kosza
Usuń trwale
Wiadomość usunięta pomyślnie
+ Udostępnij
+ Drukuj
Temat
Treść
Wiadomość wysłana pomyślnie
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 3efb53cb2..1eaebf284 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -210,6 +210,8 @@
Move to trash
Delete permanently
Message deleted successfully
+ Share
+ Print
Subject
Content
Message sent successfully
From 6e1ddb482e90008dcf8af110362abedc4d10d42b Mon Sep 17 00:00:00 2001
From: Dominik Korsa
Date: Sun, 14 Jun 2020 14:05:24 +0200
Subject: [PATCH 030/100] Message fuzzy search (#869)
---
app/build.gradle | 3 +-
.../modules/message/tab/MessageTabAdapter.kt | 56 ++++---
.../modules/message/tab/MessageTabFragment.kt | 2 +-
.../message/tab/MessageTabPresenter.kt | 147 ++++++++++++------
4 files changed, 130 insertions(+), 78 deletions(-)
diff --git a/app/build.gradle b/app/build.gradle
index 44896664a..82d92f25a 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -142,7 +142,7 @@ dependencies {
implementation "androidx.constraintlayout:constraintlayout:1.1.3"
implementation "androidx.coordinatorlayout:coordinatorlayout:1.1.0"
implementation "com.google.android.material:material:1.1.0"
- implementation "com.github.wulkanowy:material-chips-input:2.0.1"
+ implementation "com.github.wulkanowy:material-chips-input:2.1.1"
implementation "com.github.PhilJay:MPAndroidChart:v3.1.0"
implementation "me.zhanghai.android.materialprogressbar:library:1.6.1"
@@ -180,6 +180,7 @@ dependencies {
implementation 'com.wdullaer:materialdatetimepicker:4.2.3'
implementation "io.coil-kt:coil:0.11.0"
implementation "io.github.wulkanowy:AppKillerManager:3.0.0"
+ implementation 'me.xdrop:fuzzywuzzy:1.3.1'
playImplementation 'com.google.firebase:firebase-analytics:17.4.3'
playImplementation 'com.google.firebase:firebase-inappmessaging-display-ktx:19.0.7'
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabAdapter.kt
index ece6773fd..b58508a98 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabAdapter.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabAdapter.kt
@@ -4,10 +4,9 @@ import android.graphics.Typeface
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.NO_POSITION
-import androidx.recyclerview.widget.SortedList
-import androidx.recyclerview.widget.SortedListAdapterCallback
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Message
import io.github.wulkanowy.data.repositories.message.MessageFolder
@@ -20,39 +19,23 @@ class MessageTabAdapter @Inject constructor() :
var onClickListener: (Message, position: Int) -> Unit = { _, _ -> }
- private val items = SortedList(Message::class.java, object :
- SortedListAdapterCallback(this) {
+ private var items = mutableListOf()
- override fun compare(item1: Message, item2: Message): Int {
- return item2.date.compareTo(item1.date)
- }
-
- override fun areContentsTheSame(oldItem: Message?, newItem: Message?): Boolean {
- return oldItem == newItem
- }
-
- override fun areItemsTheSame(item1: Message, item2: Message): Boolean {
- return item1 == item2
- }
- })
-
- fun replaceAll(models: List) {
- items.beginBatchedUpdates()
- for (i in items.size() - 1 downTo 0) {
- val model = items.get(i)
- if (model !in models) {
- items.remove(model)
- }
- }
- items.addAll(models)
- items.endBatchedUpdates()
+ fun setDataItems(data: List) {
+ val diffResult = DiffUtil.calculateDiff(MessageTabDiffUtil(items, data))
+ items = data.toMutableList()
+ diffResult.dispatchUpdatesTo(this)
}
fun updateItem(position: Int, item: Message) {
- items.updateItemAt(position, item)
+ val currentItem = items[position]
+ items[position] = item
+ if (item != currentItem) {
+ notifyItemChanged(position)
+ }
}
- override fun getItemCount() = items.size()
+ override fun getItemCount() = items.size
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder(
ItemMessageBinding.inflate(LayoutInflater.from(parent.context), parent, false)
@@ -85,4 +68,19 @@ class MessageTabAdapter @Inject constructor() :
}
class ItemViewHolder(val binding: ItemMessageBinding) : RecyclerView.ViewHolder(binding.root)
+
+ private class MessageTabDiffUtil(private val old: List, private val new: List) :
+ DiffUtil.Callback() {
+ override fun getOldListSize(): Int = old.size
+
+ override fun getNewListSize(): Int = new.size
+
+ override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
+ return old[oldItemPosition].id == new[newItemPosition].id
+ }
+
+ override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
+ return old[oldItemPosition] == new[newItemPosition]
+ }
+ }
}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabFragment.kt
index 909bb6873..9954c6428 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabFragment.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabFragment.kt
@@ -90,7 +90,7 @@ class MessageTabFragment : BaseFragment(R.layout.frag
}
override fun updateData(data: List) {
- tabAdapter.replaceAll(data)
+ tabAdapter.setDataItems(data)
}
override fun updateItem(item: Message, position: Int) {
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabPresenter.kt
index 221762d16..533f5ac85 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabPresenter.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabPresenter.kt
@@ -1,6 +1,5 @@
package io.github.wulkanowy.ui.modules.message.tab
-import android.annotation.SuppressLint
import io.github.wulkanowy.data.db.entities.Message
import io.github.wulkanowy.data.repositories.message.MessageFolder
import io.github.wulkanowy.data.repositories.message.MessageRepository
@@ -11,8 +10,13 @@ import io.github.wulkanowy.ui.base.ErrorHandler
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
import io.github.wulkanowy.utils.SchedulersProvider
import io.github.wulkanowy.utils.toFormattedString
+import io.reactivex.subjects.PublishSubject
+import me.xdrop.fuzzywuzzy.FuzzySearch
import timber.log.Timber
+import java.util.Locale
+import java.util.concurrent.TimeUnit
import javax.inject.Inject
+import kotlin.math.pow
class MessageTabPresenter @Inject constructor(
schedulers: SchedulersProvider,
@@ -31,9 +35,12 @@ class MessageTabPresenter @Inject constructor(
private var messages = emptyList()
+ private val searchQuery = PublishSubject.create()
+
fun onAttachView(view: MessageTabView, folder: MessageFolder) {
super.onAttachView(view)
view.initView()
+ initializeSearchStream()
errorHandler.showErrorMessage = ::showErrorViewOnError
this.folder = folder
}
@@ -76,38 +83,35 @@ class MessageTabPresenter @Inject constructor(
private fun loadData(forceRefresh: Boolean) {
Timber.i("Loading $folder message data started")
- disposable.apply {
- clear()
- add(studentRepository.getCurrentStudent()
- .flatMap { student ->
- semesterRepository.getCurrentSemester(student)
- .flatMap { messageRepository.getMessages(student, it, folder, forceRefresh) }
+ disposable.add(studentRepository.getCurrentStudent()
+ .flatMap { student ->
+ semesterRepository.getCurrentSemester(student)
+ .flatMap { messageRepository.getMessages(student, it, folder, forceRefresh) }
+ }
+ .subscribeOn(schedulers.backgroundThread)
+ .observeOn(schedulers.mainThread)
+ .doFinally {
+ view?.run {
+ showRefresh(false)
+ showProgress(false)
+ enableSwipe(true)
+ notifyParentDataLoaded()
}
- .subscribeOn(schedulers.backgroundThread)
- .observeOn(schedulers.mainThread)
- .doFinally {
- view?.run {
- showRefresh(false)
- showProgress(false)
- enableSwipe(true)
- notifyParentDataLoaded()
- }
- }
- .subscribe({
- Timber.i("Loading $folder message result: Success")
- messages = it
- onSearchQueryTextChange(lastSearchQuery)
- analytics.logEvent(
- "load_data",
- "type" to "messages",
- "items" to it.size,
- "folder" to folder.name
- )
- }) {
- Timber.i("Loading $folder message result: An exception occurred")
- errorHandler.dispatch(it)
- })
- }
+ }
+ .subscribe({
+ Timber.i("Loading $folder message result: Success")
+ messages = it
+ view?.updateData(getFilteredData(lastSearchQuery))
+ analytics.logEvent(
+ "load_data",
+ "type" to "messages",
+ "items" to it.size,
+ "folder" to folder.name
+ )
+ }) {
+ Timber.i("Loading $folder message result: An exception occurred")
+ errorHandler.dispatch(it)
+ })
}
private fun showErrorViewOnError(message: String, error: Throwable) {
@@ -121,25 +125,36 @@ class MessageTabPresenter @Inject constructor(
}
}
- @SuppressLint("DefaultLocale")
fun onSearchQueryTextChange(query: String) {
- lastSearchQuery = query
+ if (query != searchQuery.toString())
+ searchQuery.onNext(query)
+ }
- val lowerCaseQuery = query.toLowerCase()
- val filteredList = mutableListOf()
- messages.forEach {
- if (lowerCaseQuery in it.subject.toLowerCase() ||
- lowerCaseQuery in it.sender.toLowerCase() ||
- lowerCaseQuery in it.recipient.toLowerCase() ||
- lowerCaseQuery in it.date.toFormattedString()
- ) {
- filteredList.add(it)
+ private fun initializeSearchStream() {
+ disposable.add(searchQuery
+ .debounce(250, TimeUnit.MILLISECONDS)
+ .map { query ->
+ lastSearchQuery = query
+ getFilteredData(query)
}
+ .subscribeOn(schedulers.backgroundThread)
+ .observeOn(schedulers.mainThread)
+ .subscribe({
+ Timber.d("Applying filter. Full list: ${messages.size}, filtered: ${it.size}")
+ updateData(it)
+ }) { Timber.e(it) })
+ }
+
+ private fun getFilteredData(query: String): List {
+ return if (query.trim().isEmpty()) {
+ messages.sortedByDescending { it.date }
+ } else {
+ messages
+ .map { it to calculateMatchRatio(it, query) }
+ .sortedByDescending { it.second }
+ .filter { it.second > 5000 }
+ .map { it.first }
}
-
- Timber.d("Applying filter. Full list: ${messages.size}, filtered: ${filteredList.size}")
-
- updateData(filteredList)
}
private fun updateData(data: List) {
@@ -151,4 +166,42 @@ class MessageTabPresenter @Inject constructor(
resetListPosition()
}
}
+
+ private fun calculateMatchRatio(message: Message, query: String): Int {
+ val subjectRatio = FuzzySearch.tokenSortPartialRatio(
+ query.toLowerCase(Locale.getDefault()),
+ message.subject
+ )
+
+ val senderOrRecipientRatio = FuzzySearch.tokenSortPartialRatio(
+ query.toLowerCase(Locale.getDefault()),
+ if (message.sender.isNotEmpty()) message.sender.toLowerCase(Locale.getDefault())
+ else message.recipient.toLowerCase(Locale.getDefault())
+ )
+
+ val dateRatio = listOf(
+ FuzzySearch.ratio(
+ query.toLowerCase(Locale.getDefault()),
+ message.date.toFormattedString("dd.MM").toLowerCase(Locale.getDefault())
+ ),
+ FuzzySearch.ratio(
+ query.toLowerCase(Locale.getDefault()),
+ message.date.toFormattedString("dd.MM.yyyy").toLowerCase(Locale.getDefault())
+ ),
+ FuzzySearch.ratio(
+ query.toLowerCase(Locale.getDefault()),
+ message.date.toFormattedString("d MMMM").toLowerCase(Locale.getDefault())
+ ),
+ FuzzySearch.ratio(
+ query.toLowerCase(Locale.getDefault()),
+ message.date.toFormattedString("d MMMM yyyy").toLowerCase(Locale.getDefault())
+ )
+ ).max() ?: 0
+
+
+ return (subjectRatio.toDouble().pow(2)
+ + senderOrRecipientRatio.toDouble().pow(2)
+ + dateRatio.toDouble().pow(2) * 2
+ ).toInt()
+ }
}
From dfe7981e7fa71321267f2d1daf545a7ae65e9eb2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafa=C5=82=20Borcz?=
Date: Sun, 14 Jun 2020 22:37:58 +0200
Subject: [PATCH 031/100] New Crowdin translations (#874)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Co-authored-by: Mikołaj Pich
---
.../main/res/values-de/preferences_values.xml | 4 +--
app/src/main/res/values-de/strings.xml | 30 ++++++++++++++---
app/src/main/res/values-pl/strings.xml | 2 +-
.../main/res/values-ru/preferences_values.xml | 2 +-
app/src/main/res/values-ru/strings.xml | 32 ++++++++++++++++++-
.../main/res/values-uk/preferences_values.xml | 2 +-
app/src/main/res/values-uk/strings.xml | 32 ++++++++++++++++++-
7 files changed, 93 insertions(+), 11 deletions(-)
diff --git a/app/src/main/res/values-de/preferences_values.xml b/app/src/main/res/values-de/preferences_values.xml
index 496287984..11935b49b 100644
--- a/app/src/main/res/values-de/preferences_values.xml
+++ b/app/src/main/res/values-de/preferences_values.xml
@@ -36,8 +36,8 @@
- Durchschnittsnote für das 2. Semester
- - Average of grades from both semesters
- - Durchschnitt der Bewertungen für das ganze Jahr
+ - Durchschnitt der Noten aus beiden Semestern
+ - Durchschnitt der Noten aus dem ganzen Jahr
- Nicht zeigen
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index 4b1669371..7cc44fd97 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -103,10 +103,26 @@
- Neue Note
- Neue Noten
+
+ - New predicted grade
+ - New predicted grades
+
+
+ - New final grade
+ - New final grades
+
- Du hast %1$d Note bekommen
- Du hast %1$d Noten bekommen
+
+ - You received %1$d predicted grade
+ - You received %1$d predicted grades
+
+
+ - You received %1$d final grade
+ - You received %1$d final grades
+
Lektion
Klassenzimmer
@@ -172,6 +188,8 @@
In den Korb wandern
Dauerhaft löschen
Nachricht erfolgreich gelöscht
+ Share
+ Print
Thema
Inhalt
Nachricht erfolgreich gesendet
@@ -214,7 +232,7 @@
Die heutige Glücksnummer ist
Keine Information über die Glücksnummer.
Glücksnummer für heute
- Die heutige Glücksnummer ist:
+ Die heutige Glücksnummer ist: %d
Mobile Geräte
Keine Geräte
@@ -245,6 +263,10 @@
Abmelden
Wollen Sie sich von einem aktiven Studenten abmelden?
Abmeldung von Student
+ Student account
+ Parent account
+ Mobile API mode
+ Hybrid mode
Version der App
Mitarbeiter
@@ -270,8 +292,8 @@
Logs teilen
Aktualisieren
- Check for updates
- Before reporting a bug, check first if an update with the bug fix is available
+ Auf Updates prüfen
+ Bevor Sie einen Fehler melden, prüfen Sie zuerst, ob ein Update mit der Fehlerbehebung verfügbar ist
Inhalt
Wiederhol
@@ -289,7 +311,7 @@
Zurück
Nächste
Suchen
- Suchen...
+ Suchen…
Keine Lektionen
Thema wählen
diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml
index a8eccabf0..bd4545e9b 100644
--- a/app/src/main/res/values-pl/strings.xml
+++ b/app/src/main/res/values-pl/strings.xml
@@ -339,7 +339,7 @@
Poprzedni
Następny
Szukaj
- Szukaj...
+ Szukaj…
Brak lekcji
Wybierz motyw
diff --git a/app/src/main/res/values-ru/preferences_values.xml b/app/src/main/res/values-ru/preferences_values.xml
index bd8bb844f..a41abf350 100644
--- a/app/src/main/res/values-ru/preferences_values.xml
+++ b/app/src/main/res/values-ru/preferences_values.xml
@@ -37,7 +37,7 @@
- Средняя оценка со 2 семестра
- Average of grades from both semesters
- - Средняя оценка с целого года
+ - Average of grades from the whole year
- Не показывать
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index 6eb8f7741..15c583173 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -107,12 +107,36 @@
- Новые оценки
- Новые оценки
+
+ - New predicted grade
+ - New predicted grades
+ - New predicted grades
+ - New predicted grades
+
+
+ - New final grade
+ - New final grades
+ - New final grades
+ - New final grades
+
- Вы получили %1$d оценку
- Вы получили %1$d оценки
- Вы получили %1$d оценок
- Вы получили %1$d оценок
+
+ - You received %1$d predicted grade
+ - You received %1$d predicted grades
+ - You received %1$d predicted grades
+ - You received %1$d predicted grades
+
+
+ - You received %1$d final grade
+ - You received %1$d final grades
+ - You received %1$d final grades
+ - You received %1$d final grades
+
Урок
Аудитория
@@ -180,6 +204,8 @@
Перенести в корзину
Удалить навсегда
Сообщение успешно удалено
+ Share
+ Print
Тема
Текст
Сообщение успешно отправлено
@@ -265,6 +291,10 @@
Выйти
Вы точно хотите выйти из данного аккаунта?
Выйти
+ Student account
+ Parent account
+ Mobile API mode
+ Hybrid mode
Версия приложения
Разработчики
@@ -309,7 +339,7 @@
Предыдущий
Следующий
Поиск
- Поиск...
+ Поиск…
Нет уроков
Выбрать тему
diff --git a/app/src/main/res/values-uk/preferences_values.xml b/app/src/main/res/values-uk/preferences_values.xml
index be2179c3e..9942621a5 100644
--- a/app/src/main/res/values-uk/preferences_values.xml
+++ b/app/src/main/res/values-uk/preferences_values.xml
@@ -37,7 +37,7 @@
- Середня оцінка з 2 семестру
- Average of grades from both semesters
- - Середня оцінка за весь рік
+ - Average of grades from the whole year
- Не показувати
diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml
index ec4dbc155..423c4e12f 100644
--- a/app/src/main/res/values-uk/strings.xml
+++ b/app/src/main/res/values-uk/strings.xml
@@ -107,12 +107,36 @@
- Нові оцінки
- Нові оцінки
+
+ - New predicted grade
+ - New predicted grades
+ - New predicted grades
+ - New predicted grades
+
+
+ - New final grade
+ - New final grades
+ - New final grades
+ - New final grades
+
- Ви отримали %1$d оцінку
- Ви отримали %1$d оцінки
- Ви отримали %1$d оцінок
- Ви отримали %1$d оцінок
+
+ - You received %1$d predicted grade
+ - You received %1$d predicted grades
+ - You received %1$d predicted grades
+ - You received %1$d predicted grades
+
+
+ - You received %1$d final grade
+ - You received %1$d final grades
+ - You received %1$d final grades
+ - You received %1$d final grades
+
Урок
Аудиторія
@@ -180,6 +204,8 @@
Перемістити у кошик
Видалити назавжди
Повідомлення було успішно видалено
+ Share
+ Print
Тема
Зміст
Повідомлення було успішно відправлено
@@ -265,6 +291,10 @@
Вийти
Ви впевнені, що хочете вийти з цього аккаунту?
Вийти з аккаунту учня
+ Student account
+ Parent account
+ Mobile API mode
+ Hybrid mode
Версія додатка
Розробники
@@ -309,7 +339,7 @@
Попередній
Наступний
Пошук
- Пошук...
+ Пошук…
Брак уроків
Увібрати тему
From c13f12f729114c5bfd4539f168fcd1dfd383b52c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miko=C5=82aj=20Pich?=
Date: Sun, 14 Jun 2020 22:40:36 +0200
Subject: [PATCH 032/100] Version 0.19.0
---
.travis.yml | 2 +-
app/build.gradle | 6 +++---
app/src/main/play/release-notes/pl-PL/default.txt | 10 ++++++----
3 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/.travis.yml b/.travis.yml
index 788aeffa7..a24058083 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -14,7 +14,7 @@ cache:
branches:
only:
- develop
- - 0.18.3
+ - 0.19.0
android:
licenses:
diff --git a/app/build.gradle b/app/build.gradle
index 82d92f25a..621e5a4fe 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -17,8 +17,8 @@ android {
testApplicationId "io.github.tests.wulkanowy"
minSdkVersion 17
targetSdkVersion 29
- versionCode 62
- versionName "0.18.3"
+ versionCode 63
+ versionName "0.19.0"
multiDexEnabled true
resValue "string", "app_name", "Wulkanowy"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@@ -124,7 +124,7 @@ configurations.all {
}
dependencies {
- implementation "io.github.wulkanowy:sdk:7dc0761"
+ implementation "io.github.wulkanowy:sdk:0.19.0"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation "androidx.core:core-ktx:1.2.0"
diff --git a/app/src/main/play/release-notes/pl-PL/default.txt b/app/src/main/play/release-notes/pl-PL/default.txt
index db9e9a9a3..68045da4a 100644
--- a/app/src/main/play/release-notes/pl-PL/default.txt
+++ b/app/src/main/play/release-notes/pl-PL/default.txt
@@ -1,6 +1,8 @@
-Wersja 0.18.3
-- poprawiliśmy liczenie średniej i dodaliśmy nowy sposób jej liczenia w ustawieniach
-- naprawiliśmy usuwanie wiadomości
-- naprawiliśmy wysyłanie wiadomości na Lubelskim Portalu Oświatowym
+Wersja 0.19.0
+- naprawiliśmy pokazywanie brakujących przedmiotów na liście podsumowania ocen
+- ulepszyliśmy wygląd menadżera kont
+- ulepszyliśmy wyszukiwarkę wiadomości
+- dodaliśmy powiadomienia o proponowanych i końcowych ocenach
+- dodaliśmy opcję udostępniania i drukowania wiadomości
Pełna lista zmian: https://github.com/wulkanowy/wulkanowy/releases
From 4434d6f024ba4f23dfed6ebf63c798f59f9a53ba Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Miko=C5=82aj=20Pich?=
Date: Sat, 20 Jun 2020 15:07:57 +0200
Subject: [PATCH 033/100] Migrate repositories from rxjava to coroutines (#885)
---
app/build.gradle | 10 +-
.../data/db/migrations/Migration12Test.kt | 7 +-
.../data/db/migrations/Migration13Test.kt | 5 +-
.../TestInternetObservingStrategy.kt | 19 --
.../attendance/AttendanceLocalTest.kt | 14 +-
.../CompletedLessonsLocalTest.kt | 17 +-
.../data/repositories/exam/ExamLocalTest.kt | 14 +-
.../data/repositories/grade/GradeLocalTest.kt | 13 +-
.../repositories/grade/GradeRepositoryTest.kt | 75 ++---
.../GradeStatisticsLocalTest.kt | 34 ++-
.../luckynumber/LuckyNumberLocalTest.kt | 18 +-
.../recipient/RecipientLocalTest.kt | 19 +-
.../repositories/student/StudentLocalTest.kt | 7 +-
.../timetable/TimetableLocalTest.kt | 19 +-
.../timetable/TimetableRepositoryTest.kt | 62 +++--
.../github/wulkanowy/data/RepositoryModule.kt | 10 -
.../wulkanowy/data/db/dao/AttendanceDao.kt | 3 +-
.../data/db/dao/AttendanceSummaryDao.kt | 3 +-
.../github/wulkanowy/data/db/dao/BaseDao.kt | 6 +-
.../data/db/dao/CompletedLessonsDao.kt | 3 +-
.../github/wulkanowy/data/db/dao/ExamDao.kt | 3 +-
.../github/wulkanowy/data/db/dao/GradeDao.kt | 4 +-
.../data/db/dao/GradePointsStatisticsDao.kt | 5 +-
.../data/db/dao/GradeStatisticsDao.kt | 5 +-
.../wulkanowy/data/db/dao/GradeSummaryDao.kt | 3 +-
.../wulkanowy/data/db/dao/HomeworkDao.kt | 3 +-
.../wulkanowy/data/db/dao/LuckyNumberDao.kt | 3 +-
.../data/db/dao/MessageAttachmentDao.kt | 2 +-
.../wulkanowy/data/db/dao/MessagesDao.kt | 8 +-
.../wulkanowy/data/db/dao/MobileDeviceDao.kt | 3 +-
.../github/wulkanowy/data/db/dao/NoteDao.kt | 3 +-
.../wulkanowy/data/db/dao/RecipientDao.kt | 3 +-
.../wulkanowy/data/db/dao/ReportingUnitDao.kt | 5 +-
.../github/wulkanowy/data/db/dao/SchoolDao.kt | 3 +-
.../wulkanowy/data/db/dao/SemesterDao.kt | 3 +-
.../wulkanowy/data/db/dao/StudentDao.kt | 15 +-
.../wulkanowy/data/db/dao/SubjectDao.kt | 3 +-
.../wulkanowy/data/db/dao/TeacherDao.kt | 3 +-
.../wulkanowy/data/db/dao/TimetableDao.kt | 3 +-
.../appcreator/AppCreatorRepository.kt | 13 +-
.../attendance/AttendanceLocal.kt | 9 +-
.../attendance/AttendanceRemote.kt | 43 ++-
.../attendance/AttendanceRepository.kt | 35 +--
.../AttendanceSummaryLocal.kt | 9 +-
.../AttendanceSummaryRemote.kt | 33 +--
.../AttendanceSummaryRepository.kt | 28 +-
.../completedlessons/CompletedLessonsLocal.kt | 9 +-
.../CompletedLessonsRemote.kt | 35 ++-
.../CompletedLessonsRepository.kt | 34 +--
.../data/repositories/exam/ExamLocal.kt | 8 +-
.../data/repositories/exam/ExamRemote.kt | 31 +--
.../data/repositories/exam/ExamRepository.kt | 34 +--
.../data/repositories/grade/GradeLocal.kt | 21 +-
.../data/repositories/grade/GradeRemote.kt | 72 ++---
.../repositories/grade/GradeRepository.kt | 134 ++++-----
.../gradestatistics/GradeStatisticsLocal.kt | 32 +--
.../gradestatistics/GradeStatisticsRemote.kt | 43 ++-
.../GradeStatisticsRepository.kt | 83 +++---
.../repositories/homework/HomeworkLocal.kt | 10 +-
.../repositories/homework/HomeworkRemote.kt | 29 +-
.../homework/HomeworkRepository.kt | 42 +--
.../repositories/logger/LoggerRepository.kt | 26 +-
.../luckynumber/LuckyNumberLocal.kt | 15 +-
.../luckynumber/LuckyNumberRemote.kt | 5 +-
.../luckynumber/LuckyNumberRepository.kt | 58 ++--
.../data/repositories/message/MessageLocal.kt | 16 +-
.../repositories/message/MessageRemote.kt | 49 ++--
.../repositories/message/MessageRepository.kt | 117 ++++----
.../mobiledevice/MobileDeviceLocal.kt | 9 +-
.../mobiledevice/MobileDeviceRemote.kt | 25 +-
.../mobiledevice/MobileDeviceRepository.kt | 45 +--
.../data/repositories/note/NoteLocal.kt | 11 +-
.../data/repositories/note/NoteRemote.kt | 29 +-
.../data/repositories/note/NoteRepository.kt | 52 ++--
.../repositories/recipient/RecipientLocal.kt | 9 +-
.../repositories/recipient/RecipientRemote.kt | 13 +-
.../recipient/RecipientRepository.kt | 39 +--
.../repositories/recover/RecoverRemote.kt | 5 +-
.../repositories/recover/RecoverRepository.kt | 20 +-
.../reportingunit/ReportingUnitLocal.kt | 11 +-
.../reportingunit/ReportingUnitRemote.kt | 23 +-
.../reportingunit/ReportingUnitRepository.kt | 46 ++--
.../data/repositories/school/SchoolLocal.kt | 7 +-
.../data/repositories/school/SchoolRemote.kt | 5 +-
.../repositories/school/SchoolRepository.kt | 39 +--
.../repositories/semester/SemesterLocal.kt | 9 +-
.../repositories/semester/SemesterRemote.kt | 31 +--
.../semester/SemesterRepository.kt | 47 ++--
.../data/repositories/student/StudentLocal.kt | 59 ++--
.../repositories/student/StudentRemote.kt | 13 +-
.../repositories/student/StudentRepository.kt | 56 ++--
.../data/repositories/subject/SubjectLocal.kt | 8 +-
.../repositories/subject/SubjectRemote.kt | 19 +-
.../repositories/subject/SubjectRepository.kt | 31 +--
.../data/repositories/teacher/TeacherLocal.kt | 9 +-
.../repositories/teacher/TeacherRemote.kt | 21 +-
.../repositories/teacher/TeacherRepository.kt | 28 +-
.../repositories/timetable/TimetableLocal.kt | 9 +-
.../repositories/timetable/TimetableRemote.kt | 45 ++-
.../timetable/TimetableRepository.kt | 52 ++--
.../java/io/github/wulkanowy/di/AppModule.kt | 5 +
.../alarm/TimetableNotificationReceiver.kt | 3 +-
.../wulkanowy/services/sync/SyncWorker.kt | 10 +-
.../sync/works/AttendanceSummaryWork.kt | 3 +-
.../services/sync/works/AttendanceWork.kt | 4 +-
.../sync/works/CompletedLessonWork.kt | 4 +-
.../wulkanowy/services/sync/works/ExamWork.kt | 3 +-
.../sync/works/GradeStatisticsWork.kt | 4 +-
.../services/sync/works/GradeWork.kt | 17 +-
.../services/sync/works/HomeworkWork.kt | 3 +-
.../services/sync/works/LuckyNumberWork.kt | 8 +-
.../services/sync/works/MessageWork.kt | 8 +-
.../wulkanowy/services/sync/works/NoteWork.kt | 8 +-
.../services/sync/works/RecipientWork.kt | 6 +-
.../services/sync/works/TeacherWork.kt | 3 +-
.../services/sync/works/TimetableWork.kt | 4 +-
.../github/wulkanowy/ui/base/BasePresenter.kt | 10 +-
.../github/wulkanowy/ui/base/ErrorDialog.kt | 4 +-
.../github/wulkanowy/ui/base/ErrorHandler.kt | 2 +-
.../about/contributor/ContributorPresenter.kt | 3 +-
.../about/logviewer/LogViewerPresenter.kt | 5 +-
.../ui/modules/account/AccountPresenter.kt | 14 +-
.../modules/attendance/AttendancePresenter.kt | 17 +-
.../summary/AttendanceSummaryPresenter.kt | 13 +-
.../ui/modules/exam/ExamPresenter.kt | 11 +-
.../ui/modules/grade/GradeAverageProvider.kt | 25 +-
.../ui/modules/grade/GradePresenter.kt | 5 +-
.../grade/details/GradeDetailsPresenter.kt | 16 +-
.../statistics/GradeStatisticsPresenter.kt | 23 +-
.../grade/summary/GradeSummaryPresenter.kt | 5 +-
.../ui/modules/homework/HomeworkPresenter.kt | 11 +-
.../details/HomeworkDetailsPresenter.kt | 3 +-
.../ui/modules/login/LoginErrorHandler.kt | 2 +-
.../login/advanced/LoginAdvancedPresenter.kt | 11 +-
.../modules/login/form/LoginFormPresenter.kt | 3 +-
.../login/recover/LoginRecoverPresenter.kt | 5 +-
.../LoginStudentSelectPresenter.kt | 8 +-
.../login/symbol/LoginSymbolPresenter.kt | 3 +-
.../luckynumber/LuckyNumberPresenter.kt | 6 +-
.../LuckyNumberWidgetConfigurePresenter.kt | 3 +-
.../LuckyNumberWidgetProvider.kt | 12 +-
.../preview/MessagePreviewPresenter.kt | 9 +-
.../message/send/SendMessagePresenter.kt | 16 +-
.../message/tab/MessageTabPresenter.kt | 7 +-
.../mobiledevice/MobileDevicePresenter.kt | 15 +-
.../token/MobileDeviceTokenPresenter.kt | 7 +-
.../ui/modules/note/NotePresenter.kt | 9 +-
.../school/SchoolPresenter.kt | 8 +-
.../teacher/TeacherPresenter.kt | 7 +-
.../ui/modules/splash/SplashPresenter.kt | 3 +-
.../modules/timetable/TimetablePresenter.kt | 11 +-
.../completed/CompletedLessonsErrorHandler.kt | 2 +-
.../completed/CompletedLessonsPresenter.kt | 11 +-
.../TimetableWidgetConfigurePresenter.kt | 3 +-
.../timetablewidget/TimetableWidgetFactory.kt | 10 +-
.../TimetableWidgetProvider.kt | 10 +-
.../wulkanowy/utils/DispatchersProvider.kt | 10 +
.../wulkanowy/utils/ResourcesExtension.kt | 8 +-
.../wulkanowy/utils/CrashlyticsUtils.kt | 2 +-
.../UnitTestInternetObservingStrategy.kt | 19 --
.../attendance/AttendanceRemoteTest.kt | 19 +-
.../CompletedLessonsRemoteTest.kt | 19 +-
.../data/repositories/exam/ExamRemoteTest.kt | 19 +-
.../GradeStatisticsRemoteTest.kt | 15 +-
.../luckynumber/LuckyNumberRemoteTest.kt | 18 +-
.../message/MessageRepositoryTest.kt | 71 ++---
.../MobileDeviceRepositoryTest.kt | 41 ++-
.../semester/SemesterRepositoryTest.kt | 104 +++----
.../repositories/student/StudentRemoteTest.kt | 17 +-
.../timetable/TimetableRemoteTest.kt | 19 +-
.../modules/grade/GradeAverageProviderTest.kt | 259 +++++++++---------
.../ui/modules/login/LoginPresenterTest.kt | 32 +--
.../login/form/LoginFormPresenterTest.kt | 170 ++++++------
.../LoginStudentSelectPresenterTest.kt | 64 +++--
.../ui/modules/main/MainPresenterTest.kt | 40 ++-
.../ui/modules/splash/SplashPresenterTest.kt | 25 +-
.../wulkanowy/utils/GradeExtensionTest.kt | 8 +-
177 files changed, 1752 insertions(+), 2004 deletions(-)
delete mode 100644 app/src/androidTest/java/io/github/wulkanowy/data/repositories/TestInternetObservingStrategy.kt
create mode 100644 app/src/main/java/io/github/wulkanowy/utils/DispatchersProvider.kt
delete mode 100644 app/src/test/java/io/github/wulkanowy/data/repositories/UnitTestInternetObservingStrategy.kt
diff --git a/app/build.gradle b/app/build.gradle
index 621e5a4fe..0f0a3303d 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -124,10 +124,13 @@ configurations.all {
}
dependencies {
- implementation "io.github.wulkanowy:sdk:0.19.0"
+ implementation "io.github.wulkanowy:sdk:61250d3"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
- implementation "androidx.core:core-ktx:1.2.0"
+ implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.7'
+ implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-rx2:1.3.7'
+
+ implementation "androidx.core:core-ktx:1.3.0"
implementation "androidx.activity:activity-ktx:1.1.0"
implementation "androidx.appcompat:appcompat:1.2.0-rc01"
implementation "androidx.appcompat:appcompat-resources:1.1.0"
@@ -167,7 +170,6 @@ dependencies {
implementation "com.ncapdevi:frag-nav:3.3.0"
implementation "com.github.YarikSOffice:lingver:1.2.2"
- implementation "com.github.pwittchen:reactivenetwork-rx2:3.0.8"
implementation "io.reactivex.rxjava2:rxandroid:2.1.1"
implementation "io.reactivex.rxjava2:rxjava:2.2.19"
@@ -197,7 +199,6 @@ dependencies {
testImplementation "junit:junit:4.13"
testImplementation "io.mockk:mockk:$mockk"
testImplementation "org.threeten:threetenbp:1.4.4"
- testImplementation "org.mockito:mockito-inline:3.3.3"
androidTestImplementation "androidx.test:core:1.2.0"
androidTestImplementation "androidx.test:runner:1.2.0"
@@ -205,7 +206,6 @@ dependencies {
androidTestImplementation "io.mockk:mockk-android:$mockk"
androidTestImplementation "androidx.room:room-testing:$room"
androidTestImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
- androidTestImplementation "org.mockito:mockito-android:3.3.3"
}
apply plugin: 'com.google.gms.google-services'
diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/db/migrations/Migration12Test.kt b/app/src/androidTest/java/io/github/wulkanowy/data/db/migrations/Migration12Test.kt
index 0bbcc4271..b312048d5 100644
--- a/app/src/androidTest/java/io/github/wulkanowy/data/db/migrations/Migration12Test.kt
+++ b/app/src/androidTest/java/io/github/wulkanowy/data/db/migrations/Migration12Test.kt
@@ -4,6 +4,7 @@ import android.content.ContentValues
import android.database.sqlite.SQLiteDatabase.CONFLICT_FAIL
import androidx.sqlite.db.SupportSQLiteDatabase
import androidx.test.ext.junit.runners.AndroidJUnit4
+import kotlinx.coroutines.runBlocking
import org.junit.Test
import org.junit.runner.RunWith
import kotlin.test.assertEquals
@@ -29,7 +30,7 @@ class Migration12Test : AbstractMigrationTest() {
helper.runMigrationsAndValidate(dbName, 12, true, Migration12())
val db = getMigratedRoomDatabase()
- val students = db.studentDao.loadAll().blockingGet()
+ val students = runBlocking { db.studentDao.loadAll() }
assertEquals(2, students.size)
@@ -58,7 +59,7 @@ class Migration12Test : AbstractMigrationTest() {
helper.runMigrationsAndValidate(dbName, 12, true, Migration12())
val db = getMigratedRoomDatabase()
- val students = db.studentDao.loadAll().blockingGet()
+ val students = runBlocking { db.studentDao.loadAll() }
assertEquals(1, students.size)
@@ -84,7 +85,7 @@ class Migration12Test : AbstractMigrationTest() {
helper.runMigrationsAndValidate(dbName, 12, true, Migration12())
val db = getMigratedRoomDatabase()
- val students = db.studentDao.loadAll().blockingGet()
+ val students = runBlocking { db.studentDao.loadAll() }
assertEquals(3, students.size)
diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/db/migrations/Migration13Test.kt b/app/src/androidTest/java/io/github/wulkanowy/data/db/migrations/Migration13Test.kt
index da4284b02..05a8a5cf0 100644
--- a/app/src/androidTest/java/io/github/wulkanowy/data/db/migrations/Migration13Test.kt
+++ b/app/src/androidTest/java/io/github/wulkanowy/data/db/migrations/Migration13Test.kt
@@ -5,6 +5,7 @@ import android.database.sqlite.SQLiteDatabase
import androidx.sqlite.db.SupportSQLiteDatabase
import io.github.wulkanowy.data.db.Converters
import io.github.wulkanowy.data.db.entities.Semester
+import kotlinx.coroutines.runBlocking
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Test
@@ -26,7 +27,7 @@ class Migration13Test : AbstractMigrationTest() {
helper.runMigrationsAndValidate(dbName, 13, true, Migration13())
val db = getMigratedRoomDatabase()
- val students = db.studentDao.loadAll().blockingGet()
+ val students = runBlocking { db.studentDao.loadAll() }
assertEquals(3, students.size)
@@ -60,7 +61,7 @@ class Migration13Test : AbstractMigrationTest() {
helper.runMigrationsAndValidate(dbName, 13, true, Migration13())
val db = getMigratedRoomDatabase()
- val students = db.studentDao.loadAll().blockingGet()
+ val students = runBlocking { db.studentDao.loadAll() }
assertEquals(2, students.size)
diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/TestInternetObservingStrategy.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/TestInternetObservingStrategy.kt
deleted file mode 100644
index 7dc93c4a4..000000000
--- a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/TestInternetObservingStrategy.kt
+++ /dev/null
@@ -1,19 +0,0 @@
-package io.github.wulkanowy.data.repositories
-
-import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingStrategy
-import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.error.ErrorHandler
-import io.reactivex.Observable
-import io.reactivex.Single
-
-class TestInternetObservingStrategy : InternetObservingStrategy {
-
- override fun checkInternetConnectivity(host: String?, port: Int, timeoutInMs: Int, httpResponse: Int, errorHandler: ErrorHandler?): Single {
- return Single.just(true)
- }
-
- override fun observeInternetConnectivity(initialIntervalInMs: Int, intervalInMs: Int, host: String?, port: Int, timeoutInMs: Int, httpResponse: Int, errorHandler: ErrorHandler?): Observable {
- return Observable.just(true)
- }
-
- override fun getDefaultPingHost() = "localhost"
-}
diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/attendance/AttendanceLocalTest.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/attendance/AttendanceLocalTest.kt
index cdfc524ad..f9326b2d5 100644
--- a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/attendance/AttendanceLocalTest.kt
+++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/attendance/AttendanceLocalTest.kt
@@ -6,6 +6,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import io.github.wulkanowy.data.db.AppDatabase
import io.github.wulkanowy.data.db.entities.Attendance
import io.github.wulkanowy.data.db.entities.Semester
+import kotlinx.coroutines.runBlocking
import org.junit.After
import org.junit.Before
import org.junit.Test
@@ -35,7 +36,7 @@ class AttendanceLocalTest {
@Test
fun saveAndReadTest() {
- attendanceLocal.saveAttendance(listOf(
+ val list = listOf(
getAttendanceEntity(
of(2018, 9, 10),
SentExcuseStatus.ACCEPTED
@@ -48,14 +49,11 @@ class AttendanceLocalTest {
of(2018, 9, 17),
SentExcuseStatus.ACCEPTED
)
- ))
+ )
+ runBlocking { attendanceLocal.saveAttendance(list) }
- val attendance = attendanceLocal
- .getAttendance(Semester(1, 2, "", 1, 3, 2019, now(), now(), 1, 1),
- of(2018, 9, 10),
- of(2018, 9, 14)
- )
- .blockingGet()
+ val semester = Semester(1, 2, "", 1, 3, 2019, now(), now(), 1, 1)
+ val attendance = runBlocking { attendanceLocal.getAttendance(semester, of(2018, 9, 10), of(2018, 9, 14)) }
assertEquals(2, attendance.size)
assertEquals(attendance[0].date, of(2018, 9, 10))
assertEquals(attendance[1].date, of(2018, 9, 14))
diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/completedlessons/CompletedLessonsLocalTest.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/completedlessons/CompletedLessonsLocalTest.kt
index 50badc468..d8aac23da 100644
--- a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/completedlessons/CompletedLessonsLocalTest.kt
+++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/completedlessons/CompletedLessonsLocalTest.kt
@@ -6,6 +6,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import io.github.wulkanowy.data.db.AppDatabase
import io.github.wulkanowy.data.db.entities.CompletedLesson
import io.github.wulkanowy.data.db.entities.Semester
+import kotlinx.coroutines.runBlocking
import org.junit.After
import org.junit.Before
import org.junit.Test
@@ -24,7 +25,8 @@ class CompletedLessonsLocalTest {
@Before
fun createDb() {
- testDb = Room.inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), AppDatabase::class.java)
+ testDb = Room
+ .inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), AppDatabase::class.java)
.build()
completedLessonsLocal = CompletedLessonsLocal(testDb.completedLessonsDao)
}
@@ -36,18 +38,15 @@ class CompletedLessonsLocalTest {
@Test
fun saveAndReadTest() {
- completedLessonsLocal.saveCompletedLessons(listOf(
+ val list = listOf(
getCompletedLesson(of(2018, 9, 10), 1),
getCompletedLesson(of(2018, 9, 14), 2),
getCompletedLesson(of(2018, 9, 17), 3)
- ))
+ )
+ runBlocking { completedLessonsLocal.saveCompletedLessons(list) }
- val completed = completedLessonsLocal
- .getCompletedLessons(Semester(1, 2, "", 1, 3, 2019, now(), now(), 1, 1),
- of(2018, 9, 10),
- of(2018, 9, 14)
- )
- .blockingGet()
+ val semester = Semester(1, 2, "", 1, 3, 2019, now(), now(), 1, 1)
+ val completed = runBlocking { completedLessonsLocal.getCompletedLessons(semester, of(2018, 9, 10), of(2018, 9, 14)) }
assertEquals(2, completed.size)
assertEquals(completed[0].date, of(2018, 9, 10))
assertEquals(completed[1].date, of(2018, 9, 14))
diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/exam/ExamLocalTest.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/exam/ExamLocalTest.kt
index 98dfc88eb..f3b179a51 100644
--- a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/exam/ExamLocalTest.kt
+++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/exam/ExamLocalTest.kt
@@ -6,6 +6,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import io.github.wulkanowy.data.db.AppDatabase
import io.github.wulkanowy.data.db.entities.Exam
import io.github.wulkanowy.data.db.entities.Semester
+import kotlinx.coroutines.runBlocking
import org.junit.After
import org.junit.Before
import org.junit.Test
@@ -34,18 +35,15 @@ class ExamLocalTest {
@Test
fun saveAndReadTest() {
- examLocal.saveExams(listOf(
+ val list = listOf(
Exam(1, 2, of(2018, 9, 10), now(), "", "", "", "", "", ""),
Exam(1, 2, of(2018, 9, 14), now(), "", "", "", "", "", ""),
Exam(1, 2, of(2018, 9, 17), now(), "", "", "", "", "", "")
- ))
+ )
+ runBlocking { examLocal.saveExams(list) }
- val exams = examLocal
- .getExams(Semester(1, 2, "", 1, 3, 2019, now(), now(), 1, 1),
- of(2018, 9, 10),
- of(2018, 9, 14)
- )
- .blockingGet()
+ val semester = Semester(1, 2, "", 1, 3, 2019, now(), now(), 1, 1)
+ val exams = runBlocking { examLocal.getExams(semester, of(2018, 9, 10), of(2018, 9, 14)) }
assertEquals(2, exams.size)
assertEquals(exams[0].date, of(2018, 9, 10))
assertEquals(exams[1].date, of(2018, 9, 14))
diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/grade/GradeLocalTest.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/grade/GradeLocalTest.kt
index eb1a55480..82129d868 100644
--- a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/grade/GradeLocalTest.kt
+++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/grade/GradeLocalTest.kt
@@ -5,6 +5,7 @@ import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import io.github.wulkanowy.data.db.AppDatabase
import io.github.wulkanowy.data.db.entities.Semester
+import kotlinx.coroutines.runBlocking
import org.junit.After
import org.junit.Before
import org.junit.Test
@@ -22,7 +23,8 @@ class GradeLocalTest {
@Before
fun createDb() {
- testDb = Room.inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), AppDatabase::class.java)
+ testDb = Room
+ .inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), AppDatabase::class.java)
.build()
gradeLocal = GradeLocal(testDb.gradeDao, testDb.gradeSummaryDao)
}
@@ -34,17 +36,16 @@ class GradeLocalTest {
@Test
fun saveAndReadTest() {
- gradeLocal.saveGrades(listOf(
+ val list = listOf(
createGradeLocal(5, 3.0, LocalDate.of(2018, 9, 10), "", 1),
createGradeLocal(4, 4.0, LocalDate.of(2019, 2, 27), "", 2),
createGradeLocal(3, 5.0, LocalDate.of(2019, 2, 28), "", 2)
- ))
+ )
+ runBlocking { gradeLocal.saveGrades(list) }
val semester = Semester(1, 2, "", 2019, 2, 1, now(), now(), 1, 1)
- val grades = gradeLocal
- .getGradesDetails(semester)
- .blockingGet()
+ val grades = runBlocking { gradeLocal.getGradesDetails(semester) }
assertEquals(2, grades.size)
assertEquals(grades[0].date, LocalDate.of(2019, 2, 27))
diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/grade/GradeRepositoryTest.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/grade/GradeRepositoryTest.kt
index cdd514772..5487fd4ce 100644
--- a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/grade/GradeRepositoryTest.kt
+++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/grade/GradeRepositoryTest.kt
@@ -5,17 +5,16 @@ import androidx.room.Room
import androidx.test.core.app.ApplicationProvider.getApplicationContext
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SdkSuppress
-import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
import io.github.wulkanowy.data.db.AppDatabase
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
-import io.github.wulkanowy.data.repositories.TestInternetObservingStrategy
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.sdk.pojo.Grade
import io.mockk.MockKAnnotations
+import io.mockk.coEvery
import io.mockk.every
import io.mockk.impl.annotations.MockK
-import io.reactivex.Single
+import kotlinx.coroutines.runBlocking
import org.junit.After
import org.junit.Before
import org.junit.Test
@@ -33,10 +32,6 @@ class GradeRepositoryTest {
@MockK
private lateinit var mockSdk: Sdk
- private val settings = InternetObservingSettings.builder()
- .strategy(TestInternetObservingStrategy())
- .build()
-
@MockK
private lateinit var semesterMock: Semester
@@ -71,15 +66,17 @@ class GradeRepositoryTest {
@Test
fun markOlderThanRegisterDateAsRead() {
- every { mockSdk.getGrades(1) } returns Single.just(listOf(
+ coEvery { mockSdk.getGrades(1) } returns (listOf(
createGradeApi(5, 4.0, of(2019, 2, 25), "Ocena pojawiła się"),
createGradeApi(5, 4.0, of(2019, 2, 26), "przed zalogowanie w aplikacji"),
createGradeApi(5, 4.0, of(2019, 2, 27), "Ocena z dnia logowania"),
createGradeApi(5, 4.0, of(2019, 2, 28), "Ocena jeszcze nowsza")
) to emptyList())
- val grades = GradeRepository(settings, gradeLocal, gradeRemote)
- .getGrades(studentMock, semesterMock, true).blockingGet().first.sortedByDescending { it.date }
+ val grades = runBlocking {
+ GradeRepository(gradeLocal, gradeRemote).getGrades(studentMock, semesterMock, true)
+ .first.sortedByDescending { it.date }
+ }
assertFalse { grades[0].isRead }
assertFalse { grades[1].isRead }
@@ -89,21 +86,24 @@ class GradeRepositoryTest {
@Test
fun mitigateOldGradesNotifications() {
- gradeLocal.saveGrades(listOf(
+ val list = listOf(
createGradeLocal(5, 3.0, of(2019, 2, 25), "Jedna ocena"),
createGradeLocal(4, 4.0, of(2019, 2, 26), "Druga"),
createGradeLocal(3, 5.0, of(2019, 2, 27), "Trzecia")
- ))
+ )
+ runBlocking { gradeLocal.saveGrades(list) }
- every { mockSdk.getGrades(1) } returns Single.just(listOf(
+ coEvery { mockSdk.getGrades(1) } returns (listOf(
createGradeApi(5, 2.0, of(2019, 2, 25), "Ocena ma datę, jest inna, ale nie zostanie powiadomiona"),
createGradeApi(4, 3.0, of(2019, 2, 26), "starszą niż ostatnia lokalnie"),
createGradeApi(3, 4.0, of(2019, 2, 27), "Ta jest z tego samego dnia co ostatnia lokalnie"),
createGradeApi(2, 5.0, of(2019, 2, 28), "Ta jest już w ogóle nowa")
) to emptyList())
- val grades = GradeRepository(settings, gradeLocal, gradeRemote)
- .getGrades(studentMock, semesterMock, true).blockingGet().first.sortedByDescending { it.date }
+ val grades = runBlocking {
+ GradeRepository(gradeLocal, gradeRemote).getGrades(studentMock, semesterMock, true)
+ .first.sortedByDescending { it.date }
+ }
assertFalse { grades[0].isRead }
assertFalse { grades[1].isRead }
@@ -113,69 +113,76 @@ class GradeRepositoryTest {
@Test
fun subtractLocaleDuplicateGrades() {
- gradeLocal.saveGrades(listOf(
+ val list = listOf(
createGradeLocal(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
createGradeLocal(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
createGradeLocal(3, 5.0, of(2019, 2, 26), "Jakaś inna ocena")
- ))
+ )
+ runBlocking { gradeLocal.saveGrades(list) }
- every { mockSdk.getGrades(1) } returns Single.just(listOf(
+ coEvery { mockSdk.getGrades(1) } returns (listOf(
createGradeApi(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
createGradeApi(3, 5.0, of(2019, 2, 26), "Jakaś inna ocena")
) to emptyList())
- val grades = GradeRepository(settings, gradeLocal, gradeRemote)
- .getGrades(studentMock, semesterMock, true).blockingGet()
+ val grades = runBlocking {
+ GradeRepository(gradeLocal, gradeRemote).getGrades(studentMock, semesterMock, true)
+ }
assertEquals(2, grades.first.size)
}
@Test
fun subtractRemoteDuplicateGrades() {
- gradeLocal.saveGrades(listOf(
+ val list = listOf(
createGradeLocal(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
createGradeLocal(3, 5.0, of(2019, 2, 26), "Jakaś inna ocena")
- ))
+ )
+ runBlocking { gradeLocal.saveGrades(list) }
- every { mockSdk.getGrades(1) } returns Single.just(listOf(
+ coEvery { mockSdk.getGrades(1) } returns (listOf(
createGradeApi(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
createGradeApi(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
createGradeApi(3, 5.0, of(2019, 2, 26), "Jakaś inna ocena")
) to emptyList())
- val grades = GradeRepository(settings, gradeLocal, gradeRemote)
- .getGrades(studentMock, semesterMock, true).blockingGet()
+ val grades = runBlocking {
+ GradeRepository(gradeLocal, gradeRemote).getGrades(studentMock, semesterMock, true)
+ }
assertEquals(3, grades.first.size)
}
@Test
fun emptyLocal() {
- gradeLocal.saveGrades(listOf())
+ runBlocking { gradeLocal.saveGrades(listOf()) }
- every { mockSdk.getGrades(1) } returns Single.just(listOf(
+ coEvery { mockSdk.getGrades(1) } returns (listOf(
createGradeApi(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
createGradeApi(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
createGradeApi(3, 5.0, of(2019, 2, 26), "Jakaś inna ocena")
) to emptyList())
- val grades = GradeRepository(settings, gradeLocal, gradeRemote)
- .getGrades(studentMock, semesterMock, true).blockingGet()
+ val grades = runBlocking {
+ GradeRepository(gradeLocal, gradeRemote).getGrades(studentMock, semesterMock, true)
+ }
assertEquals(3, grades.first.size)
}
@Test
fun emptyRemote() {
- gradeLocal.saveGrades(listOf(
+ val list = listOf(
createGradeLocal(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
createGradeLocal(3, 5.0, of(2019, 2, 26), "Jakaś inna ocena")
- ))
+ )
+ runBlocking { gradeLocal.saveGrades(list) }
- every { mockSdk.getGrades(1) } returns Single.just(emptyList() to emptyList())
+ coEvery { mockSdk.getGrades(1) } returns (emptyList() to emptyList())
- val grades = GradeRepository(settings, gradeLocal, gradeRemote)
- .getGrades(studentMock, semesterMock, true).blockingGet()
+ val grades = runBlocking {
+ GradeRepository(gradeLocal, gradeRemote).getGrades(studentMock, semesterMock, true)
+ }
assertEquals(0, grades.first.size)
}
diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/gradestatistics/GradeStatisticsLocalTest.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/gradestatistics/GradeStatisticsLocalTest.kt
index bd3635fea..deda67ba3 100644
--- a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/gradestatistics/GradeStatisticsLocalTest.kt
+++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/gradestatistics/GradeStatisticsLocalTest.kt
@@ -7,6 +7,7 @@ import io.github.wulkanowy.data.db.AppDatabase
import io.github.wulkanowy.data.db.entities.GradePointsStatistics
import io.github.wulkanowy.data.db.entities.GradeStatistics
import io.github.wulkanowy.data.db.entities.Semester
+import kotlinx.coroutines.runBlocking
import org.junit.After
import org.junit.Before
import org.junit.Test
@@ -35,25 +36,27 @@ class GradeStatisticsLocalTest {
@Test
fun saveAndRead_subject() {
- gradeStatisticsLocal.saveGradesStatistics(listOf(
+ val list = listOf(
getGradeStatistics("Matematyka", 2, 1),
getGradeStatistics("Fizyka", 1, 2)
- ))
+ )
+ runBlocking { gradeStatisticsLocal.saveGradesStatistics(list) }
- val stats = gradeStatisticsLocal.getGradesStatistics(getSemester(), false, "Matematyka").blockingGet()
+ val stats = runBlocking { gradeStatisticsLocal.getGradesStatistics(getSemester(), false, "Matematyka") }
assertEquals(1, stats.size)
assertEquals(stats[0].subject, "Matematyka")
}
@Test
fun saveAndRead_all() {
- gradeStatisticsLocal.saveGradesStatistics(listOf(
+ val list = listOf(
getGradeStatistics("Matematyka", 2, 1),
getGradeStatistics("Chemia", 2, 1),
getGradeStatistics("Fizyka", 1, 2)
- ))
+ )
+ runBlocking { gradeStatisticsLocal.saveGradesStatistics(list) }
- val stats = gradeStatisticsLocal.getGradesStatistics(getSemester(), false, "Wszystkie").blockingGet()
+ val stats = runBlocking { gradeStatisticsLocal.getGradesStatistics(getSemester(), false, "Wszystkie") }
assertEquals(3, stats.size)
assertEquals(stats[0].subject, "Wszystkie")
assertEquals(stats[1].subject, "Matematyka")
@@ -62,13 +65,14 @@ class GradeStatisticsLocalTest {
@Test
fun saveAndRead_points() {
- gradeStatisticsLocal.saveGradesPointsStatistics(listOf(
+ val list = listOf(
getGradePointsStatistics("Matematyka", 2, 1),
getGradePointsStatistics("Chemia", 2, 1),
getGradePointsStatistics("Fizyka", 1, 2)
- ))
+ )
+ runBlocking { gradeStatisticsLocal.saveGradesPointsStatistics(list) }
- val stats = gradeStatisticsLocal.getGradesPointsStatistics(getSemester(), "Matematyka").blockingGet()
+ val stats = runBlocking { gradeStatisticsLocal.getGradesPointsStatistics(getSemester(), "Matematyka") }
with(stats[0]) {
assertEquals(subject, "Matematyka")
assertEquals(others, 5.0)
@@ -78,18 +82,18 @@ class GradeStatisticsLocalTest {
@Test
fun saveAndRead_subjectEmpty() {
- gradeStatisticsLocal.saveGradesPointsStatistics(listOf())
+ runBlocking { gradeStatisticsLocal.saveGradesPointsStatistics(listOf()) }
- val stats = gradeStatisticsLocal.getGradesPointsStatistics(getSemester(), "Matematyka").blockingGet()
- assertEquals(null, stats)
+ val stats = runBlocking { gradeStatisticsLocal.getGradesPointsStatistics(getSemester(), "Matematyka") }
+ assertEquals(emptyList(), stats)
}
@Test
fun saveAndRead_allEmpty() {
- gradeStatisticsLocal.saveGradesPointsStatistics(listOf())
+ runBlocking { gradeStatisticsLocal.saveGradesPointsStatistics(listOf()) }
- val stats = gradeStatisticsLocal.getGradesPointsStatistics(getSemester(), "Wszystkie").blockingGet()
- assertEquals(null, stats)
+ val stats = runBlocking { gradeStatisticsLocal.getGradesPointsStatistics(getSemester(), "Wszystkie") }
+ assertEquals(emptyList(), stats)
}
private fun getSemester(): Semester {
diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/luckynumber/LuckyNumberLocalTest.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/luckynumber/LuckyNumberLocalTest.kt
index efad0d4d5..f37d7934b 100644
--- a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/luckynumber/LuckyNumberLocalTest.kt
+++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/luckynumber/LuckyNumberLocalTest.kt
@@ -6,6 +6,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import io.github.wulkanowy.data.db.AppDatabase
import io.github.wulkanowy.data.db.entities.LuckyNumber
import io.github.wulkanowy.data.db.entities.Student
+import kotlinx.coroutines.runBlocking
import org.junit.After
import org.junit.Before
import org.junit.Test
@@ -23,7 +24,8 @@ class LuckyNumberLocalTest {
@Before
fun createDb() {
- testDb = Room.inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), AppDatabase::class.java)
+ testDb = Room
+ .inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), AppDatabase::class.java)
.build()
luckyNumberLocal = LuckyNumberLocal(testDb.luckyNumberDao)
}
@@ -35,14 +37,14 @@ class LuckyNumberLocalTest {
@Test
fun saveAndReadTest() {
- luckyNumberLocal.saveLuckyNumber(LuckyNumber(1, LocalDate.of(2019, 1, 20), 14))
+ val number = LuckyNumber(1, LocalDate.of(2019, 1, 20), 14)
+ runBlocking { luckyNumberLocal.saveLuckyNumber(number) }
- val luckyNumber = luckyNumberLocal.getLuckyNumber(Student("", "", "", "", "", "", false, "", "", "", 1, 1, "", "", "", "", "", 1, false, now()),
- LocalDate.of(2019, 1, 20)
- ).blockingGet()
+ val student = Student("", "", "", "", "", "", false, "", "", "", 1, 1, "", "", "", "", "", 1, false, now())
+ val luckyNumber = runBlocking { luckyNumberLocal.getLuckyNumber(student, LocalDate.of(2019, 1, 20)) }
- assertEquals(1, luckyNumber.studentId)
- assertEquals(LocalDate.of(2019, 1, 20), luckyNumber.date)
- assertEquals(14, luckyNumber.luckyNumber)
+ assertEquals(1, luckyNumber?.studentId)
+ assertEquals(LocalDate.of(2019, 1, 20), luckyNumber?.date)
+ assertEquals(14, luckyNumber?.luckyNumber)
}
}
diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/recipient/RecipientLocalTest.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/recipient/RecipientLocalTest.kt
index 22578e41e..9ba8a9fb4 100644
--- a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/recipient/RecipientLocalTest.kt
+++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/recipient/RecipientLocalTest.kt
@@ -7,6 +7,7 @@ import io.github.wulkanowy.data.db.AppDatabase
import io.github.wulkanowy.data.db.entities.Recipient
import io.github.wulkanowy.data.db.entities.ReportingUnit
import io.github.wulkanowy.data.db.entities.Student
+import kotlinx.coroutines.runBlocking
import org.junit.After
import org.junit.Before
import org.junit.Test
@@ -35,17 +36,21 @@ class RecipientLocalTest {
@Test
fun saveAndReadTest() {
- recipientLocal.saveRecipients(listOf(
+ val list = listOf(
Recipient(1, "2rPracownik", "Kowalski Jan", "Kowalski Jan [KJ] - Pracownik (Fake123456)", 3, 4, 2, "hash"),
Recipient(1, "3rPracownik", "Kowalska Karolina", "Kowalska Karolina [KK] - Pracownik (Fake123456)", 4, 4, 2, "hash"),
Recipient(1, "4rPracownik", "Krupa Stanisław", "Krupa Stanisław [KS] - Uczeń (Fake123456)", 5, 4, 1, "hash")
- ))
+ )
+ runBlocking { recipientLocal.saveRecipients(list) }
- val recipients = recipientLocal.getRecipients(
- Student("fakelog.cf", "AUTO", "", "", "", "", false, "", "", "", 1, 0, "", "", "", "", "", 1, true, LocalDateTime.now()),
- 2,
- ReportingUnit(1, 4, "", 0, "", emptyList())
- ).blockingGet()
+ val student = Student("fakelog.cf", "AUTO", "", "", "", "", false, "", "", "", 1, 0, "", "", "", "", "", 1, true, LocalDateTime.now())
+ val recipients = runBlocking {
+ recipientLocal.getRecipients(
+ student = student,
+ role = 2,
+ unit = ReportingUnit(1, 4, "", 0, "", emptyList())
+ )
+ }
assertEquals(2, recipients.size)
assertEquals(1, recipients[0].studentId)
diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/student/StudentLocalTest.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/student/StudentLocalTest.kt
index 530bfb3f7..02a13344e 100644
--- a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/student/StudentLocalTest.kt
+++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/student/StudentLocalTest.kt
@@ -6,6 +6,7 @@ import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import io.github.wulkanowy.data.db.AppDatabase
import io.github.wulkanowy.data.repositories.getStudent
+import kotlinx.coroutines.runBlocking
import org.junit.After
import org.junit.Before
import org.junit.Test
@@ -36,9 +37,9 @@ class StudentLocalTest {
@Test
fun saveAndReadTest() {
- studentLocal.saveStudents(listOf(student)).blockingGet()
+ runBlocking { studentLocal.saveStudents(listOf(student)) }
- val student = studentLocal.getCurrentStudent(true).blockingGet()
- assertEquals("23", student.schoolSymbol)
+ val student = runBlocking { studentLocal.getCurrentStudent(true) }
+ assertEquals("23", student?.schoolSymbol)
}
}
diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/timetable/TimetableLocalTest.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/timetable/TimetableLocalTest.kt
index a66e5843c..fa353a332 100644
--- a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/timetable/TimetableLocalTest.kt
+++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/timetable/TimetableLocalTest.kt
@@ -5,6 +5,7 @@ import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import io.github.wulkanowy.data.db.AppDatabase
import io.github.wulkanowy.data.db.entities.Semester
+import kotlinx.coroutines.runBlocking
import org.junit.After
import org.junit.Before
import org.junit.Test
@@ -34,17 +35,21 @@ class TimetableLocalTest {
@Test
fun saveAndReadTest() {
- timetableDb.saveTimetable(listOf(
+ val list = listOf(
createTimetableLocal(of(2018, 9, 10, 0, 0, 0), 1),
createTimetableLocal(of(2018, 9, 14, 0, 0, 0), 1),
createTimetableLocal(of(2018, 9, 17, 0, 0, 0), 1)
- ))
+ )
+ runBlocking { timetableDb.saveTimetable(list) }
- val exams = timetableDb.getTimetable(
- Semester(1, 2, "", 1, 1, 2019, LocalDate.now(), LocalDate.now(), 1, 1),
- LocalDate.of(2018, 9, 10),
- LocalDate.of(2018, 9, 14)
- ).blockingGet()
+ val semester = Semester(1, 2, "", 1, 1, 2019, LocalDate.now(), LocalDate.now(), 1, 1)
+ val exams = runBlocking {
+ timetableDb.getTimetable(
+ semester = semester,
+ startDate = LocalDate.of(2018, 9, 10),
+ endDate = LocalDate.of(2018, 9, 14)
+ )
+ }
assertEquals(2, exams.size)
assertEquals(exams[0].date, LocalDate.of(2018, 9, 10))
diff --git a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/timetable/TimetableRepositoryTest.kt b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/timetable/TimetableRepositoryTest.kt
index 75f2f0b83..a91651db1 100644
--- a/app/src/androidTest/java/io/github/wulkanowy/data/repositories/timetable/TimetableRepositoryTest.kt
+++ b/app/src/androidTest/java/io/github/wulkanowy/data/repositories/timetable/TimetableRepositoryTest.kt
@@ -5,19 +5,18 @@ import androidx.room.Room
import androidx.test.core.app.ApplicationProvider.getApplicationContext
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SdkSuppress
-import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
import io.github.wulkanowy.data.db.AppDatabase
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
-import io.github.wulkanowy.data.repositories.TestInternetObservingStrategy
import io.github.wulkanowy.data.repositories.getStudent
-import io.github.wulkanowy.services.alarm.TimetableNotificationSchedulerHelper
import io.github.wulkanowy.sdk.Sdk
+import io.github.wulkanowy.services.alarm.TimetableNotificationSchedulerHelper
import io.mockk.MockKAnnotations
+import io.mockk.coEvery
import io.mockk.every
import io.mockk.impl.annotations.MockK
import io.mockk.mockk
-import io.reactivex.Single
+import kotlinx.coroutines.runBlocking
import org.junit.After
import org.junit.Before
import org.junit.Test
@@ -33,10 +32,6 @@ class TimetableRepositoryTest {
@MockK
private lateinit var mockSdk: Sdk
- private val settings = InternetObservingSettings.builder()
- .strategy(TestInternetObservingStrategy())
- .build()
-
@MockK
private lateinit var studentMock: Student
@@ -82,23 +77,31 @@ class TimetableRepositoryTest {
@Test
fun copyRoomToCompletedFromPrevious() {
- timetableLocal.saveTimetable(listOf(
- createTimetableLocal(of(2019, 3, 5, 8, 0), 1, "123", "Przyroda"),
- createTimetableLocal(of(2019, 3, 5, 8, 50), 2, "321", "Religia"),
- createTimetableLocal(of(2019, 3, 5, 9, 40), 3, "213", "W-F"),
- createTimetableLocal(of(2019, 3, 5, 10, 30),3, "213", "W-F", "Jan Kowalski")
- ))
+ runBlocking {
+ timetableLocal.saveTimetable(listOf(
+ createTimetableLocal(of(2019, 3, 5, 8, 0), 1, "123", "Przyroda"),
+ createTimetableLocal(of(2019, 3, 5, 8, 50), 2, "321", "Religia"),
+ createTimetableLocal(of(2019, 3, 5, 9, 40), 3, "213", "W-F"),
+ createTimetableLocal(of(2019, 3, 5, 10, 30), 3, "213", "W-F", "Jan Kowalski")
+ ))
+ }
- every { mockSdk.getTimetable(any(), any()) } returns Single.just(listOf(
+ coEvery { mockSdk.getTimetable(any(), any()) } returns listOf(
createTimetableRemote(of(2019, 3, 5, 8, 0), 1, "", "Przyroda"),
createTimetableRemote(of(2019, 3, 5, 8, 50), 2, "", "Religia"),
createTimetableRemote(of(2019, 3, 5, 9, 40), 3, "", "W-F"),
createTimetableRemote(of(2019, 3, 5, 10, 30), 4, "", "W-F")
- ))
+ )
- val lessons = TimetableRepository(settings, timetableLocal, timetableRemote, timetableNotificationSchedulerHelper)
- .getTimetable(student, semesterMock, LocalDate.of(2019, 3, 5), LocalDate.of(2019, 3, 5), true)
- .blockingGet()
+ val lessons = runBlocking {
+ TimetableRepository(timetableLocal, timetableRemote, timetableNotificationSchedulerHelper).getTimetable(
+ student = student,
+ semester = semesterMock,
+ start = LocalDate.of(2019, 3, 5),
+ end = LocalDate.of(2019, 3, 5),
+ forceRefresh = true
+ )
+ }
assertEquals(4, lessons.size)
assertEquals("123", lessons[0].room)
@@ -108,7 +111,7 @@ class TimetableRepositoryTest {
@Test
fun copyTeacherToCompletedFromPrevious() {
- timetableLocal.saveTimetable(listOf(
+ val list = listOf(
createTimetableLocal(of(2019, 12, 23, 8, 0), 1, "123", "Matematyka", "Paweł Poniedziałkowski", false),
createTimetableLocal(of(2019, 12, 23, 8, 50), 2, "124", "Matematyka", "Paweł Poniedziałkowski", false),
createTimetableLocal(of(2019, 12, 23, 9, 40), 3, "125", "Język polski", "Joanna Wtorkowska", true),
@@ -123,9 +126,10 @@ class TimetableRepositoryTest {
createTimetableLocal(of(2019, 12, 25, 8, 50), 2, "124", "Matematyka", "", false),
createTimetableLocal(of(2019, 12, 25, 9, 40), 3, "125", "Matematyka", "", true),
createTimetableLocal(of(2019, 12, 25, 10, 40), 4, "126", "Matematyka", "", true)
- ))
+ )
+ runBlocking { timetableLocal.saveTimetable(list) }
- every { mockSdk.getTimetable(any(), any()) } returns Single.just(listOf(
+ coEvery { mockSdk.getTimetable(any(), any()) } returns listOf(
createTimetableRemote(of(2019, 12, 23, 8, 0), 1, "123", "Matematyka", "Paweł Poniedziałkowski", false),
createTimetableRemote(of(2019, 12, 23, 8, 50), 2, "124", "Matematyka", "Jakub Wtorkowski", true),
createTimetableRemote(of(2019, 12, 23, 9, 40), 3, "125", "Język polski", "Joanna Poniedziałkowska", false),
@@ -140,11 +144,17 @@ class TimetableRepositoryTest {
createTimetableRemote(of(2019, 12, 25, 8, 50), 2, "124", "Matematyka", "Paweł Czwartkowski", true),
createTimetableRemote(of(2019, 12, 25, 9, 40), 3, "125", "Matematyka", "Paweł Środowski", false),
createTimetableRemote(of(2019, 12, 25, 10, 40), 4, "126", "Matematyka", "Paweł Czwartkowski", true)
- ))
+ )
- val lessons = TimetableRepository(settings, timetableLocal, timetableRemote, timetableNotificationSchedulerHelper)
- .getTimetable(student, semesterMock, LocalDate.of(2019, 12, 23), LocalDate.of(2019, 12, 25), true)
- .blockingGet()
+ val lessons = runBlocking {
+ TimetableRepository(timetableLocal, timetableRemote, timetableNotificationSchedulerHelper).getTimetable(
+ student = student,
+ semester = semesterMock,
+ start = LocalDate.of(2019, 12, 23),
+ end = LocalDate.of(2019, 12, 25),
+ forceRefresh = true
+ )
+ }
assertEquals(12, lessons.size)
diff --git a/app/src/main/java/io/github/wulkanowy/data/RepositoryModule.kt b/app/src/main/java/io/github/wulkanowy/data/RepositoryModule.kt
index 19af1b2f8..6ece2d978 100644
--- a/app/src/main/java/io/github/wulkanowy/data/RepositoryModule.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/RepositoryModule.kt
@@ -8,8 +8,6 @@ import androidx.preference.PreferenceManager
import com.chuckerteam.chucker.api.ChuckerCollector
import com.chuckerteam.chucker.api.ChuckerInterceptor
import com.chuckerteam.chucker.api.RetentionManager
-import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
-import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.strategy.WalledGardenInternetObservingStrategy
import dagger.Module
import dagger.Provides
import io.github.wulkanowy.data.db.AppDatabase
@@ -22,14 +20,6 @@ import javax.inject.Singleton
@Module
internal class RepositoryModule {
- @Singleton
- @Provides
- fun provideInternetObservingSettings(): InternetObservingSettings {
- return InternetObservingSettings.builder()
- .strategy(WalledGardenInternetObservingStrategy())
- .build()
- }
-
@Singleton
@Provides
fun provideSdk(chuckerCollector: ChuckerCollector, context: Context): Sdk {
diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/AttendanceDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/AttendanceDao.kt
index 3eb57473d..49527a553 100644
--- a/app/src/main/java/io/github/wulkanowy/data/db/dao/AttendanceDao.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/AttendanceDao.kt
@@ -3,7 +3,6 @@ package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.Attendance
-import io.reactivex.Maybe
import org.threeten.bp.LocalDate
import javax.inject.Singleton
@@ -12,5 +11,5 @@ import javax.inject.Singleton
interface AttendanceDao : BaseDao {
@Query("SELECT * FROM Attendance WHERE diary_id = :diaryId AND student_id = :studentId AND date >= :from AND date <= :end")
- fun loadAll(diaryId: Int, studentId: Int, from: LocalDate, end: LocalDate): Maybe>
+ suspend fun loadAll(diaryId: Int, studentId: Int, from: LocalDate, end: LocalDate): List
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/AttendanceSummaryDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/AttendanceSummaryDao.kt
index fd58533f1..1ba37c959 100644
--- a/app/src/main/java/io/github/wulkanowy/data/db/dao/AttendanceSummaryDao.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/AttendanceSummaryDao.kt
@@ -3,11 +3,10 @@ package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.AttendanceSummary
-import io.reactivex.Maybe
@Dao
interface AttendanceSummaryDao : BaseDao {
@Query("SELECT * FROM AttendanceSummary WHERE diary_id = :diaryId AND student_id = :studentId AND subject_id = :subjectId")
- fun loadAll(diaryId: Int, studentId: Int, subjectId: Int): Maybe>
+ suspend fun loadAll(diaryId: Int, studentId: Int, subjectId: Int): List
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/BaseDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/BaseDao.kt
index 32dbadb86..048e9e3cd 100644
--- a/app/src/main/java/io/github/wulkanowy/data/db/dao/BaseDao.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/BaseDao.kt
@@ -7,11 +7,11 @@ import androidx.room.Update
interface BaseDao {
@Insert
- fun insertAll(items: List): List
+ suspend fun insertAll(items: List): List
@Update
- fun updateAll(items: List)
+ suspend fun updateAll(items: List)
@Delete
- fun deleteAll(items: List)
+ suspend fun deleteAll(items: List)
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/CompletedLessonsDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/CompletedLessonsDao.kt
index e13e569b6..6406d097d 100644
--- a/app/src/main/java/io/github/wulkanowy/data/db/dao/CompletedLessonsDao.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/CompletedLessonsDao.kt
@@ -3,7 +3,6 @@ package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.CompletedLesson
-import io.reactivex.Maybe
import org.threeten.bp.LocalDate
import javax.inject.Singleton
@@ -12,5 +11,5 @@ import javax.inject.Singleton
interface CompletedLessonsDao : BaseDao {
@Query("SELECT * FROM CompletedLesson WHERE diary_id = :diaryId AND student_id = :studentId AND date >= :from AND date <= :end")
- fun loadAll(diaryId: Int, studentId: Int, from: LocalDate, end: LocalDate): Maybe>
+ suspend fun loadAll(diaryId: Int, studentId: Int, from: LocalDate, end: LocalDate): List
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/ExamDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/ExamDao.kt
index ca6b32dfc..e492f7b84 100644
--- a/app/src/main/java/io/github/wulkanowy/data/db/dao/ExamDao.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/ExamDao.kt
@@ -3,7 +3,6 @@ package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.Exam
-import io.reactivex.Maybe
import org.threeten.bp.LocalDate
import javax.inject.Singleton
@@ -12,5 +11,5 @@ import javax.inject.Singleton
interface ExamDao : BaseDao {
@Query("SELECT * FROM Exams WHERE diary_id = :diaryId AND student_id = :studentId AND date >= :from AND date <= :end")
- fun loadAll(diaryId: Int, studentId: Int, from: LocalDate, end: LocalDate): Maybe>
+ suspend fun loadAll(diaryId: Int, studentId: Int, from: LocalDate, end: LocalDate): List
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/GradeDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/GradeDao.kt
index c74d1937f..df0276203 100644
--- a/app/src/main/java/io/github/wulkanowy/data/db/dao/GradeDao.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/GradeDao.kt
@@ -3,7 +3,6 @@ package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.Grade
-import io.reactivex.Maybe
import javax.inject.Singleton
@Singleton
@@ -11,6 +10,5 @@ import javax.inject.Singleton
interface GradeDao : BaseDao {
@Query("SELECT * FROM Grades WHERE semester_id = :semesterId AND student_id = :studentId")
- fun loadAll(semesterId: Int, studentId: Int): Maybe>
-
+ suspend fun loadAll(semesterId: Int, studentId: Int): List
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/GradePointsStatisticsDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/GradePointsStatisticsDao.kt
index da1828666..b1e644bbd 100644
--- a/app/src/main/java/io/github/wulkanowy/data/db/dao/GradePointsStatisticsDao.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/GradePointsStatisticsDao.kt
@@ -3,7 +3,6 @@ package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.GradePointsStatistics
-import io.reactivex.Maybe
import javax.inject.Singleton
@Singleton
@@ -11,8 +10,8 @@ import javax.inject.Singleton
interface GradePointsStatisticsDao : BaseDao {
@Query("SELECT * FROM GradesPointsStatistics WHERE student_id = :studentId AND semester_id = :semesterId AND subject = :subjectName")
- fun loadSubject(semesterId: Int, studentId: Int, subjectName: String): Maybe>
+ suspend fun loadSubject(semesterId: Int, studentId: Int, subjectName: String): List
@Query("SELECT * FROM GradesPointsStatistics WHERE student_id = :studentId AND semester_id = :semesterId")
- fun loadAll(semesterId: Int, studentId: Int): Maybe>
+ suspend fun loadAll(semesterId: Int, studentId: Int): List
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/GradeStatisticsDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/GradeStatisticsDao.kt
index 6faa35d0b..786da0d9e 100644
--- a/app/src/main/java/io/github/wulkanowy/data/db/dao/GradeStatisticsDao.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/GradeStatisticsDao.kt
@@ -3,7 +3,6 @@ package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.GradeStatistics
-import io.reactivex.Maybe
import javax.inject.Singleton
@Singleton
@@ -11,8 +10,8 @@ import javax.inject.Singleton
interface GradeStatisticsDao : BaseDao {
@Query("SELECT * FROM GradesStatistics WHERE student_id = :studentId AND semester_id = :semesterId AND subject = :subjectName AND is_semester = :isSemester")
- fun loadSubject(semesterId: Int, studentId: Int, subjectName: String, isSemester: Boolean): Maybe>
+ suspend fun loadSubject(semesterId: Int, studentId: Int, subjectName: String, isSemester: Boolean): List
@Query("SELECT * FROM GradesStatistics WHERE student_id = :studentId AND semester_id = :semesterId AND is_semester = :isSemester")
- fun loadAll(semesterId: Int, studentId: Int, isSemester: Boolean): Maybe>
+ suspend fun loadAll(semesterId: Int, studentId: Int, isSemester: Boolean): List
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/GradeSummaryDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/GradeSummaryDao.kt
index 1165ef07f..02d4e9229 100644
--- a/app/src/main/java/io/github/wulkanowy/data/db/dao/GradeSummaryDao.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/GradeSummaryDao.kt
@@ -3,7 +3,6 @@ package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.GradeSummary
-import io.reactivex.Maybe
import javax.inject.Singleton
@Singleton
@@ -11,5 +10,5 @@ import javax.inject.Singleton
interface GradeSummaryDao : BaseDao {
@Query("SELECT * FROM GradesSummary WHERE student_id = :studentId AND semester_id = :semesterId")
- fun loadAll(semesterId: Int, studentId: Int): Maybe>
+ suspend fun loadAll(semesterId: Int, studentId: Int): List
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/HomeworkDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/HomeworkDao.kt
index 1947a0dfe..9bbf80ace 100644
--- a/app/src/main/java/io/github/wulkanowy/data/db/dao/HomeworkDao.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/HomeworkDao.kt
@@ -3,7 +3,6 @@ package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.Homework
-import io.reactivex.Maybe
import org.threeten.bp.LocalDate
import javax.inject.Singleton
@@ -12,5 +11,5 @@ import javax.inject.Singleton
interface HomeworkDao : BaseDao {
@Query("SELECT * FROM Homework WHERE semester_id = :semesterId AND student_id = :studentId AND date >= :from AND date <= :end")
- fun loadAll(semesterId: Int, studentId: Int, from: LocalDate, end: LocalDate): Maybe>
+ suspend fun loadAll(semesterId: Int, studentId: Int, from: LocalDate, end: LocalDate): List
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/LuckyNumberDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/LuckyNumberDao.kt
index f16c28d9e..b4ead2454 100644
--- a/app/src/main/java/io/github/wulkanowy/data/db/dao/LuckyNumberDao.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/LuckyNumberDao.kt
@@ -3,7 +3,6 @@ package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.LuckyNumber
-import io.reactivex.Maybe
import org.threeten.bp.LocalDate
import javax.inject.Singleton
@@ -12,5 +11,5 @@ import javax.inject.Singleton
interface LuckyNumberDao : BaseDao {
@Query("SELECT * FROM LuckyNumbers WHERE student_id = :studentId AND date = :date")
- fun load(studentId: Int, date: LocalDate): Maybe
+ suspend fun load(studentId: Int, date: LocalDate): LuckyNumber
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/MessageAttachmentDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/MessageAttachmentDao.kt
index 3c511a277..b69083a1a 100644
--- a/app/src/main/java/io/github/wulkanowy/data/db/dao/MessageAttachmentDao.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/MessageAttachmentDao.kt
@@ -9,5 +9,5 @@ import io.github.wulkanowy.data.db.entities.MessageAttachment
interface MessageAttachmentDao : BaseDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
- fun insertAttachments(items: List): List
+ suspend fun insertAttachments(items: List): List
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/MessagesDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/MessagesDao.kt
index 7a69e2707..2757978ae 100644
--- a/app/src/main/java/io/github/wulkanowy/data/db/dao/MessagesDao.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/MessagesDao.kt
@@ -5,19 +5,17 @@ import androidx.room.Query
import androidx.room.Transaction
import io.github.wulkanowy.data.db.entities.Message
import io.github.wulkanowy.data.db.entities.MessageWithAttachment
-import io.reactivex.Maybe
-import io.reactivex.Single
@Dao
interface MessagesDao : BaseDao {
@Transaction
@Query("SELECT * FROM Messages WHERE student_id = :studentId AND message_id = :messageId")
- fun loadMessageWithAttachment(studentId: Int, messageId: Int): Single
+ suspend fun loadMessageWithAttachment(studentId: Int, messageId: Int): MessageWithAttachment
@Query("SELECT * FROM Messages WHERE student_id = :studentId AND folder_id = :folder AND removed = 0 ORDER BY date DESC")
- fun loadAll(studentId: Int, folder: Int): Maybe>
+ suspend fun loadAll(studentId: Int, folder: Int): List
@Query("SELECT * FROM Messages WHERE student_id = :studentId AND removed = 1 ORDER BY date DESC")
- fun loadDeleted(studentId: Int): Maybe>
+ suspend fun loadDeleted(studentId: Int): List
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/MobileDeviceDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/MobileDeviceDao.kt
index b05b2d9cc..b07aab284 100644
--- a/app/src/main/java/io/github/wulkanowy/data/db/dao/MobileDeviceDao.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/MobileDeviceDao.kt
@@ -3,11 +3,10 @@ package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.MobileDevice
-import io.reactivex.Maybe
@Dao
interface MobileDeviceDao : BaseDao {
@Query("SELECT * FROM MobileDevices WHERE student_id = :studentId ORDER BY date DESC")
- fun loadAll(studentId: Int): Maybe>
+ suspend fun loadAll(studentId: Int): List
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/NoteDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/NoteDao.kt
index ea2fc6eb2..81c324f65 100644
--- a/app/src/main/java/io/github/wulkanowy/data/db/dao/NoteDao.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/NoteDao.kt
@@ -3,7 +3,6 @@ package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.Note
-import io.reactivex.Maybe
import javax.inject.Singleton
@Singleton
@@ -11,5 +10,5 @@ import javax.inject.Singleton
interface NoteDao : BaseDao {
@Query("SELECT * FROM Notes WHERE student_id = :studentId")
- fun loadAll(studentId: Int): Maybe>
+ suspend fun loadAll(studentId: Int): List
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/RecipientDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/RecipientDao.kt
index afb941b1a..419efde0d 100644
--- a/app/src/main/java/io/github/wulkanowy/data/db/dao/RecipientDao.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/RecipientDao.kt
@@ -3,7 +3,6 @@ package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.Recipient
-import io.reactivex.Maybe
import javax.inject.Singleton
@Singleton
@@ -11,5 +10,5 @@ import javax.inject.Singleton
interface RecipientDao : BaseDao {
@Query("SELECT * FROM Recipients WHERE student_id = :studentId AND role = :role AND unit_id = :unitId")
- fun load(studentId: Int, role: Int, unitId: Int): Maybe>
+ suspend fun load(studentId: Int, role: Int, unitId: Int): List
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/ReportingUnitDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/ReportingUnitDao.kt
index 6ddfd4941..ca697eda8 100644
--- a/app/src/main/java/io/github/wulkanowy/data/db/dao/ReportingUnitDao.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/ReportingUnitDao.kt
@@ -3,7 +3,6 @@ package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.ReportingUnit
-import io.reactivex.Maybe
import javax.inject.Singleton
@Singleton
@@ -11,8 +10,8 @@ import javax.inject.Singleton
interface ReportingUnitDao : BaseDao {
@Query("SELECT * FROM ReportingUnits WHERE student_id = :studentId")
- fun load(studentId: Int): Maybe>
+ suspend fun load(studentId: Int): List
@Query("SELECT * FROM ReportingUnits WHERE student_id = :studentId AND real_id = :unitId")
- fun loadOne(studentId: Int, unitId: Int): Maybe
+ suspend fun loadOne(studentId: Int, unitId: Int): ReportingUnit?
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/SchoolDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/SchoolDao.kt
index e9bd67557..37cb6c500 100644
--- a/app/src/main/java/io/github/wulkanowy/data/db/dao/SchoolDao.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/SchoolDao.kt
@@ -3,7 +3,6 @@ package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.School
-import io.reactivex.Maybe
import javax.inject.Singleton
@Singleton
@@ -11,5 +10,5 @@ import javax.inject.Singleton
interface SchoolDao : BaseDao {
@Query("SELECT * FROM School WHERE student_id = :studentId AND class_id = :classId")
- fun load(studentId: Int, classId: Int): Maybe
+ suspend fun load(studentId: Int, classId: Int): School?
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/SemesterDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/SemesterDao.kt
index 654b80f38..bbbc9b4e2 100644
--- a/app/src/main/java/io/github/wulkanowy/data/db/dao/SemesterDao.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/SemesterDao.kt
@@ -3,7 +3,6 @@ package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.Semester
-import io.reactivex.Maybe
import javax.inject.Singleton
@Singleton
@@ -11,5 +10,5 @@ import javax.inject.Singleton
interface SemesterDao : BaseDao {
@Query("SELECT * FROM Semesters WHERE student_id = :studentId AND class_id = :classId")
- fun loadAll(studentId: Int, classId: Int): Maybe>
+ suspend fun loadAll(studentId: Int, classId: Int): List
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/StudentDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/StudentDao.kt
index 901ddc73f..3d7d9216e 100644
--- a/app/src/main/java/io/github/wulkanowy/data/db/dao/StudentDao.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/StudentDao.kt
@@ -6,7 +6,6 @@ import androidx.room.Insert
import androidx.room.OnConflictStrategy.ABORT
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.Student
-import io.reactivex.Maybe
import javax.inject.Singleton
@Singleton
@@ -14,23 +13,23 @@ import javax.inject.Singleton
interface StudentDao {
@Insert(onConflict = ABORT)
- fun insertAll(student: List): List
+ suspend fun insertAll(student: List): List
@Delete
- fun delete(student: Student)
+ suspend fun delete(student: Student)
@Query("SELECT * FROM Students WHERE is_current = 1")
- fun loadCurrent(): Maybe
+ suspend fun loadCurrent(): Student?
@Query("SELECT * FROM Students WHERE id = :id")
- fun loadById(id: Int): Maybe
+ suspend fun loadById(id: Int): Student?
@Query("SELECT * FROM Students")
- fun loadAll(): Maybe>
+ suspend fun loadAll(): List
@Query("UPDATE Students SET is_current = 1 WHERE id = :id")
- fun updateCurrent(id: Long)
+ suspend fun updateCurrent(id: Long)
@Query("UPDATE Students SET is_current = 0")
- fun resetCurrent()
+ suspend fun resetCurrent()
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/SubjectDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/SubjectDao.kt
index 525a7129a..92477552c 100644
--- a/app/src/main/java/io/github/wulkanowy/data/db/dao/SubjectDao.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/SubjectDao.kt
@@ -3,11 +3,10 @@ package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.Subject
-import io.reactivex.Maybe
@Dao
interface SubjectDao : BaseDao {
@Query("SELECT * FROM Subjects WHERE diary_id = :diaryId AND student_id = :studentId")
- fun loadAll(diaryId: Int, studentId: Int): Maybe>
+ suspend fun loadAll(diaryId: Int, studentId: Int): List
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/TeacherDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/TeacherDao.kt
index 5ea237a84..0b0e659b4 100644
--- a/app/src/main/java/io/github/wulkanowy/data/db/dao/TeacherDao.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/TeacherDao.kt
@@ -3,7 +3,6 @@ package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.Teacher
-import io.reactivex.Maybe
import javax.inject.Singleton
@Singleton
@@ -11,5 +10,5 @@ import javax.inject.Singleton
interface TeacherDao : BaseDao {
@Query("SELECT * FROM Teachers WHERE student_id = :studentId AND class_id = :classId")
- fun loadAll(studentId: Int, classId: Int): Maybe>
+ suspend fun loadAll(studentId: Int, classId: Int): List
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/TimetableDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/TimetableDao.kt
index 6b62cc82a..59200b80b 100644
--- a/app/src/main/java/io/github/wulkanowy/data/db/dao/TimetableDao.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/TimetableDao.kt
@@ -3,7 +3,6 @@ package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.Timetable
-import io.reactivex.Maybe
import org.threeten.bp.LocalDate
import javax.inject.Singleton
@@ -12,5 +11,5 @@ import javax.inject.Singleton
interface TimetableDao : BaseDao {
@Query("SELECT * FROM Timetable WHERE diary_id = :diaryId AND student_id = :studentId AND date >= :from AND date <= :end")
- fun loadAll(diaryId: Int, studentId: Int, from: LocalDate, end: LocalDate): Maybe>
+ suspend fun loadAll(diaryId: Int, studentId: Int, from: LocalDate, end: LocalDate): List
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/appcreator/AppCreatorRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/appcreator/AppCreatorRepository.kt
index 76cf698c9..3fcd7cb57 100644
--- a/app/src/main/java/io/github/wulkanowy/data/repositories/appcreator/AppCreatorRepository.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/repositories/appcreator/AppCreatorRepository.kt
@@ -3,14 +3,19 @@ package io.github.wulkanowy.data.repositories.appcreator
import android.content.res.AssetManager
import com.google.gson.Gson
import io.github.wulkanowy.data.pojos.Contributor
-import io.reactivex.Single
+import io.github.wulkanowy.utils.DispatchersProvider
+import kotlinx.coroutines.withContext
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
-class AppCreatorRepository @Inject constructor(private val assets: AssetManager) {
- fun getAppCreators(): Single> {
- return Single.fromCallable {
+class AppCreatorRepository @Inject constructor(
+ private val assets: AssetManager,
+ private val dispatchers: DispatchersProvider
+) {
+
+ suspend fun getAppCreators(): List {
+ return withContext(dispatchers.backgroundThread) {
Gson().fromJson(
assets.open("contributors.json").bufferedReader().use { it.readText() },
Array::class.java
diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/attendance/AttendanceLocal.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/attendance/AttendanceLocal.kt
index 0f5873766..b232033d1 100644
--- a/app/src/main/java/io/github/wulkanowy/data/repositories/attendance/AttendanceLocal.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/repositories/attendance/AttendanceLocal.kt
@@ -3,7 +3,6 @@ package io.github.wulkanowy.data.repositories.attendance
import io.github.wulkanowy.data.db.dao.AttendanceDao
import io.github.wulkanowy.data.db.entities.Attendance
import io.github.wulkanowy.data.db.entities.Semester
-import io.reactivex.Maybe
import org.threeten.bp.LocalDate
import javax.inject.Inject
import javax.inject.Singleton
@@ -11,15 +10,15 @@ import javax.inject.Singleton
@Singleton
class AttendanceLocal @Inject constructor(private val attendanceDb: AttendanceDao) {
- fun saveAttendance(attendance: List) {
+ suspend fun saveAttendance(attendance: List) {
attendanceDb.insertAll(attendance)
}
- fun deleteAttendance(attendance: List) {
+ suspend fun deleteAttendance(attendance: List) {
attendanceDb.deleteAll(attendance)
}
- fun getAttendance(semester: Semester, startDate: LocalDate, endDate: LocalDate): Maybe> {
- return attendanceDb.loadAll(semester.diaryId, semester.studentId, startDate, endDate).filter { it.isNotEmpty() }
+ suspend fun getAttendance(semester: Semester, startDate: LocalDate, endDate: LocalDate): List {
+ return attendanceDb.loadAll(semester.diaryId, semester.studentId, startDate, endDate)
}
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/attendance/AttendanceRemote.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/attendance/AttendanceRemote.kt
index f64d920db..1f794f5a2 100644
--- a/app/src/main/java/io/github/wulkanowy/data/repositories/attendance/AttendanceRemote.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/repositories/attendance/AttendanceRemote.kt
@@ -6,7 +6,6 @@ import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.sdk.pojo.Absent
import io.github.wulkanowy.utils.init
-import io.reactivex.Single
import org.threeten.bp.LocalDate
import org.threeten.bp.LocalDateTime
import org.threeten.bp.LocalTime
@@ -16,33 +15,31 @@ import javax.inject.Singleton
@Singleton
class AttendanceRemote @Inject constructor(private val sdk: Sdk) {
- fun getAttendance(student: Student, semester: Semester, startDate: LocalDate, endDate: LocalDate): Single> {
+ suspend fun getAttendance(student: Student, semester: Semester, startDate: LocalDate, endDate: LocalDate): List {
return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear)
.getAttendance(startDate, endDate, semester.semesterId)
- .map { attendance ->
- attendance.map {
- Attendance(
- studentId = semester.studentId,
- diaryId = semester.diaryId,
- date = it.date,
- timeId = it.timeId,
- number = it.number,
- subject = it.subject,
- name = it.name,
- presence = it.presence,
- absence = it.absence,
- exemption = it.exemption,
- lateness = it.lateness,
- excused = it.excused,
- deleted = it.deleted,
- excusable = it.excusable,
- excuseStatus = it.excuseStatus?.name
- )
- }
+ .map {
+ Attendance(
+ studentId = semester.studentId,
+ diaryId = semester.diaryId,
+ date = it.date,
+ timeId = it.timeId,
+ number = it.number,
+ subject = it.subject,
+ name = it.name,
+ presence = it.presence,
+ absence = it.absence,
+ exemption = it.exemption,
+ lateness = it.lateness,
+ excused = it.excused,
+ deleted = it.deleted,
+ excusable = it.excusable,
+ excuseStatus = it.excuseStatus?.name
+ )
}
}
- fun excuseAbsence(student: Student, semester: Semester, absenceList: List, reason: String?): Single {
+ suspend fun excuseAbsence(student: Student, semester: Semester, absenceList: List, reason: String?): Boolean {
return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear).excuseForAbsence(absenceList.map { attendance ->
Absent(
date = LocalDateTime.of(attendance.date, LocalTime.of(0, 0)),
diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/attendance/AttendanceRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/attendance/AttendanceRepository.kt
index 68e7c5f12..0fa0090e7 100644
--- a/app/src/main/java/io/github/wulkanowy/data/repositories/attendance/AttendanceRepository.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/repositories/attendance/AttendanceRepository.kt
@@ -1,45 +1,34 @@
package io.github.wulkanowy.data.repositories.attendance
-import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
-import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
import io.github.wulkanowy.data.db.entities.Attendance
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
-import io.github.wulkanowy.utils.sunday
import io.github.wulkanowy.utils.monday
+import io.github.wulkanowy.utils.sunday
import io.github.wulkanowy.utils.uniqueSubtract
-import io.reactivex.Single
import org.threeten.bp.LocalDate
-import java.net.UnknownHostException
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class AttendanceRepository @Inject constructor(
- private val settings: InternetObservingSettings,
private val local: AttendanceLocal,
private val remote: AttendanceRemote
) {
- fun getAttendance(student: Student, semester: Semester, start: LocalDate, end: LocalDate, forceRefresh: Boolean): Single> {
- return local.getAttendance(semester, start.monday, end.sunday).filter { !forceRefresh }
- .switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings).flatMap {
- if (it) remote.getAttendance(student, semester, start.monday, end.sunday)
- else Single.error(UnknownHostException())
- }.flatMap { newAttendance ->
- local.getAttendance(semester, start.monday, end.sunday)
- .toSingle(emptyList())
- .doOnSuccess { oldAttendance ->
- local.deleteAttendance(oldAttendance.uniqueSubtract(newAttendance))
- local.saveAttendance(newAttendance.uniqueSubtract(oldAttendance))
- }
- }.flatMap {
- local.getAttendance(semester, start.monday, end.sunday)
- .toSingle(emptyList())
- }).map { list -> list.filter { it.date in start..end } }
+ suspend fun getAttendance(student: Student, semester: Semester, start: LocalDate, end: LocalDate, forceRefresh: Boolean): List {
+ return local.getAttendance(semester, start.monday, end.sunday).filter { !forceRefresh }.ifEmpty {
+ val new = remote.getAttendance(student, semester, start.monday, end.sunday)
+ val old = local.getAttendance(semester, start.monday, end.sunday)
+
+ local.deleteAttendance(old.uniqueSubtract(new))
+ local.saveAttendance(new.uniqueSubtract(old))
+
+ local.getAttendance(semester, start.monday, end.sunday)
+ }.filter { it.date in start..end }
}
- fun excuseForAbsence(student: Student, semester: Semester, attendanceList: List, reason: String? = null): Single {
+ suspend fun excuseForAbsence(student: Student, semester: Semester, attendanceList: List, reason: String? = null): Boolean {
return remote.excuseAbsence(student, semester, attendanceList, reason)
}
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/attendancesummary/AttendanceSummaryLocal.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/attendancesummary/AttendanceSummaryLocal.kt
index 2e9a10067..f949f0163 100644
--- a/app/src/main/java/io/github/wulkanowy/data/repositories/attendancesummary/AttendanceSummaryLocal.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/repositories/attendancesummary/AttendanceSummaryLocal.kt
@@ -3,22 +3,21 @@ package io.github.wulkanowy.data.repositories.attendancesummary
import io.github.wulkanowy.data.db.dao.AttendanceSummaryDao
import io.github.wulkanowy.data.db.entities.AttendanceSummary
import io.github.wulkanowy.data.db.entities.Semester
-import io.reactivex.Maybe
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class AttendanceSummaryLocal @Inject constructor(private val attendanceDb: AttendanceSummaryDao) {
- fun saveAttendanceSummary(attendance: List) {
+ suspend fun saveAttendanceSummary(attendance: List) {
attendanceDb.insertAll(attendance)
}
- fun deleteAttendanceSummary(attendance: List) {
+ suspend fun deleteAttendanceSummary(attendance: List) {
attendanceDb.deleteAll(attendance)
}
- fun getAttendanceSummary(semester: Semester, subjectId: Int): Maybe> {
- return attendanceDb.loadAll(semester.diaryId, semester.studentId, subjectId).filter { it.isNotEmpty() }
+ suspend fun getAttendanceSummary(semester: Semester, subjectId: Int): List {
+ return attendanceDb.loadAll(semester.diaryId, semester.studentId, subjectId)
}
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/attendancesummary/AttendanceSummaryRemote.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/attendancesummary/AttendanceSummaryRemote.kt
index 8fef5c391..29a0b9a7b 100644
--- a/app/src/main/java/io/github/wulkanowy/data/repositories/attendancesummary/AttendanceSummaryRemote.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/repositories/attendancesummary/AttendanceSummaryRemote.kt
@@ -5,32 +5,29 @@ import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.utils.init
-import io.reactivex.Single
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class AttendanceSummaryRemote @Inject constructor(private val sdk: Sdk) {
- fun getAttendanceSummary(student: Student, semester: Semester, subjectId: Int): Single> {
+ suspend fun getAttendanceSummary(student: Student, semester: Semester, subjectId: Int): List {
return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear)
.getAttendanceSummary(subjectId)
- .map { attendance ->
- attendance.map {
- AttendanceSummary(
- studentId = semester.studentId,
- diaryId = semester.diaryId,
- subjectId = subjectId,
- month = it.month,
- presence = it.presence,
- absence = it.absence,
- absenceExcused = it.absenceExcused,
- absenceForSchoolReasons = it.absenceForSchoolReasons,
- lateness = it.lateness,
- latenessExcused = it.latenessExcused,
- exemption = it.exemption
- )
- }
+ .map {
+ AttendanceSummary(
+ studentId = semester.studentId,
+ diaryId = semester.diaryId,
+ subjectId = subjectId,
+ month = it.month,
+ presence = it.presence,
+ absence = it.absence,
+ absenceExcused = it.absenceExcused,
+ absenceForSchoolReasons = it.absenceForSchoolReasons,
+ lateness = it.lateness,
+ latenessExcused = it.latenessExcused,
+ exemption = it.exemption
+ )
}
}
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/attendancesummary/AttendanceSummaryRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/attendancesummary/AttendanceSummaryRepository.kt
index 5f0b2b346..7ef16fb0f 100644
--- a/app/src/main/java/io/github/wulkanowy/data/repositories/attendancesummary/AttendanceSummaryRepository.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/repositories/attendancesummary/AttendanceSummaryRepository.kt
@@ -1,35 +1,27 @@
package io.github.wulkanowy.data.repositories.attendancesummary
-import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
-import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
import io.github.wulkanowy.data.db.entities.AttendanceSummary
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.utils.uniqueSubtract
-import io.reactivex.Single
-import java.net.UnknownHostException
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class AttendanceSummaryRepository @Inject constructor(
- private val settings: InternetObservingSettings,
private val local: AttendanceSummaryLocal,
private val remote: AttendanceSummaryRemote
) {
- fun getAttendanceSummary(student: Student, semester: Semester, subjectId: Int, forceRefresh: Boolean = false): Single> {
- return local.getAttendanceSummary(semester, subjectId).filter { !forceRefresh }
- .switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
- .flatMap {
- if (it) remote.getAttendanceSummary(student, semester, subjectId)
- else Single.error(UnknownHostException())
- }.flatMap { new ->
- local.getAttendanceSummary(semester, subjectId).toSingle(emptyList())
- .doOnSuccess { old ->
- local.deleteAttendanceSummary(old.uniqueSubtract(new))
- local.saveAttendanceSummary(new.uniqueSubtract(old))
- }
- }.flatMap { local.getAttendanceSummary(semester, subjectId).toSingle(emptyList()) })
+ suspend fun getAttendanceSummary(student: Student, semester: Semester, subjectId: Int, forceRefresh: Boolean = false): List {
+ return local.getAttendanceSummary(semester, subjectId).filter { !forceRefresh }.ifEmpty {
+ val new = remote.getAttendanceSummary(student, semester, subjectId)
+
+ val old = local.getAttendanceSummary(semester, subjectId)
+ local.deleteAttendanceSummary(old.uniqueSubtract(new))
+ local.saveAttendanceSummary(new.uniqueSubtract(old))
+
+ return local.getAttendanceSummary(semester, subjectId)
+ }
}
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/completedlessons/CompletedLessonsLocal.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/completedlessons/CompletedLessonsLocal.kt
index 9b275908e..f355f4166 100644
--- a/app/src/main/java/io/github/wulkanowy/data/repositories/completedlessons/CompletedLessonsLocal.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/repositories/completedlessons/CompletedLessonsLocal.kt
@@ -3,7 +3,6 @@ package io.github.wulkanowy.data.repositories.completedlessons
import io.github.wulkanowy.data.db.dao.CompletedLessonsDao
import io.github.wulkanowy.data.db.entities.CompletedLesson
import io.github.wulkanowy.data.db.entities.Semester
-import io.reactivex.Maybe
import org.threeten.bp.LocalDate
import javax.inject.Inject
import javax.inject.Singleton
@@ -11,15 +10,15 @@ import javax.inject.Singleton
@Singleton
class CompletedLessonsLocal @Inject constructor(private val completedLessonsDb: CompletedLessonsDao) {
- fun saveCompletedLessons(completedLessons: List) {
+ suspend fun saveCompletedLessons(completedLessons: List) {
completedLessonsDb.insertAll(completedLessons)
}
- fun deleteCompleteLessons(completedLessons: List) {
+ suspend fun deleteCompleteLessons(completedLessons: List) {
completedLessonsDb.deleteAll(completedLessons)
}
- fun getCompletedLessons(semester: Semester, start: LocalDate, end: LocalDate): Maybe> {
- return completedLessonsDb.loadAll(semester.diaryId, semester.studentId, start, end).filter { it.isNotEmpty() }
+ suspend fun getCompletedLessons(semester: Semester, start: LocalDate, end: LocalDate): List {
+ return completedLessonsDb.loadAll(semester.diaryId, semester.studentId, start, end)
}
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/completedlessons/CompletedLessonsRemote.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/completedlessons/CompletedLessonsRemote.kt
index bb115111e..b3d786058 100644
--- a/app/src/main/java/io/github/wulkanowy/data/repositories/completedlessons/CompletedLessonsRemote.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/repositories/completedlessons/CompletedLessonsRemote.kt
@@ -5,7 +5,6 @@ import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.utils.init
-import io.reactivex.Single
import org.threeten.bp.LocalDate
import javax.inject.Inject
import javax.inject.Singleton
@@ -13,26 +12,24 @@ import javax.inject.Singleton
@Singleton
class CompletedLessonsRemote @Inject constructor(private val sdk: Sdk) {
- fun getCompletedLessons(student: Student, semester: Semester, startDate: LocalDate, endDate: LocalDate): Single> {
+ suspend fun getCompletedLessons(student: Student, semester: Semester, startDate: LocalDate, endDate: LocalDate): List {
return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear)
.getCompletedLessons(startDate, endDate)
- .map { lessons ->
- lessons.map {
- it.absence
- CompletedLesson(
- studentId = semester.studentId,
- diaryId = semester.diaryId,
- date = it.date,
- number = it.number,
- subject = it.subject,
- topic = it.topic,
- teacher = it.teacher,
- teacherSymbol = it.teacherSymbol,
- substitution = it.substitution,
- absence = it.absence,
- resources = it.resources
- )
- }
+ .map {
+ it.absence
+ CompletedLesson(
+ studentId = semester.studentId,
+ diaryId = semester.diaryId,
+ date = it.date,
+ number = it.number,
+ subject = it.subject,
+ topic = it.topic,
+ teacher = it.teacher,
+ teacherSymbol = it.teacherSymbol,
+ substitution = it.substitution,
+ absence = it.absence,
+ resources = it.resources
+ )
}
}
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/completedlessons/CompletedLessonsRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/completedlessons/CompletedLessonsRepository.kt
index 72cc93eb4..8e81c54ae 100644
--- a/app/src/main/java/io/github/wulkanowy/data/repositories/completedlessons/CompletedLessonsRepository.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/repositories/completedlessons/CompletedLessonsRepository.kt
@@ -1,42 +1,30 @@
package io.github.wulkanowy.data.repositories.completedlessons
-import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
-import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
import io.github.wulkanowy.data.db.entities.CompletedLesson
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
-import io.github.wulkanowy.utils.sunday
import io.github.wulkanowy.utils.monday
+import io.github.wulkanowy.utils.sunday
import io.github.wulkanowy.utils.uniqueSubtract
-import io.reactivex.Single
import org.threeten.bp.LocalDate
-import java.net.UnknownHostException
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class CompletedLessonsRepository @Inject constructor(
- private val settings: InternetObservingSettings,
private val local: CompletedLessonsLocal,
private val remote: CompletedLessonsRemote
) {
- fun getCompletedLessons(student: Student, semester: Semester, start: LocalDate, end: LocalDate, forceRefresh: Boolean = false): Single> {
- return local.getCompletedLessons(semester, start.monday, end.sunday).filter { !forceRefresh }
- .switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
- .flatMap {
- if (it) remote.getCompletedLessons(student, semester, start.monday, end.sunday)
- else Single.error(UnknownHostException())
- }.flatMap { new ->
- local.getCompletedLessons(semester, start.monday, end.sunday)
- .toSingle(emptyList())
- .doOnSuccess { old ->
- local.deleteCompleteLessons(old.uniqueSubtract(new))
- local.saveCompletedLessons(new.uniqueSubtract(old))
- }
- }.flatMap {
- local.getCompletedLessons(semester, start.monday, end.sunday)
- .toSingle(emptyList())
- }).map { list -> list.filter { it.date in start..end } }
+ suspend fun getCompletedLessons(student: Student, semester: Semester, start: LocalDate, end: LocalDate, forceRefresh: Boolean = false): List {
+ return local.getCompletedLessons(semester, start.monday, end.sunday).filter { !forceRefresh }.ifEmpty {
+ val new = remote.getCompletedLessons(student, semester, start.monday, end.sunday)
+ val old = local.getCompletedLessons(semester, start.monday, end.sunday)
+
+ local.deleteCompleteLessons(old.uniqueSubtract(new))
+ local.saveCompletedLessons(new.uniqueSubtract(old))
+
+ local.getCompletedLessons(semester, start.monday, end.sunday)
+ }.filter { it.date in start..end }
}
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/exam/ExamLocal.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/exam/ExamLocal.kt
index 389eb5835..d1888380a 100644
--- a/app/src/main/java/io/github/wulkanowy/data/repositories/exam/ExamLocal.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/repositories/exam/ExamLocal.kt
@@ -3,7 +3,6 @@ package io.github.wulkanowy.data.repositories.exam
import io.github.wulkanowy.data.db.dao.ExamDao
import io.github.wulkanowy.data.db.entities.Exam
import io.github.wulkanowy.data.db.entities.Semester
-import io.reactivex.Maybe
import org.threeten.bp.LocalDate
import javax.inject.Inject
import javax.inject.Singleton
@@ -11,16 +10,15 @@ import javax.inject.Singleton
@Singleton
class ExamLocal @Inject constructor(private val examDb: ExamDao) {
- fun getExams(semester: Semester, startDate: LocalDate, endDate: LocalDate): Maybe> {
+ suspend fun getExams(semester: Semester, startDate: LocalDate, endDate: LocalDate): List {
return examDb.loadAll(semester.diaryId, semester.studentId, startDate, endDate)
- .filter { it.isNotEmpty() }
}
- fun saveExams(exams: List) {
+ suspend fun saveExams(exams: List) {
examDb.insertAll(exams)
}
- fun deleteExams(exams: List) {
+ suspend fun deleteExams(exams: List) {
examDb.deleteAll(exams)
}
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/exam/ExamRemote.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/exam/ExamRemote.kt
index fb105ceee..0668b5c14 100644
--- a/app/src/main/java/io/github/wulkanowy/data/repositories/exam/ExamRemote.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/repositories/exam/ExamRemote.kt
@@ -5,7 +5,6 @@ import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.utils.init
-import io.reactivex.Single
import org.threeten.bp.LocalDate
import javax.inject.Inject
import javax.inject.Singleton
@@ -13,24 +12,22 @@ import javax.inject.Singleton
@Singleton
class ExamRemote @Inject constructor(private val sdk: Sdk) {
- fun getExams(student: Student, semester: Semester, startDate: LocalDate, endDate: LocalDate): Single> {
+ suspend fun getExams(student: Student, semester: Semester, startDate: LocalDate, endDate: LocalDate): List {
return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear)
.getExams(startDate, endDate, semester.semesterId)
- .map { exams ->
- exams.map {
- Exam(
- studentId = semester.studentId,
- diaryId = semester.diaryId,
- date = it.date,
- entryDate = it.entryDate,
- subject = it.subject,
- group = it.group,
- type = it.type,
- description = it.description,
- teacher = it.teacher,
- teacherSymbol = it.teacherSymbol
- )
- }
+ .map {
+ Exam(
+ studentId = semester.studentId,
+ diaryId = semester.diaryId,
+ date = it.date,
+ entryDate = it.entryDate,
+ subject = it.subject,
+ group = it.group,
+ type = it.type,
+ description = it.description,
+ teacher = it.teacher,
+ teacherSymbol = it.teacherSymbol
+ )
}
}
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/exam/ExamRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/exam/ExamRepository.kt
index f29e4fdf8..13af62c5b 100644
--- a/app/src/main/java/io/github/wulkanowy/data/repositories/exam/ExamRepository.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/repositories/exam/ExamRepository.kt
@@ -1,42 +1,30 @@
package io.github.wulkanowy.data.repositories.exam
-import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
-import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
import io.github.wulkanowy.data.db.entities.Exam
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
-import io.github.wulkanowy.utils.sunday
import io.github.wulkanowy.utils.monday
+import io.github.wulkanowy.utils.sunday
import io.github.wulkanowy.utils.uniqueSubtract
-import io.reactivex.Single
import org.threeten.bp.LocalDate
-import java.net.UnknownHostException
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class ExamRepository @Inject constructor(
- private val settings: InternetObservingSettings,
private val local: ExamLocal,
private val remote: ExamRemote
) {
- fun getExams(student: Student, semester: Semester, start: LocalDate, end: LocalDate, forceRefresh: Boolean = false): Single> {
- return local.getExams(semester, start.monday, end.sunday).filter { !forceRefresh }
- .switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
- .flatMap {
- if (it) remote.getExams(student, semester, start.monday, end.sunday)
- else Single.error(UnknownHostException())
- }.flatMap { new ->
- local.getExams(semester, start.monday, end.sunday)
- .toSingle(emptyList())
- .doOnSuccess { old ->
- local.deleteExams(old.uniqueSubtract(new))
- local.saveExams(new.uniqueSubtract(old))
- }
- }.flatMap {
- local.getExams(semester, start.monday, end.sunday)
- .toSingle(emptyList())
- }).map { list -> list.filter { it.date in start..end } }
+ suspend fun getExams(student: Student, semester: Semester, start: LocalDate, end: LocalDate, forceRefresh: Boolean = false): List {
+ return local.getExams(semester, start.monday, end.sunday).filter { !forceRefresh }.ifEmpty {
+ val new = remote.getExams(student, semester, start.monday, end.sunday)
+ val old = local.getExams(semester, start.monday, end.sunday)
+
+ local.deleteExams(old.uniqueSubtract(new))
+ local.saveExams(new.uniqueSubtract(old))
+
+ local.getExams(semester, start.monday, end.sunday)
+ }.filter { it.date in start..end }
}
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/grade/GradeLocal.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/grade/GradeLocal.kt
index 52ab60178..234fc6b80 100644
--- a/app/src/main/java/io/github/wulkanowy/data/repositories/grade/GradeLocal.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/repositories/grade/GradeLocal.kt
@@ -5,7 +5,6 @@ import io.github.wulkanowy.data.db.dao.GradeSummaryDao
import io.github.wulkanowy.data.db.entities.Grade
import io.github.wulkanowy.data.db.entities.GradeSummary
import io.github.wulkanowy.data.db.entities.Semester
-import io.reactivex.Maybe
import javax.inject.Inject
import javax.inject.Singleton
@@ -15,35 +14,35 @@ class GradeLocal @Inject constructor(
private val gradeSummaryDb: GradeSummaryDao
) {
- fun saveGrades(grades: List) {
+ suspend fun saveGrades(grades: List) {
gradeDb.insertAll(grades)
}
- fun deleteGrades(grades: List) {
+ suspend fun deleteGrades(grades: List) {
gradeDb.deleteAll(grades)
}
- fun updateGrades(grades: List) {
+ suspend fun updateGrades(grades: List) {
gradeDb.updateAll(grades)
}
- fun updateGradesSummary(gradesSummary: List) {
+ suspend fun updateGradesSummary(gradesSummary: List) {
gradeSummaryDb.updateAll(gradesSummary)
}
- fun getGradesDetails(semester: Semester): Maybe> {
- return gradeDb.loadAll(semester.semesterId, semester.studentId).filter { it.isNotEmpty() }
+ suspend fun getGradesDetails(semester: Semester): List {
+ return gradeDb.loadAll(semester.semesterId, semester.studentId)
}
- fun saveGradesSummary(gradesSummary: List) {
+ suspend fun saveGradesSummary(gradesSummary: List) {
gradeSummaryDb.insertAll(gradesSummary)
}
- fun deleteGradesSummary(gradesSummary: List) {
+ suspend fun deleteGradesSummary(gradesSummary: List) {
gradeSummaryDb.deleteAll(gradesSummary)
}
- fun getGradesSummary(semester: Semester): Maybe> {
- return gradeSummaryDb.loadAll(semester.semesterId, semester.studentId).filter { it.isNotEmpty() }
+ suspend fun getGradesSummary(semester: Semester): List {
+ return gradeSummaryDb.loadAll(semester.semesterId, semester.studentId)
}
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/grade/GradeRemote.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/grade/GradeRemote.kt
index abb2f98c9..9534a8910 100644
--- a/app/src/main/java/io/github/wulkanowy/data/repositories/grade/GradeRemote.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/repositories/grade/GradeRemote.kt
@@ -6,48 +6,48 @@ import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.utils.init
-import io.reactivex.Single
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class GradeRemote @Inject constructor(private val sdk: Sdk) {
- fun getGrades(student: Student, semester: Semester): Single, List>> {
- return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear)
+ suspend fun getGrades(student: Student, semester: Semester): Pair, List> {
+ val (details, summary) = sdk
+ .init(student)
+ .switchDiary(semester.diaryId, semester.schoolYear)
.getGrades(semester.semesterId)
- .map { (details, summary) ->
- details.map {
- Grade(
- studentId = semester.studentId,
- semesterId = semester.semesterId,
- subject = it.subject,
- entry = it.entry,
- value = it.value,
- modifier = it.modifier,
- comment = it.comment,
- color = it.color,
- gradeSymbol = it.symbol,
- description = it.description,
- weight = it.weight,
- weightValue = it.weightValue,
- date = it.date,
- teacher = it.teacher
- )
- } to summary.map {
- GradeSummary(
- semesterId = semester.semesterId,
- studentId = semester.studentId,
- position = 0,
- subject = it.name,
- predictedGrade = it.predicted,
- finalGrade = it.final,
- pointsSum = it.pointsSum,
- proposedPoints = it.proposedPoints,
- finalPoints = it.finalPoints,
- average = it.average
- )
- }
- }
+
+ return details.map {
+ Grade(
+ studentId = semester.studentId,
+ semesterId = semester.semesterId,
+ subject = it.subject,
+ entry = it.entry,
+ value = it.value,
+ modifier = it.modifier,
+ comment = it.comment,
+ color = it.color,
+ gradeSymbol = it.symbol,
+ description = it.description,
+ weight = it.weight,
+ weightValue = it.weightValue,
+ date = it.date,
+ teacher = it.teacher
+ )
+ } to summary.map {
+ GradeSummary(
+ semesterId = semester.semesterId,
+ studentId = semester.studentId,
+ position = 0,
+ subject = it.name,
+ predictedGrade = it.predicted,
+ finalGrade = it.final,
+ pointsSum = it.pointsSum,
+ proposedPoints = it.proposedPoints,
+ finalPoints = it.finalPoints,
+ average = it.average
+ )
+ }
}
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/grade/GradeRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/grade/GradeRepository.kt
index 2ba68b967..6dcbb0657 100644
--- a/app/src/main/java/io/github/wulkanowy/data/repositories/grade/GradeRepository.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/repositories/grade/GradeRepository.kt
@@ -1,110 +1,96 @@
package io.github.wulkanowy.data.repositories.grade
-import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
-import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
import io.github.wulkanowy.data.db.entities.Grade
import io.github.wulkanowy.data.db.entities.GradeSummary
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.utils.uniqueSubtract
-import io.reactivex.Completable
-import io.reactivex.Single
import org.threeten.bp.LocalDateTime
-import java.net.UnknownHostException
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class GradeRepository @Inject constructor(
- private val settings: InternetObservingSettings,
private val local: GradeLocal,
private val remote: GradeRemote
) {
- fun getGrades(student: Student, semester: Semester, forceRefresh: Boolean = false, notify: Boolean = false): Single, List>> {
- return local.getGradesDetails(semester).flatMap { details ->
- local.getGradesSummary(semester).map { summary -> details to summary }
- }.filter { !forceRefresh }
- .switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings).flatMap {
- if (it) remote.getGrades(student, semester)
- else Single.error(UnknownHostException())
- }.flatMap { (newDetails, newSummary) ->
- local.getGradesDetails(semester).toSingle(emptyList())
- .doOnSuccess { old ->
- val notifyBreakDate = old.maxBy { it.date }?.date ?: student.registrationDate.toLocalDate()
- local.deleteGrades(old.uniqueSubtract(newDetails))
- local.saveGrades(newDetails.uniqueSubtract(old)
- .onEach {
- if (it.date >= notifyBreakDate) it.apply {
- isRead = false
- if (notify) isNotified = false
- }
- })
- }.flatMap {
- local.getGradesSummary(semester).toSingle(emptyList())
- .doOnSuccess { old ->
- local.deleteGradesSummary(old.uniqueSubtract(newSummary))
- local.saveGradesSummary(newSummary.uniqueSubtract(old)
- .onEach { summary ->
- val oldSummary = old.find { oldSummary -> oldSummary.subject == summary.subject }
- summary.isPredictedGradeNotified = when {
- summary.predictedGrade.isEmpty() -> true
- notify && oldSummary?.predictedGrade != summary.predictedGrade -> false
- else -> true
- }
- summary.isFinalGradeNotified = when {
- summary.finalGrade.isEmpty() -> true
- notify && oldSummary?.finalGrade != summary.finalGrade -> false
- else -> true
- }
+ suspend fun getGrades(student: Student, semester: Semester, forceRefresh: Boolean = false, notify: Boolean = false): Pair, List> {
+ val details = local.getGradesDetails(semester)
+ val summaries = local.getGradesSummary(semester)
- summary.predictedGradeLastChange = when {
- oldSummary == null -> LocalDateTime.now()
- summary.predictedGrade != oldSummary.predictedGrade -> LocalDateTime.now()
- else -> oldSummary.predictedGradeLastChange
- }
- summary.finalGradeLastChange = when {
- oldSummary == null -> LocalDateTime.now()
- summary.finalGrade != oldSummary.finalGrade -> LocalDateTime.now()
- else -> oldSummary.finalGradeLastChange
- }
- })
- }
- }
- }.flatMap {
- local.getGradesDetails(semester).toSingle(emptyList()).flatMap { details ->
- local.getGradesSummary(semester).toSingle(emptyList()).map { summary ->
- details to summary
- }
+ if ((details.isNotEmpty() || summaries.isNotEmpty()) && !forceRefresh) {
+ return details to summaries
+ }
+
+ val (newDetails, newSummary) = remote.getGrades(student, semester)
+ val oldGrades = local.getGradesDetails(semester)
+
+ val notifyBreakDate = oldGrades.maxBy { it.date }?.date ?: student.registrationDate.toLocalDate()
+ local.deleteGrades(oldGrades.uniqueSubtract(newDetails))
+ local.saveGrades(newDetails.uniqueSubtract(oldGrades).onEach {
+ if (it.date >= notifyBreakDate) it.apply {
+ isRead = false
+ if (notify) isNotified = false
}
})
+
+ val oldSummaries = local.getGradesSummary(semester)
+
+ local.deleteGradesSummary(oldSummaries.uniqueSubtract(newSummary))
+ local.saveGradesSummary(newSummary.uniqueSubtract(oldSummaries).onEach { summary ->
+ val oldSummary = oldSummaries.find { oldSummary -> oldSummary.subject == summary.subject }
+ summary.isPredictedGradeNotified = when {
+ summary.predictedGrade.isEmpty() -> true
+ notify && oldSummary?.predictedGrade != summary.predictedGrade -> false
+ else -> true
+ }
+ summary.isFinalGradeNotified = when {
+ summary.finalGrade.isEmpty() -> true
+ notify && oldSummary?.finalGrade != summary.finalGrade -> false
+ else -> true
+ }
+
+ summary.predictedGradeLastChange = when {
+ oldSummary == null -> LocalDateTime.now()
+ summary.predictedGrade != oldSummary.predictedGrade -> LocalDateTime.now()
+ else -> oldSummary.predictedGradeLastChange
+ }
+ summary.finalGradeLastChange = when {
+ oldSummary == null -> LocalDateTime.now()
+ summary.finalGrade != oldSummary.finalGrade -> LocalDateTime.now()
+ else -> oldSummary.finalGradeLastChange
+ }
+ })
+
+ return local.getGradesDetails(semester) to local.getGradesSummary(semester)
}
- fun getUnreadGrades(semester: Semester): Single> {
- return local.getGradesDetails(semester).map { it.filter { grade -> !grade.isRead } }.toSingle(emptyList())
+ suspend fun getUnreadGrades(semester: Semester): List {
+ return local.getGradesDetails(semester).filter { grade -> !grade.isRead }
}
- fun getNotNotifiedGrades(semester: Semester): Single> {
- return local.getGradesDetails(semester).map { it.filter { grade -> !grade.isNotified } }.toSingle(emptyList())
+ suspend fun getNotNotifiedGrades(semester: Semester): List {
+ return local.getGradesDetails(semester).filter { grade -> !grade.isNotified }
}
- fun getNotNotifiedPredictedGrades(semester: Semester): Single> {
- return local.getGradesSummary(semester).map { it.filter { gradeSummary -> !gradeSummary.isPredictedGradeNotified } }.toSingle(emptyList())
+ suspend fun getNotNotifiedPredictedGrades(semester: Semester): List {
+ return local.getGradesSummary(semester).filter { gradeSummary -> !gradeSummary.isPredictedGradeNotified }
}
- fun getNotNotifiedFinalGrades(semester: Semester): Single> {
- return local.getGradesSummary(semester).map { it.filter { gradeSummary -> !gradeSummary.isFinalGradeNotified } }.toSingle(emptyList())
+ suspend fun getNotNotifiedFinalGrades(semester: Semester): List {
+ return local.getGradesSummary(semester).filter { gradeSummary -> !gradeSummary.isFinalGradeNotified }
}
- fun updateGrade(grade: Grade): Completable {
- return Completable.fromCallable { local.updateGrades(listOf(grade)) }
+ suspend fun updateGrade(grade: Grade) {
+ return local.updateGrades(listOf(grade))
}
- fun updateGrades(grades: List): Completable {
- return Completable.fromCallable { local.updateGrades(grades) }
+ suspend fun updateGrades(grades: List) {
+ return local.updateGrades(grades)
}
- fun updateGradesSummary(gradesSummary: List): Completable {
- return Completable.fromCallable { local.updateGradesSummary(gradesSummary) }
+ suspend fun updateGradesSummary(gradesSummary: List) {
+ return local.updateGradesSummary(gradesSummary)
}
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/gradestatistics/GradeStatisticsLocal.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/gradestatistics/GradeStatisticsLocal.kt
index 7994bd758..d34f2b2ec 100644
--- a/app/src/main/java/io/github/wulkanowy/data/repositories/gradestatistics/GradeStatisticsLocal.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/repositories/gradestatistics/GradeStatisticsLocal.kt
@@ -5,7 +5,6 @@ import io.github.wulkanowy.data.db.dao.GradeStatisticsDao
import io.github.wulkanowy.data.db.entities.GradePointsStatistics
import io.github.wulkanowy.data.db.entities.GradeStatistics
import io.github.wulkanowy.data.db.entities.Semester
-import io.reactivex.Maybe
import javax.inject.Inject
import javax.inject.Singleton
@@ -15,46 +14,47 @@ class GradeStatisticsLocal @Inject constructor(
private val gradePointsStatisticsDb: GradePointsStatisticsDao
) {
- fun getGradesStatistics(semester: Semester, isSemester: Boolean): Maybe> {
- return gradeStatisticsDb.loadAll(semester.semesterId, semester.studentId, isSemester).filter { it.isNotEmpty() }
+ suspend fun getGradesStatistics(semester: Semester, isSemester: Boolean): List {
+ return gradeStatisticsDb.loadAll(semester.semesterId, semester.studentId, isSemester)
}
- fun getGradesPointsStatistics(semester: Semester): Maybe> {
- return gradePointsStatisticsDb.loadAll(semester.semesterId, semester.studentId).filter { it.isNotEmpty() }
+ suspend fun getGradesPointsStatistics(semester: Semester): List {
+ return gradePointsStatisticsDb.loadAll(semester.semesterId, semester.studentId)
}
- fun getGradesStatistics(semester: Semester, isSemester: Boolean, subjectName: String): Maybe> {
+ suspend fun getGradesStatistics(semester: Semester, isSemester: Boolean, subjectName: String): List {
return when (subjectName) {
- "Wszystkie" -> gradeStatisticsDb.loadAll(semester.semesterId, semester.studentId, isSemester).map { list ->
- list.groupBy { it.grade }.map {
+ "Wszystkie" -> {
+ val statistics = gradeStatisticsDb.loadAll(semester.semesterId, semester.studentId, isSemester)
+ statistics.groupBy { it.grade }.map {
GradeStatistics(semester.studentId, semester.semesterId, subjectName, it.key,
it.value.fold(0) { acc, e -> acc + e.amount }, false)
- } + list
+ } + statistics
}
else -> gradeStatisticsDb.loadSubject(semester.semesterId, semester.studentId, subjectName, isSemester)
- }.filter { it.isNotEmpty() }
+ }
}
- fun getGradesPointsStatistics(semester: Semester, subjectName: String): Maybe> {
+ suspend fun getGradesPointsStatistics(semester: Semester, subjectName: String): List {
return when (subjectName) {
"Wszystkie" -> gradePointsStatisticsDb.loadAll(semester.semesterId, semester.studentId)
else -> gradePointsStatisticsDb.loadSubject(semester.semesterId, semester.studentId, subjectName)
- }.filter { it.isNotEmpty() }
+ }
}
- fun saveGradesStatistics(gradesStatistics: List) {
+ suspend fun saveGradesStatistics(gradesStatistics: List) {
gradeStatisticsDb.insertAll(gradesStatistics)
}
- fun saveGradesPointsStatistics(gradePointsStatistics: List) {
+ suspend fun saveGradesPointsStatistics(gradePointsStatistics: List) {
gradePointsStatisticsDb.insertAll(gradePointsStatistics)
}
- fun deleteGradesStatistics(gradesStatistics: List) {
+ suspend fun deleteGradesStatistics(gradesStatistics: List) {
gradeStatisticsDb.deleteAll(gradesStatistics)
}
- fun deleteGradesPointsStatistics(gradesPointsStatistics: List) {
+ suspend fun deleteGradesPointsStatistics(gradesPointsStatistics: List) {
gradePointsStatisticsDb.deleteAll(gradesPointsStatistics)
}
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/gradestatistics/GradeStatisticsRemote.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/gradestatistics/GradeStatisticsRemote.kt
index 99e0cb987..1ff8132fc 100644
--- a/app/src/main/java/io/github/wulkanowy/data/repositories/gradestatistics/GradeStatisticsRemote.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/repositories/gradestatistics/GradeStatisticsRemote.kt
@@ -6,44 +6,39 @@ import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.utils.init
-import io.reactivex.Single
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class GradeStatisticsRemote @Inject constructor(private val sdk: Sdk) {
- fun getGradeStatistics(student: Student, semester: Semester, isSemester: Boolean): Single> {
+ suspend fun getGradeStatistics(student: Student, semester: Semester, isSemester: Boolean): List {
return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear).let {
if (isSemester) it.getGradesAnnualStatistics(semester.semesterId)
else it.getGradesPartialStatistics(semester.semesterId)
- }.map { gradeStatistics ->
- gradeStatistics.map {
- GradeStatistics(
- semesterId = semester.semesterId,
- studentId = semester.studentId,
- subject = it.subject,
- grade = it.gradeValue,
- amount = it.amount,
- semester = isSemester
- )
- }
+ }.map {
+ GradeStatistics(
+ semesterId = semester.semesterId,
+ studentId = semester.studentId,
+ subject = it.subject,
+ grade = it.gradeValue,
+ amount = it.amount,
+ semester = isSemester
+ )
}
}
- fun getGradePointsStatistics(student: Student, semester: Semester): Single> {
+ suspend fun getGradePointsStatistics(student: Student, semester: Semester): List {
return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear)
.getGradesPointsStatistics(semester.semesterId)
- .map { gradePointsStatistics ->
- gradePointsStatistics.map {
- GradePointsStatistics(
- semesterId = semester.semesterId,
- studentId = semester.studentId,
- subject = it.subject,
- others = it.others,
- student = it.student
- )
- }
+ .map {
+ GradePointsStatistics(
+ semesterId = semester.semesterId,
+ studentId = semester.studentId,
+ subject = it.subject,
+ others = it.others,
+ student = it.student
+ )
}
}
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/gradestatistics/GradeStatisticsRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/gradestatistics/GradeStatisticsRepository.kt
index 8d96d2f57..93df69406 100644
--- a/app/src/main/java/io/github/wulkanowy/data/repositories/gradestatistics/GradeStatisticsRepository.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/repositories/gradestatistics/GradeStatisticsRepository.kt
@@ -1,7 +1,5 @@
package io.github.wulkanowy.data.repositories.gradestatistics
-import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
-import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
import io.github.wulkanowy.data.db.entities.GradePointsStatistics
import io.github.wulkanowy.data.db.entities.GradeStatistics
import io.github.wulkanowy.data.db.entities.Semester
@@ -9,67 +7,54 @@ import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.pojos.GradeStatisticsItem
import io.github.wulkanowy.ui.modules.grade.statistics.ViewType
import io.github.wulkanowy.utils.uniqueSubtract
-import io.reactivex.Single
-import java.net.UnknownHostException
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class GradeStatisticsRepository @Inject constructor(
- private val settings: InternetObservingSettings,
private val local: GradeStatisticsLocal,
private val remote: GradeStatisticsRemote
) {
- fun getGradesStatistics(student: Student, semester: Semester, subjectName: String, isSemester: Boolean, forceRefresh: Boolean = false): Single> {
- return local.getGradesStatistics(semester, isSemester, subjectName).map { it.mapToStatisticItems() }.filter { !forceRefresh }
- .switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
- .flatMap {
- if (it) remote.getGradeStatistics(student, semester, isSemester)
- else Single.error(UnknownHostException())
- }.flatMap { new ->
- local.getGradesStatistics(semester, isSemester).toSingle(emptyList())
- .doOnSuccess { old ->
- local.deleteGradesStatistics(old.uniqueSubtract(new))
- local.saveGradesStatistics(new.uniqueSubtract(old))
- }
- }.flatMap { local.getGradesStatistics(semester, isSemester, subjectName).map { it.mapToStatisticItems() }.toSingle(emptyList()) })
- }
+ suspend fun getGradesStatistics(student: Student, semester: Semester, subjectName: String, isSemester: Boolean, forceRefresh: Boolean = false): List {
+ return local.getGradesStatistics(semester, isSemester, subjectName).mapToStatisticItems().filter { !forceRefresh }.ifEmpty {
+ val new = remote.getGradeStatistics(student, semester, isSemester)
+ val old = local.getGradesStatistics(semester, isSemester)
- fun getGradesPointsStatistics(student: Student, semester: Semester, subjectName: String, forceRefresh: Boolean): Single> {
- return local.getGradesPointsStatistics(semester, subjectName).map { it.mapToStatisticsItem() }.filter { !forceRefresh }
- .switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
- .flatMap {
- if (it) remote.getGradePointsStatistics(student, semester)
- else Single.error(UnknownHostException())
- }.flatMap { new ->
- local.getGradesPointsStatistics(semester).toSingle(emptyList())
- .doOnSuccess { old ->
- local.deleteGradesPointsStatistics(old.uniqueSubtract(new))
- local.saveGradesPointsStatistics(new.uniqueSubtract(old))
- }
- }.flatMap { local.getGradesPointsStatistics(semester, subjectName).map { it.mapToStatisticsItem() }.toSingle(emptyList()) })
- }
+ local.deleteGradesStatistics(old.uniqueSubtract(new))
+ local.saveGradesStatistics(new.uniqueSubtract(old))
- private fun List.mapToStatisticItems(): List {
- return groupBy { it.subject }.map {
- GradeStatisticsItem(
- type = ViewType.PARTIAL,
- partial = it.value
- .sortedByDescending { item -> item.grade }
- .filter { item -> item.amount != 0 },
- points = null
- )
+ local.getGradesStatistics(semester, isSemester, subjectName).mapToStatisticItems()
}
}
- private fun List.mapToStatisticsItem(): List {
- return map {
- GradeStatisticsItem(
- type = ViewType.POINTS,
- partial = emptyList(),
- points = it
- )
+ suspend fun getGradesPointsStatistics(student: Student, semester: Semester, subjectName: String, forceRefresh: Boolean): List {
+ return local.getGradesPointsStatistics(semester, subjectName).mapToStatisticsItem().filter { !forceRefresh }.ifEmpty {
+ val new = remote.getGradePointsStatistics(student, semester)
+ val old = local.getGradesPointsStatistics(semester)
+
+ local.deleteGradesPointsStatistics(old.uniqueSubtract(new))
+ local.saveGradesPointsStatistics(new.uniqueSubtract(old))
+
+ local.getGradesPointsStatistics(semester, subjectName).mapToStatisticsItem()
}
}
+
+ private fun List.mapToStatisticItems() = groupBy { it.subject }.map {
+ GradeStatisticsItem(
+ type = ViewType.PARTIAL,
+ partial = it.value
+ .sortedByDescending { item -> item.grade }
+ .filter { item -> item.amount != 0 },
+ points = null
+ )
+ }
+
+ private fun List.mapToStatisticsItem() = map {
+ GradeStatisticsItem(
+ type = ViewType.POINTS,
+ partial = emptyList(),
+ points = it
+ )
+ }
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/homework/HomeworkLocal.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/homework/HomeworkLocal.kt
index fdae45182..ed6bb0cf5 100644
--- a/app/src/main/java/io/github/wulkanowy/data/repositories/homework/HomeworkLocal.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/repositories/homework/HomeworkLocal.kt
@@ -3,7 +3,6 @@ package io.github.wulkanowy.data.repositories.homework
import io.github.wulkanowy.data.db.dao.HomeworkDao
import io.github.wulkanowy.data.db.entities.Homework
import io.github.wulkanowy.data.db.entities.Semester
-import io.reactivex.Maybe
import org.threeten.bp.LocalDate
import javax.inject.Inject
import javax.inject.Singleton
@@ -11,20 +10,19 @@ import javax.inject.Singleton
@Singleton
class HomeworkLocal @Inject constructor(private val homeworkDb: HomeworkDao) {
- fun saveHomework(homework: List) {
+ suspend fun saveHomework(homework: List) {
homeworkDb.insertAll(homework)
}
- fun deleteHomework(homework: List) {
+ suspend fun deleteHomework(homework: List) {
homeworkDb.deleteAll(homework)
}
- fun updateHomework(homework: List) {
+ suspend fun updateHomework(homework: List) {
homeworkDb.updateAll(homework)
}
- fun getHomework(semester: Semester, startDate: LocalDate, endDate: LocalDate): Maybe> {
+ suspend fun getHomework(semester: Semester, startDate: LocalDate, endDate: LocalDate): List {
return homeworkDb.loadAll(semester.semesterId, semester.studentId, startDate, endDate)
- .filter { it.isNotEmpty() }
}
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/homework/HomeworkRemote.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/homework/HomeworkRemote.kt
index 20ffee99c..9e99843dd 100644
--- a/app/src/main/java/io/github/wulkanowy/data/repositories/homework/HomeworkRemote.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/repositories/homework/HomeworkRemote.kt
@@ -5,7 +5,6 @@ import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.utils.init
-import io.reactivex.Single
import org.threeten.bp.LocalDate
import javax.inject.Inject
import javax.inject.Singleton
@@ -13,23 +12,21 @@ import javax.inject.Singleton
@Singleton
class HomeworkRemote @Inject constructor(private val sdk: Sdk) {
- fun getHomework(student: Student, semester: Semester, startDate: LocalDate, endDate: LocalDate): Single> {
+ suspend fun getHomework(student: Student, semester: Semester, startDate: LocalDate, endDate: LocalDate): List {
return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear)
.getHomework(startDate, endDate)
- .map { homework ->
- homework.map {
- Homework(
- semesterId = semester.semesterId,
- studentId = semester.studentId,
- date = it.date,
- entryDate = it.entryDate,
- subject = it.subject,
- content = it.content,
- teacher = it.teacher,
- teacherSymbol = it.teacherSymbol,
- attachments = it.attachments.map { attachment -> attachment.url to attachment.name }
- )
- }
+ .map {
+ Homework(
+ semesterId = semester.semesterId,
+ studentId = semester.studentId,
+ date = it.date,
+ entryDate = it.entryDate,
+ subject = it.subject,
+ content = it.content,
+ teacher = it.teacher,
+ teacherSymbol = it.teacherSymbol,
+ attachments = it.attachments.map { attachment -> attachment.url to attachment.name }
+ )
}
}
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/homework/HomeworkRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/homework/HomeworkRepository.kt
index 7e8fd5c30..ca0a84a5f 100644
--- a/app/src/main/java/io/github/wulkanowy/data/repositories/homework/HomeworkRepository.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/repositories/homework/HomeworkRepository.kt
@@ -1,49 +1,37 @@
package io.github.wulkanowy.data.repositories.homework
-import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
-import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
import io.github.wulkanowy.data.db.entities.Homework
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
-import io.github.wulkanowy.utils.sunday
import io.github.wulkanowy.utils.monday
+import io.github.wulkanowy.utils.sunday
import io.github.wulkanowy.utils.uniqueSubtract
-import io.reactivex.Completable
-import io.reactivex.Single
import org.threeten.bp.LocalDate
-import java.net.UnknownHostException
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class HomeworkRepository @Inject constructor(
- private val settings: InternetObservingSettings,
private val local: HomeworkLocal,
private val remote: HomeworkRemote
) {
- fun getHomework(student: Student, semester: Semester, start: LocalDate, end: LocalDate, forceRefresh: Boolean = false): Single> {
- return Single.fromCallable { start.monday to end.sunday }.flatMap { (monday, friday) ->
- local.getHomework(semester, monday, friday).filter { !forceRefresh }
- .switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
- .flatMap {
- if (it) remote.getHomework(student, semester, monday, friday)
- else Single.error(UnknownHostException())
- }.flatMap { new ->
- local.getHomework(semester, monday, friday).toSingle(emptyList())
- .doOnSuccess { old ->
- local.deleteHomework(old.uniqueSubtract(new))
- local.saveHomework(new.uniqueSubtract(old))
- }
- }.flatMap { local.getHomework(semester, monday, friday).toSingle(emptyList()) })
+ suspend fun getHomework(student: Student, semester: Semester, start: LocalDate, end: LocalDate, forceRefresh: Boolean = false): List {
+ return local.getHomework(semester, start.monday, end.sunday).filter { !forceRefresh }.ifEmpty {
+ val new = remote.getHomework(student, semester, start.monday, end.sunday)
+
+ val old = local.getHomework(semester, start.monday, end.sunday)
+
+ local.deleteHomework(old.uniqueSubtract(new))
+ local.saveHomework(new.uniqueSubtract(old))
+
+ local.getHomework(semester, start.monday, end.sunday)
}
}
- fun toggleDone(homework: Homework): Completable {
- return Completable.fromCallable {
- local.updateHomework(listOf(homework.apply {
- isDone = !isDone
- }))
- }
+ suspend fun toggleDone(homework: Homework) {
+ local.updateHomework(listOf(homework.apply {
+ isDone = !isDone
+ }))
}
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/logger/LoggerRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/logger/LoggerRepository.kt
index be6ad2f48..d03d3ccd6 100644
--- a/app/src/main/java/io/github/wulkanowy/data/repositories/logger/LoggerRepository.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/repositories/logger/LoggerRepository.kt
@@ -1,29 +1,31 @@
package io.github.wulkanowy.data.repositories.logger
import android.content.Context
-import io.reactivex.Single
+import io.github.wulkanowy.utils.DispatchersProvider
+import kotlinx.coroutines.withContext
import java.io.File
import java.io.FileNotFoundException
import javax.inject.Inject
-class LoggerRepository @Inject constructor(private val context: Context) {
+class LoggerRepository @Inject constructor(
+ private val context: Context,
+ private val dispatchers: DispatchersProvider
+) {
- fun getLastLogLines(): Single> {
- return getLastModified()
- .map { it.readText() }
- .map { it.split("\n") }
+ suspend fun getLastLogLines(): List {
+ return getLastModified().readText().split("\n")
}
- fun getLogFiles(): Single> {
- return Single.fromCallable {
+ suspend fun getLogFiles(): List {
+ return withContext(dispatchers.backgroundThread) {
File(context.filesDir.absolutePath).listFiles(File::isFile)?.filter {
it.name.endsWith(".log")
- }
+ }!!
}
}
- private fun getLastModified(): Single {
- return Single.fromCallable {
+ private suspend fun getLastModified(): File {
+ return withContext(dispatchers.backgroundThread) {
var lastModifiedTime = Long.MIN_VALUE
var chosenFile: File? = null
File(context.filesDir.absolutePath).listFiles(File::isFile)?.forEach { file ->
@@ -33,7 +35,7 @@ class LoggerRepository @Inject constructor(private val context: Context) {
}
}
if (chosenFile == null) throw FileNotFoundException("Log file not found")
- chosenFile
+ chosenFile!!
}
}
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/luckynumber/LuckyNumberLocal.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/luckynumber/LuckyNumberLocal.kt
index 0f4f79c84..22b5786dd 100644
--- a/app/src/main/java/io/github/wulkanowy/data/repositories/luckynumber/LuckyNumberLocal.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/repositories/luckynumber/LuckyNumberLocal.kt
@@ -3,7 +3,6 @@ package io.github.wulkanowy.data.repositories.luckynumber
import io.github.wulkanowy.data.db.dao.LuckyNumberDao
import io.github.wulkanowy.data.db.entities.LuckyNumber
import io.github.wulkanowy.data.db.entities.Student
-import io.reactivex.Maybe
import org.threeten.bp.LocalDate
import javax.inject.Inject
import javax.inject.Singleton
@@ -11,19 +10,19 @@ import javax.inject.Singleton
@Singleton
class LuckyNumberLocal @Inject constructor(private val luckyNumberDb: LuckyNumberDao) {
- fun saveLuckyNumber(luckyNumber: LuckyNumber) {
- luckyNumberDb.insertAll(listOf(luckyNumber))
+ suspend fun saveLuckyNumber(luckyNumber: LuckyNumber?) {
+ luckyNumberDb.insertAll(listOfNotNull(luckyNumber))
}
- fun updateLuckyNumber(luckyNumber: LuckyNumber) {
- luckyNumberDb.updateAll(listOf(luckyNumber))
+ suspend fun updateLuckyNumber(luckyNumber: LuckyNumber?) {
+ luckyNumberDb.updateAll(listOfNotNull(luckyNumber))
}
- fun deleteLuckyNumber(luckyNumber: LuckyNumber) {
- luckyNumberDb.deleteAll(listOf(luckyNumber))
+ suspend fun deleteLuckyNumber(luckyNumber: LuckyNumber?) {
+ luckyNumberDb.deleteAll(listOfNotNull(luckyNumber))
}
- fun getLuckyNumber(student: Student, date: LocalDate): Maybe {
+ suspend fun getLuckyNumber(student: Student, date: LocalDate): LuckyNumber? {
return luckyNumberDb.load(student.studentId, date)
}
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/luckynumber/LuckyNumberRemote.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/luckynumber/LuckyNumberRemote.kt
index 0c71897a6..e93a6c047 100644
--- a/app/src/main/java/io/github/wulkanowy/data/repositories/luckynumber/LuckyNumberRemote.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/repositories/luckynumber/LuckyNumberRemote.kt
@@ -4,7 +4,6 @@ import io.github.wulkanowy.data.db.entities.LuckyNumber
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.utils.init
-import io.reactivex.Maybe
import org.threeten.bp.LocalDate
import javax.inject.Inject
import javax.inject.Singleton
@@ -12,8 +11,8 @@ import javax.inject.Singleton
@Singleton
class LuckyNumberRemote @Inject constructor(private val sdk: Sdk) {
- fun getLuckyNumber(student: Student): Maybe {
- return sdk.init(student).getLuckyNumber(student.schoolShortName).map {
+ suspend fun getLuckyNumber(student: Student): LuckyNumber? {
+ return sdk.init(student).getLuckyNumber(student.schoolShortName)?.let {
LuckyNumber(
studentId = student.studentId,
date = LocalDate.now(),
diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/luckynumber/LuckyNumberRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/luckynumber/LuckyNumberRepository.kt
index 374b9a294..3f6089628 100644
--- a/app/src/main/java/io/github/wulkanowy/data/repositories/luckynumber/LuckyNumberRepository.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/repositories/luckynumber/LuckyNumberRepository.kt
@@ -1,54 +1,42 @@
package io.github.wulkanowy.data.repositories.luckynumber
-import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
-import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
import io.github.wulkanowy.data.db.entities.LuckyNumber
import io.github.wulkanowy.data.db.entities.Student
-import io.reactivex.Completable
-import io.reactivex.Maybe
-import org.threeten.bp.LocalDate
-import java.net.UnknownHostException
+import org.threeten.bp.LocalDate.now
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class LuckyNumberRepository @Inject constructor(
- private val settings: InternetObservingSettings,
private val local: LuckyNumberLocal,
private val remote: LuckyNumberRemote
) {
- fun getLuckyNumber(student: Student, forceRefresh: Boolean = false, notify: Boolean = false): Maybe {
- return local.getLuckyNumber(student, LocalDate.now()).filter { !forceRefresh }
- .switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
- .flatMapMaybe {
- if (it) remote.getLuckyNumber(student)
- else Maybe.error(UnknownHostException())
- }.flatMap { new ->
- local.getLuckyNumber(student, LocalDate.now())
- .doOnSuccess { old ->
- if (new != old) {
- local.deleteLuckyNumber(old)
- local.saveLuckyNumber(new.apply {
- if (notify) isNotified = false
- })
- }
- }
- .doOnComplete {
- local.saveLuckyNumber(new.apply {
- if (notify) isNotified = false
- })
- }
- }.flatMap({ local.getLuckyNumber(student, LocalDate.now()) }, { Maybe.error(it) },
- { local.getLuckyNumber(student, LocalDate.now()) })
- )
+ suspend fun getLuckyNumber(student: Student, forceRefresh: Boolean = false, notify: Boolean = false): LuckyNumber? {
+ return local.getLuckyNumber(student, now())?.takeIf { !forceRefresh } ?: run {
+ val new = remote.getLuckyNumber(student)
+ val old = local.getLuckyNumber(student, now())
+
+ if (new != old) {
+ old?.let { local.deleteLuckyNumber(it) }
+ local.saveLuckyNumber(new?.apply {
+ if (notify) isNotified = false
+ })
+ }
+
+ local.saveLuckyNumber(new?.apply {
+ if (notify) isNotified = false
+ })
+
+ local.getLuckyNumber(student, now())
+ }
}
- fun getNotNotifiedLuckyNumber(student: Student): Maybe {
- return local.getLuckyNumber(student, LocalDate.now()).filter { !it.isNotified }
+ suspend fun getNotNotifiedLuckyNumber(student: Student): LuckyNumber? {
+ return local.getLuckyNumber(student, now())
}
- fun updateLuckyNumber(luckyNumber: LuckyNumber): Completable {
- return Completable.fromCallable { local.updateLuckyNumber(luckyNumber) }
+ suspend fun updateLuckyNumber(luckyNumber: LuckyNumber) {
+ local.updateLuckyNumber(luckyNumber)
}
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/message/MessageLocal.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/message/MessageLocal.kt
index 53cf0a983..f05c49d87 100644
--- a/app/src/main/java/io/github/wulkanowy/data/repositories/message/MessageLocal.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/repositories/message/MessageLocal.kt
@@ -7,8 +7,6 @@ import io.github.wulkanowy.data.db.entities.MessageAttachment
import io.github.wulkanowy.data.db.entities.MessageWithAttachment
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.repositories.message.MessageFolder.TRASHED
-import io.reactivex.Maybe
-import io.reactivex.Single
import javax.inject.Inject
import javax.inject.Singleton
@@ -18,30 +16,30 @@ class MessageLocal @Inject constructor(
private val messageAttachmentDao: MessageAttachmentDao
) {
- fun saveMessages(messages: List) {
+ suspend fun saveMessages(messages: List) {
messagesDb.insertAll(messages)
}
- fun updateMessages(messages: List) {
+ suspend fun updateMessages(messages: List