diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 7f8591bb1..3def08953 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -2,12 +2,10 @@ name: Tests
on:
push:
- branches:
- - master
- - develop
- - 'hotfix/**'
+ branches: [ master, develop ]
tags: [ '*' ]
pull_request:
+ branches: [ master, develop ]
jobs:
diff --git a/LICENSE b/LICENSE
index a1fc37058..c97032f74 100644
--- a/LICENSE
+++ b/LICENSE
@@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.
- Copyright 2023 Wulkanowy
+ Copyright 2022 Wulkanowy
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/README.cs.md b/README.cs.md
index 8171b27d6..5c1e5ea71 100644
--- a/README.cs.md
+++ b/README.cs.md
@@ -1,13 +1,18 @@
-Česká verze / [Deutsche Version](README.de.md) / [English version](README.en.md) / [Polska wersja](README.md) / [Slovenská verzia](README.sk.md)
+[English version of README](README.en.md)
+
+[Deutsche Version von README](README.de.md)
+
+[Polska wersja README](README.md)
+
+[Slovenská verzia README](README.sk.md)
# Wulkanowy
-[](https://github.com/wulkanowy/wulkanowy/actions)
+[](https://github.com/wulkanowy/wulkanowy/actions)
[](https://codecov.io/gh/wulkanowy/wulkanowy)
[](https://discord.gg/vccAQBr)
[](https://f-droid.org/packages/io.github.wulkanowy/)
[](https://github.com/wulkanowy/wulkanowy/releases)
-[](https://translate.wulkanowy.net.pl)
Neoficiální klient deníku VULCAN UONET+ pro žáka a rodiče
@@ -34,7 +39,7 @@ Neoficiální klient deníku VULCAN UONET+ pro žáka a rodiče
* podpora více účtů s možností přejmenování žáků
* tmavý a černý (AMOLED) motiv
* offline režim
-* volitelné reklamy na podporu projektu
+* žádné reklamy
## Stáhnout
@@ -52,7 +57,7 @@ Aktuální verzi si můžete stáhnout z Google Play, F-Droid nebo Huawei AppGal
Můžete si také stáhnout [vývojovou verzi](https://wulkanowy.github.io/#download), která zahrnuje nové funkce připravované pro příští vydání
-## Postaveno s pomocí
+## Postaveno s
* [Wulkanowy SDK](https://github.com/wulkanowy/sdk)
diff --git a/README.de.md b/README.de.md
index 972f66ba9..b9e1d1ec1 100644
--- a/README.de.md
+++ b/README.de.md
@@ -1,13 +1,14 @@
-[Česká verze](README.cs.md) / Deutsche Version / [English version](README.en.md) / [Polska wersja](README.md) / [Slovenská verzia](README.sk.md)
+[Polska wersja README](README.md)
+
+[English version of README](README.en.md)
# Wulkanowy
-[](https://github.com/wulkanowy/wulkanowy/actions)
+[](https://github.com/wulkanowy/wulkanowy/actions)
[](https://codecov.io/gh/wulkanowy/wulkanowy)
[](https://discord.gg/vccAQBr)
[](https://f-droid.org/packages/io.github.wulkanowy/)
[](https://github.com/wulkanowy/wulkanowy/releases)
-[](https://translate.wulkanowy.net.pl)
Inoffizieller Android VULCAN UONET+ Registrierungsclient für Schüler und ihre Eltern
@@ -21,7 +22,7 @@ Inoffizieller Android VULCAN UONET+ Registrierungsclient für Schüler und ihre
* Prozentsatz der Anwesenheit
* Prüfungen
* Stundenplan
- * abgeschlossene Unterrichtsstunden
+ * Unterricht abgeschlossen
* Nachrichten
* Hausaufgaben
* Anmerkungen
@@ -34,7 +35,7 @@ Inoffizieller Android VULCAN UONET+ Registrierungsclient für Schüler und ihre
* Unterstützung für mehrere Konten mit der Möglichkeit, den Namen des Schülers zu ändern
* dunkles und schwarzes (AMOLED) Thema
* Offline-Modus
-* optionale Werbungen, die es uns ermöglichen das Projekt zu unterstützen
+* keine Werbung
## Herunterladen
diff --git a/README.en.md b/README.en.md
index 6e4da4637..1ac2a6721 100644
--- a/README.en.md
+++ b/README.en.md
@@ -1,13 +1,18 @@
-[Česká verze](README.cs.md) / [Deutsche Version](README.de.md) / English version / [Polska wersja](README.md) / [Slovenská verzia](README.sk.md)
+[Polska wersja README](README.md)
+
+[Deutsche Version von README](README.de.md)
+
+[Česká verze README](README.cs.md)
+
+[Slovenská verzia README](README.sk.md)
# Wulkanowy
-[](https://github.com/wulkanowy/wulkanowy/actions)
+[](https://github.com/wulkanowy/wulkanowy/actions)
[](https://codecov.io/gh/wulkanowy/wulkanowy)
[](https://discord.gg/vccAQBr)
[](https://f-droid.org/packages/io.github.wulkanowy/)
[](https://github.com/wulkanowy/wulkanowy/releases)
-[](https://translate.wulkanowy.net.pl)
Unofficial android VULCAN UONET+ register client for both students and their parents
@@ -34,7 +39,7 @@ Unofficial android VULCAN UONET+ register client for both students and their par
* support for multiple accounts with the ability to rename students
* dark and black (AMOLED) theme
* offline mode
-* optional ads which allow to support the project
+* no ads
## Download
diff --git a/README.md b/README.md
index f3d2e29a2..e7c7d4c5e 100644
--- a/README.md
+++ b/README.md
@@ -1,13 +1,18 @@
-[Česká verze](README.cs.md) / [Deutsche Version](README.de.md) / [English version](README.en.md) / Polska wersja / [Slovenská verzia](README.sk.md)
+[English version of README](README.en.md)
+
+[Deutsche Version von README](README.de.md)
+
+[Česká verze README](README.cs.md)
+
+[Slovenská verzia README](README.sk.md)
# Wulkanowy
-[](https://github.com/wulkanowy/wulkanowy/actions)
+[](https://github.com/wulkanowy/wulkanowy/actions)
[](https://codecov.io/gh/wulkanowy/wulkanowy)
[](https://discord.gg/vccAQBr)
[](https://f-droid.org/packages/io.github.wulkanowy/)
[](https://github.com/wulkanowy/wulkanowy/releases)
-[](https://translate.wulkanowy.net.pl)
Nieoficjalny klient dziennika VULCAN UONET+ dla ucznia i rodzica
@@ -34,7 +39,7 @@ Nieoficjalny klient dziennika VULCAN UONET+ dla ucznia i rodzica
* obsługa wielu kont wraz z możliwością zmiany nazwy ucznia
* ciemny i czarny (AMOLED) motyw
* tryb offline
-* opcjonalne reklamy umożliwiające wsparcie projektu
+* brak reklam
## Pobierz
diff --git a/README.sk.md b/README.sk.md
index ff0c6e3c9..2f3ba41dd 100644
--- a/README.sk.md
+++ b/README.sk.md
@@ -1,13 +1,18 @@
-[Česká verze](README.cs.md) / [Deutsche Version](README.de.md) / [English version](README.en.md) / [Polska wersja](README.md) / Slovenská verzia
+[English version of README](README.en.md)
+
+[Deutsche Version von README](README.de.md)
+
+[Polska wersja README](README.md)
+
+[Česká verze README](README.cs.md)
# Wulkanowy
-[](https://github.com/wulkanowy/wulkanowy/actions)
+[](https://github.com/wulkanowy/wulkanowy/actions)
[](https://codecov.io/gh/wulkanowy/wulkanowy)
[](https://discord.gg/vccAQBr)
[](https://f-droid.org/packages/io.github.wulkanowy/)
[](https://github.com/wulkanowy/wulkanowy/releases)
-[](https://translate.wulkanowy.net.pl)
Neoficiálny klient denníka VULCAN UONET+ pre žiaka a rodičov
@@ -34,7 +39,7 @@ Neoficiálny klient denníka VULCAN UONET+ pre žiaka a rodičov
* podpora viacerých účtov s možnosťou premenovania žiakov
* tmavý a čierny (AMOLED) motív
* offline režim
-* voliteľné reklamy na podporu projektu
+* žiadne reklamy
## Stiahnuť
@@ -52,7 +57,7 @@ Aktuálnu verziu si môžete stiahnuť z Google Play, F-Droid alebo Huawei AppGa
Môžete si tiež stiahnuť [vývojovú verziu](https://wulkanowy.github.io/#download), ktorá zahrňuje nové funkcie pripravované pre budúce vydanie
-## Postavené s pomocou
+## Postavené s
* [Wulkanowy SDK](https://github.com/wulkanowy/sdk)
diff --git a/app/build.gradle b/app/build.gradle
index ce9039dfa..5fb07377a 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -16,15 +16,15 @@ apply from: 'hooks.gradle'
android {
namespace 'io.github.wulkanowy'
- compileSdkVersion 33
+ compileSdkVersion 32
defaultConfig {
applicationId "io.github.wulkanowy"
testApplicationId "io.github.tests.wulkanowy"
minSdkVersion 21
- targetSdkVersion 33
- versionCode 119
- versionName "1.9.0"
+ targetSdkVersion 32
+ versionCode 110
+ versionName "1.7.1"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
resValue "string", "app_name", "Wulkanowy"
@@ -161,8 +161,8 @@ play {
defaultToAppBundles = false
track = 'production'
releaseStatus = com.github.triplet.gradle.androidpublisher.ReleaseStatus.IN_PROGRESS
- userFraction = 0.10d
- updatePriority = 1
+ userFraction = 0.95d
+ updatePriority = 5
enabled.set(false)
}
@@ -181,24 +181,24 @@ ext {
android_hilt = "1.0.0"
room = "2.4.3"
chucker = "3.5.2"
- mockk = "1.13.3"
+ mockk = "1.12.5"
coroutines = "1.6.4"
}
dependencies {
- implementation "io.github.wulkanowy:sdk:1.9.0"
+ implementation "io.github.wulkanowy:sdk:1.7.0"
- coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.8'
+ coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.6'
- implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.1"
+ implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.3"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines"
- implementation "androidx.core:core-ktx:1.9.0"
+ implementation "androidx.core:core-ktx:1.8.0"
implementation 'androidx.core:core-splashscreen:1.0.0'
- implementation "androidx.activity:activity-ktx:1.6.1"
- implementation "androidx.appcompat:appcompat:1.5.1"
- implementation "androidx.fragment:fragment-ktx:1.5.5"
- implementation "androidx.annotation:annotation:1.5.0"
+ implementation "androidx.activity:activity-ktx:1.5.1"
+ implementation "androidx.appcompat:appcompat:1.5.0"
+ implementation "androidx.fragment:fragment-ktx:1.5.2"
+ implementation "androidx.annotation:annotation:1.4.0"
implementation "androidx.preference:preference-ktx:1.2.0"
implementation "androidx.recyclerview:recyclerview:1.2.1"
@@ -206,10 +206,10 @@ dependencies {
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
implementation "androidx.constraintlayout:constraintlayout:2.1.4"
implementation "androidx.coordinatorlayout:coordinatorlayout:1.2.0"
- implementation "com.google.android.material:material:1.7.0"
+ implementation "com.google.android.material:material:1.6.1"
implementation "com.github.wulkanowy:material-chips-input:2.3.1"
implementation "com.github.PhilJay:MPAndroidChart:v3.1.0"
- implementation 'com.github.lopspower:CircularImageView:4.3.0'
+ implementation 'com.github.lopspower:CircularImageView:4.2.0'
implementation "androidx.work:work-runtime-ktx:$work_manager"
playImplementation "androidx.work:work-gcm:$work_manager"
@@ -236,22 +236,21 @@ dependencies {
implementation "at.favre.lib:slf4j-timber:1.0.1"
implementation 'com.github.bastienpaulfr:Treessence:1.0.5'
implementation "com.mikepenz:aboutlibraries-core:$about_libraries"
- implementation "io.coil-kt:coil:2.2.2"
- implementation "io.github.wulkanowy:AppKillerManager:3.0.1"
+ implementation "io.coil-kt:coil:2.2.0"
+ implementation "io.github.wulkanowy:AppKillerManager:3.0.0"
implementation 'me.xdrop:fuzzywuzzy:1.4.0'
implementation 'com.fredporciuncula:flow-preferences:1.8.0'
- implementation 'org.apache.commons:commons-text:1.10.0'
- playImplementation platform('com.google.firebase:firebase-bom:31.1.1')
+ playImplementation platform('com.google.firebase:firebase-bom:30.3.2')
playImplementation 'com.google.firebase:firebase-analytics-ktx'
playImplementation 'com.google.firebase:firebase-messaging:'
playImplementation 'com.google.firebase:firebase-crashlytics:'
playImplementation 'com.google.android.play:core:1.10.3'
playImplementation 'com.google.android.play:core-ktx:1.8.1'
- playImplementation 'com.google.android.gms:play-services-ads:21.4.0'
+ playImplementation 'com.google.android.gms:play-services-ads:21.1.0'
- hmsImplementation 'com.huawei.hms:hianalytics:6.9.0.301'
- hmsImplementation 'com.huawei.agconnect:agconnect-crash:1.7.3.302'
+ hmsImplementation 'com.huawei.hms:hianalytics:6.7.0.300'
+ hmsImplementation 'com.huawei.agconnect:agconnect-crash:1.7.1.300'
releaseImplementation "com.github.ChuckerTeam.Chucker:library-no-op:$chucker"
@@ -264,17 +263,17 @@ dependencies {
testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:$coroutines"
testImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
- testImplementation 'org.robolectric:robolectric:4.9.1'
- testImplementation "androidx.test:runner:1.5.1"
- testImplementation "androidx.test.ext:junit:1.1.4"
- testImplementation "androidx.test:core:1.5.0"
+ testImplementation 'org.robolectric:robolectric:4.8.1'
+ testImplementation "androidx.test:runner:1.4.0"
+ testImplementation "androidx.test.ext:junit:1.1.3"
+ testImplementation "androidx.test:core:1.4.0"
testImplementation "androidx.room:room-testing:$room"
testImplementation "com.google.dagger:hilt-android-testing:$hilt_version"
kaptTest "com.google.dagger:hilt-android-compiler:$hilt_version"
- androidTestImplementation "androidx.test:core:1.5.0"
- androidTestImplementation "androidx.test:runner:1.5.1"
- androidTestImplementation "androidx.test.ext:junit:1.1.4"
+ androidTestImplementation "androidx.test:core:1.4.0"
+ androidTestImplementation "androidx.test:runner:1.4.0"
+ androidTestImplementation "androidx.test.ext:junit:1.1.3"
androidTestImplementation "io.mockk:mockk-android:$mockk"
androidTestImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
}
diff --git a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/52.json b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/52.json
deleted file mode 100644
index 129d1917b..000000000
--- a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/52.json
+++ /dev/null
@@ -1,2421 +0,0 @@
-{
- "formatVersion": 1,
- "database": {
- "version": 52,
- "identityHash": "8742176f26afcc81279d4a073dca2949",
- "entities": [
- {
- "tableName": "Students",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`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, `user_name` TEXT 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, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `nick` TEXT NOT NULL, `avatar_color` INTEGER NOT NULL)",
- "fields": [
- {
- "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": "userName",
- "columnName": "user_name",
- "affinity": "TEXT",
- "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
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "nick",
- "columnName": "nick",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "avatarColor",
- "columnName": "avatar_color",
- "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"
- ],
- "orders": [],
- "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}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `kindergarten_diary_id` INTEGER NOT NULL DEFAULT 0, `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, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_current` INTEGER NOT NULL)",
- "fields": [
- {
- "fieldPath": "studentId",
- "columnName": "student_id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "diaryId",
- "columnName": "diary_id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "kindergartenDiaryId",
- "columnName": "kindergarten_diary_id",
- "affinity": "INTEGER",
- "notNull": true,
- "defaultValue": "0"
- },
- {
- "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
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "current",
- "columnName": "is_current",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [
- {
- "name": "index_Semesters_student_id_diary_id_kindergarten_diary_id_semester_id",
- "unique": true,
- "columnNames": [
- "student_id",
- "diary_id",
- "kindergarten_diary_id",
- "semester_id"
- ],
- "orders": [],
- "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Semesters_student_id_diary_id_kindergarten_diary_id_semester_id` ON `${TABLE_NAME}` (`student_id`, `diary_id`, `kindergarten_diary_id`, `semester_id`)"
- }
- ],
- "foreignKeys": []
- },
- {
- "tableName": "Exams",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`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, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)",
- "fields": [
- {
- "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
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "isNotified",
- "columnName": "is_notified",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "Timetable",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`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, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)",
- "fields": [
- {
- "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
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "isNotified",
- "columnName": "is_notified",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "Attendance",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`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, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)",
- "fields": [
- {
- "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
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "isNotified",
- "columnName": "is_notified",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "AttendanceSummary",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`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, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)",
- "fields": [
- {
- "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
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "Grades",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`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, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)",
- "fields": [
- {
- "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
- },
- {
- "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
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "GradesSummary",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`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, `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)",
- "fields": [
- {
- "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
- },
- {
- "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
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "GradePartialStatistics",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `class_average` TEXT NOT NULL, `student_average` TEXT NOT NULL, `class_amounts` TEXT NOT NULL, `student_amounts` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)",
- "fields": [
- {
- "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": "classAverage",
- "columnName": "class_average",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "studentAverage",
- "columnName": "student_average",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "classAmounts",
- "columnName": "class_amounts",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "studentAmounts",
- "columnName": "student_amounts",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "GradesPointsStatistics",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `others` REAL NOT NULL, `student` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)",
- "fields": [
- {
- "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
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "GradeSemesterStatistics",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `amounts` TEXT NOT NULL, `student_grade` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)",
- "fields": [
- {
- "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": "amounts",
- "columnName": "amounts",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "studentGrade",
- "columnName": "student_grade",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "Messages",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`message_global_key` TEXT NOT NULL, `mailbox_key` TEXT NOT NULL, `message_id` INTEGER NOT NULL, `correspondents` TEXT NOT NULL, `subject` TEXT NOT NULL, `date` INTEGER NOT NULL, `folder_id` INTEGER NOT NULL, `unread` INTEGER NOT NULL, `read_by` INTEGER, `unread_by` INTEGER, `has_attachments` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `content` TEXT NOT NULL, `sender` TEXT, `recipients` TEXT)",
- "fields": [
- {
- "fieldPath": "messageGlobalKey",
- "columnName": "message_global_key",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "mailboxKey",
- "columnName": "mailbox_key",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "messageId",
- "columnName": "message_id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "correspondents",
- "columnName": "correspondents",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "subject",
- "columnName": "subject",
- "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": "readBy",
- "columnName": "read_by",
- "affinity": "INTEGER",
- "notNull": false
- },
- {
- "fieldPath": "unreadBy",
- "columnName": "unread_by",
- "affinity": "INTEGER",
- "notNull": false
- },
- {
- "fieldPath": "hasAttachments",
- "columnName": "has_attachments",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "isNotified",
- "columnName": "is_notified",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "content",
- "columnName": "content",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "sender",
- "columnName": "sender",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "recipients",
- "columnName": "recipients",
- "affinity": "TEXT",
- "notNull": false
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "MessageAttachments",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`real_id` INTEGER NOT NULL, `message_global_key` 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": "messageGlobalKey",
- "columnName": "message_global_key",
- "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}` (`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, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)",
- "fields": [
- {
- "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
- },
- {
- "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
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "Homework",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`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, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_done` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `is_added_by_user` INTEGER NOT NULL)",
- "fields": [
- {
- "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
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "isDone",
- "columnName": "is_done",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "isNotified",
- "columnName": "is_notified",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "isAddedByUser",
- "columnName": "is_added_by_user",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "Subjects",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)",
- "fields": [
- {
- "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
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "LuckyNumbers",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `lucky_number` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)",
- "fields": [
- {
- "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
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "isNotified",
- "columnName": "is_notified",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "CompletedLesson",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`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, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)",
- "fields": [
- {
- "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
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "Mailboxes",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`globalKey` TEXT NOT NULL, `fullName` TEXT NOT NULL, `userName` TEXT NOT NULL, `userLoginId` INTEGER NOT NULL, `studentName` TEXT NOT NULL, `schoolNameShort` TEXT NOT NULL, `type` TEXT NOT NULL, PRIMARY KEY(`globalKey`))",
- "fields": [
- {
- "fieldPath": "globalKey",
- "columnName": "globalKey",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "fullName",
- "columnName": "fullName",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "userName",
- "columnName": "userName",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "userLoginId",
- "columnName": "userLoginId",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "studentName",
- "columnName": "studentName",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "schoolNameShort",
- "columnName": "schoolNameShort",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "type",
- "columnName": "type",
- "affinity": "TEXT",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "globalKey"
- ],
- "autoGenerate": false
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "Recipients",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`mailboxGlobalKey` TEXT NOT NULL, `studentMailboxGlobalKey` TEXT NOT NULL, `fullName` TEXT NOT NULL, `userName` TEXT NOT NULL, `schoolShortName` TEXT NOT NULL, `type` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)",
- "fields": [
- {
- "fieldPath": "mailboxGlobalKey",
- "columnName": "mailboxGlobalKey",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "studentMailboxGlobalKey",
- "columnName": "studentMailboxGlobalKey",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "fullName",
- "columnName": "fullName",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "userName",
- "columnName": "userName",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "schoolShortName",
- "columnName": "schoolShortName",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "type",
- "columnName": "type",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "MobileDevices",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`user_login_id` INTEGER NOT NULL, `device_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)",
- "fields": [
- {
- "fieldPath": "userLoginId",
- "columnName": "user_login_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
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "Teachers",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `short_name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)",
- "fields": [
- {
- "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
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "School",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`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, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)",
- "fields": [
- {
- "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
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "Conferences",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `subject` TEXT NOT NULL, `agenda` TEXT NOT NULL, `present_on_conference` TEXT NOT NULL, `conference_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)",
- "fields": [
- {
- "fieldPath": "studentId",
- "columnName": "student_id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "diaryId",
- "columnName": "diary_id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "title",
- "columnName": "title",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "subject",
- "columnName": "subject",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "agenda",
- "columnName": "agenda",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "presentOnConference",
- "columnName": "present_on_conference",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "conferenceId",
- "columnName": "conference_id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "date",
- "columnName": "date",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "isNotified",
- "columnName": "is_notified",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "TimetableAdditional",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `repeat_id` BLOB DEFAULT NULL, `is_added_by_user` INTEGER NOT NULL DEFAULT 0)",
- "fields": [
- {
- "fieldPath": "studentId",
- "columnName": "student_id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "diaryId",
- "columnName": "diary_id",
- "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": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "repeatId",
- "columnName": "repeat_id",
- "affinity": "BLOB",
- "notNull": false,
- "defaultValue": "NULL"
- },
- {
- "fieldPath": "isAddedByUser",
- "columnName": "is_added_by_user",
- "affinity": "INTEGER",
- "notNull": true,
- "defaultValue": "0"
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "StudentInfo",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `full_name` TEXT NOT NULL, `first_name` TEXT NOT NULL, `second_name` TEXT NOT NULL, `surname` TEXT NOT NULL, `birth_date` INTEGER NOT NULL, `birth_place` TEXT NOT NULL, `gender` TEXT NOT NULL, `has_polish_citizenship` INTEGER NOT NULL, `family_name` TEXT NOT NULL, `parents_names` TEXT NOT NULL, `address` TEXT NOT NULL, `registered_address` TEXT NOT NULL, `correspondence_address` TEXT NOT NULL, `phone_number` TEXT NOT NULL, `cell_phone_number` TEXT NOT NULL, `email` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `first_guardian_full_name` TEXT, `first_guardian_kinship` TEXT, `first_guardian_address` TEXT, `first_guardian_phones` TEXT, `first_guardian_email` TEXT, `second_guardian_full_name` TEXT, `second_guardian_kinship` TEXT, `second_guardian_address` TEXT, `second_guardian_phones` TEXT, `second_guardian_email` TEXT)",
- "fields": [
- {
- "fieldPath": "studentId",
- "columnName": "student_id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "fullName",
- "columnName": "full_name",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "firstName",
- "columnName": "first_name",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "secondName",
- "columnName": "second_name",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "surname",
- "columnName": "surname",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "birthDate",
- "columnName": "birth_date",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "birthPlace",
- "columnName": "birth_place",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "gender",
- "columnName": "gender",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "hasPolishCitizenship",
- "columnName": "has_polish_citizenship",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "familyName",
- "columnName": "family_name",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "parentsNames",
- "columnName": "parents_names",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "address",
- "columnName": "address",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "registeredAddress",
- "columnName": "registered_address",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "correspondenceAddress",
- "columnName": "correspondence_address",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "phoneNumber",
- "columnName": "phone_number",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "cellPhoneNumber",
- "columnName": "cell_phone_number",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "email",
- "columnName": "email",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "firstGuardian.fullName",
- "columnName": "first_guardian_full_name",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "firstGuardian.kinship",
- "columnName": "first_guardian_kinship",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "firstGuardian.address",
- "columnName": "first_guardian_address",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "firstGuardian.phones",
- "columnName": "first_guardian_phones",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "firstGuardian.email",
- "columnName": "first_guardian_email",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "secondGuardian.fullName",
- "columnName": "second_guardian_full_name",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "secondGuardian.kinship",
- "columnName": "second_guardian_kinship",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "secondGuardian.address",
- "columnName": "second_guardian_address",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "secondGuardian.phones",
- "columnName": "second_guardian_phones",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "secondGuardian.email",
- "columnName": "second_guardian_email",
- "affinity": "TEXT",
- "notNull": false
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "TimetableHeaders",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)",
- "fields": [
- {
- "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": "content",
- "columnName": "content",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "SchoolAnnouncements",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`user_login_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)",
- "fields": [
- {
- "fieldPath": "userLoginId",
- "columnName": "user_login_id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "date",
- "columnName": "date",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "subject",
- "columnName": "subject",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "content",
- "columnName": "content",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "isNotified",
- "columnName": "is_notified",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "Notifications",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `type` TEXT NOT NULL, `destination` TEXT NOT NULL DEFAULT '{\"type\":\"io.github.wulkanowy.ui.modules.Destination.Dashboard\"}', `date` INTEGER NOT NULL, `data` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)",
- "fields": [
- {
- "fieldPath": "studentId",
- "columnName": "student_id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "title",
- "columnName": "title",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "content",
- "columnName": "content",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "type",
- "columnName": "type",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "destination",
- "columnName": "destination",
- "affinity": "TEXT",
- "notNull": true,
- "defaultValue": "'{\"type\":\"io.github.wulkanowy.ui.modules.Destination.Dashboard\"}'"
- },
- {
- "fieldPath": "date",
- "columnName": "date",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "data",
- "columnName": "data",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "AdminMessages",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `version_name` INTEGER, `version_max` INTEGER, `target_register_host` TEXT, `target_flavor` TEXT, `destination_url` TEXT, `priority` TEXT NOT NULL, `type` TEXT NOT NULL, `is_dismissible` INTEGER NOT NULL, PRIMARY KEY(`id`))",
- "fields": [
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "title",
- "columnName": "title",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "content",
- "columnName": "content",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "versionMin",
- "columnName": "version_name",
- "affinity": "INTEGER",
- "notNull": false
- },
- {
- "fieldPath": "versionMax",
- "columnName": "version_max",
- "affinity": "INTEGER",
- "notNull": false
- },
- {
- "fieldPath": "targetRegisterHost",
- "columnName": "target_register_host",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "targetFlavor",
- "columnName": "target_flavor",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "destinationUrl",
- "columnName": "destination_url",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "priority",
- "columnName": "priority",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "type",
- "columnName": "type",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "isDismissible",
- "columnName": "is_dismissible",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": false
- },
- "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, '8742176f26afcc81279d4a073dca2949')"
- ]
- }
-}
\ No newline at end of file
diff --git a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/53.json b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/53.json
deleted file mode 100644
index 985617872..000000000
--- a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/53.json
+++ /dev/null
@@ -1,2439 +0,0 @@
-{
- "formatVersion": 1,
- "database": {
- "version": 53,
- "identityHash": "1dc96a366125ec9f8567da87cdc9c863",
- "entities": [
- {
- "tableName": "Students",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`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, `user_name` TEXT 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, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `nick` TEXT NOT NULL, `avatar_color` INTEGER NOT NULL)",
- "fields": [
- {
- "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": "userName",
- "columnName": "user_name",
- "affinity": "TEXT",
- "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
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "nick",
- "columnName": "nick",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "avatarColor",
- "columnName": "avatar_color",
- "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"
- ],
- "orders": [],
- "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}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `kindergarten_diary_id` INTEGER NOT NULL DEFAULT 0, `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, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_current` INTEGER NOT NULL)",
- "fields": [
- {
- "fieldPath": "studentId",
- "columnName": "student_id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "diaryId",
- "columnName": "diary_id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "kindergartenDiaryId",
- "columnName": "kindergarten_diary_id",
- "affinity": "INTEGER",
- "notNull": true,
- "defaultValue": "0"
- },
- {
- "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
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "current",
- "columnName": "is_current",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [
- {
- "name": "index_Semesters_student_id_diary_id_kindergarten_diary_id_semester_id",
- "unique": true,
- "columnNames": [
- "student_id",
- "diary_id",
- "kindergarten_diary_id",
- "semester_id"
- ],
- "orders": [],
- "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Semesters_student_id_diary_id_kindergarten_diary_id_semester_id` ON `${TABLE_NAME}` (`student_id`, `diary_id`, `kindergarten_diary_id`, `semester_id`)"
- }
- ],
- "foreignKeys": []
- },
- {
- "tableName": "Exams",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`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, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)",
- "fields": [
- {
- "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
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "isNotified",
- "columnName": "is_notified",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "Timetable",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`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, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)",
- "fields": [
- {
- "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
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "isNotified",
- "columnName": "is_notified",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "Attendance",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`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, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)",
- "fields": [
- {
- "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
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "isNotified",
- "columnName": "is_notified",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "AttendanceSummary",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`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, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)",
- "fields": [
- {
- "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
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "Grades",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`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, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)",
- "fields": [
- {
- "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
- },
- {
- "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
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "GradesSummary",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`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, `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)",
- "fields": [
- {
- "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
- },
- {
- "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
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "GradePartialStatistics",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `class_average` TEXT NOT NULL, `student_average` TEXT NOT NULL, `class_amounts` TEXT NOT NULL, `student_amounts` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)",
- "fields": [
- {
- "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": "classAverage",
- "columnName": "class_average",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "studentAverage",
- "columnName": "student_average",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "classAmounts",
- "columnName": "class_amounts",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "studentAmounts",
- "columnName": "student_amounts",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "GradesPointsStatistics",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `others` REAL NOT NULL, `student` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)",
- "fields": [
- {
- "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
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "GradeSemesterStatistics",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `amounts` TEXT NOT NULL, `student_grade` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)",
- "fields": [
- {
- "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": "amounts",
- "columnName": "amounts",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "studentGrade",
- "columnName": "student_grade",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "Messages",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`email` TEXT NOT NULL, `message_global_key` TEXT NOT NULL, `mailbox_key` TEXT NOT NULL, `message_id` INTEGER NOT NULL, `correspondents` TEXT NOT NULL, `subject` TEXT NOT NULL, `date` INTEGER NOT NULL, `folder_id` INTEGER NOT NULL, `unread` INTEGER NOT NULL, `read_by` INTEGER, `unread_by` INTEGER, `has_attachments` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `content` TEXT NOT NULL, `sender` TEXT, `recipients` TEXT)",
- "fields": [
- {
- "fieldPath": "email",
- "columnName": "email",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "messageGlobalKey",
- "columnName": "message_global_key",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "mailboxKey",
- "columnName": "mailbox_key",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "messageId",
- "columnName": "message_id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "correspondents",
- "columnName": "correspondents",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "subject",
- "columnName": "subject",
- "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": "readBy",
- "columnName": "read_by",
- "affinity": "INTEGER",
- "notNull": false
- },
- {
- "fieldPath": "unreadBy",
- "columnName": "unread_by",
- "affinity": "INTEGER",
- "notNull": false
- },
- {
- "fieldPath": "hasAttachments",
- "columnName": "has_attachments",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "isNotified",
- "columnName": "is_notified",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "content",
- "columnName": "content",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "sender",
- "columnName": "sender",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "recipients",
- "columnName": "recipients",
- "affinity": "TEXT",
- "notNull": false
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "MessageAttachments",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`real_id` INTEGER NOT NULL, `message_global_key` 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": "messageGlobalKey",
- "columnName": "message_global_key",
- "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}` (`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, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)",
- "fields": [
- {
- "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
- },
- {
- "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
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "Homework",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`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, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_done` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `is_added_by_user` INTEGER NOT NULL)",
- "fields": [
- {
- "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
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "isDone",
- "columnName": "is_done",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "isNotified",
- "columnName": "is_notified",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "isAddedByUser",
- "columnName": "is_added_by_user",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "Subjects",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)",
- "fields": [
- {
- "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
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "LuckyNumbers",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `lucky_number` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)",
- "fields": [
- {
- "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
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "isNotified",
- "columnName": "is_notified",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "CompletedLesson",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`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, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)",
- "fields": [
- {
- "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
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "Mailboxes",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`globalKey` TEXT NOT NULL, `email` TEXT NOT NULL, `symbol` TEXT NOT NULL, `schoolId` TEXT NOT NULL, `fullName` TEXT NOT NULL, `userName` TEXT NOT NULL, `studentName` TEXT NOT NULL, `schoolNameShort` TEXT NOT NULL, `type` TEXT NOT NULL, PRIMARY KEY(`globalKey`))",
- "fields": [
- {
- "fieldPath": "globalKey",
- "columnName": "globalKey",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "email",
- "columnName": "email",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "symbol",
- "columnName": "symbol",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "schoolId",
- "columnName": "schoolId",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "fullName",
- "columnName": "fullName",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "userName",
- "columnName": "userName",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "studentName",
- "columnName": "studentName",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "schoolNameShort",
- "columnName": "schoolNameShort",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "type",
- "columnName": "type",
- "affinity": "TEXT",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "globalKey"
- ],
- "autoGenerate": false
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "Recipients",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`mailboxGlobalKey` TEXT NOT NULL, `studentMailboxGlobalKey` TEXT NOT NULL, `fullName` TEXT NOT NULL, `userName` TEXT NOT NULL, `schoolShortName` TEXT NOT NULL, `type` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)",
- "fields": [
- {
- "fieldPath": "mailboxGlobalKey",
- "columnName": "mailboxGlobalKey",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "studentMailboxGlobalKey",
- "columnName": "studentMailboxGlobalKey",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "fullName",
- "columnName": "fullName",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "userName",
- "columnName": "userName",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "schoolShortName",
- "columnName": "schoolShortName",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "type",
- "columnName": "type",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "MobileDevices",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`user_login_id` INTEGER NOT NULL, `device_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)",
- "fields": [
- {
- "fieldPath": "userLoginId",
- "columnName": "user_login_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
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "Teachers",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `short_name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)",
- "fields": [
- {
- "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
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "School",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`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, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)",
- "fields": [
- {
- "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
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "Conferences",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `subject` TEXT NOT NULL, `agenda` TEXT NOT NULL, `present_on_conference` TEXT NOT NULL, `conference_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)",
- "fields": [
- {
- "fieldPath": "studentId",
- "columnName": "student_id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "diaryId",
- "columnName": "diary_id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "title",
- "columnName": "title",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "subject",
- "columnName": "subject",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "agenda",
- "columnName": "agenda",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "presentOnConference",
- "columnName": "present_on_conference",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "conferenceId",
- "columnName": "conference_id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "date",
- "columnName": "date",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "isNotified",
- "columnName": "is_notified",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "TimetableAdditional",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `repeat_id` BLOB DEFAULT NULL, `is_added_by_user` INTEGER NOT NULL DEFAULT 0)",
- "fields": [
- {
- "fieldPath": "studentId",
- "columnName": "student_id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "diaryId",
- "columnName": "diary_id",
- "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": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "repeatId",
- "columnName": "repeat_id",
- "affinity": "BLOB",
- "notNull": false,
- "defaultValue": "NULL"
- },
- {
- "fieldPath": "isAddedByUser",
- "columnName": "is_added_by_user",
- "affinity": "INTEGER",
- "notNull": true,
- "defaultValue": "0"
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "StudentInfo",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `full_name` TEXT NOT NULL, `first_name` TEXT NOT NULL, `second_name` TEXT NOT NULL, `surname` TEXT NOT NULL, `birth_date` INTEGER NOT NULL, `birth_place` TEXT NOT NULL, `gender` TEXT NOT NULL, `has_polish_citizenship` INTEGER NOT NULL, `family_name` TEXT NOT NULL, `parents_names` TEXT NOT NULL, `address` TEXT NOT NULL, `registered_address` TEXT NOT NULL, `correspondence_address` TEXT NOT NULL, `phone_number` TEXT NOT NULL, `cell_phone_number` TEXT NOT NULL, `email` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `first_guardian_full_name` TEXT, `first_guardian_kinship` TEXT, `first_guardian_address` TEXT, `first_guardian_phones` TEXT, `first_guardian_email` TEXT, `second_guardian_full_name` TEXT, `second_guardian_kinship` TEXT, `second_guardian_address` TEXT, `second_guardian_phones` TEXT, `second_guardian_email` TEXT)",
- "fields": [
- {
- "fieldPath": "studentId",
- "columnName": "student_id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "fullName",
- "columnName": "full_name",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "firstName",
- "columnName": "first_name",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "secondName",
- "columnName": "second_name",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "surname",
- "columnName": "surname",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "birthDate",
- "columnName": "birth_date",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "birthPlace",
- "columnName": "birth_place",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "gender",
- "columnName": "gender",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "hasPolishCitizenship",
- "columnName": "has_polish_citizenship",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "familyName",
- "columnName": "family_name",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "parentsNames",
- "columnName": "parents_names",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "address",
- "columnName": "address",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "registeredAddress",
- "columnName": "registered_address",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "correspondenceAddress",
- "columnName": "correspondence_address",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "phoneNumber",
- "columnName": "phone_number",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "cellPhoneNumber",
- "columnName": "cell_phone_number",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "email",
- "columnName": "email",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "firstGuardian.fullName",
- "columnName": "first_guardian_full_name",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "firstGuardian.kinship",
- "columnName": "first_guardian_kinship",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "firstGuardian.address",
- "columnName": "first_guardian_address",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "firstGuardian.phones",
- "columnName": "first_guardian_phones",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "firstGuardian.email",
- "columnName": "first_guardian_email",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "secondGuardian.fullName",
- "columnName": "second_guardian_full_name",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "secondGuardian.kinship",
- "columnName": "second_guardian_kinship",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "secondGuardian.address",
- "columnName": "second_guardian_address",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "secondGuardian.phones",
- "columnName": "second_guardian_phones",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "secondGuardian.email",
- "columnName": "second_guardian_email",
- "affinity": "TEXT",
- "notNull": false
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "TimetableHeaders",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)",
- "fields": [
- {
- "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": "content",
- "columnName": "content",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "SchoolAnnouncements",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`user_login_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)",
- "fields": [
- {
- "fieldPath": "userLoginId",
- "columnName": "user_login_id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "date",
- "columnName": "date",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "subject",
- "columnName": "subject",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "content",
- "columnName": "content",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "isNotified",
- "columnName": "is_notified",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "Notifications",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `type` TEXT NOT NULL, `destination` TEXT NOT NULL DEFAULT '{\"type\":\"io.github.wulkanowy.ui.modules.Destination.Dashboard\"}', `date` INTEGER NOT NULL, `data` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)",
- "fields": [
- {
- "fieldPath": "studentId",
- "columnName": "student_id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "title",
- "columnName": "title",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "content",
- "columnName": "content",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "type",
- "columnName": "type",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "destination",
- "columnName": "destination",
- "affinity": "TEXT",
- "notNull": true,
- "defaultValue": "'{\"type\":\"io.github.wulkanowy.ui.modules.Destination.Dashboard\"}'"
- },
- {
- "fieldPath": "date",
- "columnName": "date",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "data",
- "columnName": "data",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "AdminMessages",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `version_name` INTEGER, `version_max` INTEGER, `target_register_host` TEXT, `target_flavor` TEXT, `destination_url` TEXT, `priority` TEXT NOT NULL, `type` TEXT NOT NULL, `is_dismissible` INTEGER NOT NULL, PRIMARY KEY(`id`))",
- "fields": [
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "title",
- "columnName": "title",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "content",
- "columnName": "content",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "versionMin",
- "columnName": "version_name",
- "affinity": "INTEGER",
- "notNull": false
- },
- {
- "fieldPath": "versionMax",
- "columnName": "version_max",
- "affinity": "INTEGER",
- "notNull": false
- },
- {
- "fieldPath": "targetRegisterHost",
- "columnName": "target_register_host",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "targetFlavor",
- "columnName": "target_flavor",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "destinationUrl",
- "columnName": "destination_url",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "priority",
- "columnName": "priority",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "type",
- "columnName": "type",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "isDismissible",
- "columnName": "is_dismissible",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": false
- },
- "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, '1dc96a366125ec9f8567da87cdc9c863')"
- ]
- }
-}
\ No newline at end of file
diff --git a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/54.json b/app/schemas/io.github.wulkanowy.data.db.AppDatabase/54.json
deleted file mode 100644
index 7b41672b9..000000000
--- a/app/schemas/io.github.wulkanowy.data.db.AppDatabase/54.json
+++ /dev/null
@@ -1,2439 +0,0 @@
-{
- "formatVersion": 1,
- "database": {
- "version": 54,
- "identityHash": "1dc96a366125ec9f8567da87cdc9c863",
- "entities": [
- {
- "tableName": "Students",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`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, `user_name` TEXT 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, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `nick` TEXT NOT NULL, `avatar_color` INTEGER NOT NULL)",
- "fields": [
- {
- "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": "userName",
- "columnName": "user_name",
- "affinity": "TEXT",
- "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
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "nick",
- "columnName": "nick",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "avatarColor",
- "columnName": "avatar_color",
- "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"
- ],
- "orders": [],
- "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}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `kindergarten_diary_id` INTEGER NOT NULL DEFAULT 0, `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, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_current` INTEGER NOT NULL)",
- "fields": [
- {
- "fieldPath": "studentId",
- "columnName": "student_id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "diaryId",
- "columnName": "diary_id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "kindergartenDiaryId",
- "columnName": "kindergarten_diary_id",
- "affinity": "INTEGER",
- "notNull": true,
- "defaultValue": "0"
- },
- {
- "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
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "current",
- "columnName": "is_current",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [
- {
- "name": "index_Semesters_student_id_diary_id_kindergarten_diary_id_semester_id",
- "unique": true,
- "columnNames": [
- "student_id",
- "diary_id",
- "kindergarten_diary_id",
- "semester_id"
- ],
- "orders": [],
- "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_Semesters_student_id_diary_id_kindergarten_diary_id_semester_id` ON `${TABLE_NAME}` (`student_id`, `diary_id`, `kindergarten_diary_id`, `semester_id`)"
- }
- ],
- "foreignKeys": []
- },
- {
- "tableName": "Exams",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`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, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)",
- "fields": [
- {
- "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
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "isNotified",
- "columnName": "is_notified",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "Timetable",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`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, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)",
- "fields": [
- {
- "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
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "isNotified",
- "columnName": "is_notified",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "Attendance",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`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, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)",
- "fields": [
- {
- "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
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "isNotified",
- "columnName": "is_notified",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "AttendanceSummary",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`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, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)",
- "fields": [
- {
- "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
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "Grades",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`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, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)",
- "fields": [
- {
- "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
- },
- {
- "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
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "GradesSummary",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`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, `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)",
- "fields": [
- {
- "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
- },
- {
- "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
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "GradePartialStatistics",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `class_average` TEXT NOT NULL, `student_average` TEXT NOT NULL, `class_amounts` TEXT NOT NULL, `student_amounts` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)",
- "fields": [
- {
- "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": "classAverage",
- "columnName": "class_average",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "studentAverage",
- "columnName": "student_average",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "classAmounts",
- "columnName": "class_amounts",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "studentAmounts",
- "columnName": "student_amounts",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "GradesPointsStatistics",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `others` REAL NOT NULL, `student` REAL NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)",
- "fields": [
- {
- "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
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "GradeSemesterStatistics",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `semester_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `amounts` TEXT NOT NULL, `student_grade` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)",
- "fields": [
- {
- "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": "amounts",
- "columnName": "amounts",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "studentGrade",
- "columnName": "student_grade",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "Messages",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`email` TEXT NOT NULL, `message_global_key` TEXT NOT NULL, `mailbox_key` TEXT NOT NULL, `message_id` INTEGER NOT NULL, `correspondents` TEXT NOT NULL, `subject` TEXT NOT NULL, `date` INTEGER NOT NULL, `folder_id` INTEGER NOT NULL, `unread` INTEGER NOT NULL, `read_by` INTEGER, `unread_by` INTEGER, `has_attachments` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL, `content` TEXT NOT NULL, `sender` TEXT, `recipients` TEXT)",
- "fields": [
- {
- "fieldPath": "email",
- "columnName": "email",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "messageGlobalKey",
- "columnName": "message_global_key",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "mailboxKey",
- "columnName": "mailbox_key",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "messageId",
- "columnName": "message_id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "correspondents",
- "columnName": "correspondents",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "subject",
- "columnName": "subject",
- "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": "readBy",
- "columnName": "read_by",
- "affinity": "INTEGER",
- "notNull": false
- },
- {
- "fieldPath": "unreadBy",
- "columnName": "unread_by",
- "affinity": "INTEGER",
- "notNull": false
- },
- {
- "fieldPath": "hasAttachments",
- "columnName": "has_attachments",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "isNotified",
- "columnName": "is_notified",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "content",
- "columnName": "content",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "sender",
- "columnName": "sender",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "recipients",
- "columnName": "recipients",
- "affinity": "TEXT",
- "notNull": false
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "MessageAttachments",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`real_id` INTEGER NOT NULL, `message_global_key` 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": "messageGlobalKey",
- "columnName": "message_global_key",
- "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}` (`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, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_read` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL)",
- "fields": [
- {
- "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
- },
- {
- "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
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "Homework",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`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, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_done` INTEGER NOT NULL, `is_notified` INTEGER NOT NULL, `is_added_by_user` INTEGER NOT NULL)",
- "fields": [
- {
- "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
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "isDone",
- "columnName": "is_done",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "isNotified",
- "columnName": "is_notified",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "isAddedByUser",
- "columnName": "is_added_by_user",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "Subjects",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `real_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)",
- "fields": [
- {
- "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
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "LuckyNumbers",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `lucky_number` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)",
- "fields": [
- {
- "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
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "isNotified",
- "columnName": "is_notified",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "CompletedLesson",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`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, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)",
- "fields": [
- {
- "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
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "Mailboxes",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`globalKey` TEXT NOT NULL, `email` TEXT NOT NULL, `symbol` TEXT NOT NULL, `schoolId` TEXT NOT NULL, `fullName` TEXT NOT NULL, `userName` TEXT NOT NULL, `studentName` TEXT NOT NULL, `schoolNameShort` TEXT NOT NULL, `type` TEXT NOT NULL, PRIMARY KEY(`globalKey`))",
- "fields": [
- {
- "fieldPath": "globalKey",
- "columnName": "globalKey",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "email",
- "columnName": "email",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "symbol",
- "columnName": "symbol",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "schoolId",
- "columnName": "schoolId",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "fullName",
- "columnName": "fullName",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "userName",
- "columnName": "userName",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "studentName",
- "columnName": "studentName",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "schoolNameShort",
- "columnName": "schoolNameShort",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "type",
- "columnName": "type",
- "affinity": "TEXT",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "globalKey"
- ],
- "autoGenerate": false
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "Recipients",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`mailboxGlobalKey` TEXT NOT NULL, `studentMailboxGlobalKey` TEXT NOT NULL, `fullName` TEXT NOT NULL, `userName` TEXT NOT NULL, `schoolShortName` TEXT NOT NULL, `type` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)",
- "fields": [
- {
- "fieldPath": "mailboxGlobalKey",
- "columnName": "mailboxGlobalKey",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "studentMailboxGlobalKey",
- "columnName": "studentMailboxGlobalKey",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "fullName",
- "columnName": "fullName",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "userName",
- "columnName": "userName",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "schoolShortName",
- "columnName": "schoolShortName",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "type",
- "columnName": "type",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "MobileDevices",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`user_login_id` INTEGER NOT NULL, `device_id` INTEGER NOT NULL, `name` TEXT NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)",
- "fields": [
- {
- "fieldPath": "userLoginId",
- "columnName": "user_login_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
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "Teachers",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `class_id` INTEGER NOT NULL, `subject` TEXT NOT NULL, `name` TEXT NOT NULL, `short_name` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)",
- "fields": [
- {
- "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
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "School",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`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, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)",
- "fields": [
- {
- "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
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "Conferences",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `subject` TEXT NOT NULL, `agenda` TEXT NOT NULL, `present_on_conference` TEXT NOT NULL, `conference_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)",
- "fields": [
- {
- "fieldPath": "studentId",
- "columnName": "student_id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "diaryId",
- "columnName": "diary_id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "title",
- "columnName": "title",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "subject",
- "columnName": "subject",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "agenda",
- "columnName": "agenda",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "presentOnConference",
- "columnName": "present_on_conference",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "conferenceId",
- "columnName": "conference_id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "date",
- "columnName": "date",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "isNotified",
- "columnName": "is_notified",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "TimetableAdditional",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `start` INTEGER NOT NULL, `end` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `repeat_id` BLOB DEFAULT NULL, `is_added_by_user` INTEGER NOT NULL DEFAULT 0)",
- "fields": [
- {
- "fieldPath": "studentId",
- "columnName": "student_id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "diaryId",
- "columnName": "diary_id",
- "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": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "repeatId",
- "columnName": "repeat_id",
- "affinity": "BLOB",
- "notNull": false,
- "defaultValue": "NULL"
- },
- {
- "fieldPath": "isAddedByUser",
- "columnName": "is_added_by_user",
- "affinity": "INTEGER",
- "notNull": true,
- "defaultValue": "0"
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "StudentInfo",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `full_name` TEXT NOT NULL, `first_name` TEXT NOT NULL, `second_name` TEXT NOT NULL, `surname` TEXT NOT NULL, `birth_date` INTEGER NOT NULL, `birth_place` TEXT NOT NULL, `gender` TEXT NOT NULL, `has_polish_citizenship` INTEGER NOT NULL, `family_name` TEXT NOT NULL, `parents_names` TEXT NOT NULL, `address` TEXT NOT NULL, `registered_address` TEXT NOT NULL, `correspondence_address` TEXT NOT NULL, `phone_number` TEXT NOT NULL, `cell_phone_number` TEXT NOT NULL, `email` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `first_guardian_full_name` TEXT, `first_guardian_kinship` TEXT, `first_guardian_address` TEXT, `first_guardian_phones` TEXT, `first_guardian_email` TEXT, `second_guardian_full_name` TEXT, `second_guardian_kinship` TEXT, `second_guardian_address` TEXT, `second_guardian_phones` TEXT, `second_guardian_email` TEXT)",
- "fields": [
- {
- "fieldPath": "studentId",
- "columnName": "student_id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "fullName",
- "columnName": "full_name",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "firstName",
- "columnName": "first_name",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "secondName",
- "columnName": "second_name",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "surname",
- "columnName": "surname",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "birthDate",
- "columnName": "birth_date",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "birthPlace",
- "columnName": "birth_place",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "gender",
- "columnName": "gender",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "hasPolishCitizenship",
- "columnName": "has_polish_citizenship",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "familyName",
- "columnName": "family_name",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "parentsNames",
- "columnName": "parents_names",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "address",
- "columnName": "address",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "registeredAddress",
- "columnName": "registered_address",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "correspondenceAddress",
- "columnName": "correspondence_address",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "phoneNumber",
- "columnName": "phone_number",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "cellPhoneNumber",
- "columnName": "cell_phone_number",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "email",
- "columnName": "email",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "firstGuardian.fullName",
- "columnName": "first_guardian_full_name",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "firstGuardian.kinship",
- "columnName": "first_guardian_kinship",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "firstGuardian.address",
- "columnName": "first_guardian_address",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "firstGuardian.phones",
- "columnName": "first_guardian_phones",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "firstGuardian.email",
- "columnName": "first_guardian_email",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "secondGuardian.fullName",
- "columnName": "second_guardian_full_name",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "secondGuardian.kinship",
- "columnName": "second_guardian_kinship",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "secondGuardian.address",
- "columnName": "second_guardian_address",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "secondGuardian.phones",
- "columnName": "second_guardian_phones",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "secondGuardian.email",
- "columnName": "second_guardian_email",
- "affinity": "TEXT",
- "notNull": false
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "TimetableHeaders",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `diary_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)",
- "fields": [
- {
- "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": "content",
- "columnName": "content",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "SchoolAnnouncements",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`user_login_id` INTEGER NOT NULL, `date` INTEGER NOT NULL, `subject` TEXT NOT NULL, `content` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `is_notified` INTEGER NOT NULL)",
- "fields": [
- {
- "fieldPath": "userLoginId",
- "columnName": "user_login_id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "date",
- "columnName": "date",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "subject",
- "columnName": "subject",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "content",
- "columnName": "content",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "isNotified",
- "columnName": "is_notified",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "Notifications",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`student_id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `type` TEXT NOT NULL, `destination` TEXT NOT NULL DEFAULT '{\"type\":\"io.github.wulkanowy.ui.modules.Destination.Dashboard\"}', `date` INTEGER NOT NULL, `data` TEXT, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)",
- "fields": [
- {
- "fieldPath": "studentId",
- "columnName": "student_id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "title",
- "columnName": "title",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "content",
- "columnName": "content",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "type",
- "columnName": "type",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "destination",
- "columnName": "destination",
- "affinity": "TEXT",
- "notNull": true,
- "defaultValue": "'{\"type\":\"io.github.wulkanowy.ui.modules.Destination.Dashboard\"}'"
- },
- {
- "fieldPath": "date",
- "columnName": "date",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "data",
- "columnName": "data",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "AdminMessages",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `version_name` INTEGER, `version_max` INTEGER, `target_register_host` TEXT, `target_flavor` TEXT, `destination_url` TEXT, `priority` TEXT NOT NULL, `type` TEXT NOT NULL, `is_dismissible` INTEGER NOT NULL, PRIMARY KEY(`id`))",
- "fields": [
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "title",
- "columnName": "title",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "content",
- "columnName": "content",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "versionMin",
- "columnName": "version_name",
- "affinity": "INTEGER",
- "notNull": false
- },
- {
- "fieldPath": "versionMax",
- "columnName": "version_max",
- "affinity": "INTEGER",
- "notNull": false
- },
- {
- "fieldPath": "targetRegisterHost",
- "columnName": "target_register_host",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "targetFlavor",
- "columnName": "target_flavor",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "destinationUrl",
- "columnName": "destination_url",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "priority",
- "columnName": "priority",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "type",
- "columnName": "type",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "isDismissible",
- "columnName": "is_dismissible",
- "affinity": "INTEGER",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": false
- },
- "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, '1dc96a366125ec9f8567da87cdc9c863')"
- ]
- }
-}
\ No newline at end of file
diff --git a/app/src/debug/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/debug/res/mipmap-anydpi-v26/ic_launcher.xml
index b7b756b9e..7dbec2cb9 100644
--- a/app/src/debug/res/mipmap-anydpi-v26/ic_launcher.xml
+++ b/app/src/debug/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -2,5 +2,4 @@
-
-
+
\ No newline at end of file
diff --git a/app/src/debug/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/debug/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 000000000..7dbec2cb9
--- /dev/null
+++ b/app/src/debug/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/debug/res/mipmap-hdpi/ic_launcher_round.png b/app/src/debug/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 000000000..81e723ecc
Binary files /dev/null and b/app/src/debug/res/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/app/src/debug/res/mipmap-mdpi/ic_launcher_round.png b/app/src/debug/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 000000000..394b57076
Binary files /dev/null and b/app/src/debug/res/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/app/src/debug/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/debug/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 000000000..365b4d663
Binary files /dev/null and b/app/src/debug/res/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/app/src/debug/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/debug/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 000000000..463c089b3
Binary files /dev/null and b/app/src/debug/res/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/app/src/debug/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/debug/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 000000000..53d6f5bbd
Binary files /dev/null and b/app/src/debug/res/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/app/src/fdroid/java/io/github/wulkanowy/utils/AnalyticsHelper.kt b/app/src/fdroid/java/io/github/wulkanowy/utils/AnalyticsHelper.kt
index a3eed484a..3bf7e1693 100644
--- a/app/src/fdroid/java/io/github/wulkanowy/utils/AnalyticsHelper.kt
+++ b/app/src/fdroid/java/io/github/wulkanowy/utils/AnalyticsHelper.kt
@@ -8,7 +8,15 @@ import javax.inject.Singleton
@Suppress("UNUSED_PARAMETER")
class AnalyticsHelper @Inject constructor() {
- fun logEvent(name: String, vararg params: Pair) = Unit
- fun setCurrentScreen(activity: Activity, name: String?) = Unit
- fun popCurrentScreen(name: String?) = Unit
+ fun logEvent(name: String, vararg params: Pair) {
+ // do nothing
+ }
+
+ fun setCurrentScreen(activity: Activity, name: String?) {
+ // do nothing
+ }
+
+ fun popCurrentScreen(name: String?) {
+ // do nothing
+ }
}
diff --git a/app/src/hms/java/io/github/wulkanowy/utils/AnalyticsHelper.kt b/app/src/hms/java/io/github/wulkanowy/utils/AnalyticsHelper.kt
index 1f78931ae..5d33825f1 100644
--- a/app/src/hms/java/io/github/wulkanowy/utils/AnalyticsHelper.kt
+++ b/app/src/hms/java/io/github/wulkanowy/utils/AnalyticsHelper.kt
@@ -3,38 +3,26 @@ package io.github.wulkanowy.utils
import android.app.Activity
import android.content.Context
import android.os.Bundle
-import com.huawei.agconnect.crash.AGConnectCrash
import com.huawei.hms.analytics.HiAnalytics
import dagger.hilt.android.qualifiers.ApplicationContext
-import io.github.wulkanowy.data.repositories.PreferencesRepository
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class AnalyticsHelper @Inject constructor(
- @ApplicationContext private val context: Context,
- preferencesRepository: PreferencesRepository,
- appInfo: AppInfo,
+ @ApplicationContext private val context: Context
) {
private val analytics by lazy { HiAnalytics.getInstance(context) }
- private val connectCrash by lazy { AGConnectCrash.getInstance() }
-
- init {
- if (!appInfo.isDebug) {
- connectCrash.setUserId(preferencesRepository.installationId)
- }
- }
-
fun logEvent(name: String, vararg params: Pair) {
Bundle().apply {
- params.forEach { (key, value) ->
- if (value == null) return@forEach
- when (value) {
- is String -> putString(key, value)
- is Int -> putInt(key, value)
- is Boolean -> putBoolean(key, value)
+ params.forEach {
+ if (it.second == null) return@forEach
+ when (it.second) {
+ is String, is String? -> putString(it.first, it.second as String)
+ is Int, is Int? -> putInt(it.first, it.second as Int)
+ is Boolean, is Boolean? -> putBoolean(it.first, it.second as Boolean)
}
}
analytics.onEvent(name, this)
diff --git a/app/src/hms/java/io/github/wulkanowy/utils/CrashLogUtils.kt b/app/src/hms/java/io/github/wulkanowy/utils/CrashLogUtils.kt
index 377e83666..b0c34f413 100644
--- a/app/src/hms/java/io/github/wulkanowy/utils/CrashLogUtils.kt
+++ b/app/src/hms/java/io/github/wulkanowy/utils/CrashLogUtils.kt
@@ -3,7 +3,6 @@ package io.github.wulkanowy.utils
import android.util.Log
import com.huawei.agconnect.crash.AGConnectCrash
import fr.bipi.tressence.base.FormatterPriorityTree
-import fr.bipi.tressence.common.StackTraceRecorder
class CrashLogTree : FormatterPriorityTree(Log.VERBOSE) {
@@ -23,10 +22,16 @@ class CrashLogExceptionTree : FormatterPriorityTree(Log.ERROR, ExceptionFilter)
override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
if (skipLog(priority, tag, message, t)) return
+ // Disabled due to a bug in the Huawei library
+
+ /*connectCrash.setCustomKey("priority", priority)
+ connectCrash.setCustomKey("tag", tag.orEmpty())
+ connectCrash.setCustomKey("message", message)
+
if (t != null) {
connectCrash.recordException(t)
} else {
connectCrash.recordException(StackTraceRecorder(format(priority, tag, message)))
- }
+ }*/
}
}
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 3773093b2..7835db902 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -8,8 +8,7 @@
-
-
+
@@ -37,14 +36,13 @@
+ tools:ignore="GoogleAppIndexingWarning,UnusedAttribute">
Resource.mapData(block: (T) -> U) = when (this) {
fun Flow>.logResourceStatus(name: String, showData: Boolean = false) = onEach {
val description = when (it) {
- is Resource.Intermediate -> "intermediate data received" + if (showData) " (data: `${it.data}`)" else ""
is Resource.Loading -> "started"
+ is Resource.Intermediate -> "intermediate data received" + if (showData) " (data: `${it.data}`)" else ""
is Resource.Success -> "success" + if (showData) " (data: `${it.data}`)" else ""
is Resource.Error -> "exception occurred: ${it.error}"
}
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 cfb53485f..15b38805b 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
@@ -47,7 +47,6 @@ import javax.inject.Singleton
AutoMigration(from = 44, to = 45),
AutoMigration(from = 46, to = 47),
AutoMigration(from = 47, to = 48),
- AutoMigration(from = 51, to = 52),
],
version = AppDatabase.VERSION_SCHEMA,
exportSchema = true
@@ -56,7 +55,7 @@ import javax.inject.Singleton
abstract class AppDatabase : RoomDatabase() {
companion object {
- const val VERSION_SCHEMA = 54
+ const val VERSION_SCHEMA = 51
fun getMigrations(sharedPrefProvider: SharedPrefProvider, appInfo: AppInfo) = arrayOf(
Migration2(),
@@ -106,8 +105,6 @@ abstract class AppDatabase : RoomDatabase() {
Migration49(),
Migration50(),
Migration51(),
- Migration53(),
- Migration54(),
)
fun newInstance(
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 056a5cbd1..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
@@ -2,12 +2,11 @@ package io.github.wulkanowy.data.db.dao
import androidx.room.Delete
import androidx.room.Insert
-import androidx.room.OnConflictStrategy
import androidx.room.Update
interface BaseDao {
- @Insert(onConflict = OnConflictStrategy.REPLACE)
+ @Insert
suspend fun insertAll(items: List): List
@Update
diff --git a/app/src/main/java/io/github/wulkanowy/data/db/dao/MailboxDao.kt b/app/src/main/java/io/github/wulkanowy/data/db/dao/MailboxDao.kt
index 084192a07..8589db311 100644
--- a/app/src/main/java/io/github/wulkanowy/data/db/dao/MailboxDao.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/db/dao/MailboxDao.kt
@@ -3,16 +3,15 @@ package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.Mailbox
-import kotlinx.coroutines.flow.Flow
import javax.inject.Singleton
@Singleton
@Dao
interface MailboxDao : BaseDao {
- @Query("SELECT * FROM Mailboxes WHERE email = :email")
- suspend fun loadAll(email: String): List
+ @Query("SELECT * FROM Mailboxes WHERE userLoginId = :userLoginId ")
+ suspend fun loadAll(userLoginId: Int): List
- @Query("SELECT * FROM Mailboxes WHERE email = :email AND symbol = :symbol AND schoolId = :schoolId")
- fun loadAll(email: String, symbol: String, schoolId: String): Flow>
+ @Query("SELECT * FROM Mailboxes WHERE userLoginId = :userLoginId AND studentName = :studentName ")
+ suspend fun load(userLoginId: Int, studentName: String): Mailbox?
}
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 1709f7636..8c730c9bc 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
@@ -16,7 +16,4 @@ interface MessagesDao : BaseDao {
@Query("SELECT * FROM Messages WHERE mailbox_key = :mailboxKey AND folder_id = :folder ORDER BY date DESC")
fun loadAll(mailboxKey: String, folder: Int): Flow>
-
- @Query("SELECT * FROM Messages WHERE email = :email AND folder_id = :folder ORDER BY date DESC")
- fun loadAll(folder: Int, email: String): Flow>
}
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 b4b7379f2..5e6eec668 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
@@ -13,7 +13,4 @@ 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): Flow>
-
- @Query("SELECT * FROM Timetable WHERE diary_id = :diaryId AND student_id = :studentId AND date >= :from AND date <= :end")
- fun load(diaryId: Int, studentId: Int, from: LocalDate, end: LocalDate): List
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/db/entities/Mailbox.kt b/app/src/main/java/io/github/wulkanowy/data/db/entities/Mailbox.kt
index e65e213dd..7c08e481d 100644
--- a/app/src/main/java/io/github/wulkanowy/data/db/entities/Mailbox.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/db/entities/Mailbox.kt
@@ -1,27 +1,20 @@
package io.github.wulkanowy.data.db.entities
-import android.os.Parcelable
import androidx.room.Entity
import androidx.room.PrimaryKey
-import kotlinx.parcelize.Parcelize
-@Parcelize
@Entity(tableName = "Mailboxes")
data class Mailbox(
@PrimaryKey
val globalKey: String,
-
- val email: String,
- val symbol: String,
- val schoolId: String,
-
val fullName: String,
val userName: String,
+ val userLoginId: Int,
val studentName: String,
val schoolNameShort: String,
val type: MailboxType,
-) : java.io.Serializable, Parcelable
+)
enum class MailboxType {
STUDENT,
diff --git a/app/src/main/java/io/github/wulkanowy/data/db/entities/Message.kt b/app/src/main/java/io/github/wulkanowy/data/db/entities/Message.kt
index d1356b33d..77874e03d 100644
--- a/app/src/main/java/io/github/wulkanowy/data/db/entities/Message.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/db/entities/Message.kt
@@ -9,9 +9,6 @@ import java.time.Instant
@Entity(tableName = "Messages")
data class Message(
- @ColumnInfo(name = "email")
- val email: String,
-
@ColumnInfo(name = "message_global_key")
val messageGlobalKey: String,
@@ -32,12 +29,6 @@ data class Message(
var unread: Boolean,
- @ColumnInfo(name = "read_by")
- val readBy: Int?,
-
- @ColumnInfo(name = "unread_by")
- val unreadBy: Int?,
-
@ColumnInfo(name = "has_attachments")
val hasAttachments: Boolean
) : Serializable {
diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration53.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration53.kt
deleted file mode 100644
index 12624a51a..000000000
--- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration53.kt
+++ /dev/null
@@ -1,57 +0,0 @@
-package io.github.wulkanowy.data.db.migrations
-
-import androidx.room.migration.Migration
-import androidx.sqlite.db.SupportSQLiteDatabase
-
-class Migration53 : Migration(52, 53) {
-
- override fun migrate(database: SupportSQLiteDatabase) {
- createMailboxTable(database)
- recreateMessagesTable(database)
- }
-
- private fun createMailboxTable(database: SupportSQLiteDatabase) {
- database.execSQL("DROP TABLE IF EXISTS Mailboxes")
- database.execSQL(
- """
- CREATE TABLE IF NOT EXISTS `Mailboxes` (
- `globalKey` TEXT NOT NULL,
- `email` TEXT NOT NULL,
- `symbol` TEXT NOT NULL,
- `schoolId` TEXT NOT NULL,
- `fullName` TEXT NOT NULL,
- `userName` TEXT NOT NULL,
- `studentName` TEXT NOT NULL,
- `schoolNameShort` TEXT NOT NULL,
- `type` TEXT NOT NULL,
- PRIMARY KEY(`globalKey`)
- )""".trimIndent()
- )
- }
-
- private fun recreateMessagesTable(database: SupportSQLiteDatabase) {
- database.execSQL("DROP TABLE IF EXISTS Messages")
- database.execSQL(
- """
- CREATE TABLE IF NOT EXISTS `Messages` (
- `email` TEXT NOT NULL,
- `message_global_key` TEXT NOT NULL,
- `mailbox_key` TEXT NOT NULL,
- `message_id` INTEGER NOT NULL,
- `correspondents` TEXT NOT NULL,
- `subject` TEXT NOT NULL,
- `date` INTEGER NOT NULL,
- `folder_id` INTEGER NOT NULL,
- `unread` INTEGER NOT NULL,
- `read_by` INTEGER,
- `unread_by` INTEGER,
- `has_attachments` INTEGER NOT NULL,
- `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
- `is_notified` INTEGER NOT NULL,
- `content` TEXT NOT NULL,
- `sender` TEXT,
- `recipients` TEXT
- )""".trimIndent()
- )
- }
-}
diff --git a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration54.kt b/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration54.kt
deleted file mode 100644
index 678bd32f2..000000000
--- a/app/src/main/java/io/github/wulkanowy/data/db/migrations/Migration54.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-package io.github.wulkanowy.data.db.migrations
-
-import androidx.room.migration.Migration
-import androidx.sqlite.db.SupportSQLiteDatabase
-
-class Migration54 : Migration(53, 54) {
-
- override fun migrate(database: SupportSQLiteDatabase) {
- migrateResman(database)
- removeTomaszowMazowieckiStudents(database)
- }
-
- private fun migrateResman(database: SupportSQLiteDatabase) {
- database.execSQL("""
- UPDATE Students SET
- scrapper_base_url = 'https://vulcan.net.pl',
- login_type = 'ADFSLightScoped',
- symbol = 'rzeszowprojekt'
- WHERE scrapper_base_url = 'https://resman.pl'
- """.trimIndent())
- }
-
- private fun removeTomaszowMazowieckiStudents(database: SupportSQLiteDatabase) {
- database.execSQL("DELETE FROM Students WHERE symbol = 'tomaszowmazowiecki'")
- }
-}
diff --git a/app/src/main/java/io/github/wulkanowy/data/mappers/AttendanceMapper.kt b/app/src/main/java/io/github/wulkanowy/data/mappers/AttendanceMapper.kt
index c0ed0c8c2..46e67fdaa 100644
--- a/app/src/main/java/io/github/wulkanowy/data/mappers/AttendanceMapper.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/mappers/AttendanceMapper.kt
@@ -3,22 +3,17 @@ package io.github.wulkanowy.data.mappers
import io.github.wulkanowy.data.db.entities.Attendance
import io.github.wulkanowy.data.db.entities.AttendanceSummary
import io.github.wulkanowy.data.db.entities.Semester
-import io.github.wulkanowy.data.db.entities.Timetable
import io.github.wulkanowy.sdk.pojo.Attendance as SdkAttendance
import io.github.wulkanowy.sdk.pojo.AttendanceSummary as SdkAttendanceSummary
-fun List.mapToEntities(semester: Semester, lessons: List) = map {
+fun List.mapToEntities(semester: Semester) = map {
Attendance(
studentId = semester.studentId,
diaryId = semester.diaryId,
date = it.date,
timeId = it.timeId,
number = it.number,
- subject = it.subject.ifBlank {
- lessons.find { lesson ->
- lesson.date == it.date && lesson.number == it.number
- }?.subject.orEmpty()
- },
+ subject = it.subject,
name = it.name,
presence = it.presence,
absence = it.absence,
diff --git a/app/src/main/java/io/github/wulkanowy/data/mappers/MailboxMapper.kt b/app/src/main/java/io/github/wulkanowy/data/mappers/MailboxMapper.kt
index 0cf547770..2ccca1b90 100644
--- a/app/src/main/java/io/github/wulkanowy/data/mappers/MailboxMapper.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/mappers/MailboxMapper.kt
@@ -10,11 +10,9 @@ fun List.mapToEntities(student: Student) = map {
globalKey = it.globalKey,
fullName = it.fullName,
userName = it.userName,
+ userLoginId = student.userLoginId,
studentName = it.studentName,
schoolNameShort = it.schoolNameShort,
type = MailboxType.valueOf(it.type.name),
- email = student.email,
- symbol = student.symbol,
- schoolId = student.schoolSymbol,
)
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/mappers/MessageMapper.kt b/app/src/main/java/io/github/wulkanowy/data/mappers/MessageMapper.kt
index 2ede5aa1b..2e7967f0e 100644
--- a/app/src/main/java/io/github/wulkanowy/data/mappers/MessageMapper.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/mappers/MessageMapper.kt
@@ -2,36 +2,21 @@ package io.github.wulkanowy.data.mappers
import io.github.wulkanowy.data.db.entities.*
import io.github.wulkanowy.sdk.pojo.MailboxType
-import timber.log.Timber
import io.github.wulkanowy.sdk.pojo.Message as SdkMessage
import io.github.wulkanowy.sdk.pojo.MessageAttachment as SdkMessageAttachment
import io.github.wulkanowy.sdk.pojo.Recipient as SdkRecipient
-fun List.mapToEntities(
- student: Student,
- mailbox: Mailbox?,
- allMailboxes: List
-): List = map {
+fun List.mapToEntities(mailbox: Mailbox) = map {
Message(
messageGlobalKey = it.globalKey,
- mailboxKey = mailbox?.globalKey ?: allMailboxes.find { box ->
- box.fullName == it.mailbox
- }?.globalKey.let { mailboxKey ->
- if (mailboxKey == null) {
- Timber.e("Can't find ${it.mailbox} in $allMailboxes")
- "unknown"
- } else mailboxKey
- },
- email = student.email,
+ mailboxKey = mailbox.globalKey,
messageId = it.id,
correspondents = it.correspondents,
subject = it.subject.trim(),
date = it.dateZoned.toInstant(),
folderId = it.folderId,
unread = it.unread,
- unreadBy = it.unreadBy,
- readBy = it.readBy,
- hasAttachments = it.hasAttachments,
+ hasAttachments = it.hasAttachments
).apply {
content = it.content.orEmpty()
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/mappers/RegisterUserMapper.kt b/app/src/main/java/io/github/wulkanowy/data/mappers/RegisterUserMapper.kt
deleted file mode 100644
index 2dfd7e062..000000000
--- a/app/src/main/java/io/github/wulkanowy/data/mappers/RegisterUserMapper.kt
+++ /dev/null
@@ -1,87 +0,0 @@
-package io.github.wulkanowy.data.mappers
-
-import io.github.wulkanowy.data.db.entities.Student
-import io.github.wulkanowy.data.db.entities.StudentWithSemesters
-import io.github.wulkanowy.data.pojos.*
-import io.github.wulkanowy.sdk.Sdk
-import io.github.wulkanowy.sdk.mapper.mapSemesters
-import java.time.Instant
-import io.github.wulkanowy.sdk.scrapper.register.RegisterStudent as SdkRegisterStudent
-import io.github.wulkanowy.sdk.scrapper.register.RegisterUser as SdkRegisterUser
-
-fun SdkRegisterUser.mapToPojo(password: String) = RegisterUser(
- email = email,
- login = login,
- password = password,
- baseUrl = baseUrl,
- loginType = loginType,
- symbols = symbols.map { registerSymbol ->
- RegisterSymbol(
- symbol = registerSymbol.symbol,
- error = registerSymbol.error,
- userName = registerSymbol.userName,
- schools = registerSymbol.schools.map {
- RegisterUnit(
- userLoginId = it.userLoginId,
- schoolId = it.schoolId,
- schoolName = it.schoolName,
- schoolShortName = it.schoolShortName,
- parentIds = it.parentIds,
- studentIds = it.studentIds,
- employeeIds = it.employeeIds,
- error = it.error,
- students = it.subjects
- .filterIsInstance()
- .map { registerSubject ->
- RegisterStudent(
- studentId = registerSubject.studentId,
- studentName = registerSubject.studentName,
- studentSecondName = registerSubject.studentSecondName,
- studentSurname = registerSubject.studentSurname,
- className = registerSubject.className,
- classId = registerSubject.classId,
- isParent = registerSubject.isParent,
- semesters = registerSubject.semesters
- .mapSemesters()
- .mapToEntities(registerSubject.studentId),
- )
- },
- )
- }
- )
- }
-)
-
-fun RegisterStudent.mapToStudentWithSemesters(
- user: RegisterUser,
- symbol: RegisterSymbol,
- unit: RegisterUnit,
- colors: List,
-): StudentWithSemesters = StudentWithSemesters(
- semesters = semesters,
- student = Student(
- email = user.login, // for compatibility
- userName = symbol.userName,
- userLoginId = unit.userLoginId,
- isParent = isParent,
- className = className,
- classId = classId,
- studentId = studentId,
- symbol = symbol.symbol,
- loginType = user.loginType.name,
- schoolName = unit.schoolName,
- schoolShortName = unit.schoolShortName,
- schoolSymbol = unit.schoolId,
- studentName = "$studentName $studentSurname",
- loginMode = Sdk.Mode.SCRAPPER.name,
- scrapperBaseUrl = user.baseUrl,
- mobileBaseUrl = "",
- certificateKey = "",
- privateKey = "",
- password = user.password,
- isCurrent = false,
- registrationDate = Instant.now(),
- ).apply {
- avatarColor = colors.random()
- },
-)
diff --git a/app/src/main/java/io/github/wulkanowy/data/pojos/RegisterUser.kt b/app/src/main/java/io/github/wulkanowy/data/pojos/RegisterUser.kt
deleted file mode 100644
index 4aea33771..000000000
--- a/app/src/main/java/io/github/wulkanowy/data/pojos/RegisterUser.kt
+++ /dev/null
@@ -1,43 +0,0 @@
-package io.github.wulkanowy.data.pojos
-
-import io.github.wulkanowy.data.db.entities.Semester
-import io.github.wulkanowy.sdk.scrapper.Scrapper
-
-data class RegisterUser(
- val email: String,
- val password: String,
- val login: String, // may be the same as email
- val baseUrl: String,
- val loginType: Scrapper.LoginType,
- val symbols: List,
-) : java.io.Serializable
-
-data class RegisterSymbol(
- val symbol: String,
- val error: Throwable?,
- val userName: String,
- val schools: List,
-) : java.io.Serializable
-
-data class RegisterUnit(
- val userLoginId: Int,
- val schoolId: String,
- val schoolName: String,
- val schoolShortName: String,
- val parentIds: List,
- val studentIds: List,
- val employeeIds: List,
- val error: Throwable?,
- val students: List,
-) : java.io.Serializable
-
-data class RegisterStudent(
- val studentId: Int,
- val studentName: String,
- val studentSecondName: String,
- val studentSurname: String,
- val className: String,
- val classId: Int,
- val isParent: Boolean,
- val semesters: List,
-) : java.io.Serializable
diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/AttendanceRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/AttendanceRepository.kt
index fd5d8bd16..9aa6562a6 100644
--- a/app/src/main/java/io/github/wulkanowy/data/repositories/AttendanceRepository.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/repositories/AttendanceRepository.kt
@@ -1,7 +1,6 @@
package io.github.wulkanowy.data.repositories
import io.github.wulkanowy.data.db.dao.AttendanceDao
-import io.github.wulkanowy.data.db.dao.TimetableDao
import io.github.wulkanowy.data.db.entities.Attendance
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
@@ -10,10 +9,8 @@ import io.github.wulkanowy.data.networkBoundResource
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.sdk.pojo.Absent
import io.github.wulkanowy.utils.*
-import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.sync.Mutex
-import kotlinx.coroutines.withContext
import java.time.LocalDate
import java.time.LocalDateTime
import java.time.LocalTime
@@ -23,7 +20,6 @@ import javax.inject.Singleton
@Singleton
class AttendanceRepository @Inject constructor(
private val attendanceDb: AttendanceDao,
- private val timetableDb: TimetableDao,
private val sdk: Sdk,
private val refreshHelper: AutoRefreshHelper,
) {
@@ -52,15 +48,10 @@ class AttendanceRepository @Inject constructor(
attendanceDb.loadAll(semester.diaryId, semester.studentId, start.monday, end.sunday)
},
fetch = {
- val lessons = withContext(Dispatchers.IO) {
- timetableDb.load(
- semester.diaryId, semester.studentId, start.monday, end.sunday
- )
- }
sdk.init(student)
.switchDiary(semester.diaryId, semester.kindergartenDiaryId, semester.schoolYear)
.getAttendance(start.monday, end.sunday, semester.semesterId)
- .mapToEntities(semester, lessons)
+ .mapToEntities(semester)
},
saveFetchResult = { old, new ->
attendanceDb.deleteAll(old uniqueSubtract new)
diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/MailboxRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/MailboxRepository.kt
new file mode 100644
index 000000000..7f5974920
--- /dev/null
+++ b/app/src/main/java/io/github/wulkanowy/data/repositories/MailboxRepository.kt
@@ -0,0 +1,48 @@
+package io.github.wulkanowy.data.repositories
+
+import io.github.wulkanowy.data.db.dao.MailboxDao
+import io.github.wulkanowy.data.db.entities.Mailbox
+import io.github.wulkanowy.data.db.entities.Student
+import io.github.wulkanowy.data.mappers.mapToEntities
+import io.github.wulkanowy.sdk.Sdk
+import io.github.wulkanowy.utils.AutoRefreshHelper
+import io.github.wulkanowy.utils.getRefreshKey
+import io.github.wulkanowy.utils.init
+import io.github.wulkanowy.utils.uniqueSubtract
+import javax.inject.Inject
+import javax.inject.Singleton
+
+@Singleton
+class MailboxRepository @Inject constructor(
+ private val mailboxDao: MailboxDao,
+ private val sdk: Sdk,
+ private val refreshHelper: AutoRefreshHelper,
+) {
+ private val cacheKey = "mailboxes"
+
+ suspend fun refreshMailboxes(student: Student) {
+ val new = sdk.init(student).getMailboxes().mapToEntities(student)
+ val old = mailboxDao.loadAll(student.userLoginId)
+
+ mailboxDao.deleteAll(old uniqueSubtract new)
+ mailboxDao.insertAll(new uniqueSubtract old)
+
+ refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, student))
+ }
+
+ suspend fun getMailbox(student: Student): Mailbox {
+ val isExpired = refreshHelper.shouldBeRefreshed(getRefreshKey(cacheKey, student))
+ val mailbox = mailboxDao.load(student.userLoginId, student.studentName)
+
+ return if (isExpired || mailbox == null) {
+ refreshMailboxes(student)
+ val newMailbox = mailboxDao.load(student.userLoginId, student.studentName)
+
+ requireNotNull(newMailbox) {
+ "Mailbox for ${student.userName} - ${student.studentName} not found!"
+ }
+
+ newMailbox
+ } else mailbox
+ }
+}
diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/MessageRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/MessageRepository.kt
index 6dfc3ab73..00cbffb84 100644
--- a/app/src/main/java/io/github/wulkanowy/data/repositories/MessageRepository.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/repositories/MessageRepository.kt
@@ -3,9 +3,8 @@ package io.github.wulkanowy.data.repositories
import android.content.Context
import dagger.hilt.android.qualifiers.ApplicationContext
import io.github.wulkanowy.R
-import io.github.wulkanowy.data.*
+import io.github.wulkanowy.data.Resource
import io.github.wulkanowy.data.db.SharedPrefProvider
-import io.github.wulkanowy.data.db.dao.MailboxDao
import io.github.wulkanowy.data.db.dao.MessageAttachmentDao
import io.github.wulkanowy.data.db.dao.MessagesDao
import io.github.wulkanowy.data.db.entities.*
@@ -14,8 +13,8 @@ import io.github.wulkanowy.data.enums.MessageFolder.RECEIVED
import io.github.wulkanowy.data.enums.MessageFolder.TRASHED
import io.github.wulkanowy.data.mappers.mapFromEntities
import io.github.wulkanowy.data.mappers.mapToEntities
+import io.github.wulkanowy.data.networkBoundResource
import io.github.wulkanowy.data.pojos.MessageDraft
-import io.github.wulkanowy.domain.messages.GetMailboxByStudentUseCase
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.sdk.pojo.Folder
import io.github.wulkanowy.utils.AutoRefreshHelper
@@ -41,18 +40,16 @@ class MessageRepository @Inject constructor(
private val refreshHelper: AutoRefreshHelper,
private val sharedPrefProvider: SharedPrefProvider,
private val json: Json,
- private val mailboxDao: MailboxDao,
- private val getMailboxByStudentUseCase: GetMailboxByStudentUseCase,
) {
private val saveFetchResultMutex = Mutex()
- private val messagesCacheKey = "message"
- private val mailboxCacheKey = "mailboxes"
+ private val cacheKey = "message"
+ @Suppress("UNUSED_PARAMETER")
fun getMessages(
student: Student,
- mailbox: Mailbox?,
+ mailbox: Mailbox,
folder: MessageFolder,
forceRefresh: Boolean,
notify: Boolean = false,
@@ -61,20 +58,13 @@ class MessageRepository @Inject constructor(
isResultEmpty = { it.isEmpty() },
shouldFetch = {
val isExpired = refreshHelper.shouldBeRefreshed(
- key = getRefreshKey(messagesCacheKey, mailbox, folder)
+ key = getRefreshKey(cacheKey, student, folder)
)
it.isEmpty() || forceRefresh || isExpired
},
- query = {
- if (mailbox == null) {
- messagesDb.loadAll(folder.id, student.email)
- } else messagesDb.loadAll(mailbox.globalKey, folder.id)
- },
+ query = { messagesDb.loadAll(mailbox.globalKey, folder.id) },
fetch = {
- sdk.init(student).getMessages(
- folder = Folder.valueOf(folder.name),
- mailboxKey = mailbox?.globalKey,
- ).mapToEntities(student, mailbox, mailboxDao.loadAll(student.email))
+ sdk.init(student).getMessages(Folder.valueOf(folder.name)).mapToEntities(mailbox)
},
saveFetchResult = { old, new ->
messagesDb.deleteAll(old uniqueSubtract new)
@@ -82,9 +72,7 @@ class MessageRepository @Inject constructor(
it.isNotified = !notify
})
- refreshHelper.updateLastRefreshTimestamp(
- getRefreshKey(messagesCacheKey, mailbox, folder)
- )
+ refreshHelper.updateLastRefreshTimestamp(getRefreshKey(cacheKey, student, folder))
}
)
@@ -99,11 +87,9 @@ class MessageRepository @Inject constructor(
Timber.d("Message content in db empty: ${it.message.content.isBlank()}")
it.message.unread || it.message.content.isBlank()
},
- query = {
- messagesDb.loadMessageWithAttachment(message.messageGlobalKey)
- },
+ query = { messagesDb.loadMessageWithAttachment(message.messageGlobalKey) },
fetch = {
- sdk.init(student).getMessageDetails(it!!.message.messageGlobalKey, markAsRead)
+ sdk.init(student).getMessageDetails(it!!.message.messageGlobalKey)
},
saveFetchResult = { old, new ->
checkNotNull(old) { "Fetched message no longer exist!" }
@@ -112,7 +98,7 @@ class MessageRepository @Inject constructor(
id = message.id
unread = !markAsRead
sender = new.sender
- recipients = new.recipients.singleOrNull() ?: "Wielu adresatów"
+ recipients = new.recipients.firstOrNull() ?: "Wielu adresoatów"
content = content.ifBlank { new.content }
})
)
@@ -124,10 +110,8 @@ class MessageRepository @Inject constructor(
}
)
- fun getMessagesFromDatabase(student: Student, mailbox: Mailbox?): Flow> {
- return if (mailbox == null) {
- messagesDb.loadAll(RECEIVED.id, student.email)
- } else messagesDb.loadAll(mailbox.globalKey, RECEIVED.id)
+ fun getMessagesFromDatabase(mailbox: Mailbox): Flow> {
+ return messagesDb.loadAll(mailbox.globalKey, RECEIVED.id)
}
suspend fun updateMessages(messages: List) {
@@ -149,7 +133,7 @@ class MessageRepository @Inject constructor(
)
}
- suspend fun deleteMessages(student: Student, mailbox: Mailbox?, messages: List) {
+ suspend fun deleteMessages(student: Student, mailbox: Mailbox, messages: List) {
val firstMessage = messages.first()
sdk.init(student).deleteMessages(
messages = messages.map { it.messageGlobalKey },
@@ -178,49 +162,15 @@ class MessageRepository @Inject constructor(
).first()
}
- suspend fun deleteMessage(student: Student, mailbox: Mailbox?, message: Message) {
+ suspend fun deleteMessage(student: Student, mailbox: Mailbox, message: Message) {
deleteMessages(student, mailbox, listOf(message))
}
- suspend fun getMailboxes(student: Student, forceRefresh: Boolean) = networkBoundResource(
- mutex = saveFetchResultMutex,
- isResultEmpty = { it.isEmpty() },
- shouldFetch = {
- val isExpired = refreshHelper.shouldBeRefreshed(
- key = getRefreshKey(mailboxCacheKey, student),
- )
- it.isEmpty() || isExpired || forceRefresh
- },
- query = { mailboxDao.loadAll(student.email, student.symbol, student.schoolSymbol) },
- fetch = {
- sdk.init(student).getMailboxes().mapToEntities(student)
- },
- saveFetchResult = { old, new ->
- mailboxDao.deleteAll(old uniqueSubtract new)
- mailboxDao.insertAll(new uniqueSubtract old)
-
- refreshHelper.updateLastRefreshTimestamp(getRefreshKey(mailboxCacheKey, student))
- }
- )
-
- suspend fun getMailboxByStudent(student: Student): Mailbox? {
- val mailbox = getMailboxByStudentUseCase(student)
-
- return if (mailbox == null) {
- getMailboxes(student, forceRefresh = true)
- .onResourceError { throw it }
- .onResourceSuccess { Timber.i("Found ${it.size} new mailboxes") }
- .waitForResult()
-
- getMailboxByStudentUseCase(student)
- } else mailbox
- }
-
var draftMessage: MessageDraft?
- get() = sharedPrefProvider.getString(context.getString(R.string.pref_key_message_draft))
+ get() = sharedPrefProvider.getString(context.getString(R.string.pref_key_message_send_draft))
?.let { json.decodeFromString(it) }
set(value) = sharedPrefProvider.putString(
- context.getString(R.string.pref_key_message_draft),
+ context.getString(R.string.pref_key_message_send_draft),
value?.let { json.encodeToString(it) }
)
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/PreferencesRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/PreferencesRepository.kt
index afc262868..486538e0c 100644
--- a/app/src/main/java/io/github/wulkanowy/data/repositories/PreferencesRepository.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/repositories/PreferencesRepository.kt
@@ -10,16 +10,17 @@ import io.github.wulkanowy.R
import io.github.wulkanowy.data.enums.*
import io.github.wulkanowy.ui.modules.dashboard.DashboardItem
import io.github.wulkanowy.ui.modules.grade.GradeAverageMode
+import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import java.time.Instant
-import java.util.*
import javax.inject.Inject
import javax.inject.Singleton
+@OptIn(ExperimentalCoroutinesApi::class)
@Singleton
class PreferencesRepository @Inject constructor(
@ApplicationContext val context: Context,
@@ -315,16 +316,6 @@ class PreferencesRepository @Inject constructor(
putBoolean(context.getString(R.string.pref_key_ads_enabled), value)
}
- var installationId: String
- get() = sharedPref.getString(PREF_KEY_INSTALLATION_ID, null).orEmpty()
- private set(value) = sharedPref.edit { putString(PREF_KEY_INSTALLATION_ID, value) }
-
- init {
- if (installationId.isEmpty()) {
- installationId = UUID.randomUUID().toString()
- }
- }
-
private fun getLong(id: Int, default: Int) = getLong(context.getString(id), default)
private fun getLong(id: String, default: Int) =
@@ -340,14 +331,23 @@ class PreferencesRepository @Inject constructor(
private fun getBoolean(id: String, default: Int) =
sharedPref.getBoolean(id, context.resources.getBoolean(default))
+ private fun getBoolean(id: Int, default: Boolean) =
+ sharedPref.getBoolean(context.getString(id), default)
+
private companion object {
- private const val PREF_KEY_INSTALLATION_ID = "installation_id"
+
private const val PREF_KEY_DASHBOARD_ITEMS_POSITION = "dashboard_items_position"
+
private const val PREF_KEY_IN_APP_REVIEW_COUNT = "in_app_review_count"
+
private const val PREF_KEY_IN_APP_REVIEW_DATE = "in_app_review_date"
+
private const val PREF_KEY_IN_APP_REVIEW_DONE = "in_app_review_done"
+
private const val PREF_KEY_APP_SUPPORT_SHOWN = "app_support_shown"
+
private const val PREF_KEY_PERSONALIZED_ADS_ENABLED = "personalized_ads_enabled"
+
private const val PREF_KEY_ADMIN_DISMISSED_MESSAGE_IDS = "admin_message_dismissed_ids"
}
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/RecipientRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/RecipientRepository.kt
index 79984ce6d..e80f028e1 100644
--- a/app/src/main/java/io/github/wulkanowy/data/repositories/RecipientRepository.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/repositories/RecipientRepository.kt
@@ -33,11 +33,9 @@ class RecipientRepository @Inject constructor(
suspend fun getRecipients(
student: Student,
- mailbox: Mailbox?,
- type: MailboxType,
+ mailbox: Mailbox,
+ type: MailboxType
): List {
- mailbox ?: return emptyList()
-
val cached = recipientDb.loadAll(type, mailbox.globalKey)
val isExpired = refreshHelper.shouldBeRefreshed(getRefreshKey(cacheKey, student))
@@ -49,15 +47,11 @@ class RecipientRepository @Inject constructor(
suspend fun getMessageSender(
student: Student,
- mailbox: Mailbox?,
- message: Message,
- ): List {
- mailbox ?: return emptyList()
-
- return sdk.init(student)
- .getMessageReplayDetails(message.messageGlobalKey)
- .sender
- .let(::listOf)
- .mapToEntities(mailbox.globalKey)
- }
+ mailbox: Mailbox,
+ message: Message
+ ): List = sdk.init(student)
+ .getMessageReplayDetails(message.messageGlobalKey)
+ .sender
+ .let(::listOf)
+ .mapToEntities(mailbox.globalKey)
}
diff --git a/app/src/main/java/io/github/wulkanowy/data/repositories/StudentRepository.kt b/app/src/main/java/io/github/wulkanowy/data/repositories/StudentRepository.kt
index b1d1ba832..f006b7d28 100644
--- a/app/src/main/java/io/github/wulkanowy/data/repositories/StudentRepository.kt
+++ b/app/src/main/java/io/github/wulkanowy/data/repositories/StudentRepository.kt
@@ -11,8 +11,6 @@ import io.github.wulkanowy.data.db.entities.StudentNickAndAvatar
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
import io.github.wulkanowy.data.exceptions.NoCurrentStudentException
import io.github.wulkanowy.data.mappers.mapToEntities
-import io.github.wulkanowy.data.mappers.mapToPojo
-import io.github.wulkanowy.data.pojos.RegisterUser
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.utils.AppInfo
import io.github.wulkanowy.utils.DispatchersProvider
@@ -54,14 +52,6 @@ class StudentRepository @Inject constructor(
sdk.getStudentsFromScrapper(email, password, scrapperBaseUrl, symbol)
.mapToEntities(password, appInfo.defaultColorsForAvatar)
- suspend fun getUserSubjectsFromScrapper(
- email: String,
- password: String,
- scrapperBaseUrl: String,
- symbol: String
- ): RegisterUser = sdk.getUserSubjectsFromScrapper(email, password, scrapperBaseUrl, symbol)
- .mapToPojo(password)
-
suspend fun getStudentsHybrid(
email: String,
password: String,
diff --git a/app/src/main/java/io/github/wulkanowy/domain/messages/GetMailboxByStudentUseCase.kt b/app/src/main/java/io/github/wulkanowy/domain/messages/GetMailboxByStudentUseCase.kt
deleted file mode 100644
index 669514aae..000000000
--- a/app/src/main/java/io/github/wulkanowy/domain/messages/GetMailboxByStudentUseCase.kt
+++ /dev/null
@@ -1,65 +0,0 @@
-package io.github.wulkanowy.domain.messages
-
-import io.github.wulkanowy.data.db.dao.MailboxDao
-import io.github.wulkanowy.data.db.entities.Mailbox
-import io.github.wulkanowy.data.db.entities.Student
-import javax.inject.Inject
-
-class GetMailboxByStudentUseCase @Inject constructor(
- private val mailboxDao: MailboxDao,
-) {
-
- suspend operator fun invoke(student: Student): Mailbox? {
- return mailboxDao.loadAll(student.email)
- .filterByStudent(student)
- }
-
- private fun List.filterByStudent(student: Student): Mailbox? {
- val normalizedStudentName = student.studentName.normalizeStudentName()
-
- return singleOrNull {
- it.studentName.normalizeStudentName() == normalizedStudentName
- } ?: singleOrNull {
- it.studentName.normalizeStudentName() == normalizedStudentName
- && it.schoolNameShort == student.schoolShortName
- } ?: singleOrNull {
- it.studentName.getFirstAndLastPart() == normalizedStudentName.getFirstAndLastPart()
- } ?: singleOrNull {
- it.studentName.getReversedName() == normalizedStudentName
- } ?: singleOrNull {
- it.studentName.getUnauthorizedVersion() == normalizedStudentName
- }
- }
-
- private fun String.normalizeStudentName(): String {
- return trim().split(" ")
- .filter { it.isNotBlank() }
- .joinToString(" ") { part ->
- part.lowercase().replaceFirstChar { it.uppercase() }
- }
- }
-
- private fun String.getFirstAndLastPart(): String {
- val parts = normalizeStudentName().split(" ")
-
- val endParts = parts.filterIndexed { i, _ ->
- i == 0 || parts.size - 1 == i
- }
- return endParts.joinToString(" ")
- }
-
- private fun String.getReversedName(): String {
- val parts = normalizeStudentName().split(" ")
-
- return parts
- .asReversed()
- .joinToString(" ")
- }
-
- private fun String.getUnauthorizedVersion(): String {
- return normalizeStudentName().split(" ")
- .joinToString(" ") {
- it.first() + "*".repeat(it.length - 1)
- }
- }
-}
diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewAttendanceNotification.kt b/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewAttendanceNotification.kt
index 99473a8ec..49842c9a6 100644
--- a/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewAttendanceNotification.kt
+++ b/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewAttendanceNotification.kt
@@ -8,6 +8,7 @@ import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.pojos.GroupNotificationData
import io.github.wulkanowy.data.pojos.NotificationData
import io.github.wulkanowy.ui.modules.Destination
+import io.github.wulkanowy.ui.modules.splash.SplashActivity
import io.github.wulkanowy.utils.descriptionRes
import io.github.wulkanowy.utils.getPlural
import io.github.wulkanowy.utils.toFormattedString
@@ -21,9 +22,8 @@ class NewAttendanceNotification @Inject constructor(
suspend fun notify(items: List, student: Student) {
val lines = items.filterNot { it.presence || it.name == "UNKNOWN" }
.map {
- val lesson = it.subject.ifBlank { "Lekcja ${it.number}" }
val description = context.getString(it.descriptionRes)
- "${it.date.toFormattedString("dd.MM")} - $lesson: $description"
+ "${it.date.toFormattedString("dd.MM")} - ${it.subject}: $description"
}
.ifEmpty { return }
diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewMessageNotification.kt b/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewMessageNotification.kt
index 45523d51e..3b7bcff05 100644
--- a/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewMessageNotification.kt
+++ b/app/src/main/java/io/github/wulkanowy/services/sync/notifications/NewMessageNotification.kt
@@ -8,6 +8,7 @@ import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.pojos.GroupNotificationData
import io.github.wulkanowy.data.pojos.NotificationData
import io.github.wulkanowy.ui.modules.Destination
+import io.github.wulkanowy.ui.modules.splash.SplashActivity
import io.github.wulkanowy.utils.getPlural
import javax.inject.Inject
diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/works/MessageWork.kt b/app/src/main/java/io/github/wulkanowy/services/sync/works/MessageWork.kt
index c7824e61f..180568267 100644
--- a/app/src/main/java/io/github/wulkanowy/services/sync/works/MessageWork.kt
+++ b/app/src/main/java/io/github/wulkanowy/services/sync/works/MessageWork.kt
@@ -3,6 +3,7 @@ package io.github.wulkanowy.services.sync.works
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.enums.MessageFolder.RECEIVED
+import io.github.wulkanowy.data.repositories.MailboxRepository
import io.github.wulkanowy.data.repositories.MessageRepository
import io.github.wulkanowy.data.waitForResult
import io.github.wulkanowy.services.sync.notifications.NewMessageNotification
@@ -11,11 +12,12 @@ import javax.inject.Inject
class MessageWork @Inject constructor(
private val messageRepository: MessageRepository,
+ private val mailboxRepository: MailboxRepository,
private val newMessageNotification: NewMessageNotification,
) : Work {
override suspend fun doWork(student: Student, semester: Semester, notify: Boolean) {
- val mailbox = messageRepository.getMailboxByStudent(student)
+ val mailbox = mailboxRepository.getMailbox(student)
messageRepository.getMessages(
student = student,
mailbox = mailbox,
@@ -24,7 +26,7 @@ class MessageWork @Inject constructor(
notify = notify
).waitForResult()
- messageRepository.getMessagesFromDatabase(student, mailbox).first()
+ messageRepository.getMessagesFromDatabase(mailbox).first()
.filter { !it.isNotified && it.unread }.let {
if (it.isNotEmpty()) newMessageNotification.notify(it, student)
messageRepository.updateMessages(it.onEach { message -> message.isNotified = true })
diff --git a/app/src/main/java/io/github/wulkanowy/services/sync/works/RecipientWork.kt b/app/src/main/java/io/github/wulkanowy/services/sync/works/RecipientWork.kt
index 90b20651d..b1322ada3 100644
--- a/app/src/main/java/io/github/wulkanowy/services/sync/works/RecipientWork.kt
+++ b/app/src/main/java/io/github/wulkanowy/services/sync/works/RecipientWork.kt
@@ -1,23 +1,22 @@
package io.github.wulkanowy.services.sync.works
-import io.github.wulkanowy.data.dataOrNull
import io.github.wulkanowy.data.db.entities.MailboxType
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
-import io.github.wulkanowy.data.repositories.MessageRepository
+import io.github.wulkanowy.data.repositories.MailboxRepository
import io.github.wulkanowy.data.repositories.RecipientRepository
-import io.github.wulkanowy.data.toFirstResult
import javax.inject.Inject
class RecipientWork @Inject constructor(
- private val messageRepository: MessageRepository,
+ private val mailboxRepository: MailboxRepository,
private val recipientRepository: RecipientRepository
) : Work {
override suspend fun doWork(student: Student, semester: Semester, notify: Boolean) {
- val mailboxes = messageRepository.getMailboxes(student, forceRefresh = true).toFirstResult()
- mailboxes.dataOrNull?.forEach {
- recipientRepository.refreshRecipients(student, it, MailboxType.EMPLOYEE)
- }
+ mailboxRepository.refreshMailboxes(student)
+
+ val mailbox = mailboxRepository.getMailbox(student)
+
+ recipientRepository.refreshRecipients(student, mailbox, MailboxType.EMPLOYEE)
}
}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/base/ErrorDialog.kt b/app/src/main/java/io/github/wulkanowy/ui/base/ErrorDialog.kt
index fe0e64697..48c003b7e 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/base/ErrorDialog.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/base/ErrorDialog.kt
@@ -4,6 +4,7 @@ import android.app.Dialog
import android.content.ClipData
import android.content.ClipboardManager
import android.os.Bundle
+import android.view.LayoutInflater
import android.widget.Toast
import android.widget.Toast.LENGTH_LONG
import androidx.appcompat.app.AlertDialog
@@ -14,7 +15,6 @@ import androidx.fragment.app.DialogFragment
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R
-import io.github.wulkanowy.data.repositories.PreferencesRepository
import io.github.wulkanowy.databinding.DialogErrorBinding
import io.github.wulkanowy.utils.*
import javax.inject.Inject
@@ -25,9 +25,6 @@ class ErrorDialog : DialogFragment() {
@Inject
lateinit var appInfo: AppInfo
- @Inject
- lateinit var preferencesRepository: PreferencesRepository
-
companion object {
private const val ARGUMENT_KEY = "error"
@@ -37,9 +34,9 @@ class ErrorDialog : DialogFragment() {
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
- val error = requireArguments().serializable(ARGUMENT_KEY)
+ val error = requireArguments().getSerializable(ARGUMENT_KEY) as Throwable
- val binding = DialogErrorBinding.inflate(layoutInflater)
+ val binding = DialogErrorBinding.inflate(LayoutInflater.from(context))
binding.bindErrorDetails(error)
return getAlertDialog(binding, error).apply {
@@ -102,8 +99,7 @@ class ErrorDialog : DialogFragment() {
R.string.about_feedback_template,
"${appInfo.systemManufacturer} ${appInfo.systemModel}",
appInfo.systemVersion.toString(),
- "${appInfo.versionName}-${appInfo.buildFlavor}",
- preferencesRepository.installationId,
+ "${appInfo.versionName}-${appInfo.buildFlavor}"
) + "\n" + content,
onActivityNotFound = {
requireContext().openInternetBrowser(
diff --git a/app/src/main/java/io/github/wulkanowy/ui/base/ThemeManager.kt b/app/src/main/java/io/github/wulkanowy/ui/base/ThemeManager.kt
index e1c234575..2d83bbbf9 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/base/ThemeManager.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/base/ThemeManager.kt
@@ -1,9 +1,6 @@
package io.github.wulkanowy.ui.base
-import android.content.pm.PackageInfo
-import android.content.pm.PackageManager
import android.content.pm.PackageManager.GET_ACTIVITIES
-import android.os.Build
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
@@ -44,8 +41,9 @@ class ThemeManager @Inject constructor(private val preferencesRepository: Prefer
)
}
- private fun isThemeApplicable(activity: AppCompatActivity): Boolean =
- getPackageInfo(activity)
+ private fun isThemeApplicable(activity: AppCompatActivity) =
+ activity.packageManager
+ .getPackageInfo(activity.packageName, GET_ACTIVITIES)
.activities
.singleOrNull { it.name == activity::class.java.canonicalName }
?.theme
@@ -54,14 +52,4 @@ class ThemeManager @Inject constructor(private val preferencesRepository: Prefer
|| it == R.style.WulkanowyTheme_Login || it == R.style.WulkanowyTheme_Login_Black
|| it == R.style.WulkanowyTheme_MessageSend || it == R.style.WulkanowyTheme_MessageSend_Black
}
-
- @Suppress("DEPRECATION")
- private fun getPackageInfo(activity: AppCompatActivity): PackageInfo {
- return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
- activity.packageManager.getPackageInfo(
- activity.packageName,
- PackageManager.PackageInfoFlags.of(GET_ACTIVITIES.toLong())
- )
- } else activity.packageManager.getPackageInfo(activity.packageName, GET_ACTIVITIES)
- }
}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutFragment.kt
index d7f39e303..701656b55 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutFragment.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/about/AboutFragment.kt
@@ -6,7 +6,6 @@ import android.view.View
import androidx.recyclerview.widget.LinearLayoutManager
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R
-import io.github.wulkanowy.data.repositories.PreferencesRepository
import io.github.wulkanowy.databinding.FragmentAboutBinding
import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.modules.about.contributor.ContributorFragment
@@ -31,9 +30,6 @@ class AboutFragment : BaseFragment(R.layout.fragment_about
@Inject
lateinit var appInfo: AppInfo
- @Inject
- lateinit var preferencesRepository: PreferencesRepository
-
override val versionRes: Triple?
get() = context?.run {
val buildTimestamp =
@@ -189,8 +185,7 @@ class AboutFragment : BaseFragment(R.layout.fragment_about
R.string.about_feedback_template,
"${appInfo.systemManufacturer} ${appInfo.systemModel}",
appInfo.systemVersion.toString(),
- "${appInfo.versionName}-${appInfo.buildFlavor}",
- preferencesRepository.installationId,
+ "${appInfo.versionName}-${appInfo.buildFlavor}"
),
onActivityNotFound = {
requireContext().openInternetBrowser(
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountFragment.kt
index f115372a5..051c93c95 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountFragment.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/account/AccountFragment.kt
@@ -34,7 +34,6 @@ class AccountFragment : BaseFragment(R.layout.fragment_a
override val titleStringId = R.string.account_title
- @Suppress("DEPRECATION")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true)
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountdetails/AccountDetailsFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountdetails/AccountDetailsFragment.kt
index 41b97b075..c3137ec58 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountdetails/AccountDetailsFragment.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountdetails/AccountDetailsFragment.kt
@@ -6,7 +6,6 @@ import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import androidx.appcompat.app.AlertDialog
-import androidx.core.os.bundleOf
import androidx.core.view.get
import androidx.core.view.isVisible
import dagger.hilt.android.AndroidEntryPoint
@@ -22,7 +21,6 @@ import io.github.wulkanowy.ui.modules.studentinfo.StudentInfoFragment
import io.github.wulkanowy.ui.modules.studentinfo.StudentInfoView
import io.github.wulkanowy.utils.createNameInitialsDrawable
import io.github.wulkanowy.utils.nickOrName
-import io.github.wulkanowy.utils.serializable
import javax.inject.Inject
@AndroidEntryPoint
@@ -39,12 +37,12 @@ class AccountDetailsFragment :
private const val ARGUMENT_KEY = "Data"
- fun newInstance(student: Student) = AccountDetailsFragment().apply {
- arguments = bundleOf(ARGUMENT_KEY to student)
- }
+ fun newInstance(student: Student) =
+ AccountDetailsFragment().apply {
+ arguments = Bundle().apply { putSerializable(ARGUMENT_KEY, student) }
+ }
}
- @Suppress("DEPRECATION")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true)
@@ -53,7 +51,7 @@ class AccountDetailsFragment :
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentAccountDetailsBinding.bind(view)
- presenter.onAttachView(this, requireArguments().serializable(ARGUMENT_KEY))
+ presenter.onAttachView(this, requireArguments()[ARGUMENT_KEY] as Student)
}
override fun initView() {
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountedit/AccountEditDialog.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountedit/AccountEditDialog.kt
index 6e2bc8c44..21a7a492d 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountedit/AccountEditDialog.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountedit/AccountEditDialog.kt
@@ -4,13 +4,11 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
-import androidx.core.os.bundleOf
import androidx.recyclerview.widget.GridLayoutManager
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.databinding.DialogAccountEditBinding
import io.github.wulkanowy.ui.base.BaseDialogFragment
-import io.github.wulkanowy.utils.serializable
import javax.inject.Inject
@AndroidEntryPoint
@@ -26,9 +24,12 @@ class AccountEditDialog : BaseDialogFragment(), Accoun
private const val ARGUMENT_KEY = "student_with_semesters"
- fun newInstance(student: Student) = AccountEditDialog().apply {
- arguments = bundleOf(ARGUMENT_KEY to student)
- }
+ fun newInstance(student: Student) =
+ AccountEditDialog().apply {
+ arguments = Bundle().apply {
+ putSerializable(ARGUMENT_KEY, student)
+ }
+ }
}
override fun onCreate(savedInstanceState: Bundle?) {
@@ -44,7 +45,7 @@ class AccountEditDialog : BaseDialogFragment(), Accoun
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
- presenter.onAttachView(this, requireArguments().serializable(ARGUMENT_KEY))
+ presenter.onAttachView(this, requireArguments()[ARGUMENT_KEY] as Student)
}
override fun initView() {
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountquick/AccountQuickDialog.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountquick/AccountQuickDialog.kt
index d23978f5f..4279102e1 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountquick/AccountQuickDialog.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/account/accountquick/AccountQuickDialog.kt
@@ -4,7 +4,6 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
-import androidx.core.os.bundleOf
import androidx.recyclerview.widget.LinearLayoutManager
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
@@ -14,7 +13,6 @@ import io.github.wulkanowy.ui.modules.account.AccountAdapter
import io.github.wulkanowy.ui.modules.account.AccountFragment
import io.github.wulkanowy.ui.modules.account.AccountItem
import io.github.wulkanowy.ui.modules.main.MainActivity
-import io.github.wulkanowy.utils.serializable
import javax.inject.Inject
@AndroidEntryPoint
@@ -32,7 +30,9 @@ class AccountQuickDialog : BaseDialogFragment(), Acco
fun newInstance(studentsWithSemesters: List) =
AccountQuickDialog().apply {
- arguments = bundleOf(STUDENTS_ARGUMENT_KEY to studentsWithSemesters.toTypedArray())
+ arguments = Bundle().apply {
+ putSerializable(STUDENTS_ARGUMENT_KEY, studentsWithSemesters.toTypedArray())
+ }
}
}
@@ -49,8 +49,8 @@ class AccountQuickDialog : BaseDialogFragment(), Acco
@Suppress("UNCHECKED_CAST")
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- val studentsWithSemesters = requireArguments()
- .serializable>(STUDENTS_ARGUMENT_KEY).toList()
+ val studentsWithSemesters =
+ (requireArguments()[STUDENTS_ARGUMENT_KEY] as Array).toList()
presenter.onAttachView(this, studentsWithSemesters)
}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceDialog.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceDialog.kt
index eab24f91d..9b5c63e4c 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceDialog.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceDialog.kt
@@ -4,13 +4,11 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
-import androidx.core.os.bundleOf
import androidx.fragment.app.DialogFragment
import io.github.wulkanowy.data.db.entities.Attendance
import io.github.wulkanowy.databinding.DialogAttendanceBinding
import io.github.wulkanowy.utils.descriptionRes
import io.github.wulkanowy.utils.lifecycleAwareVariable
-import io.github.wulkanowy.utils.serializable
import io.github.wulkanowy.utils.toFormattedString
class AttendanceDialog : DialogFragment() {
@@ -24,14 +22,16 @@ class AttendanceDialog : DialogFragment() {
private const val ARGUMENT_KEY = "Item"
fun newInstance(exam: Attendance) = AttendanceDialog().apply {
- arguments = bundleOf(ARGUMENT_KEY to exam)
+ arguments = Bundle().apply { putSerializable(ARGUMENT_KEY, exam) }
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NO_TITLE, 0)
- attendance = requireArguments().serializable(ARGUMENT_KEY)
+ arguments?.run {
+ attendance = getSerializable(ARGUMENT_KEY) as Attendance
+ }
}
override fun onCreateView(
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceFragment.kt
index 21f30b046..6354b5e04 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceFragment.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/attendance/AttendanceFragment.kt
@@ -84,7 +84,6 @@ class AttendanceFragment : BaseFragment(R.layout.frag
}
}
- @Suppress("DEPRECATION")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true)
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/conference/ConferenceDialog.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/conference/ConferenceDialog.kt
index 7834b6e8b..477b762b9 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/conference/ConferenceDialog.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/conference/ConferenceDialog.kt
@@ -4,13 +4,11 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
-import androidx.core.os.bundleOf
import androidx.core.view.isVisible
import androidx.fragment.app.DialogFragment
import io.github.wulkanowy.data.db.entities.Conference
import io.github.wulkanowy.databinding.DialogConferenceBinding
import io.github.wulkanowy.utils.lifecycleAwareVariable
-import io.github.wulkanowy.utils.serializable
import io.github.wulkanowy.utils.toFormattedString
class ConferenceDialog : DialogFragment() {
@@ -24,14 +22,16 @@ class ConferenceDialog : DialogFragment() {
private const val ARGUMENT_KEY = "item"
fun newInstance(conference: Conference) = ConferenceDialog().apply {
- arguments = bundleOf(ARGUMENT_KEY to conference)
+ arguments = Bundle().apply { putSerializable(ARGUMENT_KEY, conference) }
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NO_TITLE, 0)
- conference = requireArguments().serializable(ARGUMENT_KEY)
+ arguments?.let {
+ conference = it.getSerializable(ARGUMENT_KEY) as Conference
+ }
}
override fun onCreateView(
@@ -57,4 +57,4 @@ class ConferenceDialog : DialogFragment() {
conferenceDialogAgendaTitle.isVisible = conference.agenda.isNotBlank()
}
}
-}
+}
\ No newline at end of file
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/DashboardFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/DashboardFragment.kt
index cd66d6c2f..de0b4a6c9 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/DashboardFragment.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/DashboardFragment.kt
@@ -61,7 +61,6 @@ class DashboardFragment : BaseFragment(R.layout.fragme
fun newInstance() = DashboardFragment()
}
- @Suppress("DEPRECATION")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true)
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/DashboardItem.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/DashboardItem.kt
index d019dea68..e220ae236 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/DashboardItem.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/DashboardItem.kt
@@ -33,27 +33,18 @@ sealed class DashboardItem(val type: Type) {
}
data class HorizontalGroup(
- val unreadMessagesCount: Cell? = null,
- val attendancePercentage: Cell? = null,
- val luckyNumber: Cell? = null,
+ val unreadMessagesCount: Int? = null,
+ val attendancePercentage: Double? = null,
+ val luckyNumber: Int? = null,
override val error: Throwable? = null,
override val isLoading: Boolean = false
) : DashboardItem(Type.HORIZONTAL_GROUP) {
- data class Cell(
- val data: T?,
- val error: Boolean,
- val isLoading: Boolean,
- ) {
- val isHidden: Boolean
- get() = data == null && !error && !isLoading
- }
-
override val isDataLoaded
- get() = unreadMessagesCount?.isLoading == false || attendancePercentage?.isLoading == false || luckyNumber?.isLoading == false
+ get() = unreadMessagesCount != null || attendancePercentage != null || luckyNumber != null
val isFullDataLoaded
- get() = luckyNumber?.isLoading != true && attendancePercentage?.isLoading != true && unreadMessagesCount?.isLoading != true
+ get() = luckyNumber != -1 && attendancePercentage != -1.0 && unreadMessagesCount != -1
}
data class Grades(
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/DashboardPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/DashboardPresenter.kt
index 22b0d267e..350300937 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/DashboardPresenter.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/DashboardPresenter.kt
@@ -25,6 +25,7 @@ class DashboardPresenter @Inject constructor(
private val gradeRepository: GradeRepository,
private val semesterRepository: SemesterRepository,
private val messageRepository: MessageRepository,
+ private val mailboxRepository: MailboxRepository,
private val attendanceSummaryRepository: AttendanceSummaryRepository,
private val timetableRepository: TimetableRepository,
private val homeworkRepository: HomeworkRepository,
@@ -226,71 +227,50 @@ class DashboardPresenter @Inject constructor(
private fun loadHorizontalGroup(student: Student, forceRefresh: Boolean) {
flow {
+ val semester = semesterRepository.getCurrentSemester(student)
+ val mailbox = mailboxRepository.getMailbox(student)
val selectedTiles = preferencesRepository.selectedDashboardTiles
- val flowSuccess = flowOf(Resource.Success(null))
+ val flowSuccess = flowOf(Resource.Success(null))
val luckyNumberFlow = luckyNumberRepository.getLuckyNumber(student, forceRefresh)
.mapResourceData {
it ?: LuckyNumber(0, LocalDate.now(), 0)
}
- .onResourceError { errorHandler.dispatch(it) }
.takeIf { DashboardItem.Tile.LUCKY_NUMBER in selectedTiles } ?: flowSuccess
- val messageFLow = flatResourceFlow {
- val mailbox = messageRepository.getMailboxByStudent(student)
+ val messageFLow = messageRepository.getMessages(
+ student = student,
+ mailbox = mailbox,
+ folder = MessageFolder.RECEIVED,
+ forceRefresh = forceRefresh
+ ).takeIf { DashboardItem.Tile.MESSAGES in selectedTiles } ?: flowSuccess
- messageRepository.getMessages(
- student = student,
- mailbox = mailbox,
- folder = MessageFolder.RECEIVED,
- forceRefresh = forceRefresh
- )
- }
- .onResourceError { errorHandler.dispatch(it) }
- .takeIf { DashboardItem.Tile.MESSAGES in selectedTiles } ?: flowSuccess
-
- val attendanceFlow = flatResourceFlow {
- val semester = semesterRepository.getCurrentSemester(student)
- attendanceSummaryRepository.getAttendanceSummary(
- student = student,
- semester = semester,
- subjectId = -1,
- forceRefresh = forceRefresh
- )
- }
- .onResourceError { errorHandler.dispatch(it) }
- .takeIf { DashboardItem.Tile.ATTENDANCE in selectedTiles } ?: flowSuccess
+ val attendanceFlow = attendanceSummaryRepository.getAttendanceSummary(
+ student = student,
+ semester = semester,
+ subjectId = -1,
+ forceRefresh = forceRefresh
+ ).takeIf { DashboardItem.Tile.ATTENDANCE in selectedTiles } ?: flowSuccess
emitAll(
combine(
- flow = luckyNumberFlow,
- flow2 = messageFLow,
- flow3 = attendanceFlow,
+ luckyNumberFlow,
+ messageFLow,
+ attendanceFlow
) { luckyNumberResource, messageResource, attendanceResource ->
val resList = listOf(luckyNumberResource, messageResource, attendanceResource)
+ resList.firstNotNullOfOrNull { it.errorOrNull }?.let { throw it }
+ val isLoading = resList.any { it is Resource.Loading }
+
+ val luckyNumber = luckyNumberResource.dataOrNull?.luckyNumber
+ val messageCount = messageResource.dataOrNull?.count { it.unread }
+ val attendancePercentage = attendanceResource.dataOrNull?.calculatePercentage()
DashboardItem.HorizontalGroup(
- isLoading = resList.any { it is Resource.Loading },
- error = resList.map { it.errorOrNull }.let { errors ->
- if (errors.all { it != null }) {
- errors.firstOrNull()
- } else null
- },
- attendancePercentage = DashboardItem.HorizontalGroup.Cell(
- data = attendanceResource.dataOrNull?.calculatePercentage(),
- error = attendanceResource.errorOrNull != null,
- isLoading = attendanceResource is Resource.Loading,
- ),
- unreadMessagesCount = DashboardItem.HorizontalGroup.Cell(
- data = messageResource.dataOrNull?.count { it.unread },
- error = messageResource.errorOrNull != null,
- isLoading = messageResource is Resource.Loading,
- ),
- luckyNumber = DashboardItem.HorizontalGroup.Cell(
- data = luckyNumberResource.dataOrNull?.luckyNumber,
- error = luckyNumberResource.errorOrNull != null,
- isLoading = luckyNumberResource is Resource.Loading,
- )
+ isLoading = isLoading,
+ attendancePercentage = if (attendancePercentage == 0.0 && isLoading) -1.0 else attendancePercentage,
+ unreadMessagesCount = if (messageCount == 0 && isLoading) -1 else messageCount,
+ luckyNumber = if (luckyNumber == 0 && isLoading) -1 else luckyNumber
)
})
}
@@ -301,8 +281,11 @@ class DashboardPresenter @Inject constructor(
if (it.isLoading) {
Timber.i("Loading horizontal group data started")
+
+ if (it.isFullDataLoaded) {
+ firstLoadedItemList += DashboardItem.Type.HORIZONTAL_GROUP
+ }
} else {
- firstLoadedItemList += DashboardItem.Type.HORIZONTAL_GROUP
Timber.i("Loading horizontal group result: Success")
}
}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/adapters/DashboardAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/adapters/DashboardAdapter.kt
index 2c06e45fd..a3c423a8b 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/adapters/DashboardAdapter.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/dashboard/adapters/DashboardAdapter.kt
@@ -171,105 +171,81 @@ class DashboardAdapter @Inject constructor() : RecyclerView.Adapter {
- updateMarginsRelative(
- end = if (isAttendanceHidden && isMessagesHidden && !isLuckyNumberHidden) {
- 0
- } else context.dpToPx(8f).toInt()
- )
- }
- }
- }
-
- private fun ItemDashboardHorizontalGroupBinding.bindMessages(
- item: DashboardItem.HorizontalGroup,
- isWideErrorShow: Boolean
- ) {
- dashboardHorizontalGroupItemMessageError.isVisible = item.unreadMessagesCount?.error == true
- with(dashboardHorizontalGroupItemMessageValue) {
- isVisible = item.unreadMessagesCount?.error != true
- text = item.unreadMessagesCount?.data.toString()
- }
- with(dashboardHorizontalGroupItemMessageContainer) {
- isVisible = item.unreadMessagesCount?.isHidden == false && !isWideErrorShow
- setOnClickListener { onMessageTileClickListener() }
- }
- }
-
- private fun ItemDashboardHorizontalGroupBinding.bindAttendance(
- item: DashboardItem.HorizontalGroup,
- isWideErrorShow: Boolean
- ) {
- val attendancePercentage = item.attendancePercentage?.data
+ (isLoading && !item.isDataLoaded) || (isLoading && !item.isFullDataLoaded)
val attendanceColor = when {
attendancePercentage == null || attendancePercentage == .0 -> {
- root.context.getThemeAttrColor(R.attr.colorOnSurface)
+ context.getThemeAttrColor(R.attr.colorOnSurface)
}
attendancePercentage <= ATTENDANCE_SECOND_WARNING_THRESHOLD -> {
- root.context.getThemeAttrColor(R.attr.colorPrimary)
+ context.getThemeAttrColor(R.attr.colorPrimary)
}
attendancePercentage <= ATTENDANCE_FIRST_WARNING_THRESHOLD -> {
- root.context.getThemeAttrColor(R.attr.colorTimetableChange)
+ context.getThemeAttrColor(R.attr.colorTimetableChange)
}
- else -> root.context.getThemeAttrColor(R.attr.colorOnSurface)
+ else -> context.getThemeAttrColor(R.attr.colorOnSurface)
}
val attendanceString = if (attendancePercentage == null || attendancePercentage == .0) {
- root.context.getString(R.string.dashboard_horizontal_group_no_data)
+ context.getString(R.string.dashboard_horizontal_group_no_data)
} else {
"%.2f%%".format(attendancePercentage)
}
- dashboardHorizontalGroupItemAttendanceError.isVisible =
- item.attendancePercentage?.error == true
- with(dashboardHorizontalGroupItemAttendanceValue) {
- isVisible = item.attendancePercentage?.error != true
+ with(binding.dashboardHorizontalGroupItemAttendanceValue) {
text = attendanceString
setTextColor(attendanceColor)
}
- with(dashboardHorizontalGroupItemAttendanceContainer) {
- isVisible = item.attendancePercentage?.isHidden == false && !isWideErrorShow
- setOnClickListener { onAttendanceTileClickListener() }
- updateLayoutParams {
- matchConstraintPercentWidth = when {
- item.luckyNumber?.isHidden == true && item.unreadMessagesCount?.isHidden == true -> 1.0f
- item.luckyNumber?.isHidden == true || item.unreadMessagesCount?.isHidden == true -> 0.5f
- else -> 0.4f
+
+ with(binding) {
+ dashboardHorizontalGroupItemMessageValue.text = unreadMessagesCount.toString()
+ dashboardHorizontalGroupItemLuckyValue.text = if (luckyNumber == 0) {
+ context.getString(R.string.dashboard_horizontal_group_no_data)
+ } else luckyNumber?.toString()
+
+ dashboardHorizontalGroupItemInfoContainer.isVisible = error != null || isLoadingVisible
+ dashboardHorizontalGroupItemInfoProgress.isVisible = isLoadingVisible
+ dashboardHorizontalGroupItemInfoErrorText.isVisible = error != null
+
+ with(dashboardHorizontalGroupItemLuckyContainer) {
+ isVisible = luckyNumber != null && luckyNumber != -1 && !isLoadingVisible
+ setOnClickListener { onLuckyNumberTileClickListener() }
+
+ updateLayoutParams {
+ updateMarginsRelative(
+ end = if (attendancePercentage == null && unreadMessagesCount == null && luckyNumber != null) {
+ 0
+ } else {
+ context.dpToPx(8f).toInt()
+ }
+ )
}
}
+
+ with(dashboardHorizontalGroupItemAttendanceContainer) {
+ isVisible =
+ attendancePercentage != null && attendancePercentage != -1.0 && !isLoadingVisible
+ updateLayoutParams {
+ matchConstraintPercentWidth = when {
+ luckyNumber == null && unreadMessagesCount == null -> 1.0f
+ luckyNumber == null || unreadMessagesCount == null -> 0.5f
+ else -> 0.4f
+ }
+ }
+ setOnClickListener { onAttendanceTileClickListener() }
+ }
+
+ with(dashboardHorizontalGroupItemMessageContainer) {
+ isVisible =
+ unreadMessagesCount != null && unreadMessagesCount != -1 && !isLoadingVisible
+ setOnClickListener { onMessageTileClickListener() }
+ }
}
}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/logviewer/LogViewerFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/logviewer/LogViewerFragment.kt
index 929e72645..1e11c874b 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/logviewer/LogViewerFragment.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/logviewer/LogViewerFragment.kt
@@ -1,7 +1,9 @@
package io.github.wulkanowy.ui.modules.debug.logviewer
import android.content.Intent
-import android.content.Intent.*
+import android.content.Intent.EXTRA_EMAIL
+import android.content.Intent.EXTRA_STREAM
+import android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION
import android.os.Bundle
import android.view.Menu
import android.view.MenuInflater
@@ -34,7 +36,6 @@ class LogViewerFragment : BaseFragment(R.layout.fragme
fun newInstance() = LogViewerFragment()
}
- @Suppress("DEPRECATION")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true)
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/message.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/message.kt
index 27d8613a3..6ff26162b 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/message.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/debug/notification/mock/message.kt
@@ -19,12 +19,9 @@ val debugMessageItems = listOf(
private fun generateMessage(sender: String, subject: String) = Message(
subject = subject,
messageId = 123,
- email = "",
date = Instant.now(),
folderId = 0,
unread = true,
- readBy = 2,
- unreadBy = 2,
hasAttachments = false,
messageGlobalKey = "",
correspondents = sender,
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/exam/ExamDialog.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/exam/ExamDialog.kt
index 876b563f9..41adc008a 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/exam/ExamDialog.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/exam/ExamDialog.kt
@@ -4,14 +4,12 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
-import androidx.core.os.bundleOf
import androidx.fragment.app.DialogFragment
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Exam
import io.github.wulkanowy.databinding.DialogExamBinding
import io.github.wulkanowy.utils.lifecycleAwareVariable
import io.github.wulkanowy.utils.openCalendarEventAdd
-import io.github.wulkanowy.utils.serializable
import io.github.wulkanowy.utils.toFormattedString
import java.time.LocalTime
@@ -26,14 +24,16 @@ class ExamDialog : DialogFragment() {
private const val ARGUMENT_KEY = "Item"
fun newInstance(exam: Exam) = ExamDialog().apply {
- arguments = bundleOf(ARGUMENT_KEY to exam)
+ arguments = Bundle().apply { putSerializable(ARGUMENT_KEY, exam) }
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NO_TITLE, 0)
- exam = requireArguments().serializable(ARGUMENT_KEY)
+ arguments?.run {
+ exam = getSerializable(ARGUMENT_KEY) as Exam
+ }
}
override fun onCreateView(
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeFragment.kt
index 15df47a19..0a8561eec 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeFragment.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/GradeFragment.kt
@@ -51,7 +51,6 @@ class GradeFragment : BaseFragment(R.layout.fragment_grade
override val currentPageIndex get() = binding.gradeViewPager.currentItem
- @Suppress("DEPRECATION")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true)
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsDialog.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsDialog.kt
index a1ef2ec5a..34594111f 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsDialog.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsDialog.kt
@@ -5,7 +5,6 @@ import android.view.LayoutInflater
import android.view.View
import android.view.View.GONE
import android.view.ViewGroup
-import androidx.core.os.bundleOf
import androidx.fragment.app.DialogFragment
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Grade
@@ -28,19 +27,22 @@ class GradeDetailsDialog : DialogFragment() {
private const val COLOR_THEME_KEY = "Theme"
- fun newInstance(grade: Grade, colorTheme: GradeColorTheme) = GradeDetailsDialog().apply {
- arguments = bundleOf(
- ARGUMENT_KEY to grade,
- COLOR_THEME_KEY to colorTheme
- )
- }
+ fun newInstance(grade: Grade, colorTheme: GradeColorTheme) =
+ GradeDetailsDialog().apply {
+ arguments = Bundle().apply {
+ putSerializable(ARGUMENT_KEY, grade)
+ putSerializable(COLOR_THEME_KEY, colorTheme)
+ }
+ }
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NO_TITLE, 0)
- grade = requireArguments().serializable(ARGUMENT_KEY)
- gradeColorTheme = requireArguments().serializable(COLOR_THEME_KEY)
+ arguments?.run {
+ grade = getSerializable(ARGUMENT_KEY) as Grade
+ gradeColorTheme = getSerializable(COLOR_THEME_KEY) as GradeColorTheme
+ }
}
override fun onCreateView(
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsFragment.kt
index 23d767a6f..81f3226ad 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsFragment.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsFragment.kt
@@ -5,7 +5,9 @@ import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
-import android.view.View.*
+import android.view.View.GONE
+import android.view.View.INVISIBLE
+import android.view.View.VISIBLE
import androidx.recyclerview.widget.LinearLayoutManager
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R
@@ -40,7 +42,6 @@ class GradeDetailsFragment :
override val isViewEmpty
get() = gradeDetailsAdapter.itemCount == 0
- @Suppress("DEPRECATION")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true)
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsPresenter.kt
index 4261c507d..8cde5d6b9 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsPresenter.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/details/GradeDetailsPresenter.kt
@@ -3,6 +3,7 @@ package io.github.wulkanowy.ui.modules.grade.details
import io.github.wulkanowy.data.*
import io.github.wulkanowy.data.db.entities.Grade
import io.github.wulkanowy.data.enums.GradeExpandMode
+import io.github.wulkanowy.data.enums.GradeSortingMode
import io.github.wulkanowy.data.enums.GradeSortingMode.*
import io.github.wulkanowy.data.repositories.GradeRepository
import io.github.wulkanowy.data.repositories.PreferencesRepository
@@ -131,17 +132,16 @@ class GradeDetailsPresenter @Inject constructor(
}
.logResourceStatus("load grade details")
.onResourceData {
- val gradeItems = createGradeItems(it)
view?.run {
enableSwipe(true)
showProgress(false)
showErrorView(false)
- showContent(gradeItems.isNotEmpty())
- showEmpty(gradeItems.isEmpty())
+ showContent(it.isNotEmpty())
+ showEmpty(it.isEmpty())
updateNewGradesAmount(it)
updateMarkAsDoneButton()
updateData(
- data = gradeItems,
+ data = createGradeItems(it),
expandMode = preferencesRepository.gradeExpandMode,
preferencesRepository.gradeColorTheme
)
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/statistics/GradeStatisticsFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/statistics/GradeStatisticsFragment.kt
index edc384c5e..2af59c011 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/statistics/GradeStatisticsFragment.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/statistics/GradeStatisticsFragment.kt
@@ -15,7 +15,6 @@ import io.github.wulkanowy.ui.modules.grade.GradeFragment
import io.github.wulkanowy.ui.modules.grade.GradeView
import io.github.wulkanowy.utils.dpToPx
import io.github.wulkanowy.utils.getThemeAttrColor
-import io.github.wulkanowy.utils.serializable
import io.github.wulkanowy.utils.setOnItemSelectedListener
import javax.inject.Inject
@@ -49,8 +48,8 @@ class GradeStatisticsFragment :
messageContainer = binding.gradeStatisticsRecycler
presenter.onAttachView(
view = this,
- type = savedInstanceState?.serializable(SAVED_CHART_TYPE),
- subjectName = savedInstanceState?.serializable(SAVED_SUBJECT_NAME),
+ type = savedInstanceState?.getSerializable(SAVED_CHART_TYPE) as? GradeStatisticsItem.DataType,
+ subjectName = savedInstanceState?.getSerializable(SAVED_SUBJECT_NAME) as? String,
)
}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/summary/GradeSummaryAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/summary/GradeSummaryAdapter.kt
index 8dcade56e..082c847e5 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/grade/summary/GradeSummaryAdapter.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/grade/summary/GradeSummaryAdapter.kt
@@ -10,7 +10,6 @@ import io.github.wulkanowy.data.db.entities.GradeSummary
import io.github.wulkanowy.data.repositories.PreferencesRepository
import io.github.wulkanowy.databinding.ItemGradeSummaryBinding
import io.github.wulkanowy.databinding.ScrollableHeaderGradeSummaryBinding
-import io.github.wulkanowy.sdk.scrapper.grades.isGradeValid
import io.github.wulkanowy.utils.calcFinalAverage
import java.util.Locale
import javax.inject.Inject
@@ -62,7 +61,7 @@ class GradeSummaryAdapter @Inject constructor(
if (items.isEmpty()) return
val context = binding.root.context
- val finalItemsCount = items.count { isGradeValid(it.finalGrade) }
+ val finalItemsCount = items.count { it.finalGrade.matches("[0-6][+-]?".toRegex()) }
val calculatedItemsCount = items.count { value -> value.average != 0.0 }
val allItemsCount = items.count { !it.subject.equals("zachowanie", true) }
val finalAverage = items.calcFinalAverage(
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/homework/details/HomeworkDetailsDialog.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/homework/details/HomeworkDetailsDialog.kt
index 5e2cc65dc..f9d463510 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/homework/details/HomeworkDetailsDialog.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/homework/details/HomeworkDetailsDialog.kt
@@ -7,7 +7,6 @@ import android.view.View
import android.view.ViewGroup
import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
-import androidx.core.os.bundleOf
import androidx.recyclerview.widget.LinearLayoutManager
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R
@@ -15,7 +14,6 @@ import io.github.wulkanowy.data.db.entities.Homework
import io.github.wulkanowy.databinding.DialogHomeworkBinding
import io.github.wulkanowy.ui.base.BaseDialogFragment
import io.github.wulkanowy.utils.openInternetBrowser
-import io.github.wulkanowy.utils.serializable
import javax.inject.Inject
@AndroidEntryPoint
@@ -37,14 +35,16 @@ class HomeworkDetailsDialog : BaseDialogFragment(), Homew
private const val ARGUMENT_KEY = "Item"
fun newInstance(homework: Homework) = HomeworkDetailsDialog().apply {
- arguments = bundleOf(ARGUMENT_KEY to homework)
+ arguments = Bundle().apply { putSerializable(ARGUMENT_KEY, homework) }
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NO_TITLE, 0)
- homework = requireArguments().serializable(ARGUMENT_KEY)
+ arguments?.run {
+ homework = getSerializable(ARGUMENT_KEY) as Homework
+ }
}
override fun onCreateView(
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginActivity.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginActivity.kt
index c17c92efd..aac60b56d 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginActivity.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginActivity.kt
@@ -2,17 +2,13 @@ package io.github.wulkanowy.ui.modules.login
import android.content.Context
import android.content.Intent
-import android.content.pm.PackageManager
-import android.os.Build.VERSION_CODES.TIRAMISU
import android.os.Bundle
import android.view.MenuItem
-import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
-import androidx.fragment.app.FragmentManager.POP_BACK_STACK_INCLUSIVE
import androidx.fragment.app.commit
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R
-import io.github.wulkanowy.data.pojos.RegisterUser
+import io.github.wulkanowy.data.db.entities.StudentWithSemesters
import io.github.wulkanowy.databinding.ActivityLoginBinding
import io.github.wulkanowy.ui.base.BaseActivity
import io.github.wulkanowy.ui.modules.login.advanced.LoginAdvancedFragment
@@ -20,9 +16,6 @@ import io.github.wulkanowy.ui.modules.login.form.LoginFormFragment
import io.github.wulkanowy.ui.modules.login.recover.LoginRecoverFragment
import io.github.wulkanowy.ui.modules.login.studentselect.LoginStudentSelectFragment
import io.github.wulkanowy.ui.modules.login.symbol.LoginSymbolFragment
-import io.github.wulkanowy.ui.modules.main.MainActivity
-import io.github.wulkanowy.ui.modules.notifications.NotificationsFragment
-import io.github.wulkanowy.utils.AppInfo
import io.github.wulkanowy.utils.UpdateHelper
import javax.inject.Inject
@@ -35,9 +28,6 @@ class LoginActivity : BaseActivity(), Logi
@Inject
lateinit var updateHelper: UpdateHelper
- @Inject
- lateinit var appInfo: AppInfo
-
companion object {
fun getStartIntent(context: Context) = Intent(context, LoginActivity::class.java)
}
@@ -65,7 +55,7 @@ class LoginActivity : BaseActivity(), Logi
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
- if (item.itemId == android.R.id.home) onBackPressedDispatcher.onBackPressed()
+ if (item.itemId == android.R.id.home) onBackPressed()
return true
}
@@ -77,24 +67,8 @@ class LoginActivity : BaseActivity(), Logi
openFragment(LoginSymbolFragment.newInstance(loginData))
}
- fun navigateToStudentSelect(loginData: LoginData, registerUser: RegisterUser) {
- openFragment(LoginStudentSelectFragment.newInstance(loginData, registerUser))
- }
-
- fun navigateToNotifications() {
- val isNotificationsPermissionRequired = appInfo.systemVersion >= TIRAMISU
- val isPermissionGranted = ContextCompat.checkSelfPermission(
- this, "android.permission.POST_NOTIFICATIONS"
- ) == PackageManager.PERMISSION_GRANTED
-
- if (isNotificationsPermissionRequired && !isPermissionGranted) {
- openFragment(NotificationsFragment.newInstance(), clearBackStack = true)
- } else navigateToFinish()
- }
-
- fun navigateToFinish() {
- startActivity(MainActivity.getStartIntent(this))
- finish()
+ fun navigateToStudentSelect(studentsWithSemesters: List) {
+ openFragment(LoginStudentSelectFragment.newInstance(studentsWithSemesters))
}
fun onAdvancedLoginClick() {
@@ -106,8 +80,6 @@ class LoginActivity : BaseActivity(), Logi
}
private fun openFragment(fragment: Fragment, clearBackStack: Boolean = false) {
- supportFragmentManager.popBackStack(fragment::class.java.name, POP_BACK_STACK_INCLUSIVE)
-
supportFragmentManager.commit {
replace(R.id.loginContainer, fragment)
setReorderingAllowed(true)
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginData.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginData.kt
index ae6c22492..5d4743589 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginData.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/LoginData.kt
@@ -6,5 +6,4 @@ data class LoginData(
val login: String,
val password: String,
val baseUrl: String,
- val symbol: String?,
) : Serializable
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/advanced/LoginAdvancedFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/advanced/LoginAdvancedFragment.kt
index 8c90623e1..37dcb38b3 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/advanced/LoginAdvancedFragment.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/advanced/LoginAdvancedFragment.kt
@@ -8,7 +8,7 @@ import android.widget.ArrayAdapter
import androidx.core.widget.doOnTextChanged
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R
-import io.github.wulkanowy.data.pojos.RegisterUser
+import io.github.wulkanowy.data.db.entities.StudentWithSemesters
import io.github.wulkanowy.databinding.FragmentLoginAdvancedBinding
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.ui.base.BaseFragment
@@ -327,8 +327,8 @@ class LoginAdvancedFragment :
(activity as? LoginActivity)?.navigateToSymbolFragment(loginData)
}
- override fun navigateToStudentSelect(loginData: LoginData, registerUser: RegisterUser) {
- (activity as? LoginActivity)?.navigateToStudentSelect(loginData, registerUser)
+ override fun navigateToStudentSelect(studentsWithSemesters: List) {
+ (activity as? LoginActivity)?.navigateToStudentSelect(studentsWithSemesters)
}
override fun onResume() {
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/advanced/LoginAdvancedPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/advanced/LoginAdvancedPresenter.kt
index 33a76e5f9..1b42c6c52 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/advanced/LoginAdvancedPresenter.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/advanced/LoginAdvancedPresenter.kt
@@ -4,15 +4,9 @@ import io.github.wulkanowy.data.Resource
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
import io.github.wulkanowy.data.logResourceStatus
import io.github.wulkanowy.data.onResourceNotLoading
-import io.github.wulkanowy.data.pojos.RegisterStudent
-import io.github.wulkanowy.data.pojos.RegisterSymbol
-import io.github.wulkanowy.data.pojos.RegisterUnit
-import io.github.wulkanowy.data.pojos.RegisterUser
import io.github.wulkanowy.data.repositories.StudentRepository
import io.github.wulkanowy.data.resourceFlow
import io.github.wulkanowy.sdk.Sdk
-import io.github.wulkanowy.sdk.scrapper.Scrapper
-import io.github.wulkanowy.sdk.scrapper.getNormalizedSymbol
import io.github.wulkanowy.ui.base.BasePresenter
import io.github.wulkanowy.ui.modules.login.LoginData
import io.github.wulkanowy.ui.modules.login.LoginErrorHandler
@@ -148,23 +142,19 @@ class LoginAdvancedPresenter @Inject constructor(
is Resource.Success -> {
analytics.logEvent(
"registration_form",
- "success" to true,
- "students" to it.data.size,
- "error" to "No error"
- )
- val loginData = LoginData(
- login = view?.formUsernameValue.orEmpty().trim(),
- password = view?.formPassValue.orEmpty().trim(),
- baseUrl = view?.formHostValue.orEmpty().trim(),
- symbol = view?.formSymbolValue.orEmpty().trim().getNormalizedSymbol(),
- )
- when (it.data.size) {
- 0 -> view?.navigateToSymbol(loginData)
- else -> view?.navigateToStudentSelect(
- loginData = loginData,
- registerUser = it.data.toRegisterUser(loginData),
- )
- }
+ "success" to true,
+ "students" to it.data.size,
+ "error" to "No error"
+ )
+ val loginData = LoginData(
+ login = view?.formUsernameValue.orEmpty().trim(),
+ password = view?.formPassValue.orEmpty().trim(),
+ baseUrl = view?.formHostValue.orEmpty().trim()
+ )
+ when (it.data.size) {
+ 0 -> view?.navigateToSymbol(loginData)
+ else -> view?.navigateToStudentSelect(it.data)
+ }
}
is Resource.Error -> {
analytics.logEvent(
@@ -183,58 +173,6 @@ class LoginAdvancedPresenter @Inject constructor(
}.launch("login")
}
- private fun List.toRegisterUser(loginData: LoginData) = RegisterUser(
- email = loginData.login,
- password = loginData.password,
- login = loginData.login,
- baseUrl = loginData.baseUrl,
- loginType = firstOrNull()?.student?.loginType?.let(
- Scrapper.LoginType::valueOf
- ) ?: Scrapper.LoginType.AUTO,
- symbols = this
- .groupBy { students -> students.student.symbol }
- .map { (symbol, students) ->
- RegisterSymbol(
- symbol = symbol,
- error = null,
- userName = "",
- schools = students
- .groupBy { student ->
- Triple(
- first = student.student.schoolSymbol,
- second = student.student.userLoginId,
- third = student.student.schoolShortName
- )
- }
- .map { (groupKey, students) ->
- val (schoolId, loginId, schoolName) = groupKey
- RegisterUnit(
- students = students.map {
- RegisterStudent(
- studentId = it.student.studentId,
- studentName = it.student.studentName,
- studentSecondName = it.student.studentName,
- studentSurname = it.student.studentName,
- className = it.student.className,
- classId = it.student.classId,
- isParent = it.student.isParent,
- semesters = it.semesters,
- )
- },
- userLoginId = loginId,
- schoolId = schoolId,
- schoolName = schoolName,
- schoolShortName = schoolName,
- parentIds = listOf(),
- studentIds = listOf(),
- employeeIds = listOf(),
- error = null
- )
- }
- )
- },
- )
-
private suspend fun getStudentsAppropriatesToLoginType(): List {
val email = view?.formUsernameValue.orEmpty()
val password = view?.formPassValue.orEmpty()
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/advanced/LoginAdvancedView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/advanced/LoginAdvancedView.kt
index 824fa0288..f9b84f1ab 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/advanced/LoginAdvancedView.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/advanced/LoginAdvancedView.kt
@@ -1,7 +1,6 @@
package io.github.wulkanowy.ui.modules.login.advanced
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
-import io.github.wulkanowy.data.pojos.RegisterUser
import io.github.wulkanowy.ui.base.BaseView
import io.github.wulkanowy.ui.modules.login.LoginData
@@ -73,7 +72,7 @@ interface LoginAdvancedView : BaseView {
fun navigateToSymbol(loginData: LoginData)
- fun navigateToStudentSelect(loginData: LoginData, registerUser: RegisterUser)
+ fun navigateToStudentSelect(studentsWithSemesters: List)
fun setErrorPinRequired()
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormFragment.kt
index a0e7608d6..d31f5cf0f 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormFragment.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormFragment.kt
@@ -9,8 +9,7 @@ import androidx.core.view.isVisible
import androidx.core.widget.doOnTextChanged
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R
-import io.github.wulkanowy.data.pojos.RegisterUser
-import io.github.wulkanowy.data.repositories.PreferencesRepository
+import io.github.wulkanowy.data.db.entities.StudentWithSemesters
import io.github.wulkanowy.databinding.FragmentLoginFormBinding
import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.modules.login.LoginActivity
@@ -33,9 +32,6 @@ class LoginFormFragment : BaseFragment(R.layout.fragme
@Inject
lateinit var appInfo: AppInfo
- @Inject
- lateinit var preferencesRepository: PreferencesRepository
-
companion object {
fun newInstance() = LoginFormFragment()
}
@@ -226,8 +222,8 @@ class LoginFormFragment : BaseFragment(R.layout.fragme
(activity as? LoginActivity)?.navigateToSymbolFragment(loginData)
}
- override fun navigateToStudentSelect(loginData: LoginData, registerUser: RegisterUser) {
- (activity as? LoginActivity)?.navigateToStudentSelect(loginData, registerUser)
+ override fun navigateToStudentSelect(studentsWithSemesters: List) {
+ (activity as? LoginActivity)?.navigateToStudentSelect(studentsWithSemesters)
}
override fun openAdvancedLogin() {
@@ -264,9 +260,8 @@ class LoginFormFragment : BaseFragment(R.layout.fragme
R.string.login_email_text,
"${appInfo.systemManufacturer} ${appInfo.systemModel}",
appInfo.systemVersion.toString(),
- "${appInfo.versionName}-${appInfo.buildFlavor}",
+ appInfo.versionName,
"$formHostValue/$formHostSymbol",
- preferencesRepository.installationId,
lastError
)
)
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenter.kt
index 8035ea0ad..0acb0ea6d 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenter.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenter.kt
@@ -93,7 +93,7 @@ class LoginFormPresenter @Inject constructor(
if (!validateCredentials(email, password, host)) return
resourceFlow {
- studentRepository.getUserSubjectsFromScrapper(
+ studentRepository.getStudentsScrapper(
email = email,
password = password,
scrapperBaseUrl = host,
@@ -109,14 +109,14 @@ class LoginFormPresenter @Inject constructor(
}
}
.onResourceSuccess {
- val loginData = LoginData(email, password, host, symbol)
- when (it.symbols.size) {
- 0 -> view?.navigateToSymbol(loginData)
- else -> view?.navigateToStudentSelect(loginData, it)
+ when (it.size) {
+ 0 -> view?.navigateToSymbol(LoginData(email, password, host))
+ else -> view?.navigateToStudentSelect(it)
}
analytics.logEvent(
"registration_form",
"success" to true,
+ "students" to it.size,
"scrapperBaseUrl" to host,
"error" to "No error"
)
@@ -134,6 +134,7 @@ class LoginFormPresenter @Inject constructor(
analytics.logEvent(
"registration_form",
"success" to false,
+ "students" to -1,
"scrapperBaseUrl" to host,
"error" to it.message.ifNullOrBlank { "No message" }
)
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormView.kt
index 5a816fb32..8003975db 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormView.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/form/LoginFormView.kt
@@ -1,6 +1,6 @@
package io.github.wulkanowy.ui.modules.login.form
-import io.github.wulkanowy.data.pojos.RegisterUser
+import io.github.wulkanowy.data.db.entities.StudentWithSemesters
import io.github.wulkanowy.ui.base.BaseView
import io.github.wulkanowy.ui.modules.login.LoginData
@@ -60,7 +60,7 @@ interface LoginFormView : BaseView {
fun navigateToSymbol(loginData: LoginData)
- fun navigateToStudentSelect(loginData: LoginData, registerUser: RegisterUser)
+ fun navigateToStudentSelect(studentsWithSemesters: List)
fun openPrivacyPolicyPage()
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/recover/LoginRecoverFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/recover/LoginRecoverFragment.kt
index b9afba986..786bbfce8 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/recover/LoginRecoverFragment.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/recover/LoginRecoverFragment.kt
@@ -98,7 +98,7 @@ class LoginRecoverFragment :
loginRecoverButton.setOnClickListener { presenter.onRecoverClick() }
loginRecoverErrorRetry.setOnClickListener { presenter.onRecoverClick() }
loginRecoverErrorDetails.setOnClickListener { presenter.onDetailsClick() }
- loginRecoverLogin.setOnClickListener { (activity as LoginActivity).onBackPressedDispatcher.onBackPressed() }
+ loginRecoverLogin.setOnClickListener { (activity as LoginActivity).onBackPressed() }
}
with(bindingLocal.loginRecoverHost) {
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 e6d131829..c046c2ff5 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
@@ -2,182 +2,65 @@ package io.github.wulkanowy.ui.modules.login.studentselect
import android.annotation.SuppressLint
import android.view.LayoutInflater
+import android.view.View
import android.view.ViewGroup
-import androidx.core.view.isVisible
-import androidx.recyclerview.widget.DiffUtil.ItemCallback
-import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
-import io.github.wulkanowy.R
-import io.github.wulkanowy.databinding.*
+import io.github.wulkanowy.data.db.entities.StudentWithSemesters
+import io.github.wulkanowy.databinding.ItemLoginStudentSelectBinding
import javax.inject.Inject
-@SuppressLint("SetTextI18n")
class LoginStudentSelectAdapter @Inject constructor() :
- ListAdapter(Differ) {
+ RecyclerView.Adapter() {
- override fun getItemViewType(position: Int): Int = getItem(position).type.ordinal
+ private val checkedList = mutableMapOf()
- override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
- val inflater = LayoutInflater.from(parent.context)
- return when (LoginStudentSelectItemType.values()[viewType]) {
- LoginStudentSelectItemType.EMPTY_SYMBOLS_HEADER -> EmptySymbolsHeaderViewHolder(
- ItemLoginStudentSelectEmptySymbolHeaderBinding.inflate(inflater, parent, false),
- )
- LoginStudentSelectItemType.SYMBOL_HEADER -> SymbolsHeaderViewHolder(
- ItemLoginStudentSelectHeaderSymbolBinding.inflate(inflater, parent, false)
- )
- LoginStudentSelectItemType.SCHOOL_HEADER -> SchoolHeaderViewHolder(
- ItemLoginStudentSelectHeaderSchoolBinding.inflate(inflater, parent, false)
- )
- LoginStudentSelectItemType.STUDENT -> StudentViewHolder(
- ItemLoginStudentSelectStudentBinding.inflate(inflater, parent, false)
- )
- LoginStudentSelectItemType.HELP -> HelpViewHolder(
- ItemLoginStudentSelectHelpBinding.inflate(inflater, parent, false)
- )
+ var items = emptyList>()
+ set(value) {
+ field = value
+ checkedList.clear()
}
- }
- override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
- when (holder) {
- is EmptySymbolsHeaderViewHolder -> holder.bind(getItem(position) as LoginStudentSelectItem.EmptySymbolsHeader)
- is SymbolsHeaderViewHolder -> holder.bind(getItem(position) as LoginStudentSelectItem.SymbolHeader)
- is SchoolHeaderViewHolder -> holder.bind(getItem(position) as LoginStudentSelectItem.SchoolHeader)
- is StudentViewHolder -> holder.bind(getItem(position) as LoginStudentSelectItem.Student)
- is HelpViewHolder -> holder.bind(getItem(position) as LoginStudentSelectItem.Help)
- }
- }
+ var onClickListener: (StudentWithSemesters, alreadySaved: Boolean) -> Unit = { _, _ -> }
- private class EmptySymbolsHeaderViewHolder(
- private val binding: ItemLoginStudentSelectEmptySymbolHeaderBinding,
- ) : RecyclerView.ViewHolder(binding.root) {
+ override fun getItemCount() = items.size
- fun bind(item: LoginStudentSelectItem.EmptySymbolsHeader) {
- with(binding) {
- loginStudentSelectEmptySymbolChevron.rotation = if (item.isExpanded) 270f else 90f
- root.setOnClickListener { item.onClick() }
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder(
+ ItemLoginStudentSelectBinding.inflate(LayoutInflater.from(parent.context), parent, false)
+ )
+
+ @SuppressLint("SetTextI18n")
+ override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
+ val (studentAndSemesters, alreadySaved) = items[position]
+ val student = studentAndSemesters.student
+ val semesters = studentAndSemesters.semesters
+ val diary = semesters.maxByOrNull { it.semesterId }
+
+ with(holder.binding) {
+ loginItemName.text = "${student.studentName} ${diary?.diaryName.orEmpty()}"
+ loginItemSchool.text = student.schoolName
+ loginItemName.isEnabled = !alreadySaved
+ loginItemSchool.isEnabled = !alreadySaved
+ loginItemSignedIn.visibility = if (alreadySaved) View.VISIBLE else View.GONE
+
+ with(loginItemCheck) {
+ isEnabled = !alreadySaved
+ keyListener = null
+ isChecked = checkedList[position] ?: false
}
- }
- }
- private class SymbolsHeaderViewHolder(
- private val binding: ItemLoginStudentSelectHeaderSymbolBinding,
- ) : RecyclerView.ViewHolder(binding.root) {
-
- fun bind(item: LoginStudentSelectItem.SymbolHeader) {
- with(binding) {
- loginStudentSelectHeaderSymbolValue.text = buildString {
- append(root.context.getString(R.string.mobile_device_symbol))
- append(": ")
- append(item.humanReadableName ?: item.symbol.symbol)
- if (!item.humanReadableName.isNullOrBlank()) {
- append(" (${item.symbol.symbol})")
- }
- }
- loginStudentSelectHeaderSymbolUsername.text = item.symbol.userName
- loginStudentSelectHeaderSymbolUsername.isVisible = item.symbol.userName.isNotBlank()
- loginStudentSelectHeaderSymbolError.text = item.symbol.error?.message
- loginStudentSelectHeaderSymbolError.isVisible = item.symbol.error != null
- loginStudentSelectHeaderSymbolError.maxLines = when {
- item.isErrorExpanded -> Int.MAX_VALUE
- else -> 2
- }
-
- if (item.symbol.error != null) {
- root.setOnClickListener { item.onClick(item.symbol) }
- } else root.setOnClickListener(null)
- }
- }
- }
-
- private class SchoolHeaderViewHolder(
- private val binding: ItemLoginStudentSelectHeaderSchoolBinding,
- ) : RecyclerView.ViewHolder(binding.root) {
-
- fun bind(item: LoginStudentSelectItem.SchoolHeader) {
- with(binding) {
- loginStudentSelectHeaderSchoolName.text = buildString {
- append(item.unit.schoolName.trim())
- append(" (")
- append(item.unit.schoolShortName)
- append(")")
- }
- loginStudentSelectHeaderSchoolDetails.isVisible = item.unit.students.isEmpty()
- loginStudentSelectHeaderSchoolError.text = item.unit.error?.message
- loginStudentSelectHeaderSchoolError.isVisible = item.unit.error != null
- loginStudentSelectHeaderSchoolError.maxLines = when {
- item.isErrorExpanded -> Int.MAX_VALUE
- else -> 2
- }
-
- if (item.unit.error != null) {
- root.setOnClickListener { item.onClick(item.unit) }
- } else root.setOnClickListener(null)
- }
- }
- }
-
- private class StudentViewHolder(
- private val binding: ItemLoginStudentSelectStudentBinding,
- ) : RecyclerView.ViewHolder(binding.root) {
-
- fun bind(item: LoginStudentSelectItem.Student) {
- val student = item.student
- val semesters = student.semesters
- val diary = semesters.maxByOrNull { it.semesterId }
-
- with(binding) {
- loginItemName.text = "${student.studentName} ${student.studentSurname}"
- loginItemName.isEnabled = item.isEnabled
- loginItemSignedIn.text = if (!item.isEnabled) {
- root.context.getString(R.string.login_signed_in)
- } else diary?.diaryName
+ root.setOnClickListener {
+ onClickListener(studentAndSemesters, alreadySaved)
with(loginItemCheck) {
- keyListener = null
- isEnabled = item.isEnabled
- isChecked = item.isSelected || !item.isEnabled
- }
-
- root.isEnabled = item.isEnabled
- root.setOnClickListener {
- item.onClick(item)
+ if (isEnabled) {
+ isChecked = !isChecked
+ checkedList[position] = isChecked
+ }
}
}
}
}
- private class HelpViewHolder(
- private val binding: ItemLoginStudentSelectHelpBinding,
- ) : RecyclerView.ViewHolder(binding.root) {
-
- fun bind(item: LoginStudentSelectItem.Help) {
- with(binding) {
- loginStudentSelectHelpSymbol.isVisible = item.isSymbolButtonVisible
- loginStudentSelectHelpSymbol.setOnClickListener { item.onEnterSymbolClick() }
- loginStudentSelectHelpMail.setOnClickListener { item.onContactUsClick() }
- loginStudentSelectHelpDiscord.setOnClickListener { item.onDiscordClick() }
- }
- }
- }
-
- private object Differ : ItemCallback() {
-
- override fun areItemsTheSame(
- oldItem: LoginStudentSelectItem, newItem: LoginStudentSelectItem
- ): Boolean = when {
- oldItem is LoginStudentSelectItem.EmptySymbolsHeader && newItem is LoginStudentSelectItem.EmptySymbolsHeader -> true
- oldItem is LoginStudentSelectItem.SymbolHeader && newItem is LoginStudentSelectItem.SymbolHeader -> {
- oldItem.symbol == newItem.symbol
- }
- oldItem is LoginStudentSelectItem.Student && newItem is LoginStudentSelectItem.Student -> {
- oldItem.student == newItem.student
- }
- else -> oldItem == newItem
- }
-
- override fun areContentsTheSame(
- oldItem: LoginStudentSelectItem, newItem: LoginStudentSelectItem
- ): Boolean = oldItem == newItem
- }
+ class ItemViewHolder(val binding: ItemLoginStudentSelectBinding) :
+ RecyclerView.ViewHolder(binding.root)
}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectFragment.kt
index 169702151..6c910fe03 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectFragment.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectFragment.kt
@@ -2,20 +2,20 @@ package io.github.wulkanowy.ui.modules.login.studentselect
import android.os.Bundle
import android.view.View
+import android.view.View.GONE
+import android.view.View.VISIBLE
import androidx.core.os.bundleOf
-import androidx.core.view.isVisible
+import androidx.recyclerview.widget.LinearLayoutManager
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R
-import io.github.wulkanowy.data.pojos.RegisterUser
-import io.github.wulkanowy.data.repositories.PreferencesRepository
+import io.github.wulkanowy.data.db.entities.StudentWithSemesters
import io.github.wulkanowy.databinding.FragmentLoginStudentSelectBinding
import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.modules.login.LoginActivity
-import io.github.wulkanowy.ui.modules.login.LoginData
+import io.github.wulkanowy.ui.modules.main.MainActivity
import io.github.wulkanowy.utils.AppInfo
import io.github.wulkanowy.utils.openEmailClient
import io.github.wulkanowy.utils.openInternetBrowser
-import io.github.wulkanowy.utils.serializable
import javax.inject.Inject
@AndroidEntryPoint
@@ -32,26 +32,12 @@ class LoginStudentSelectFragment :
@Inject
lateinit var appInfo: AppInfo
- @Inject
- lateinit var preferencesRepository: PreferencesRepository
-
- private lateinit var symbolsNames: Array
- private lateinit var symbolsValues: Array
-
- override val symbols: Map by lazy {
- symbolsValues.zip(symbolsNames).toMap()
- }
-
companion object {
- private const val ARG_LOGIN = "LOGIN"
- private const val ARG_STUDENTS = "STUDENTS"
+ const val ARG_STUDENTS = "STUDENTS"
- fun newInstance(loginData: LoginData, registerUser: RegisterUser) =
+ fun newInstance(studentsWithSemesters: List) =
LoginStudentSelectFragment().apply {
- arguments = bundleOf(
- ARG_LOGIN to loginData,
- ARG_STUDENTS to registerUser,
- )
+ arguments = bundleOf(ARG_STUDENTS to studentsWithSemesters)
}
}
@@ -59,50 +45,62 @@ class LoginStudentSelectFragment :
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentLoginStudentSelectBinding.bind(view)
-
- symbolsNames = resources.getStringArray(R.array.symbols)
- symbolsValues = resources.getStringArray(R.array.symbols_values)
-
presenter.onAttachView(
view = this,
- loginData = requireArguments().serializable(ARG_LOGIN),
- registerUser = requireArguments().serializable(ARG_STUDENTS),
+ students = requireArguments().getSerializable(ARG_STUDENTS) as List,
)
}
override fun initView() {
(requireActivity() as LoginActivity).showActionBar(true)
+ loginAdapter.onClickListener = presenter::onItemSelected
+
with(binding) {
loginStudentSelectSignIn.setOnClickListener { presenter.onSignIn() }
- loginStudentSelectRecycler.adapter = loginAdapter
+ loginStudentSelectContactDiscord.setOnClickListener { presenter.onDiscordClick() }
+ loginStudentSelectContactEmail.setOnClickListener { presenter.onEmailClick() }
+
+ with(loginStudentSelectRecycler) {
+ layoutManager = LinearLayoutManager(context)
+ adapter = loginAdapter
+ }
}
}
- override fun updateData(data: List) {
- loginAdapter.submitList(data)
+ override fun updateData(data: List>) {
+ with(loginAdapter) {
+ items = data
+ notifyDataSetChanged()
+ }
}
- override fun navigateToSymbol(loginData: LoginData) {
- (requireActivity() as LoginActivity).navigateToSymbolFragment(loginData)
- }
-
- override fun navigateToNext() {
- (requireActivity() as LoginActivity).navigateToNotifications()
+ override fun openMainView() {
+ startActivity(MainActivity.getStartIntent(requireContext()))
+ requireActivity().finish()
}
override fun showProgress(show: Boolean) {
- binding.loginStudentSelectProgress.isVisible = show
+ binding.loginStudentSelectProgress.visibility = if (show) VISIBLE else GONE
}
override fun showContent(show: Boolean) {
- binding.loginStudentSelectContent.isVisible = show
+ binding.loginStudentSelectContent.visibility = if (show) VISIBLE else GONE
}
override fun enableSignIn(enable: Boolean) {
binding.loginStudentSelectSignIn.isEnabled = enable
}
+ override fun showContact(show: Boolean) {
+ binding.loginStudentSelectContact.visibility = if (show) VISIBLE else GONE
+ }
+
+ override fun onDestroyView() {
+ presenter.onDetachView()
+ super.onDestroyView()
+ }
+
override fun openDiscordInvite() {
context?.openInternetBrowser("https://discord.gg/vccAQBr", ::showMessage)
}
@@ -113,19 +111,12 @@ class LoginStudentSelectFragment :
email = "wulkanowyinc@gmail.com",
subject = requireContext().getString(R.string.login_email_subject),
body = requireContext().getString(
- R.string.login_email_text,
- "${appInfo.systemManufacturer} ${appInfo.systemModel}",
+ R.string.login_email_text, appInfo.systemModel,
appInfo.systemVersion.toString(),
- "${appInfo.versionName}-${appInfo.buildFlavor}",
+ appInfo.versionName,
"Select users to log in",
- preferencesRepository.installationId,
lastError
)
)
}
-
- override fun onDestroyView() {
- presenter.onDetachView()
- super.onDestroyView()
- }
}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectItem.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectItem.kt
deleted file mode 100644
index 1edc8e7b4..000000000
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectItem.kt
+++ /dev/null
@@ -1,50 +0,0 @@
-package io.github.wulkanowy.ui.modules.login.studentselect
-
-import io.github.wulkanowy.data.pojos.RegisterStudent
-import io.github.wulkanowy.data.pojos.RegisterSymbol
-import io.github.wulkanowy.data.pojos.RegisterUnit
-
-sealed class LoginStudentSelectItem(val type: LoginStudentSelectItemType) {
-
- data class EmptySymbolsHeader(
- val isExpanded: Boolean,
- val onClick: () -> Unit,
- ) : LoginStudentSelectItem(LoginStudentSelectItemType.EMPTY_SYMBOLS_HEADER)
-
- data class SymbolHeader(
- val symbol: RegisterSymbol,
- val humanReadableName: String?,
- val isErrorExpanded: Boolean,
- val onClick: (RegisterSymbol) -> Unit,
- ) : LoginStudentSelectItem(LoginStudentSelectItemType.SYMBOL_HEADER)
-
- data class SchoolHeader(
- val unit: RegisterUnit,
- val isErrorExpanded: Boolean,
- val onClick: (RegisterUnit) -> Unit,
- ) : LoginStudentSelectItem(LoginStudentSelectItemType.SCHOOL_HEADER)
-
- data class Student(
- val symbol: RegisterSymbol,
- val unit: RegisterUnit,
- val student: RegisterStudent,
- val isEnabled: Boolean,
- val isSelected: Boolean,
- val onClick: (Student) -> Unit,
- ) : LoginStudentSelectItem(LoginStudentSelectItemType.STUDENT)
-
- data class Help(
- val onEnterSymbolClick: () -> Unit,
- val onContactUsClick: () -> Unit,
- val onDiscordClick: () -> Unit,
- val isSymbolButtonVisible: Boolean,
- ) : LoginStudentSelectItem(LoginStudentSelectItemType.HELP)
-}
-
-enum class LoginStudentSelectItemType {
- EMPTY_SYMBOLS_HEADER,
- SYMBOL_HEADER,
- SCHOOL_HEADER,
- STUDENT,
- HELP,
-}
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 f94ea7b72..3455b3cf1 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
@@ -1,23 +1,15 @@
package io.github.wulkanowy.ui.modules.login.studentselect
import io.github.wulkanowy.data.Resource
-import io.github.wulkanowy.data.dataOrNull
+import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
import io.github.wulkanowy.data.logResourceStatus
-import io.github.wulkanowy.data.mappers.mapToStudentWithSemesters
-import io.github.wulkanowy.data.pojos.RegisterStudent
-import io.github.wulkanowy.data.pojos.RegisterSymbol
-import io.github.wulkanowy.data.pojos.RegisterUnit
-import io.github.wulkanowy.data.pojos.RegisterUser
import io.github.wulkanowy.data.repositories.StudentRepository
import io.github.wulkanowy.data.resourceFlow
-import io.github.wulkanowy.sdk.scrapper.login.AccountPermissionException
import io.github.wulkanowy.services.sync.SyncManager
import io.github.wulkanowy.ui.base.BasePresenter
-import io.github.wulkanowy.ui.modules.login.LoginData
import io.github.wulkanowy.ui.modules.login.LoginErrorHandler
import io.github.wulkanowy.utils.AnalyticsHelper
-import io.github.wulkanowy.utils.AppInfo
import io.github.wulkanowy.utils.ifNullOrBlank
import kotlinx.coroutines.flow.onEach
import timber.log.Timber
@@ -27,30 +19,18 @@ class LoginStudentSelectPresenter @Inject constructor(
studentRepository: StudentRepository,
private val loginErrorHandler: LoginErrorHandler,
private val syncManager: SyncManager,
- private val analytics: AnalyticsHelper,
- private val appInfo: AppInfo,
+ private val analytics: AnalyticsHelper
) : BasePresenter(loginErrorHandler, studentRepository) {
private var lastError: Throwable? = null
- private lateinit var registerUser: RegisterUser
- private lateinit var loginData: LoginData
+ private val selectedStudents = mutableListOf()
- private lateinit var students: List
- private var isEmptySymbolsExpanded = false
- private var expandedSymbolError: RegisterSymbol? = null
- private var expandedSchoolError: RegisterUnit? = null
-
- private val selectedStudents = mutableListOf()
-
- fun onAttachView(
- view: LoginStudentSelectView,
- loginData: LoginData,
- registerUser: RegisterUser,
- ) {
+ fun onAttachView(view: LoginStudentSelectView, students: List) {
super.onAttachView(view)
with(view) {
initView()
+ showContact(false)
enableSignIn(false)
loginErrorHandler.onStudentDuplicate = {
showMessage(it)
@@ -58,171 +38,50 @@ class LoginStudentSelectPresenter @Inject constructor(
}
}
- this.loginData = loginData
- this.registerUser = registerUser
- loadData()
+ if (students.size == 1) registerStudents(students)
+ loadData(students)
}
- private fun loadData() {
- resetSelectedState()
-
- resourceFlow { studentRepository.getSavedStudents(false) }.onEach {
- students = it.dataOrNull.orEmpty()
- when (it) {
- is Resource.Loading -> Timber.d("Login student select students load started")
- is Resource.Success -> refreshItems()
- is Resource.Error -> {
- errorHandler.dispatch(it.error)
- lastError = it.error
- refreshItems()
- }
- }
- }.launch()
- }
-
- private fun createItems(): List = buildList {
- val notEmptySymbols = registerUser.symbols.filter { it.schools.isNotEmpty() }
- val emptySymbols = registerUser.symbols.filter { it.schools.isEmpty() }
-
- if (emptySymbols.isNotEmpty() && notEmptySymbols.isNotEmpty() && emptySymbols.any { it.symbol == loginData.symbol }) {
- add(createEmptySymbolItem(emptySymbols.first { it.symbol == loginData.symbol }))
- }
-
- addAll(createNotEmptySymbolItems(notEmptySymbols, students))
- addAll(createEmptySymbolItems(emptySymbols, notEmptySymbols.isNotEmpty()))
-
- val helpItem = LoginStudentSelectItem.Help(
- onEnterSymbolClick = ::onEnterSymbol,
- onContactUsClick = ::onEmailClick,
- onDiscordClick = ::onDiscordClick,
- isSymbolButtonVisible = "login" !in loginData.baseUrl,
- )
- add(helpItem)
- }
-
- private fun createNotEmptySymbolItems(
- notEmptySymbols: List,
- students: List,
- ) = buildList {
- notEmptySymbols.forEach { registerSymbol ->
- val symbolHeader = LoginStudentSelectItem.SymbolHeader(
- symbol = registerSymbol,
- humanReadableName = view?.symbols?.get(registerSymbol.symbol),
- isErrorExpanded = expandedSymbolError == registerSymbol,
- onClick = ::onSymbolItemClick,
- )
- add(symbolHeader)
-
- registerSymbol.schools.forEach { registerUnit ->
- val schoolHeader = LoginStudentSelectItem.SchoolHeader(
- unit = registerUnit,
- isErrorExpanded = expandedSchoolError == registerUnit,
- onClick = ::onUnitItemClick,
- )
- add(schoolHeader)
-
- registerUnit.students.forEach {
- add(createStudentItem(it, registerSymbol, registerUnit, students))
- }
- }
- }
- }
-
- private fun createStudentItem(
- student: RegisterStudent,
- symbol: RegisterSymbol,
- school: RegisterUnit,
- students: List,
- ) = LoginStudentSelectItem.Student(
- symbol = symbol,
- unit = school,
- student = student,
- onClick = ::onItemSelected,
- isEnabled = students.none {
- it.student.email == registerUser.login
- && it.student.symbol == symbol.symbol
- && it.student.studentId == student.studentId
- && it.student.schoolSymbol == school.schoolId
- && it.student.classId == student.classId
- },
- isSelected = selectedStudents
- .filter { it.symbol.symbol == symbol.symbol }
- .filter { it.unit.schoolId == school.schoolId }
- .filter { it.student.studentId == student.studentId }
- .filter { it.student.classId == student.classId }
- .size == 1,
- )
-
- private fun createEmptySymbolItems(
- emptySymbols: List,
- isNotEmptySymbolsExist: Boolean,
- ) = buildList {
- val filteredEmptySymbols = emptySymbols.filter {
- it.error !is AccountPermissionException
- }.ifEmpty { emptySymbols.takeIf { !isNotEmptySymbolsExist }.orEmpty() }
-
- if (filteredEmptySymbols.isNotEmpty() && isNotEmptySymbolsExist) {
- val emptyHeader = LoginStudentSelectItem.EmptySymbolsHeader(
- isExpanded = isEmptySymbolsExpanded,
- onClick = ::onEmptySymbolsToggle,
- )
- add(emptyHeader)
- if (isEmptySymbolsExpanded) {
- filteredEmptySymbols.forEach {
- add(createEmptySymbolItem(it))
- }
- }
- }
-
- if (filteredEmptySymbols.isNotEmpty() && !isNotEmptySymbolsExist) {
- filteredEmptySymbols.forEach {
- add(createEmptySymbolItem(it))
- }
- }
- }
-
- private fun createEmptySymbolItem(registerSymbol: RegisterSymbol) =
- LoginStudentSelectItem.SymbolHeader(
- symbol = registerSymbol,
- humanReadableName = view?.symbols?.get(registerSymbol.symbol),
- isErrorExpanded = expandedSymbolError == registerSymbol,
- onClick = ::onSymbolItemClick,
- )
-
fun onSignIn() {
registerStudents(selectedStudents)
}
- private fun onEmptySymbolsToggle() {
- isEmptySymbolsExpanded = !isEmptySymbolsExpanded
-
- refreshItems()
- }
-
- private fun onItemSelected(item: LoginStudentSelectItem.Student) {
- if (!item.isEnabled) return
+ fun onItemSelected(studentWithSemester: StudentWithSemesters, alreadySaved: Boolean) {
+ if (alreadySaved) return
selectedStudents
- .removeAll {
- it.student.studentId == item.student.studentId &&
- it.student.classId == item.student.classId &&
- it.unit.schoolId == item.unit.schoolId &&
- it.symbol.symbol == item.symbol.symbol
- }
- .let { if (!it) selectedStudents.add(item) }
+ .removeAll { it == studentWithSemester }
+ .let { if (!it) selectedStudents.add(studentWithSemester) }
view?.enableSignIn(selectedStudents.isNotEmpty())
- refreshItems()
}
- private fun onSymbolItemClick(symbol: RegisterSymbol) {
- expandedSymbolError = if (symbol != expandedSymbolError) symbol else null
- refreshItems()
+ private fun compareStudents(a: Student, b: Student): Boolean {
+ return a.email == b.email
+ && a.symbol == b.symbol
+ && a.studentId == b.studentId
+ && a.schoolSymbol == b.schoolSymbol
+ && a.classId == b.classId
}
- private fun onUnitItemClick(unit: RegisterUnit) {
- expandedSchoolError = if (unit != expandedSchoolError) unit else null
- refreshItems()
+ private fun loadData(studentsWithSemesters: List) {
+ resetSelectedState()
+
+ resourceFlow { studentRepository.getSavedStudents(false) }.onEach {
+ when (it) {
+ is Resource.Loading -> Timber.d("Login student select students load started")
+ is Resource.Success -> view?.updateData(studentsWithSemesters.map { studentWithSemesters ->
+ studentWithSemesters to it.data.any { item ->
+ compareStudents(studentWithSemesters.student, item.student)
+ }
+ })
+ is Resource.Error -> {
+ errorHandler.dispatch(it.error)
+ lastError = it.error
+ view?.updateData(studentsWithSemesters.map { student -> student to false })
+ }
+ }
+ }.launch()
}
private fun resetSelectedState() {
@@ -230,20 +89,7 @@ class LoginStudentSelectPresenter @Inject constructor(
view?.enableSignIn(false)
}
- private fun refreshItems() {
- view?.updateData(createItems())
- }
-
- private fun registerStudents(students: List) {
- val studentsWithSemesters = students
- .filterIsInstance().map { item ->
- item.student.mapToStudentWithSemesters(
- user = registerUser,
- symbol = item.symbol,
- unit = item.unit,
- colors = appInfo.defaultColorsForAvatar,
- )
- }
+ private fun registerStudents(studentsWithSemesters: List) {
resourceFlow { studentRepository.saveStudents(studentsWithSemesters) }
.logResourceStatus("registration")
.onEach {
@@ -254,13 +100,14 @@ class LoginStudentSelectPresenter @Inject constructor(
}
is Resource.Success -> {
syncManager.startOneTimeSyncWorker(quiet = true)
- view?.navigateToNext()
+ view?.openMainView()
logRegisterEvent(studentsWithSemesters)
}
is Resource.Error -> {
view?.apply {
showProgress(false)
showContent(true)
+ showContact(true)
}
lastError = it.error
loginErrorHandler.dispatch(it.error)
@@ -270,22 +117,12 @@ class LoginStudentSelectPresenter @Inject constructor(
}.launch("register")
}
- private fun onEnterSymbol() {
- view?.navigateToSymbol(loginData)
- }
-
- private fun onDiscordClick() {
+ fun onDiscordClick() {
view?.openDiscordInvite()
}
- private fun onEmailClick() {
- view?.openEmail(lastError?.message.ifNullOrBlank {
- registerUser.symbols.flatMap { symbol ->
- symbol.schools.map { it.error?.message } + symbol.error?.message
- }.filterNotNull().distinct().joinToString("; ") {
- it.take(46) + "..."
- }.ifEmpty { "blank" }
- })
+ fun onEmailClick() {
+ view?.openEmail(lastError?.message.ifNullOrBlank { "empty" })
}
private fun logRegisterEvent(
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectView.kt
index 39f312bf3..f2acd76c5 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectView.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectView.kt
@@ -1,19 +1,15 @@
package io.github.wulkanowy.ui.modules.login.studentselect
+import io.github.wulkanowy.data.db.entities.StudentWithSemesters
import io.github.wulkanowy.ui.base.BaseView
-import io.github.wulkanowy.ui.modules.login.LoginData
interface LoginStudentSelectView : BaseView {
- val symbols: Map
-
fun initView()
- fun updateData(data: List)
+ fun updateData(data: List>)
- fun navigateToSymbol(loginData: LoginData)
-
- fun navigateToNext()
+ fun openMainView()
fun showProgress(show: Boolean)
@@ -21,6 +17,8 @@ interface LoginStudentSelectView : BaseView {
fun enableSignIn(enable: Boolean)
+ fun showContact(show: Boolean)
+
fun openDiscordInvite()
fun openEmail(lastError: String)
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolFragment.kt
index 67416cb63..58bdf6cef 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolFragment.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolFragment.kt
@@ -12,13 +12,16 @@ import androidx.core.text.parseAsHtml
import androidx.core.widget.doOnTextChanged
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R
-import io.github.wulkanowy.data.pojos.RegisterUser
-import io.github.wulkanowy.data.repositories.PreferencesRepository
+import io.github.wulkanowy.data.db.entities.StudentWithSemesters
import io.github.wulkanowy.databinding.FragmentLoginSymbolBinding
import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.modules.login.LoginActivity
import io.github.wulkanowy.ui.modules.login.LoginData
-import io.github.wulkanowy.utils.*
+import io.github.wulkanowy.utils.AppInfo
+import io.github.wulkanowy.utils.hideSoftInput
+import io.github.wulkanowy.utils.openEmailClient
+import io.github.wulkanowy.utils.openInternetBrowser
+import io.github.wulkanowy.utils.showSoftInput
import javax.inject.Inject
@AndroidEntryPoint
@@ -31,9 +34,6 @@ class LoginSymbolFragment :
@Inject
lateinit var appInfo: AppInfo
- @Inject
- lateinit var preferencesRepository: PreferencesRepository
-
companion object {
private const val SAVED_LOGIN_DATA = "LOGIN_DATA"
@@ -42,8 +42,6 @@ class LoginSymbolFragment :
}
}
- override val symbolValue: String? get() = binding.loginSymbolName.text?.toString()
-
override val symbolNameError: CharSequence?
get() = binding.loginSymbolNameLayout.error
@@ -52,7 +50,7 @@ class LoginSymbolFragment :
binding = FragmentLoginSymbolBinding.bind(view)
presenter.onAttachView(
view = this,
- loginData = requireArguments().serializable(SAVED_LOGIN_DATA),
+ loginData = requireArguments().getSerializable(SAVED_LOGIN_DATA) as LoginData,
)
}
@@ -60,7 +58,7 @@ class LoginSymbolFragment :
(requireActivity() as LoginActivity).showActionBar(true)
with(binding) {
- loginSymbolSignIn.setOnClickListener { presenter.attemptLogin() }
+ loginSymbolSignIn.setOnClickListener { presenter.attemptLogin(loginSymbolName.text.toString()) }
loginSymbolFaq.setOnClickListener { presenter.onFaqClick() }
loginSymbolContactEmail.setOnClickListener { presenter.onEmailClick() }
@@ -94,13 +92,9 @@ class LoginSymbolFragment :
}
override fun setErrorSymbolRequire() {
- setErrorSymbol(getString(R.string.error_field_required))
- }
-
- override fun setErrorSymbol(message: String) {
- with(binding.loginSymbolNameLayout) {
+ binding.loginSymbolNameLayout.apply {
requestFocus()
- error = message
+ error = getString(R.string.error_field_required)
}
}
@@ -131,8 +125,8 @@ class LoginSymbolFragment :
binding.loginSymbolContainer.visibility = if (show) VISIBLE else GONE
}
- override fun navigateToStudentSelect(loginData: LoginData, registerUser: RegisterUser) {
- (activity as? LoginActivity)?.navigateToStudentSelect(loginData, registerUser)
+ override fun navigateToStudentSelect(studentsWithSemesters: List) {
+ (activity as? LoginActivity)?.navigateToStudentSelect(studentsWithSemesters)
}
override fun onSaveInstanceState(outState: Bundle) {
@@ -165,9 +159,8 @@ class LoginSymbolFragment :
R.string.login_email_text,
"${appInfo.systemManufacturer} ${appInfo.systemModel}",
appInfo.systemVersion.toString(),
- "${appInfo.versionName}-${appInfo.buildFlavor}",
+ appInfo.versionName,
"$host/${binding.loginSymbolName.text}",
- preferencesRepository.installationId,
lastError
)
)
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolPresenter.kt
index a6ccd7a57..691cd4481 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolPresenter.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolPresenter.kt
@@ -1,12 +1,9 @@
package io.github.wulkanowy.ui.modules.login.symbol
import io.github.wulkanowy.data.Resource
-import io.github.wulkanowy.data.dataOrNull
import io.github.wulkanowy.data.onResourceNotLoading
-import io.github.wulkanowy.data.pojos.RegisterUser
import io.github.wulkanowy.data.repositories.StudentRepository
import io.github.wulkanowy.data.resourceFlow
-import io.github.wulkanowy.sdk.scrapper.getNormalizedSymbol
import io.github.wulkanowy.ui.base.BasePresenter
import io.github.wulkanowy.ui.modules.login.LoginData
import io.github.wulkanowy.ui.modules.login.LoginErrorHandler
@@ -26,14 +23,9 @@ class LoginSymbolPresenter @Inject constructor(
lateinit var loginData: LoginData
- private var registerUser: RegisterUser? = null
-
fun onAttachView(view: LoginSymbolView, loginData: LoginData) {
super.onAttachView(view)
this.loginData = loginData
- loginErrorHandler.onBadCredentials = {
- view.setErrorSymbol(it.orEmpty())
- }
with(view) {
initView()
showContact(false)
@@ -47,24 +39,20 @@ class LoginSymbolPresenter @Inject constructor(
view?.apply { if (symbolNameError != null) clearSymbolError() }
}
- fun attemptLogin() {
- if (view?.symbolValue.isNullOrBlank()) {
+ fun attemptLogin(symbol: String) {
+ if (symbol.isBlank()) {
view?.setErrorSymbolRequire()
return
}
- loginData = loginData.copy(
- symbol = view?.symbolValue?.getNormalizedSymbol(),
- )
resourceFlow {
- studentRepository.getUserSubjectsFromScrapper(
+ studentRepository.getStudentsScrapper(
email = loginData.login,
password = loginData.password,
scrapperBaseUrl = loginData.baseUrl,
- symbol = view?.symbolValue.orEmpty(),
+ symbol = symbol,
)
}.onEach {
- registerUser = it.dataOrNull
when (it) {
is Resource.Loading -> view?.run {
Timber.i("Login with symbol started")
@@ -73,7 +61,7 @@ class LoginSymbolPresenter @Inject constructor(
showContent(false)
}
is Resource.Success -> {
- when (it.data.symbols.size) {
+ when (it.data.size) {
0 -> {
Timber.i("Login with symbol result: Empty student list")
view?.run {
@@ -83,14 +71,15 @@ class LoginSymbolPresenter @Inject constructor(
}
else -> {
Timber.i("Login with symbol result: Success")
- view?.navigateToStudentSelect(loginData, requireNotNull(it.data))
+ view?.navigateToStudentSelect(requireNotNull(it.data))
}
}
analytics.logEvent(
"registration_symbol",
"success" to true,
+ "students" to it.data.size,
"scrapperBaseUrl" to loginData.baseUrl,
- "symbol" to view?.symbolValue,
+ "symbol" to symbol,
"error" to "No error"
)
}
@@ -101,7 +90,7 @@ class LoginSymbolPresenter @Inject constructor(
"success" to false,
"students" to -1,
"scrapperBaseUrl" to loginData.baseUrl,
- "symbol" to view?.symbolValue,
+ "symbol" to symbol,
"error" to it.error.message.ifNullOrBlank { "No message" }
)
loginErrorHandler.dispatch(it.error)
@@ -122,12 +111,6 @@ class LoginSymbolPresenter @Inject constructor(
}
fun onEmailClick() {
- view?.openEmail(loginData.baseUrl, lastError?.message.ifNullOrBlank {
- registerUser?.symbols?.flatMap { symbol ->
- symbol.schools.map { it.error?.message } + symbol.error?.message
- }?.filterNotNull()?.distinct()?.joinToString(";") {
- it.take(46) + "..."
- } ?: "blank"
- })
+ view?.openEmail(loginData.baseUrl, lastError?.message.ifNullOrBlank { "empty" })
}
}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolView.kt
index 6b62d1f7f..527895b77 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolView.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/login/symbol/LoginSymbolView.kt
@@ -1,13 +1,10 @@
package io.github.wulkanowy.ui.modules.login.symbol
-import io.github.wulkanowy.data.pojos.RegisterUser
+import io.github.wulkanowy.data.db.entities.StudentWithSemesters
import io.github.wulkanowy.ui.base.BaseView
-import io.github.wulkanowy.ui.modules.login.LoginData
interface LoginSymbolView : BaseView {
- val symbolValue: String?
-
val symbolNameError: CharSequence?
fun initView()
@@ -18,8 +15,6 @@ interface LoginSymbolView : BaseView {
fun setErrorSymbolRequire()
- fun setErrorSymbol(message: String)
-
fun clearSymbolError()
fun clearAndFocusSymbol()
@@ -32,7 +27,7 @@ interface LoginSymbolView : BaseView {
fun showContent(show: Boolean)
- fun navigateToStudentSelect(loginData: LoginData, registerUser: RegisterUser)
+ fun navigateToStudentSelect(studentsWithSemesters: List)
fun showContact(show: Boolean)
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainActivity.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainActivity.kt
index d332ee350..5cd6fa103 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainActivity.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainActivity.kt
@@ -6,8 +6,6 @@ import android.os.Build.VERSION_CODES.P
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
-import androidx.activity.OnBackPressedCallback
-import androidx.activity.addCallback
import androidx.core.view.ViewCompat
import androidx.core.view.isVisible
import androidx.fragment.app.DialogFragment
@@ -52,8 +50,6 @@ class MainActivity : BaseActivity(), MainVie
@Inject
lateinit var appInfo: AppInfo
- private var onBackCallback: OnBackPressedCallback? = null
-
private var accountMenu: MenuItem? = null
private val overlayProvider by lazy { ElevationOverlayProvider(this) }
@@ -92,9 +88,6 @@ class MainActivity : BaseActivity(), MainVie
this.savedInstanceState = savedInstanceState
messageContainer = binding.mainMessageContainer
updateHelper.messageContainer = binding.mainFragmentContainer
- onBackCallback = onBackPressedDispatcher.addCallback(this, enabled = false) {
- presenter.onBackPressed()
- }
val destination = intent.getStringExtra(EXTRA_START_DESTINATION)
?.takeIf { savedInstanceState == null }
@@ -273,7 +266,6 @@ class MainActivity : BaseActivity(), MainVie
analytics.popCurrentScreen(navController.currentFrag!!::class.simpleName)
navController.pushFragment(fragment)
- onBackCallback?.isEnabled = !isRootView
}
override fun popView(depth: Int) {
@@ -281,7 +273,10 @@ class MainActivity : BaseActivity(), MainVie
analytics.popCurrentScreen(navController.currentFrag!!::class.simpleName)
navController.safelyPopFragments(depth)
- onBackCallback?.isEnabled = !isRootView
+ }
+
+ override fun onBackPressed() {
+ presenter.onBackPressed { super.onBackPressed() }
}
override fun showStudentAvatar(student: Student) {
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainPresenter.kt
index 458e966d4..9c32d8583 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainPresenter.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/main/MainPresenter.kt
@@ -139,9 +139,12 @@ class MainPresenter @Inject constructor(
return true
}
- fun onBackPressed() {
+ fun onBackPressed(default: () -> Unit) {
Timber.i("Back pressed in main view")
- view?.popView()
+ view?.run {
+ if (isRootView) default()
+ else popView()
+ }
}
fun onTabSelected(index: Int, wasSelected: Boolean): Boolean {
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/mailboxchooser/MailboxChooserAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/mailboxchooser/MailboxChooserAdapter.kt
deleted file mode 100644
index 59f6d288d..000000000
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/mailboxchooser/MailboxChooserAdapter.kt
+++ /dev/null
@@ -1,81 +0,0 @@
-package io.github.wulkanowy.ui.modules.message.mailboxchooser
-
-import android.view.LayoutInflater
-import android.view.ViewGroup
-import androidx.core.view.isVisible
-import androidx.recyclerview.widget.DiffUtil.ItemCallback
-import androidx.recyclerview.widget.ListAdapter
-import androidx.recyclerview.widget.RecyclerView
-import io.github.wulkanowy.R
-import io.github.wulkanowy.data.db.entities.Mailbox
-import io.github.wulkanowy.data.db.entities.MailboxType
-import io.github.wulkanowy.databinding.ItemMailboxChooserBinding
-import javax.inject.Inject
-
-class MailboxChooserAdapter @Inject constructor() :
- ListAdapter(Differ) {
-
- override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder(
- ItemMailboxChooserBinding.inflate(
- LayoutInflater.from(parent.context), parent, false
- )
- )
-
- override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
- holder.bind(getItem(position))
- }
-
- class ItemViewHolder(
- private val binding: ItemMailboxChooserBinding,
- ) : RecyclerView.ViewHolder(binding.root) {
-
- fun bind(item: MailboxChooserItem) {
- with(binding) {
- mailboxItemName.text = item.mailbox?.getFirstLine()
- ?: root.resources.getString(R.string.message_chip_all_mailboxes)
- mailboxItemSchool.text = item.mailbox?.getSecondLine()
- mailboxItemSchool.isVisible = !item.isAll
-
- root.setOnClickListener { item.onClickListener(item.mailbox) }
- }
- }
-
- private fun Mailbox.getFirstLine() = buildString {
- if (studentName.isNotBlank() && studentName != userName) {
- append(studentName)
- append(" - ")
- }
- append(userName)
- }
-
- private fun Mailbox.getSecondLine() = buildString {
- append(schoolNameShort)
- append(" - ")
- append(getMailboxType(type))
- }
-
- private fun getMailboxType(type: MailboxType): String = when (type) {
- MailboxType.STUDENT -> R.string.message_mailbox_type_student
- MailboxType.PARENT -> R.string.message_mailbox_type_parent
- MailboxType.GUARDIAN -> R.string.message_mailbox_type_guardian
- MailboxType.EMPLOYEE -> R.string.message_mailbox_type_employee
- MailboxType.UNKNOWN -> null
- }.let { it?.let { it1 -> binding.root.resources.getString(it1) }.orEmpty() }
- }
-
- private object Differ : ItemCallback() {
- override fun areItemsTheSame(
- oldItem: MailboxChooserItem,
- newItem: MailboxChooserItem
- ): Boolean {
- return oldItem.mailbox?.globalKey == newItem.mailbox?.globalKey
- }
-
- override fun areContentsTheSame(
- oldItem: MailboxChooserItem,
- newItem: MailboxChooserItem
- ): Boolean {
- return oldItem == newItem
- }
- }
-}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/mailboxchooser/MailboxChooserDialog.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/mailboxchooser/MailboxChooserDialog.kt
deleted file mode 100644
index 37f9a19b5..000000000
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/mailboxchooser/MailboxChooserDialog.kt
+++ /dev/null
@@ -1,75 +0,0 @@
-package io.github.wulkanowy.ui.modules.message.mailboxchooser
-
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import androidx.core.os.bundleOf
-import androidx.fragment.app.setFragmentResult
-import dagger.hilt.android.AndroidEntryPoint
-import io.github.wulkanowy.data.db.entities.Mailbox
-import io.github.wulkanowy.databinding.DialogMailboxChooserBinding
-import io.github.wulkanowy.ui.base.BaseDialogFragment
-import io.github.wulkanowy.utils.parcelableArray
-import javax.inject.Inject
-
-@AndroidEntryPoint
-class MailboxChooserDialog : BaseDialogFragment(), MailboxChooserView {
-
- @Inject
- lateinit var presenter: MailboxChooserPresenter
-
- @Inject
- lateinit var mailboxAdapter: MailboxChooserAdapter
-
- companion object {
- const val LISTENER_KEY = "mailbox_selected"
- const val MAILBOX_KEY = "selected_mailbox"
- const val REQUIRED_KEY = "is_mailbox_required"
-
- fun newInstance(mailboxes: List, isMailboxRequired: Boolean, folder: String) =
- MailboxChooserDialog().apply {
- arguments = bundleOf(
- MAILBOX_KEY to mailboxes.toTypedArray(),
- REQUIRED_KEY to isMailboxRequired,
- LISTENER_KEY to folder,
- )
- }
- }
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setStyle(STYLE_NO_TITLE, 0)
- }
-
- override fun onCreateView(
- inflater: LayoutInflater,
- container: ViewGroup?,
- savedInstanceState: Bundle?
- ) = DialogMailboxChooserBinding.inflate(inflater).apply { binding = this }.root
-
- @Suppress("UNCHECKED_CAST")
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- presenter.onAttachView(
- view = this,
- requireMailbox = requireArguments().getBoolean(REQUIRED_KEY, false),
- mailboxes = requireArguments().parcelableArray(MAILBOX_KEY).orEmpty().toList(),
- )
- }
-
- override fun initView() {
- binding.accountQuickDialogRecycler.adapter = mailboxAdapter
- }
-
- override fun submitData(items: List) {
- mailboxAdapter.submitList(items)
- }
-
- override fun onMailboxSelected(item: Mailbox?) {
- setFragmentResult(
- requestKey = requireArguments().getString(LISTENER_KEY).orEmpty(),
- result = bundleOf(MAILBOX_KEY to item),
- )
- dismiss()
- }
-}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/mailboxchooser/MailboxChooserItem.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/mailboxchooser/MailboxChooserItem.kt
deleted file mode 100644
index 6923cf085..000000000
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/mailboxchooser/MailboxChooserItem.kt
+++ /dev/null
@@ -1,9 +0,0 @@
-package io.github.wulkanowy.ui.modules.message.mailboxchooser
-
-import io.github.wulkanowy.data.db.entities.Mailbox
-
-data class MailboxChooserItem(
- val mailbox: Mailbox? = null,
- val isAll: Boolean = false,
- val onClickListener: (Mailbox?) -> Unit,
-)
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/mailboxchooser/MailboxChooserPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/mailboxchooser/MailboxChooserPresenter.kt
deleted file mode 100644
index 5bd7c84ab..000000000
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/mailboxchooser/MailboxChooserPresenter.kt
+++ /dev/null
@@ -1,38 +0,0 @@
-package io.github.wulkanowy.ui.modules.message.mailboxchooser
-
-import io.github.wulkanowy.data.db.entities.Mailbox
-import io.github.wulkanowy.data.repositories.StudentRepository
-import io.github.wulkanowy.ui.base.BasePresenter
-import io.github.wulkanowy.ui.base.ErrorHandler
-import timber.log.Timber
-import javax.inject.Inject
-
-class MailboxChooserPresenter @Inject constructor(
- errorHandler: ErrorHandler,
- studentRepository: StudentRepository
-) : BasePresenter(errorHandler, studentRepository) {
-
- fun onAttachView(view: MailboxChooserView, mailboxes: List, requireMailbox: Boolean) {
- super.onAttachView(view)
-
- view.initView()
- Timber.i("Mailbox chooser view was initialized")
- view.submitData(getMailboxItems(mailboxes, requireMailbox))
- }
-
- private fun getMailboxItems(
- mailboxes: List,
- requireMailbox: Boolean,
- ): List = buildList {
- if (!requireMailbox) {
- add(MailboxChooserItem(isAll = true, onClickListener = ::onMailboxSelect))
- }
- addAll(mailboxes.map {
- MailboxChooserItem(mailbox = it, isAll = false, onClickListener = ::onMailboxSelect)
- })
- }
-
- fun onMailboxSelect(item: Mailbox?) {
- view?.onMailboxSelected(item)
- }
-}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/mailboxchooser/MailboxChooserView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/mailboxchooser/MailboxChooserView.kt
deleted file mode 100644
index 2e20ee815..000000000
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/mailboxchooser/MailboxChooserView.kt
+++ /dev/null
@@ -1,13 +0,0 @@
-package io.github.wulkanowy.ui.modules.message.mailboxchooser
-
-import io.github.wulkanowy.data.db.entities.Mailbox
-import io.github.wulkanowy.ui.base.BaseView
-
-interface MailboxChooserView : BaseView {
-
- fun initView()
-
- fun submitData(items: List)
-
- fun onMailboxSelected(item: Mailbox?)
-}
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 d3c6b95c7..3c1c53d39 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
@@ -1,5 +1,6 @@
package io.github.wulkanowy.ui.modules.message.preview
+import android.annotation.SuppressLint
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@@ -73,20 +74,15 @@ class MessagePreviewAdapter @Inject constructor() :
}
}
+ @SuppressLint("SetTextI18n")
private fun bindMessage(holder: MessageViewHolder, message: Message) {
val context = holder.binding.root.context
- val recipientCount = (message.unreadBy ?: 0) + (message.readBy ?: 0)
- val isReceived = message.unreadBy == null
- val readText = when {
- recipientCount > 1 -> {
- context.getString(R.string.message_read_by, message.readBy, recipientCount)
- }
- message.readBy == 1 || (isReceived && !message.unread) -> {
- context.getString(R.string.message_read, context.getString(R.string.all_yes))
- }
- else -> context.getString(R.string.message_read, context.getString(R.string.all_no))
+ val readTextValue = when {
+ !message.unread -> R.string.all_yes
+ else -> R.string.all_no
}
+ val readText = context.getString(R.string.message_read, context.getString(readTextValue))
with(holder.binding) {
messagePreviewSubject.text = message.subject.ifBlank {
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 6c54d9fcb..2a5523f4d 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
@@ -13,7 +13,6 @@ import android.webkit.WebResourceRequest
import android.webkit.WebView
import android.webkit.WebViewClient
import androidx.core.content.getSystemService
-import androidx.core.os.bundleOf
import androidx.recyclerview.widget.LinearLayoutManager
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R
@@ -24,7 +23,6 @@ import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.modules.main.MainActivity
import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.ui.modules.message.send.SendMessageActivity
-import io.github.wulkanowy.utils.serializable
import io.github.wulkanowy.utils.shareText
import javax.inject.Inject
@@ -68,12 +66,13 @@ class MessagePreviewFragment :
companion object {
const val MESSAGE_ID_KEY = "message_id"
- fun newInstance(message: Message) = MessagePreviewFragment().apply {
- arguments = bundleOf(MESSAGE_ID_KEY to message)
+ fun newInstance(message: Message): MessagePreviewFragment {
+ return MessagePreviewFragment().apply {
+ arguments = Bundle().apply { putSerializable(MESSAGE_ID_KEY, message) }
+ }
}
}
- @Suppress("DEPRECATION")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true)
@@ -84,8 +83,8 @@ class MessagePreviewFragment :
binding = FragmentMessagePreviewBinding.bind(view)
messageContainer = binding.messagePreviewContainer
presenter.onAttachView(
- view = this,
- message = (savedInstanceState ?: arguments)?.serializable(MESSAGE_ID_KEY),
+ this,
+ (savedInstanceState ?: arguments)?.getSerializable(MESSAGE_ID_KEY) as? Message
)
}
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 56f23b6fa..c011f41f3 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
@@ -6,6 +6,7 @@ import io.github.wulkanowy.data.*
import io.github.wulkanowy.data.db.entities.Message
import io.github.wulkanowy.data.db.entities.MessageAttachment
import io.github.wulkanowy.data.enums.MessageFolder
+import io.github.wulkanowy.data.repositories.MailboxRepository
import io.github.wulkanowy.data.repositories.MessageRepository
import io.github.wulkanowy.data.repositories.StudentRepository
import io.github.wulkanowy.ui.base.BasePresenter
@@ -20,6 +21,7 @@ class MessagePreviewPresenter @Inject constructor(
errorHandler: ErrorHandler,
studentRepository: StudentRepository,
private val messageRepository: MessageRepository,
+ private val mailboxRepository: MailboxRepository,
private val analytics: AnalyticsHelper
) : BasePresenter(errorHandler, studentRepository) {
@@ -185,7 +187,7 @@ class MessagePreviewPresenter @Inject constructor(
presenterScope.launch {
runCatching {
val student = studentRepository.getCurrentStudent(decryptPass = true)
- val mailbox = messageRepository.getMailboxByStudent(student)
+ val mailbox = mailboxRepository.getMailbox(student)
messageRepository.deleteMessage(student, mailbox, message!!)
}
.onFailure {
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessageActivity.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessageActivity.kt
index 14f3d718d..334e389e2 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessageActivity.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessageActivity.kt
@@ -19,16 +19,11 @@ import androidx.core.text.toHtml
import androidx.core.widget.doOnTextChanged
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R
-import io.github.wulkanowy.data.db.entities.Mailbox
import io.github.wulkanowy.data.db.entities.Message
import io.github.wulkanowy.databinding.ActivitySendMessageBinding
import io.github.wulkanowy.ui.base.BaseActivity
-import io.github.wulkanowy.ui.modules.message.mailboxchooser.MailboxChooserDialog
-import io.github.wulkanowy.ui.modules.message.mailboxchooser.MailboxChooserDialog.Companion.MAILBOX_KEY
-import io.github.wulkanowy.ui.modules.message.mailboxchooser.MailboxChooserDialog.Companion.LISTENER_KEY
import io.github.wulkanowy.utils.dpToPx
import io.github.wulkanowy.utils.hideSoftInput
-import io.github.wulkanowy.utils.nullableSerializable
import io.github.wulkanowy.utils.showSoftInput
import javax.inject.Inject
@@ -105,17 +100,13 @@ class SendMessageActivity : BaseActivity
- presenter.onMailboxSelected(bundle.nullableSerializable(MAILBOX_KEY))
- }
}
@SuppressLint("ClickableViewAccessibility")
@@ -214,14 +205,6 @@ class SendMessageActivity : BaseActivity) {
- MailboxChooserDialog.newInstance(
- mailboxes = mailboxes,
- isMailboxRequired = true,
- folder = LISTENER_KEY,
- ).show(supportFragmentManager, "chooser")
- }
-
override fun popView() {
finish()
}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessagePresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessagePresenter.kt
index e776e9941..6c07ee6ad 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessagePresenter.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessagePresenter.kt
@@ -1,15 +1,15 @@
package io.github.wulkanowy.ui.modules.message.send
-import io.github.wulkanowy.data.*
+import io.github.wulkanowy.data.Resource
import io.github.wulkanowy.data.db.entities.Mailbox
import io.github.wulkanowy.data.db.entities.MailboxType
import io.github.wulkanowy.data.db.entities.Message
import io.github.wulkanowy.data.db.entities.Recipient
+import io.github.wulkanowy.data.logResourceStatus
+import io.github.wulkanowy.data.onResourceNotLoading
import io.github.wulkanowy.data.pojos.MessageDraft
-import io.github.wulkanowy.data.repositories.MessageRepository
-import io.github.wulkanowy.data.repositories.PreferencesRepository
-import io.github.wulkanowy.data.repositories.RecipientRepository
-import io.github.wulkanowy.data.repositories.StudentRepository
+import io.github.wulkanowy.data.repositories.*
+import io.github.wulkanowy.data.resourceFlow
import io.github.wulkanowy.ui.base.BasePresenter
import io.github.wulkanowy.ui.base.ErrorHandler
import io.github.wulkanowy.utils.AnalyticsHelper
@@ -28,6 +28,7 @@ class SendMessagePresenter @Inject constructor(
errorHandler: ErrorHandler,
studentRepository: StudentRepository,
private val messageRepository: MessageRepository,
+ private val mailboxRepository: MailboxRepository,
private val recipientRepository: RecipientRepository,
private val preferencesRepository: PreferencesRepository,
private val analytics: AnalyticsHelper
@@ -35,19 +36,10 @@ class SendMessagePresenter @Inject constructor(
private val messageUpdateChannel = Channel()
- private var message: Message? = null
- private var isReplay: Boolean? = null
-
- private var mailboxes: List = emptyList()
- private var selectedMailbox: Mailbox? = null
-
fun onAttachView(view: SendMessageView, reason: String?, message: Message?, reply: Boolean?) {
super.onAttachView(view)
view.initView()
initializeSubjectStream()
- this.message = message
- this.isReplay = reply
-
Timber.i("Send message view was initialized")
loadData(message, reply)
with(view) {
@@ -55,7 +47,7 @@ class SendMessagePresenter @Inject constructor(
view.showMessageBackupDialog()
}
reason?.let {
- setSubject("Usprawiedliwienie")
+ setSubject("Usprawiedliwenie")
setContent(it)
}
message?.let {
@@ -118,31 +110,16 @@ class SendMessagePresenter @Inject constructor(
return false
}
- fun onOpenMailboxChooser() {
- view?.showMailboxChooser(mailboxes)
- }
-
- fun onMailboxSelected(mailbox: Mailbox?) {
- selectedMailbox = mailbox
-
- loadData(message, isReplay)
- }
-
private fun loadData(message: Message?, reply: Boolean?) {
resourceFlow {
val student = studentRepository.getCurrentStudent()
-
- if (selectedMailbox == null && mailboxes.isEmpty()) {
- selectedMailbox = messageRepository.getMailboxByStudent(student)
- mailboxes = messageRepository.getMailboxes(student, false).toFirstResult()
- .dataOrNull.orEmpty()
- }
+ val mailbox = mailboxRepository.getMailbox(student)
Timber.i("Loading recipients started")
val recipients = createChips(
recipients = recipientRepository.getRecipients(
student = student,
- mailbox = selectedMailbox,
+ mailbox = mailbox,
type = MailboxType.EMPLOYEE,
)
)
@@ -153,7 +130,7 @@ class SendMessagePresenter @Inject constructor(
message != null && reply == true -> recipientRepository.getMessageSender(
student = student,
message = message,
- mailbox = selectedMailbox,
+ mailbox = mailbox,
)
else -> emptyList()
}.let { createChips(it) }
@@ -162,42 +139,39 @@ class SendMessagePresenter @Inject constructor(
messageRecipients.size
)
- recipients to messageRecipients
+ Triple(mailbox, recipients, messageRecipients)
}
.logResourceStatus("load recipients")
- .onResourceLoading {
- view?.run {
- showProgress(true)
- showContent(false)
- }
- }
- .onResourceNotLoading {
- view?.run { showProgress(false) }
- }
- .onResourceError {
- view?.showContent(true)
- errorHandler.dispatch(it)
- }
- .onResourceSuccess {
- it.let { (recipientChips, selectedRecipientChips) ->
- view?.run {
- setMailbox(getMailboxName(selectedMailbox))
- setRecipients(recipientChips)
- if (selectedRecipientChips.isNotEmpty()) setSelectedRecipients(
- selectedRecipientChips
- )
- showContent(true)
+ .onEach {
+ when (it) {
+ is Resource.Loading -> view?.run {
+ showProgress(true)
+ showContent(false)
+ }
+ is Resource.Success -> it.data.let { (mailbox, recipientChips, selectedRecipientChips) ->
+ view?.run {
+ setMailbox(getMailboxName(mailbox))
+ setRecipients(recipientChips)
+ if (selectedRecipientChips.isNotEmpty()) setSelectedRecipients(
+ selectedRecipientChips
+ )
+ showContent(true)
+ }
+ }
+ is Resource.Error -> {
+ view?.showContent(true)
+ errorHandler.dispatch(it.error)
}
}
- }
- .launch()
+ }.onResourceNotLoading {
+ view?.run { showProgress(false) }
+ }.launch()
}
private fun sendMessage(subject: String, content: String, recipients: List) {
- val mailbox = selectedMailbox ?: return
-
resourceFlow {
val student = studentRepository.getCurrentStudent()
+ val mailbox = mailboxRepository.getMailbox(student)
messageRepository.sendMessage(
student = student,
subject = subject,
@@ -248,21 +222,18 @@ class SendMessagePresenter @Inject constructor(
}
}
- private fun getMailboxName(mailbox: Mailbox?): String {
- mailbox ?: return ""
-
- // username - accountType [\n student name - ] (school short name)
+ private fun getMailboxName(mailbox: Mailbox): String {
return buildString {
append(mailbox.userName)
append(" - ")
append(getMailboxType(mailbox.type))
- appendLine()
if (mailbox.type == MailboxType.PARENT) {
- append(mailbox.studentName)
append(" - ")
+ append(mailbox.studentName)
}
+ append(" - ")
append("(${mailbox.schoolNameShort})")
}
}
@@ -296,9 +267,9 @@ class SendMessagePresenter @Inject constructor(
private fun saveDraftMessage() {
messageRepository.draftMessage = MessageDraft(
- recipients = view?.formRecipientsData!!,
- subject = view?.formSubjectValue!!,
- content = view?.formContentValue!!,
+ view?.formRecipientsData!!,
+ view?.formSubjectValue!!,
+ view?.formContentValue!!
)
}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessageView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessageView.kt
index e27a09d60..1057114b8 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessageView.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/send/SendMessageView.kt
@@ -61,5 +61,4 @@ interface SendMessageView : BaseView {
fun getMessageBackupDialogStringWithRecipients(recipients: String): String
fun clearDraft()
- fun showMailboxChooser(mailboxes: List)
}
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 6df6153c5..55f03ef84 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
@@ -1,34 +1,28 @@
package io.github.wulkanowy.ui.modules.message.tab
-import android.content.res.ColorStateList
import android.graphics.Typeface
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.CompoundButton
import androidx.core.view.isVisible
-import androidx.core.widget.ImageViewCompat
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import io.github.wulkanowy.R
import io.github.wulkanowy.databinding.ItemMessageBinding
import io.github.wulkanowy.databinding.ItemMessageChipsBinding
-import io.github.wulkanowy.utils.getCompatColor
-import io.github.wulkanowy.utils.getThemeAttrColor
import io.github.wulkanowy.utils.toFormattedString
import javax.inject.Inject
class MessageTabAdapter @Inject constructor() :
RecyclerView.Adapter() {
- lateinit var onItemClickListener: (MessageTabDataItem.MessageItem, position: Int) -> Unit
+ var onItemClickListener: (MessageTabDataItem.MessageItem, position: Int) -> Unit = { _, _ -> }
- lateinit var onLongItemClickListener: (MessageTabDataItem.MessageItem) -> Unit
+ var onLongItemClickListener: (MessageTabDataItem.MessageItem) -> Unit = {}
- lateinit var onHeaderClickListener: (CompoundButton, Boolean) -> Unit
+ var onHeaderClickListener: (CompoundButton, Boolean) -> Unit = { _, _ -> }
- lateinit var onMailboxClickListener: () -> Unit
-
- lateinit var onChangesDetectedListener: () -> Unit
+ var onChangesDetectedListener = {}
private var items = mutableListOf()
@@ -52,12 +46,12 @@ class MessageTabAdapter @Inject constructor() :
val inflater = LayoutInflater.from(parent.context)
return when (MessageItemViewType.values()[viewType]) {
- MessageItemViewType.FILTERS -> HeaderViewHolder(
- ItemMessageChipsBinding.inflate(inflater, parent, false)
- )
MessageItemViewType.MESSAGE -> ItemViewHolder(
ItemMessageBinding.inflate(inflater, parent, false)
)
+ MessageItemViewType.FILTERS -> HeaderViewHolder(
+ ItemMessageChipsBinding.inflate(inflater, parent, false)
+ )
}
}
@@ -72,20 +66,6 @@ class MessageTabAdapter @Inject constructor() :
val item = items[position] as MessageTabDataItem.FilterHeader
with(holder.binding) {
- chipMailbox.text = item.selectedMailbox
- ?: root.context.getString(R.string.message_chip_all_mailboxes)
- chipMailbox.chipBackgroundColor = ColorStateList.valueOf(
- if (item.selectedMailbox == null) {
- root.context.getCompatColor(R.color.mtrl_choice_chip_background_color)
- } else root.context.getThemeAttrColor(android.R.attr.colorPrimary, 64)
- )
- chipMailbox.setTextColor(
- if (item.selectedMailbox == null) {
- root.context.getThemeAttrColor(android.R.attr.textColorPrimary)
- } else root.context.getThemeAttrColor(android.R.attr.colorPrimary)
- )
- chipMailbox.setOnClickListener { onMailboxClickListener() }
-
if (item.onlyUnread == null) {
chipUnread.isVisible = false
} else {
@@ -94,7 +74,6 @@ class MessageTabAdapter @Inject constructor() :
chipUnread.setOnCheckedChangeListener(onHeaderClickListener)
}
chipUnread.isEnabled = item.isEnabled
-
chipAttachments.isEnabled = item.isEnabled
chipAttachments.isChecked = item.onlyWithAttachments
chipAttachments.setOnCheckedChangeListener(onHeaderClickListener)
@@ -106,35 +85,21 @@ class MessageTabAdapter @Inject constructor() :
val message = item.message
with(holder.binding) {
- val normalFont = Typeface.create("sans-serif", Typeface.NORMAL)
- val boldFont = Typeface.create("sans-serif-black", Typeface.NORMAL)
-
- val primaryColor = root.context.getThemeAttrColor(android.R.attr.textColorPrimary)
- val secondaryColor = root.context.getThemeAttrColor(android.R.attr.textColorSecondary)
-
- val currentFont = if (message.unread) boldFont else normalFont
- val currentTextColor = if (message.unread) primaryColor else secondaryColor
+ val style = if (message.unread) Typeface.BOLD else Typeface.NORMAL
with(messageItemAuthor) {
text = message.correspondents
- setTextColor(currentTextColor)
- typeface = currentFont
+ setTypeface(null, style)
}
- with(messageItemSubject) {
+ messageItemSubject.run {
text = message.subject.ifBlank { context.getString(R.string.message_no_subject) }
- setTextColor(currentTextColor)
- typeface = currentFont
+ setTypeface(null, style)
}
- with(messageItemDate) {
+ messageItemDate.run {
text = message.date.toFormattedString()
- setTextColor(currentTextColor)
- typeface = currentFont
+ setTypeface(null, style)
}
- with(messageItemAttachmentIcon) {
- ImageViewCompat.setImageTintList(this, ColorStateList.valueOf(currentTextColor))
- isVisible = message.hasAttachments
- }
- messageItemUnreadIndicator.isVisible = message.unread
+ messageItemAttachmentIcon.isVisible = message.hasAttachments
root.setOnClickListener {
holder.bindingAdapterPosition.let {
@@ -146,7 +111,7 @@ class MessageTabAdapter @Inject constructor() :
root.setOnLongClickListener {
onLongItemClickListener(item)
- true
+ return@setOnLongClickListener true
}
with(messageItemCheckbox) {
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabDataItem.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabDataItem.kt
index c0bd4170e..634dfc0e7 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabDataItem.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabDataItem.kt
@@ -11,7 +11,6 @@ sealed class MessageTabDataItem(val viewType: MessageItemViewType) {
) : MessageTabDataItem(MessageItemViewType.MESSAGE)
data class FilterHeader(
- val selectedMailbox: String?,
val onlyUnread: Boolean?,
val onlyWithAttachments: Boolean,
val isEnabled: Boolean
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 c78ccc6ec..654b0e226 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
@@ -9,26 +9,21 @@ import android.view.View.*
import android.widget.CompoundButton
import androidx.appcompat.view.ActionMode
import androidx.appcompat.widget.SearchView
-import androidx.core.os.bundleOf
import androidx.core.view.updatePadding
-import androidx.fragment.app.setFragmentResultListener
import androidx.recyclerview.widget.LinearLayoutManager
import dagger.hilt.android.AndroidEntryPoint
import io.github.wulkanowy.R
-import io.github.wulkanowy.data.db.entities.Mailbox
import io.github.wulkanowy.data.db.entities.Message
import io.github.wulkanowy.data.enums.MessageFolder
import io.github.wulkanowy.databinding.FragmentMessageTabBinding
import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.modules.main.MainActivity
import io.github.wulkanowy.ui.modules.message.MessageFragment
-import io.github.wulkanowy.ui.modules.message.mailboxchooser.MailboxChooserDialog
import io.github.wulkanowy.ui.modules.message.preview.MessagePreviewFragment
import io.github.wulkanowy.ui.widgets.DividerItemDecoration
import io.github.wulkanowy.utils.dpToPx
import io.github.wulkanowy.utils.getThemeAttrColor
import io.github.wulkanowy.utils.hideSoftInput
-import io.github.wulkanowy.utils.nullableSerializable
import javax.inject.Inject
@AndroidEntryPoint
@@ -45,8 +40,12 @@ class MessageTabFragment : BaseFragment(R.layout.frag
const val MESSAGE_TAB_FOLDER_ID = "message_tab_folder_id"
- fun newInstance(folder: MessageFolder) = MessageTabFragment().apply {
- arguments = bundleOf(MESSAGE_TAB_FOLDER_ID to folder.name)
+ fun newInstance(folder: MessageFolder): MessageTabFragment {
+ return MessageTabFragment().apply {
+ arguments = Bundle().apply {
+ putString(MESSAGE_TAB_FOLDER_ID, folder.name)
+ }
+ }
}
}
@@ -84,7 +83,6 @@ class MessageTabFragment : BaseFragment(R.layout.frag
}
}
- @Suppress("DEPRECATION")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true)
@@ -106,7 +104,6 @@ class MessageTabFragment : BaseFragment(R.layout.frag
onItemClickListener = presenter::onMessageItemSelected
onLongItemClickListener = presenter::onMessageItemLongSelected
onHeaderClickListener = ::onChipChecked
- onMailboxClickListener = presenter::onMailboxFilterSelected
onChangesDetectedListener = ::resetListPosition
}
@@ -126,15 +123,8 @@ class MessageTabFragment : BaseFragment(R.layout.frag
messageTabErrorRetry.setOnClickListener { presenter.onRetry() }
messageTabErrorDetails.setOnClickListener { presenter.onDetailsClick() }
}
-
- setFragmentResultListener(requireArguments().getString(MESSAGE_TAB_FOLDER_ID)!!) { _, bundle ->
- presenter.onMailboxSelected(
- mailbox = bundle.nullableSerializable(MailboxChooserDialog.MAILBOX_KEY),
- )
- }
}
- @Suppress("DEPRECATION")
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
super.onCreateOptionsMenu(menu, inflater)
inflater.inflate(R.menu.action_menu_message_tab, menu)
@@ -256,16 +246,6 @@ class MessageTabFragment : BaseFragment(R.layout.frag
)
}
- override fun showMailboxChooser(mailboxes: List) {
- (activity as? MainActivity)?.showDialogFragment(
- MailboxChooserDialog.newInstance(
- mailboxes = mailboxes,
- isMailboxRequired = false,
- folder = requireArguments().getString(MESSAGE_TAB_FOLDER_ID)!!,
- )
- )
- }
-
override fun hideKeyboard() {
activity?.hideSoftInput()
}
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 ea142db2b..54711a689 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,9 +1,9 @@
package io.github.wulkanowy.ui.modules.message.tab
import io.github.wulkanowy.data.*
-import io.github.wulkanowy.data.db.entities.Mailbox
import io.github.wulkanowy.data.db.entities.Message
import io.github.wulkanowy.data.enums.MessageFolder
+import io.github.wulkanowy.data.repositories.MailboxRepository
import io.github.wulkanowy.data.repositories.MessageRepository
import io.github.wulkanowy.data.repositories.StudentRepository
import io.github.wulkanowy.ui.base.BasePresenter
@@ -26,6 +26,7 @@ class MessageTabPresenter @Inject constructor(
errorHandler: ErrorHandler,
studentRepository: StudentRepository,
private val messageRepository: MessageRepository,
+ private val mailboxRepository: MailboxRepository,
private val analytics: AnalyticsHelper
) : BasePresenter(errorHandler, studentRepository) {
@@ -35,9 +36,6 @@ class MessageTabPresenter @Inject constructor(
private var lastSearchQuery = ""
- private var mailboxes: List = emptyList()
- private var selectedMailbox: Mailbox? = null
-
private var messages = emptyList()
private val searchChannel = Channel()
@@ -124,7 +122,8 @@ class MessageTabPresenter @Inject constructor(
runCatching {
val student = studentRepository.getCurrentStudent(true)
- messageRepository.deleteMessages(student, selectedMailbox, messageList)
+ val mailbox = mailboxRepository.getMailbox(student)
+ messageRepository.deleteMessages(student, mailbox, messageList)
}
.onFailure(errorHandler::dispatch)
.onSuccess { view?.showMessagesDeleted() }
@@ -203,28 +202,13 @@ class MessageTabPresenter @Inject constructor(
}
}
- fun onMailboxFilterSelected() {
- view?.showMailboxChooser(mailboxes)
- }
-
- fun onMailboxSelected(mailbox: Mailbox?) {
- selectedMailbox = mailbox
- loadData(false)
- }
-
private fun loadData(forceRefresh: Boolean) {
Timber.i("Loading $folder message data started")
flatResourceFlow {
val student = studentRepository.getCurrentStudent()
-
- if (selectedMailbox == null && mailboxes.isEmpty()) {
- selectedMailbox = messageRepository.getMailboxByStudent(student)
- mailboxes = messageRepository.getMailboxes(student, forceRefresh).toFirstResult()
- .dataOrNull.orEmpty()
- }
-
- messageRepository.getMessages(student, selectedMailbox, folder, forceRefresh)
+ val mailbox = mailboxRepository.getMailbox(student)
+ messageRepository.getMessages(student, mailbox, folder, forceRefresh)
}
.logResourceStatus("load $folder message")
.onResourceData {
@@ -343,16 +327,7 @@ class MessageTabPresenter @Inject constructor(
MessageTabDataItem.FilterHeader(
onlyUnread = onlyUnread.takeIf { folder != MessageFolder.SENT },
onlyWithAttachments = onlyWithAttachments,
- isEnabled = !isActionMode,
- selectedMailbox = selectedMailbox?.let {
- buildString {
- if (it.studentName.isNotBlank() && it.studentName != it.userName) {
- append(it.studentName)
- append(" - ")
- }
- append(it.userName)
- }
- },
+ isEnabled = !isActionMode
)
)
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabView.kt
index 6ece6621b..bfa43b209 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabView.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/message/tab/MessageTabView.kt
@@ -1,6 +1,5 @@
package io.github.wulkanowy.ui.modules.message.tab
-import io.github.wulkanowy.data.db.entities.Mailbox
import io.github.wulkanowy.data.db.entities.Message
import io.github.wulkanowy.ui.base.BaseView
@@ -47,6 +46,4 @@ interface MessageTabView : BaseView {
fun showActionMode(show: Boolean)
fun showRecyclerBottomPadding(show: Boolean)
-
- fun showMailboxChooser(mailboxes: List)
}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/note/NoteDialog.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/note/NoteDialog.kt
index e46ab42cc..5811456b6 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/note/NoteDialog.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/note/NoteDialog.kt
@@ -6,7 +6,6 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.content.ContextCompat
-import androidx.core.os.bundleOf
import androidx.fragment.app.DialogFragment
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Note
@@ -14,7 +13,6 @@ import io.github.wulkanowy.databinding.DialogNoteBinding
import io.github.wulkanowy.sdk.scrapper.notes.NoteCategory
import io.github.wulkanowy.utils.getThemeAttrColor
import io.github.wulkanowy.utils.lifecycleAwareVariable
-import io.github.wulkanowy.utils.serializable
import io.github.wulkanowy.utils.toFormattedString
class NoteDialog : DialogFragment() {
@@ -27,15 +25,17 @@ class NoteDialog : DialogFragment() {
private const val ARGUMENT_KEY = "Item"
- fun newInstance(note: Note) = NoteDialog().apply {
- arguments = bundleOf(ARGUMENT_KEY to note)
+ fun newInstance(exam: Note) = NoteDialog().apply {
+ arguments = Bundle().apply { putSerializable(ARGUMENT_KEY, exam) }
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NO_TITLE, 0)
- note = requireArguments().serializable(ARGUMENT_KEY)
+ arguments?.run {
+ note = getSerializable(ARGUMENT_KEY) as Note
+ }
}
override fun onCreateView(
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/notifications/NotificationsFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/notifications/NotificationsFragment.kt
deleted file mode 100644
index 163ba8cdf..000000000
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/notifications/NotificationsFragment.kt
+++ /dev/null
@@ -1,64 +0,0 @@
-package io.github.wulkanowy.ui.modules.notifications
-
-import android.os.Bundle
-import android.view.View
-import androidx.activity.result.contract.ActivityResultContracts.RequestPermission
-import androidx.appcompat.app.AlertDialog
-import dagger.hilt.android.AndroidEntryPoint
-import io.github.wulkanowy.R
-import io.github.wulkanowy.databinding.FragmentNotificationsBinding
-import io.github.wulkanowy.ui.base.BaseFragment
-import io.github.wulkanowy.ui.modules.login.LoginActivity
-import io.github.wulkanowy.utils.openNotificationSettings
-
-@AndroidEntryPoint
-class NotificationsFragment :
- BaseFragment(R.layout.fragment_notifications) {
-
- private val permission = "android.permission.POST_NOTIFICATIONS"
-
- private val requestPermissionLauncher = registerForActivityResult(RequestPermission()) {
- if (it) {
- navigateToFinish()
- } else showSettingsDialog()
- }
-
- companion object {
- fun newInstance() = NotificationsFragment()
- }
-
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- super.onViewCreated(view, savedInstanceState)
- binding = FragmentNotificationsBinding.bind(view)
- initView()
- }
-
- private fun initView() {
- with(binding) {
- notificationsSkip.setOnClickListener { navigateToFinish() }
- notificationsEnable.setOnClickListener { requestPermission() }
- }
- }
-
- private fun showSettingsDialog() {
- AlertDialog.Builder(requireContext())
- .setTitle(R.string.notifications_header_title)
- .setMessage(R.string.notifications_header_description)
- .setNegativeButton(R.string.notifications_skip) { dialog, _ ->
- dialog.dismiss()
- navigateToFinish()
- }
- .setPositiveButton(R.string.pref_notification_go_to_settings) { _, _ ->
- requireActivity().openNotificationSettings()
- }
- .show()
- }
-
- private fun requestPermission() {
- requestPermissionLauncher.launch(permission)
- }
-
- private fun navigateToFinish() {
- (requireActivity() as LoginActivity).navigateToFinish()
- }
-}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/schoolannouncement/SchoolAnnouncementAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/schoolannouncement/SchoolAnnouncementAdapter.kt
index 46999599b..62f6251ec 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/schoolannouncement/SchoolAnnouncementAdapter.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/schoolannouncement/SchoolAnnouncementAdapter.kt
@@ -2,10 +2,10 @@ package io.github.wulkanowy.ui.modules.schoolannouncement
import android.view.LayoutInflater
import android.view.ViewGroup
+import androidx.core.text.parseAsHtml
import androidx.recyclerview.widget.RecyclerView
import io.github.wulkanowy.data.db.entities.SchoolAnnouncement
import io.github.wulkanowy.databinding.ItemSchoolAnnouncementBinding
-import io.github.wulkanowy.utils.parseUonetHtml
import io.github.wulkanowy.utils.toFormattedString
import javax.inject.Inject
@@ -28,7 +28,7 @@ class SchoolAnnouncementAdapter @Inject constructor() :
with(holder.binding) {
schoolAnnouncementItemDate.text = item.date.toFormattedString()
schoolAnnouncementItemType.text = item.subject
- schoolAnnouncementItemContent.text = item.content.parseUonetHtml()
+ schoolAnnouncementItemContent.text = item.content.parseAsHtml()
root.setOnClickListener { onItemClickListener(item) }
}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/schoolannouncement/SchoolAnnouncementDialog.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/schoolannouncement/SchoolAnnouncementDialog.kt
index e33a48f03..7dcd51cea 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/schoolannouncement/SchoolAnnouncementDialog.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/schoolannouncement/SchoolAnnouncementDialog.kt
@@ -4,13 +4,11 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
-import androidx.core.os.bundleOf
+import androidx.core.text.parseAsHtml
import androidx.fragment.app.DialogFragment
import io.github.wulkanowy.data.db.entities.SchoolAnnouncement
import io.github.wulkanowy.databinding.DialogSchoolAnnouncementBinding
import io.github.wulkanowy.utils.lifecycleAwareVariable
-import io.github.wulkanowy.utils.parseUonetHtml
-import io.github.wulkanowy.utils.serializable
import io.github.wulkanowy.utils.toFormattedString
class SchoolAnnouncementDialog : DialogFragment() {
@@ -23,15 +21,17 @@ class SchoolAnnouncementDialog : DialogFragment() {
private const val ARGUMENT_KEY = "item"
- fun newInstance(announcement: SchoolAnnouncement) = SchoolAnnouncementDialog().apply {
- arguments = bundleOf(ARGUMENT_KEY to announcement)
+ fun newInstance(exam: SchoolAnnouncement) = SchoolAnnouncementDialog().apply {
+ arguments = Bundle().apply { putSerializable(ARGUMENT_KEY, exam) }
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NO_TITLE, 0)
- announcement = requireArguments().serializable(ARGUMENT_KEY)
+ arguments?.run {
+ announcement = getSerializable(ARGUMENT_KEY) as SchoolAnnouncement
+ }
}
override fun onCreateView(
@@ -46,7 +46,7 @@ class SchoolAnnouncementDialog : DialogFragment() {
with(binding) {
announcementDialogSubjectValue.text = announcement.subject
announcementDialogDateValue.text = announcement.date.toFormattedString()
- announcementDialogDescriptionValue.text = announcement.content.parseUonetHtml()
+ announcementDialogDescriptionValue.text = announcement.content.parseAsHtml()
announcementDialogClose.setOnClickListener { dismiss() }
}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/notifications/NotificationsFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/notifications/NotificationsFragment.kt
index 77a3c6cf4..364ad2137 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/notifications/NotificationsFragment.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/notifications/NotificationsFragment.kt
@@ -1,16 +1,18 @@
package io.github.wulkanowy.ui.modules.settings.notifications
+import android.annotation.SuppressLint
import android.content.Intent
import android.content.SharedPreferences
-import android.content.pm.PackageManager
+import android.net.Uri
+import android.os.Build
import android.os.Bundle
+import android.provider.Settings
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AlertDialog
import androidx.core.app.NotificationManagerCompat
-import androidx.core.content.ContextCompat
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import androidx.preference.SwitchPreferenceCompat
@@ -24,7 +26,7 @@ import io.github.wulkanowy.ui.base.ErrorDialog
import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.utils.AppInfo
import io.github.wulkanowy.utils.openInternetBrowser
-import io.github.wulkanowy.utils.openNotificationSettings
+import timber.log.Timber
import javax.inject.Inject
@AndroidEntryPoint
@@ -40,14 +42,7 @@ class NotificationsFragment : PreferenceFragmentCompat(),
override val titleStringId get() = R.string.pref_settings_notifications_title
- private val notificationsPermission = "android.permission.POST_NOTIFICATIONS"
-
override val isNotificationPermissionGranted: Boolean
- get() = ContextCompat.checkSelfPermission(
- requireContext(), notificationsPermission
- ) == PackageManager.PERMISSION_GRANTED
-
- override val isNotificationPiggybackPermissionGranted: Boolean
get() {
val packageNameList =
NotificationManagerCompat.getEnabledListenerPackages(requireContext())
@@ -56,13 +51,6 @@ class NotificationsFragment : PreferenceFragmentCompat(),
return appPackageName in packageNameList
}
- private val requestPermissionLauncher =
- registerForActivityResult(ActivityResultContracts.RequestPermission()) {
- if (it) {
- presenter.onNotificationsPermissionResult()
- } else openNotificationsPermissionDialog()
- }
-
private val notificationSettingsPiggybackContract =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
presenter.onNotificationPiggybackPermissionResult()
@@ -168,29 +156,25 @@ class NotificationsFragment : PreferenceFragmentCompat(),
.show()
}
+ @SuppressLint("InlinedApi")
override fun openSystemSettings() {
- requireActivity().openNotificationSettings()
- }
-
- override fun requestNotificationPermissions() {
- requestPermissionLauncher.launch(notificationsPermission)
- }
-
- override fun openNotificationsPermissionDialog() {
- AlertDialog.Builder(requireContext())
- .setTitle(R.string.notifications_header_title)
- .setMessage(R.string.notifications_header_description)
- .setPositiveButton(R.string.pref_notification_go_to_settings) { _, _ ->
- requireActivity().openNotificationSettings()
+ val intent = if (appInfo.systemVersion >= Build.VERSION_CODES.O) {
+ Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS).apply {
+ putExtra("android.provider.extra.APP_PACKAGE", requireActivity().packageName)
}
- .setNegativeButton(android.R.string.cancel) { _, _ ->
- setNotificationPreferencesChecked(false)
+ } else {
+ Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
+ data = Uri.fromParts("package", requireActivity().packageName, null)
}
- .setOnDismissListener { setNotificationPreferencesChecked(false) }
- .show()
+ }
+ try {
+ requireActivity().startActivity(intent)
+ } catch (e: Exception) {
+ Timber.e(e)
+ }
}
- override fun openNotificationPiggyBackPermissionDialog() {
+ override fun openNotificationPermissionDialog() {
AlertDialog.Builder(requireContext())
.setTitle(getString(R.string.pref_notification_piggyback_popup_title))
.setMessage(getString(R.string.pref_notification_piggyback_popup_description))
@@ -218,11 +202,6 @@ class NotificationsFragment : PreferenceFragmentCompat(),
.show()
}
- override fun setNotificationPreferencesChecked(isChecked: Boolean) {
- findPreference(getString(R.string.pref_key_notifications_enable))?.isChecked =
- isChecked
- }
-
override fun setNotificationPiggybackPreferenceChecked(isChecked: Boolean) {
findPreference(getString(R.string.pref_key_notifications_piggyback))?.isChecked =
isChecked
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/notifications/NotificationsPresenter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/notifications/NotificationsPresenter.kt
index 232b03480..4cbdac945 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/notifications/NotificationsPresenter.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/notifications/NotificationsPresenter.kt
@@ -26,13 +26,12 @@ class NotificationsPresenter @Inject constructor(
with(view) {
enableNotification(
- notificationKey = preferencesRepository.notificationsEnableKey,
- enable = preferencesRepository.isServiceEnabled
+ preferencesRepository.notificationsEnableKey,
+ preferencesRepository.isServiceEnabled
)
initView(appInfo.isDebug)
}
- checkNotificationsPermissionState()
checkNotificationPiggybackState()
Timber.i("Settings notifications view was initialized")
@@ -50,17 +49,12 @@ class NotificationsPresenter @Inject constructor(
view?.openNotificationExactAlarmSettings()
}
}
- notificationsEnableKey -> {
- if (isNotificationsEnable && view?.isNotificationPermissionGranted == false) {
- view?.requestNotificationPermissions()
- }
- }
isDebugNotificationEnableKey -> {
chuckerCollector.showNotification = isDebugNotificationEnable
}
isNotificationPiggybackEnabledKey -> {
- if (isNotificationPiggybackEnabled && view?.isNotificationPiggybackPermissionGranted == false) {
- view?.openNotificationPiggyBackPermissionDialog()
+ if (isNotificationPiggybackEnabled && view?.isNotificationPermissionGranted == false) {
+ view?.openNotificationPermissionDialog()
}
}
}
@@ -76,15 +70,9 @@ class NotificationsPresenter @Inject constructor(
view?.openSystemSettings()
}
- fun onNotificationsPermissionResult() {
- view?.run {
- setNotificationPreferencesChecked(isNotificationPermissionGranted)
- }
- }
-
fun onNotificationPiggybackPermissionResult() {
view?.run {
- setNotificationPiggybackPreferenceChecked(isNotificationPiggybackPermissionGranted)
+ setNotificationPiggybackPreferenceChecked(isNotificationPermissionGranted)
}
}
@@ -92,18 +80,10 @@ class NotificationsPresenter @Inject constructor(
view?.setUpcomingLessonsNotificationPreferenceChecked(timetableNotificationHelper.canScheduleExactAlarms())
}
- private fun checkNotificationsPermissionState() {
- if (preferencesRepository.isNotificationsEnable) {
- view?.run {
- setNotificationPreferencesChecked(isNotificationPermissionGranted)
- }
- }
- }
-
private fun checkNotificationPiggybackState() {
if (preferencesRepository.isNotificationPiggybackEnabled) {
view?.run {
- setNotificationPiggybackPreferenceChecked(isNotificationPiggybackPermissionGranted)
+ setNotificationPiggybackPreferenceChecked(isNotificationPermissionGranted)
}
}
}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/notifications/NotificationsView.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/notifications/NotificationsView.kt
index a391681cb..2bf8e31f4 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/settings/notifications/NotificationsView.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/settings/notifications/NotificationsView.kt
@@ -6,8 +6,6 @@ interface NotificationsView : BaseView {
val isNotificationPermissionGranted: Boolean
- val isNotificationPiggybackPermissionGranted: Boolean
-
fun initView(showDebugNotificationSwitch: Boolean)
fun showFixSyncDialog()
@@ -16,16 +14,10 @@ interface NotificationsView : BaseView {
fun enableNotification(notificationKey: String, enable: Boolean)
- fun requestNotificationPermissions()
-
- fun openNotificationsPermissionDialog()
-
- fun openNotificationPiggyBackPermissionDialog()
+ fun openNotificationPermissionDialog()
fun openNotificationExactAlarmSettings()
- fun setNotificationPreferencesChecked(isChecked: Boolean)
-
fun setNotificationPiggybackPreferenceChecked(isChecked: Boolean)
fun setUpcomingLessonsNotificationPreferenceChecked(isChecked: Boolean)
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/studentinfo/StudentInfoFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/studentinfo/StudentInfoFragment.kt
index 598046a2d..361a59440 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/studentinfo/StudentInfoFragment.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/studentinfo/StudentInfoFragment.kt
@@ -8,7 +8,6 @@ import android.view.MenuInflater
import android.view.View
import android.widget.Toast
import androidx.core.content.getSystemService
-import androidx.core.os.bundleOf
import androidx.core.view.get
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
@@ -25,8 +24,6 @@ import io.github.wulkanowy.ui.modules.main.MainActivity
import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.utils.capitalise
import io.github.wulkanowy.utils.getThemeAttrColor
-import io.github.wulkanowy.utils.nullableSerializable
-import io.github.wulkanowy.utils.serializable
import javax.inject.Inject
@AndroidEntryPoint
@@ -41,9 +38,7 @@ class StudentInfoFragment :
lateinit var studentInfoAdapter: StudentInfoAdapter
override val titleStringId: Int
- get() = when (
- requireArguments().nullableSerializable(INFO_TYPE_ARGUMENT_KEY)
- ) {
+ get() = when (requireArguments().getSerializable(INFO_TYPE_ARGUMENT_KEY) as? StudentInfoView.Type) {
StudentInfoView.Type.PERSONAL -> R.string.account_personal_data
StudentInfoView.Type.CONTACT -> R.string.account_contact
StudentInfoView.Type.ADDRESS -> R.string.account_address
@@ -63,14 +58,13 @@ class StudentInfoFragment :
fun newInstance(type: StudentInfoView.Type, studentWithSemesters: StudentWithSemesters) =
StudentInfoFragment().apply {
- arguments = bundleOf(
- INFO_TYPE_ARGUMENT_KEY to type,
- STUDENT_ARGUMENT_KEY to studentWithSemesters
- )
+ arguments = Bundle().apply {
+ putSerializable(INFO_TYPE_ARGUMENT_KEY, type)
+ putSerializable(STUDENT_ARGUMENT_KEY, studentWithSemesters)
+ }
}
}
- @Suppress("DEPRECATION")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true)
@@ -80,9 +74,9 @@ class StudentInfoFragment :
super.onViewCreated(view, savedInstanceState)
binding = FragmentStudentInfoBinding.bind(view)
presenter.onAttachView(
- view = this,
- type = requireArguments().serializable(INFO_TYPE_ARGUMENT_KEY),
- studentWithSemesters = requireArguments().serializable(STUDENT_ARGUMENT_KEY),
+ this,
+ requireArguments().getSerializable(INFO_TYPE_ARGUMENT_KEY) as StudentInfoView.Type,
+ requireArguments().getSerializable(STUDENT_ARGUMENT_KEY) as StudentWithSemesters
)
}
@@ -159,6 +153,7 @@ class StudentInfoFragment :
)
}
+ @OptIn(ExperimentalStdlibApi::class)
override fun showFamilyTypeData(studentInfo: StudentInfo) {
val items = buildList {
add(studentInfo.firstGuardian?.let {
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableAdapter.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableAdapter.kt
index 2f0d697fc..d6917672a 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableAdapter.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableAdapter.kt
@@ -191,7 +191,7 @@ class TimetableAdapter @Inject constructor() :
)
} else {
timetableItemDescription.visibility = GONE
- timetableItemRoom.isVisible = lesson.room.isNotBlank() || lesson.roomOld.isNotBlank()
+ timetableItemRoom.visibility = VISIBLE
timetableItemGroup.isVisible = item.showGroupsInPlan && lesson.group.isNotBlank()
timetableItemTeacher.visibility = VISIBLE
}
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableDialog.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableDialog.kt
index 4f5547d20..c9243b12e 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableDialog.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableDialog.kt
@@ -8,12 +8,14 @@ import android.view.View
import android.view.View.GONE
import android.view.View.VISIBLE
import android.view.ViewGroup
-import androidx.core.os.bundleOf
import androidx.fragment.app.DialogFragment
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.entities.Timetable
import io.github.wulkanowy.databinding.DialogTimetableBinding
-import io.github.wulkanowy.utils.*
+import io.github.wulkanowy.utils.capitalise
+import io.github.wulkanowy.utils.getThemeAttrColor
+import io.github.wulkanowy.utils.lifecycleAwareVariable
+import io.github.wulkanowy.utils.toFormattedString
import java.time.Instant
class TimetableDialog : DialogFragment() {
@@ -26,15 +28,17 @@ class TimetableDialog : DialogFragment() {
private const val ARGUMENT_KEY = "Item"
- fun newInstance(lesson: Timetable) = TimetableDialog().apply {
- arguments = bundleOf(ARGUMENT_KEY to lesson)
+ fun newInstance(exam: Timetable) = TimetableDialog().apply {
+ arguments = Bundle().apply { putSerializable(ARGUMENT_KEY, exam) }
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NO_TITLE, 0)
- lesson = requireArguments().serializable(ARGUMENT_KEY)
+ arguments?.run {
+ lesson = getSerializable(ARGUMENT_KEY) as Timetable
+ }
}
override fun onCreateView(
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableFragment.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableFragment.kt
index e95d6f827..fdd4aface 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableFragment.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/TimetableFragment.kt
@@ -7,7 +7,6 @@ import android.view.MenuItem
import android.view.View
import android.view.View.GONE
import android.view.View.VISIBLE
-import androidx.core.os.bundleOf
import androidx.core.text.parseAsHtml
import androidx.recyclerview.widget.LinearLayoutManager
import dagger.hilt.android.AndroidEntryPoint
@@ -40,7 +39,9 @@ class TimetableFragment : BaseFragment(R.layout.fragme
private const val ARGUMENT_DATE_KEY = "ARGUMENT_DATE"
fun newInstance(date: LocalDate? = null) = TimetableFragment().apply {
- arguments = date?.let { bundleOf(ARGUMENT_DATE_KEY to it.toEpochDay()) }
+ arguments = Bundle().apply {
+ date?.let { putLong(ARGUMENT_DATE_KEY, it.toEpochDay()) }
+ }
}
}
@@ -50,7 +51,6 @@ class TimetableFragment : BaseFragment(R.layout.fragme
override val currentStackSize get() = (activity as? MainActivity)?.currentStackSize
- @Suppress("DEPRECATION")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true)
diff --git a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/completed/CompletedLessonDialog.kt b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/completed/CompletedLessonDialog.kt
index ddd7488e4..7d32278f0 100644
--- a/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/completed/CompletedLessonDialog.kt
+++ b/app/src/main/java/io/github/wulkanowy/ui/modules/timetable/completed/CompletedLessonDialog.kt
@@ -4,12 +4,10 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
-import androidx.core.os.bundleOf
import androidx.fragment.app.DialogFragment
import io.github.wulkanowy.data.db.entities.CompletedLesson
import io.github.wulkanowy.databinding.DialogLessonCompletedBinding
import io.github.wulkanowy.utils.lifecycleAwareVariable
-import io.github.wulkanowy.utils.serializable
class CompletedLessonDialog : DialogFragment() {
@@ -21,15 +19,17 @@ class CompletedLessonDialog : DialogFragment() {
private const val ARGUMENT_KEY = "Item"
- fun newInstance(lesson: CompletedLesson) = CompletedLessonDialog().apply {
- arguments = bundleOf(ARGUMENT_KEY to lesson)
+ fun newInstance(exam: CompletedLesson) = CompletedLessonDialog().apply {
+ arguments = Bundle().apply { putSerializable(ARGUMENT_KEY, exam) }
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NO_TITLE, 0)
- completedLesson = requireArguments().serializable(ARGUMENT_KEY)
+ arguments?.run {
+ completedLesson = getSerializable(ARGUMENT_KEY) as CompletedLesson
+ }
}
override fun onCreateView(
diff --git a/app/src/main/java/io/github/wulkanowy/utils/BundleExtension.kt b/app/src/main/java/io/github/wulkanowy/utils/BundleExtension.kt
deleted file mode 100644
index d0d47025e..000000000
--- a/app/src/main/java/io/github/wulkanowy/utils/BundleExtension.kt
+++ /dev/null
@@ -1,32 +0,0 @@
-package io.github.wulkanowy.utils
-
-import android.content.Intent
-import android.os.Build
-import android.os.Bundle
-import java.io.Serializable
-
-inline fun Bundle.serializable(key: String): T = when {
- Build.VERSION.SDK_INT >= 33 -> getSerializable(key, T::class.java)!!
- else -> @Suppress("DEPRECATION") getSerializable(key) as T
-}
-
-inline fun Bundle.nullableSerializable(key: String): T? = when {
- Build.VERSION.SDK_INT >= 33 -> getSerializable(key, T::class.java)
- else -> @Suppress("DEPRECATION") getSerializable(key) as T?
-}
-
-@Suppress("DEPRECATION", "UNCHECKED_CAST")
-inline fun Bundle.parcelableArray(key: String): Array? = when {
- Build.VERSION.SDK_INT >= 33 -> getParcelableArray(key, T::class.java)
- else -> getParcelableArray(key) as Array?
-}
-
-inline fun Intent.serializable(key: String): T = when {
- Build.VERSION.SDK_INT >= 33 -> getSerializableExtra(key, T::class.java)!!
- else -> @Suppress("DEPRECATION") getSerializableExtra(key) as T
-}
-
-inline fun Intent.nullableSerializable(key: String): T? = when {
- Build.VERSION.SDK_INT >= 33 -> getSerializableExtra(key, T::class.java)
- else -> @Suppress("DEPRECATION") getSerializableExtra(key) as T?
-}
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 cc4c5aaa4..dd91d36d4 100644
--- a/app/src/main/java/io/github/wulkanowy/utils/ContextExtension.kt
+++ b/app/src/main/java/io/github/wulkanowy/utils/ContextExtension.kt
@@ -2,11 +2,9 @@ package io.github.wulkanowy.utils
import android.annotation.SuppressLint
import android.content.Context
-import android.content.res.ColorStateList
import android.graphics.*
import android.text.TextPaint
import android.util.DisplayMetrics.DENSITY_DEFAULT
-import android.widget.ImageView
import androidx.annotation.*
import androidx.core.content.ContextCompat
import androidx.core.graphics.ColorUtils
@@ -14,7 +12,6 @@ import androidx.core.graphics.applyCanvas
import androidx.core.graphics.drawable.RoundedBitmapDrawable
import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory
import androidx.core.graphics.drawable.toBitmap
-import androidx.core.widget.ImageViewCompat
@ColorInt
@@ -88,7 +85,3 @@ fun Context.createNameInitialsDrawable(
return RoundedBitmapDrawableFactory.create(this.resources, bitmap)
.apply { isCircular = true }
}
-
-fun ImageView.setTint(@ColorInt color: Int) {
- ImageViewCompat.setImageTintList(this, ColorStateList.valueOf(color))
-}
diff --git a/app/src/main/java/io/github/wulkanowy/utils/ExceptionExtension.kt b/app/src/main/java/io/github/wulkanowy/utils/ExceptionExtension.kt
index a4c2537ac..43cecd400 100644
--- a/app/src/main/java/io/github/wulkanowy/utils/ExceptionExtension.kt
+++ b/app/src/main/java/io/github/wulkanowy/utils/ExceptionExtension.kt
@@ -15,17 +15,16 @@ import java.net.ConnectException
import java.net.SocketException
import java.net.SocketTimeoutException
import java.net.UnknownHostException
-import java.security.cert.CertPathValidatorException
import java.security.cert.CertificateExpiredException
import java.security.cert.CertificateNotYetValidException
import javax.net.ssl.SSLHandshakeException
fun Resources.getErrorString(error: Throwable): String = when (error) {
is UnknownHostException -> R.string.error_no_internet
- is ConnectException,
is SocketException,
is SocketTimeoutException,
is InterruptedIOException,
+ is ConnectException,
is StreamResetException -> R.string.error_timeout
is NotLoggedInException -> R.string.error_login_failed
is PasswordChangeRequiredException -> R.string.error_password_change_required
@@ -43,10 +42,10 @@ fun Resources.getErrorString(error: Throwable): String = when (error) {
fun Throwable.isShouldBeReported(): Boolean = when (this) {
is UnknownHostException,
- is ConnectException,
is SocketException,
is SocketTimeoutException,
is InterruptedIOException,
+ is ConnectException,
is StreamResetException,
is ServiceUnavailableException,
is FeatureDisabledException,
@@ -71,6 +70,5 @@ private fun Throwable?.isCausedByCertificateNotValidNow(): Boolean {
private fun Throwable?.isCertificateNotValidNow(): Boolean {
val isNotYetValid = this is CertificateNotYetValidException
val isExpired = this is CertificateExpiredException
- val isInvalidPath = this is CertPathValidatorException
- return isNotYetValid || isExpired || isInvalidPath
+ return isNotYetValid || isExpired
}
diff --git a/app/src/main/java/io/github/wulkanowy/utils/GradeExtension.kt b/app/src/main/java/io/github/wulkanowy/utils/GradeExtension.kt
index 61924d4e9..ff65d6376 100644
--- a/app/src/main/java/io/github/wulkanowy/utils/GradeExtension.kt
+++ b/app/src/main/java/io/github/wulkanowy/utils/GradeExtension.kt
@@ -4,7 +4,6 @@ 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.enums.GradeColorTheme
-import io.github.wulkanowy.sdk.scrapper.grades.getGradeValueWithModifier
import io.github.wulkanowy.sdk.scrapper.grades.isGradeValid
fun List.calcAverage(isOptionalArithmeticAverage: Boolean): Double {
@@ -21,15 +20,20 @@ fun List.calcAverage(isOptionalArithmeticAverage: Boolean): Double {
}
fun List.calcFinalAverage(plusModifier: Double, minusModifier: Double) = asSequence()
- .mapNotNull { summary ->
- val (gradeValue, gradeModifier) = getGradeValueWithModifier(summary.finalGrade)
- if (gradeValue == null || gradeModifier == null) return@mapNotNull null
-
- when {
- gradeModifier > 0 -> gradeValue + plusModifier
- gradeModifier < 0 -> gradeValue - minusModifier
- else -> gradeValue + 0.0
- }
+ .mapNotNull {
+ if (it.finalGrade.matches("[0-6][+-]?".toRegex())) {
+ when {
+ it.finalGrade.endsWith('+') -> {
+ it.finalGrade.removeSuffix("+").toDouble() + plusModifier
+ }
+ it.finalGrade.endsWith('-') -> {
+ it.finalGrade.removeSuffix("-").toDouble() - minusModifier
+ }
+ else -> {
+ it.finalGrade.toDouble()
+ }
+ }
+ } else null
}
.average()
.let { if (it.isNaN()) 0.0 else it }
diff --git a/app/src/main/java/io/github/wulkanowy/utils/IntentUtils.kt b/app/src/main/java/io/github/wulkanowy/utils/IntentUtils.kt
index 62b85af4d..1ef03f2e6 100644
--- a/app/src/main/java/io/github/wulkanowy/utils/IntentUtils.kt
+++ b/app/src/main/java/io/github/wulkanowy/utils/IntentUtils.kt
@@ -1,15 +1,11 @@
package io.github.wulkanowy.utils
-import android.app.Activity
import android.content.ActivityNotFoundException
import android.content.Context
import android.content.Intent
import android.net.Uri
-import android.os.Build
import android.provider.CalendarContract
-import android.provider.Settings
import io.github.wulkanowy.BuildConfig
-import timber.log.Timber
import java.time.LocalDateTime
import java.time.ZoneId
@@ -90,23 +86,6 @@ fun Context.openDialer(phone: String) {
}
}
-fun Activity.openNotificationSettings() {
- val intent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS).apply {
- putExtra("android.provider.extra.APP_PACKAGE", packageName)
- }
- } else {
- Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
- data = Uri.fromParts("package", packageName, null)
- }
- }
- try {
- startActivity(intent)
- } catch (e: Exception) {
- Timber.e(e)
- }
-}
-
fun Context.shareText(text: String, subject: String?) {
val sendIntent: Intent = Intent().apply {
action = Intent.ACTION_SEND
diff --git a/app/src/main/java/io/github/wulkanowy/utils/RefreshUtils.kt b/app/src/main/java/io/github/wulkanowy/utils/RefreshUtils.kt
index 93e67be01..c69fec65c 100644
--- a/app/src/main/java/io/github/wulkanowy/utils/RefreshUtils.kt
+++ b/app/src/main/java/io/github/wulkanowy/utils/RefreshUtils.kt
@@ -4,7 +4,6 @@ import android.content.Context
import dagger.hilt.android.qualifiers.ApplicationContext
import io.github.wulkanowy.R
import io.github.wulkanowy.data.db.SharedPrefProvider
-import io.github.wulkanowy.data.db.entities.Mailbox
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.enums.MessageFolder
@@ -26,8 +25,8 @@ fun getRefreshKey(name: String, student: Student): String {
return "${name}_${student.userLoginId}"
}
-fun getRefreshKey(name: String, mailbox: Mailbox?, folder: MessageFolder): String {
- return "${name}_${mailbox?.globalKey ?: "all"}_${folder.id}"
+fun getRefreshKey(name: String, student: Student, folder: MessageFolder): String {
+ return "${name}_${student.id}_${folder.id}"
}
class AutoRefreshHelper @Inject constructor(
diff --git a/app/src/main/java/io/github/wulkanowy/utils/SemesterExtension.kt b/app/src/main/java/io/github/wulkanowy/utils/SemesterExtension.kt
index 380d6bf6e..6e11a8b2c 100644
--- a/app/src/main/java/io/github/wulkanowy/utils/SemesterExtension.kt
+++ b/app/src/main/java/io/github/wulkanowy/utils/SemesterExtension.kt
@@ -15,8 +15,5 @@ fun List.getCurrentOrLast(): Semester {
// when there is more than one current semester - find one with higher id
singleOrNull { semester -> semester.semesterId == maxByOrNull { it.semesterId }?.semesterId }?.let { return it }
- // when there is no active kindergarten semester - get one from last year
- singleOrNull { semester -> semester.schoolYear == maxByOrNull { it.schoolYear }?.schoolYear }?.let { return it }
-
throw IllegalArgumentException("Duplicated last semester! Semesters: ${joinToString(separator = "\n")}")
}
diff --git a/app/src/main/java/io/github/wulkanowy/utils/StringExtension.kt b/app/src/main/java/io/github/wulkanowy/utils/StringExtension.kt
index 8043e3659..bddd7df4c 100644
--- a/app/src/main/java/io/github/wulkanowy/utils/StringExtension.kt
+++ b/app/src/main/java/io/github/wulkanowy/utils/StringExtension.kt
@@ -1,15 +1,7 @@
package io.github.wulkanowy.utils
-import androidx.core.text.parseAsHtml
-import org.apache.commons.text.StringEscapeUtils
-
inline fun String?.ifNullOrBlank(defaultValue: () -> String) =
if (isNullOrBlank()) defaultValue() else this
fun String.capitalise() =
- replaceFirstChar { if (it.isLowerCase()) it.titlecase() else it.toString() }
-
-fun String.parseUonetHtml() = this
- .let(StringEscapeUtils::unescapeHtml4)
- .replace("\n", "
")
- .parseAsHtml()
+ replaceFirstChar { if (it.isLowerCase()) it.titlecase() else it.toString() }
\ No newline at end of file
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 9e24f9d9e..4b6dcaf28 100644
--- a/app/src/main/play/release-notes/pl-PL/default.txt
+++ b/app/src/main/play/release-notes/pl-PL/default.txt
@@ -1,10 +1,9 @@
-Wersja 1.9.0
+Wersja 1.7.1
-- dodaliśmy obsługę Androida 13 (w tym ikona aplikacji obsługująca Material You)
-- przerobiliśmy ekran wyboru ucznia przy pierwszym logowaniu
-- naprawiliśmy usuwanie wiadomości w niektórych przypadkach
-- naprawiliśmy błąd występujący przy resecie hasła
-- naprawiliśmy literówkę w tytule domyślnej treści wiadomości usprawiedliwiania
-- naprawiliśmy nazwę aplikacji przy ustawionym w telefonie jezyku francuskim
+- naprawiliśmy logowanie do aplikacji
+- dodaliśmy wsparcie nowego modułu Wiadomości Plus
+- dodaliśmy nową możliwość wsparcia naszego projektu przez opcjonalne reklamy
+- dodaliśmy sortowanie po średniej
+- naprawiliśmy też kilka usterek wpływających na komfort używania aplikacji
Pełna lista zmian: https://github.com/wulkanowy/wulkanowy/releases
diff --git a/app/src/main/res/drawable/ic_circle.xml b/app/src/main/res/drawable/ic_circle.xml
deleted file mode 100644
index d2932fe62..000000000
--- a/app/src/main/res/drawable/ic_circle.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
-
-
-
-
diff --git a/app/src/main/res/drawable/ic_error_filled.xml b/app/src/main/res/drawable/ic_error_filled.xml
deleted file mode 100644
index 61b575dc6..000000000
--- a/app/src/main/res/drawable/ic_error_filled.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
diff --git a/app/src/main/res/drawable/ic_launcher_foreground_dev_mono.xml b/app/src/main/res/drawable/ic_launcher_foreground_dev_mono.xml
deleted file mode 100644
index b1b01a0b6..000000000
--- a/app/src/main/res/drawable/ic_launcher_foreground_dev_mono.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
-
-
-
-
diff --git a/app/src/main/res/drawable/ic_launcher_foreground_mono.xml b/app/src/main/res/drawable/ic_launcher_foreground_mono.xml
deleted file mode 100644
index e2e747316..000000000
--- a/app/src/main/res/drawable/ic_launcher_foreground_mono.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
diff --git a/app/src/main/res/layout/activity_send_message.xml b/app/src/main/res/layout/activity_send_message.xml
index a8041d61c..320782bdc 100644
--- a/app/src/main/res/layout/activity_send_message.xml
+++ b/app/src/main/res/layout/activity_send_message.xml
@@ -55,29 +55,17 @@
android:id="@+id/sendMessageFrom"
android:layout_width="0dp"
android:layout_height="58dp"
- android:layout_marginStart="8dp"
- android:background="?selectableItemBackground"
+ android:layout_marginStart="16dp"
+ android:layout_marginLeft="16dp"
+ android:layout_marginEnd="16dp"
+ android:layout_marginRight="16dp"
android:gravity="center_vertical"
- android:paddingStart="8dp"
- android:paddingEnd="32dp"
android:textSize="18sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/sendMessageFromHint"
app:layout_constraintTop_toTopOf="parent"
tools:text="Jan Kowalski" />
-
-
-
-
-
-
-
-
-
-
-
-
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 c47b9ae35..bf5431164 100644
--- a/app/src/main/res/layout/fragment_login_student_select.xml
+++ b/app/src/main/res/layout/fragment_login_student_select.xml
@@ -3,14 +3,92 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:orientation="vertical"
- tools:context=".ui.modules.login.studentselect.LoginStudentSelectFragment">
+ android:orientation="vertical">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ tools:itemCount="6"
+ tools:listitem="@layout/item_login_student_select" />
-
-
diff --git a/app/src/main/res/layout/fragment_notifications.xml b/app/src/main/res/layout/fragment_notifications.xml
deleted file mode 100644
index 8e506e1e7..000000000
--- a/app/src/main/res/layout/fragment_notifications.xml
+++ /dev/null
@@ -1,69 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/main/res/layout/item_dashboard_horizontal_group.xml b/app/src/main/res/layout/item_dashboard_horizontal_group.xml
index 0c59d1ebf..1d43d5115 100644
--- a/app/src/main/res/layout/item_dashboard_horizontal_group.xml
+++ b/app/src/main/res/layout/item_dashboard_horizontal_group.xml
@@ -37,25 +37,9 @@
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
- app:layout_goneMarginEnd="16dp"
app:tint="?colorOnSurface"
tools:ignore="ContentDescription" />
-
-
-
-
+ tools:text="16" />
@@ -178,25 +145,9 @@
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
- app:layout_goneMarginEnd="16dp"
app:tint="?colorOnSurface"
tools:ignore="ContentDescription" />
-
-
-
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/item_login_student_select_student.xml b/app/src/main/res/layout/item_login_student_select.xml
similarity index 71%
rename from app/src/main/res/layout/item_login_student_select_student.xml
rename to app/src/main/res/layout/item_login_student_select.xml
index d071b1bbf..1003636fc 100644
--- a/app/src/main/res/layout/item_login_student_select_student.xml
+++ b/app/src/main/res/layout/item_login_student_select.xml
@@ -4,7 +4,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?selectableItemBackground"
- android:minHeight="56dp"
+ android:minHeight="72dp"
android:paddingTop="8dp"
android:paddingBottom="8dp"
tools:context=".ui.modules.login.studentselect.LoginStudentSelectAdapter">
@@ -14,10 +14,9 @@
android:layout_width="32dp"
android:layout_height="24dp"
android:layout_centerVertical="true"
- android:layout_marginStart="32dp"
+ android:layout_marginStart="12dp"
android:layout_marginEnd="28dp"
android:background="@android:color/transparent"
- android:clickable="false"
tools:text=" " />
+
+
+ android:textSize="14sp"
+ android:visibility="gone"
+ tools:visibility="visible" />
diff --git a/app/src/main/res/layout/item_login_student_select_empty_symbol_header.xml b/app/src/main/res/layout/item_login_student_select_empty_symbol_header.xml
deleted file mode 100644
index be0fd905c..000000000
--- a/app/src/main/res/layout/item_login_student_select_empty_symbol_header.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/main/res/layout/item_login_student_select_header_school.xml b/app/src/main/res/layout/item_login_student_select_header_school.xml
deleted file mode 100644
index 30a8bbf0b..000000000
--- a/app/src/main/res/layout/item_login_student_select_header_school.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/main/res/layout/item_login_student_select_header_symbol.xml b/app/src/main/res/layout/item_login_student_select_header_symbol.xml
deleted file mode 100644
index cc1bf709d..000000000
--- a/app/src/main/res/layout/item_login_student_select_header_symbol.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/main/res/layout/item_login_student_select_help.xml b/app/src/main/res/layout/item_login_student_select_help.xml
deleted file mode 100644
index b6d81c7cd..000000000
--- a/app/src/main/res/layout/item_login_student_select_help.xml
+++ /dev/null
@@ -1,61 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/main/res/layout/item_mailbox_chooser.xml b/app/src/main/res/layout/item_mailbox_chooser.xml
deleted file mode 100644
index 7c93199bc..000000000
--- a/app/src/main/res/layout/item_mailbox_chooser.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-
-
-
-
-
-
-
-
diff --git a/app/src/main/res/layout/item_message.xml b/app/src/main/res/layout/item_message.xml
index 39fbaad01..c25faacc8 100644
--- a/app/src/main/res/layout/item_message.xml
+++ b/app/src/main/res/layout/item_message.xml
@@ -30,7 +30,6 @@
android:layout_marginEnd="10dp"
android:ellipsize="end"
android:singleLine="true"
- android:textColor="?android:textColorSecondary"
android:textSize="15sp"
app:layout_constraintEnd_toStartOf="@+id/messageItemDate"
app:layout_constraintStart_toEndOf="@id/messageItemCheckbox"
@@ -41,13 +40,10 @@
android:id="@+id/messageItemDate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginEnd="8dp"
android:gravity="end"
- android:textColor="?android:textColorSecondary"
android:textSize="13sp"
- app:layout_constraintEnd_toStartOf="@id/messageItemUnreadIndicator"
+ app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
- app:layout_goneMarginEnd="0dp"
tools:text="@tools:sample/date/ddmmyy" />
-
-
diff --git a/app/src/main/res/layout/item_message_chips.xml b/app/src/main/res/layout/item_message_chips.xml
index da2e20311..481a94835 100644
--- a/app/src/main/res/layout/item_message_chips.xml
+++ b/app/src/main/res/layout/item_message_chips.xml
@@ -1,30 +1,21 @@
-
-
-
+ app:layout_constraintTop_toTopOf="parent">
-
+
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 57cf05ddb..5011e2356 100644
--- a/app/src/main/res/menu/action_menu_message_preview.xml
+++ b/app/src/main/res/menu/action_menu_message_preview.xml
@@ -8,20 +8,6 @@
android:title="@string/message_reply"
app:iconTint="@color/material_on_surface_emphasis_medium"
app:showAsAction="ifRoom" />
-
-
+
+
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
index da1bca126..d59ec8e17 100644
--- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -2,5 +2,4 @@
-
-
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 000000000..d59ec8e17
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 000000000..85f6a2c87
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 000000000..dc6ac682d
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 000000000..dd67b8771
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 000000000..b7d82f5d5
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 000000000..7ad000eec
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml
index 4a91cc852..d036e7e42 100644
--- a/app/src/main/res/values-cs/strings.xml
+++ b/app/src/main/res/values-cs/strings.xml
@@ -55,7 +55,7 @@
Neplatný symbol
Žák nebyl nalezen. Zkontrolujte správnost symbolu a vybrané varianty deníku UONET+
Vybraný žák je už přihlášen
- Symbol najdete na stránce deníku v Uczeń→ Dostęp Mobilny → Wygeneruj kod dostępu.\n\nUjistěte se, že jste nastavili správnou variantu deníku v poli Variace deníku UONET+ na první přihlašovací obrazovce
+ Symbol najdete na stránce deníku v Uczeń→ Dostęp Mobilny → Zarejestruj urządzenie mobilne.\n\nUjistěte se, že jste na předchozí obrazovce nastavili správnou variantu deníku do pole Variace deníku UONET+
Vyberte žáky, kteří se mají do aplikace přihlásit
Jiné možnosti
V tomto režimu nefungují následující: šťastné číslo, statistiky třídy, shrnutí frekvencí, ospravedlnění nepřítomnosti, dokončené lekce, informace o škole a prohlížení seznamu registrovaných zařízení
@@ -72,14 +72,6 @@
Obnovit
Žák je už přihlášen
Standardní
- Jiná místa vyhledávání
- Nebyli nalezeni žádní aktivní žáci
- Zadejte jiný symbol
-
- Povolit oznámení
- Povolit upozornění, abyste nezmeškali zprávu od učitele nebo o nové známce
- Přeskočit
- Zapnout
Manažer účtů
Přihlásit se
@@ -317,11 +309,9 @@
Zpráva neexistuje
Musíte vybrat alespoň 1 příjemce
Obsah zprávy musí mít alespoň 3 znaky
- Všechny poštovní schránky
Pouze nepřečtené
Pouze s přílohami
Přečtena: %s
- Přečtena přes: %1$d z %2$d osob
- %1$d zpráva
- %1$d zprávy
@@ -349,7 +339,6 @@
- %1$d vybraných
Zprávy odstraněné
- Vyberte poštovní schránku
Žádné informace o poznámkách
Body
@@ -493,8 +482,6 @@
Přítomnost na setkání
Agenda
- Místo
- Téma
Školní oznámení
Žádná školní oznámení
@@ -748,7 +735,7 @@
Volbu můžete kdykoliv změnit v nastavení aplikace. Můžeme použít Vaše data k zobrazení reklam šitých pro vás nebo pomocí méně vašich dat zobrazovat nepřizpůsobené reklamy. Podrobnosti naleznete v našich Zásadách ochrany osobních údajů
Přizpůsobené reklamy
Nepřizpůsobené reklamy
- Je mi více než 18 let
+ Mám ukončené 18 let
Ano, přizpůsobené reklamy
Ano, nepřizpůsobené reklamy
Pokročilé
diff --git a/app/src/main/res/values-da-rDK/preferences_values.xml b/app/src/main/res/values-da-rDK/preferences_values.xml
deleted file mode 100644
index ac2b6e9e5..000000000
--- a/app/src/main/res/values-da-rDK/preferences_values.xml
+++ /dev/null
@@ -1,65 +0,0 @@
-
-
-
- - Light
- - Dark
- - Black (AMOLED)
-
-
- - System language
- - Polski
- - English
- - Pусский
- - Українська
- - Deutsch
- - Čeština
- - Slovenčina
-
-
- - 15 minutes
- - 30 minutes
- - 1 hour
- - 2 hours
- - 6 hours
- - 12 hours
- - 24 hours
-
-
- - 0,00
- - 0,25
- - 0,33
- - 0,5
- - 0,75
-
-
- - Alphabetically
- - By date
- - By average
-
-
- - Dzienniczek+
- - Wulkanowy
- - Grade colors in register
-
-
- - Up to 1 at once
- - Always expanded
- - Unlimited expansions
-
-
- - Average of grades only from selected semester
- - Average of averages from both semesters
- - Average of grades from the whole year
-
-
- - Lucky number
- - Unread messages
- - Attendance
- - Lessons
- - Grades
- - Homework
- - School announcements
- - Exams
- - Conferences
-
-
diff --git a/app/src/main/res/values-da-rDK/strings.xml b/app/src/main/res/values-da-rDK/strings.xml
deleted file mode 100644
index 667231274..000000000
--- a/app/src/main/res/values-da-rDK/strings.xml
+++ /dev/null
@@ -1,728 +0,0 @@
-
-
-
- Login
- Wulkanowy
- Grades
- Attendance
- Exams
- Timetable
- Settings
- More
- About
- Log viewer
- Debug
- Notification debug
- Contributors
- Licenses
- Messages
- New message
- New homework
- Notes and achievements
- Homework
- Accounts manager
- Select account
- Account details
- Student info
- Dashboard
- Notifications center
-
- Semester %1$d, %2$d/%3$d
-
- Sign in with the student or parent account
- Enter the symbol from the register page for account: <b>%1$s</b>
- Username
- Email
- Login, PESEL or e-mail
- Password
- UONET+ register variant
- Mobile API
- Scraper
- Hybrid
- Token
- PIN
- Symbol
- Sign in
- Password too short
- Login details are incorrect
- %1$s. Make sure the correct UONET+ register variation is selected below
- Invalid PIN
- Invalid token
- Token expired
- Invalid email
- Use the assigned login instead of email
- Use the assigned login or email in @%1$s
- Invalid symbol
- Student not found. Validate the symbol and the chosen variation of the UONET+ register
- Selected student is already logged in
- The symbol can be found on the register page in Uczeń → Dostęp Mobilny → Wygeneruj kod dostępu.\n\nMake sure that you have set the appropriate register variant in the UONET+ register variant field on the first login screen
- Select students to log in to the application
- Other options
- In this mode, a lucky number does not work, a class grade stats, summary of attendance, excuse for absence, completed lessons, school information and preview of the list of registered devices
- This mode displays the same data as it appears on the register website
- The combination of the best features of the other two modes. It works faster than scraper and provides features not available in the Mobile API mode. It is in the experimental phase
- Privacy policy
- Trouble signing in? Contact us!
- Email
- Discord
- Send email
- Make sure you select the correct UONET+ register variation!
- I forgot my password
- Recover your account
- Recover
- Student is already signed in
- Standard
- Other search locations
- No active students found
- Enter a different symbol
-
- Enable notifications
- Enable notifications so you don\'t miss message from teacher or new grade
- Skip
- Enable
-
- Account manager
- Log in
- Session expired
- Session expired, log in again
- Application support
- Do you like this app? Support its development by enabling non-invasive ads that you can disable at any time
- Enable ads
-
- Grade
- Semester %d
- Change semester
- No grades
- Weight
- Weight: %s
- Comment
- Number of new ratings: %1$d
- Average: %1$.2f
- Points: %s
- No average
- Total points
- Final grade
- Predicted grade
- Calculated average
- How does Calculated Average work?
- The Calculated Average is the arithmetic average calculated from the subjects averages. It allows you to know the approximate final average. It is calculated in a way selected by the user in the application settings. It is recommended that you choose the appropriate option. This is because the calculation of school averages differs. Additionally, if your school reports the average of the subjects on the Vulcan page, the application downloads them and does not calculate these averages. This can be changed by forcing the calculation of the average in the application settings.\n\nAverage of grades only from selected semester:\n1. Calculating the weighted average for each subject in a given semester\n2.Adding calculated averages\n3. Calculation of the arithmetic average of the summed averages\n\nAverage of averages from both semesters:\n1.Calculating the weighted average for each subject in semester 1 and 2\n2. Calculating the arithmetic average of the calculated averages for semesters 1 and 2 for each subject.\n3. Adding calculated averages\n4. Calculation of the arithmetic average of the summed averages\n\nAverage of grades from the whole year:\n1. Calculating weighted average over the year for each subject. The final average in the 1st semester is irrelevant.\n2. Adding calculated averages\n3. Calculating the arithmetic average of summed averages
- How does the Final Average work?
- The Final Average is the arithmetic average calculated from all currently available final grades in the given semester.\n\nThe calculation scheme consists of the following steps:\n1. Summing up the final grades given by teachers\n2. Divide by the number of subjects that have already been graded
- Final average
- from %1$d of %2$d subjects
- Summary
- Class
- Mark as read
- Partial
- Semester
- Points
- Legend
- Class average: %1$s
- Your average: %1$s
- Your grade: %1$s
- Class
- Student
-
- - %d grade
- - %d grades
-
-
- - 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
-
-
- Lesson
- Room
- Group
- Hours
- Changes
- No lessons this day
- %s min
- %s sec
- %1$s left
- in %1$s
- Finished
- Now: %s
- Next: %s
- Later: %s
- %1$s lesson %2$d - %3$s
- Change of room from %1$s to %2$s
- Change of teacher from %1$s to %2$s
- Change of subject from %1$s to %2$s
-
- - Timetable change
- - Timetable changes
-
-
- - %1$s - %2$d change in timetable
- - %1$s - %2$d changes in timetable
-
-
- - %1$d change in timetable
- - %1$d changes in timetable
-
-
- - %d change
- - %d changes
-
-
- Completed lessons
- Show completed lessons
- No info about completed lessons
- Topic
- Absence
- Resources
-
- Additional lessons
- Show additional lessons
- No info about additional lessons
- New lesson
- New additional lesson
- Additional lesson added successfully
- Additional lesson deleted successfully
- Repeat weekly
- Delete additional lesson
- Just this lesson
- All in the series
- Start time
- End time
- End time must be greater than start time
-
- Attendance summary
- Absent for school reasons
- Excused absence
- Unexcused absence
- Exemption
- Excused lateness
- Unexcused lateness
- Present
- Deleted
- Unknown
- Number of lesson
- No entries
- Absence reason (optional)
- Send
- Absence excuse request sent successfully!
- You must select at least one absence!
- Excuse
-
- - New attendance
- - New attendance
-
-
- - %1$d new attendance
- - %1$d attendance
-
-
- - %d attendance
- - %d attendance
-
-
- Total
-
- No exams this week
- Type
- Entry date
-
- - New exam
- - New exams
-
-
- - %d new exam
- - %d new exams
-
-
- - %d exam
- - %d exams
-
-
- Inbox
- Sent
- Trash
- (no subject)
- No messages
- From:
- To:
- Date: %1$s
- Reply
- Forward
- Select all
- Unselect all
- Move to trash
- Delete permanently
- Message deleted successfully
- student
- parent
- guardian
- employee
- Share
- Print
- Subject
- Content
- Message sent successfully
- Message does not exist
- You need to choose at least 1 recipient
- The message content must be at least 3 characters
- All mailboxes
- Only unread
- Only with attachments
- Read: %s
- Read by: %1$d of %2$d people
-
- - %1$d message
- - %1$d messages
-
-
- - New message
- - New messages
-
- Do you want to restore draft message?
- Do you want to restore draft message with recipients: %s?
-
- - You received %1$d message
- - You received %1$d messages
-
-
- - %1$d selected
- - %1$d selected
-
- Messages deleted
- Choose mailbox
-
- No info about notes
- Points
-
- - %d note
- - %d notes
-
-
- - New note
- - New notes
-
-
- - You received %1$d note
- - You received %1$d notes
-
-
-
- - %d praise
- - %d praises
-
-
- - New praise
- - New praises
-
-
- - You received %1$d praise
- - You received %1$d praises
-
-
-
- - %d neutral note
- - %d neutral notes
-
-
- - New neutral note
- - New neutral notes
-
-
- - You received %1$d neutral note
- - You received %1$d neutral notes
-
-
- No info about homework
- Mark as done
- Mark as undone
- Add homework
- Homework added successfully
- Homework deleted successfully
- Attachments
-
- - New homework
- - New homework
-
-
- - You received %d new homework
- - You received %d new homework
-
-
- - %d homework
- - %d homework
-
-
- Lucky number
- Today\'s lucky number is
- No info about the lucky number
- Lucky number for today
- Today\'s lucky number is: %s
- Show history
-
- Lucky number history
- No info about lucky numbers
-
- Mobile devices
- No devices
- Deregister
- Device removed
- QR code
- Token
- Symbol
- PIN
-
- School and teachers
-
- School
- No info about school
- School name
- School address
- Telephone
- Name of headmaster
- Name of pedagogue
- Show on map
- Call
-
- Teachers
- No info about teachers
- No subject
-
- Conferences
- No info about conferences
-
- - %d conference
- - %d conferences
-
-
- - New conference
- - New conferences
-
-
- - You have %1$d new conference
- - You have %1$d new conferences
-
- Present at conference
- Agenda
- Place
- Topic
-
- School announcements
- No school announcements
-
- - %d school announcement
- - %d school announcements
-
-
- - New school announcement
- - New school announcements
-
-
- - You have %1$d new school announcement
- - You have %1$d new school announcements
-
-
- Add account
- Logout
- Do you want to log out this student?
- Student logout
- Student account
- Parent account
- Edit data
- Accounts manager
- Select student
- Family
- Contact
- Residence details
- Personal information
-
- App version
- Contributors
- List of Wulkanowy developers
- Report a bug
- Send a bug report via e-mail
- FAQ
- Read Frequently Asked Questions
- Discord server
- Join the Wulkanowy community
- Facebook fanpage
- Twitter page
- Follow us on twitter
- Like our facebook fanpage
- Privacy policy
- Rules for collecting personal data
- System settings
- Open system settings
- Homepage
- Visit the website and help develop the application
- Licenses
- Licenses of libraries used in the application
-
- License
-
- Avatar
- See more on GitHub
-
- No info about student or student family
- Name
- Second name
- Gender
- Polish citizenship
- Family name
- Mother\'s and father\'s names
- Phone
- Cellphone
- E-mail
- Address of residence
- Address of registration
- Correspondence address
- Surname and first name
- Degree of kinship
- Address
- Phones
- Male
- Female
- Last name
- Guardian
-
- Nick
- Add nick
- Choose avatar color
-
- Share logs
- Refresh
-
- Lessons
- (Tomorrow)
- (Today and tomorrow)
- In a moment:
- Soon:
- First:
- Now:
- End of lessons
- Next:
- Later:
-
- - %1$d more lesson
- - %1$d more lessons
-
- until %1$s
- No upcoming lessons
- An error occurred while loading the lessons
- Homework
- No homework to do
- An error occurred while loading the homework
-
- - %1$d more homework
- - %1$d more homework
-
- due %1$s
- Last grades
- No new grades
- An error occurred while loading the grades
- School announcements
- No current announcements
- An error occurred while loading the announcements
-
- - %1$d more announcement
- - %1$d more announcements
-
- Exams
- No upcoming exams
- An error occurred while loading the exams
-
- - %1$d more exam
- - %1$d more exams
-
- Conferences
- No upcoming conferences
- An error occurred while loading the conferences
-
- - %1$d more conference
- - %1$d more conferences
-
- An error occurred while loading data
- None
-
- Check for updates
- Before reporting a bug, check first if an update with the bug fix is available
-
- Content
- Retry
- Description
- No description
- Teacher
- Date
- Entry date
- Color
- Details
- Category
- Close
- No data
- Subject
- Prev
- Next
- Search
- Search…
- Yes
- No
- Save
- Title
- Add
- Copied
- Undo
- Change
- Add to calendar
-
- No lessons
- Choose theme
- Light
- Dark
- System Theme
-
- App
- Default view
- Calculated average options
- Force average calculation by app
- Show presence
- Theme
- Grades expanding
- Mark current lesson
- Show groups next to subjects
- Show chart list in class grades
- Show subjects without grades
- Grades color scheme
- Subjects sorting
- Language
- Notifications
- Other
- Show notifications
- Show upcoming lesson notifications
- Make upcoming lesson notification persistent
- Turn off when notification is not showing in your watch/band
- Open system notification settings
- 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.
- Show debug notifications
- Synchronization is disabled
- Official app notifications
- Capture official app notifications
- Remove official app notifications after capture
- Capture notifications
- With this feature you can gain a substitute of push notifications like in the official app. All you need to do is allow Wulkanowy to receive all notifications in your system settings.\n\nHow it works?\nWhen you get a notification in Dziennik VULCAN, Wulkanowy will be notified (that\'s what these extra permissions are for) and will trigger a sync so that can send its own notification.\n\nFOR ADVANCED USERS ONLY
- Upcoming lesson notifications
- You must allow the Wulkanowy app to set alarms and reminders in your system settings to use this feature.
- Go to settings
- Synchronization
- Automatic update
- Suspended on holidays
- Updates interval
- Wi-Fi only
- Sync now
- Synced!
- Sync failed
- Sync in progress
- Last full sync: %s
- Value of the plus
- Value of the minus
- Reply with message history
- Show arithmetic average when no weights provided
- Support
- Privacy Policy
- Agreements
- Consent to processing of data related to ads
- Show ads in app
- Watch single ad to support project
- Consent to data processing
- To view an advertisement you must agree to the data processing terms of our Privacy Policy
- Agree
- Privacy policy
- Ad is loading
- Thank you for your support, come back later for more ads
- Can we use your data to display ads?
- You can change your choice anytime in the app settings. We may use your data to display ads tailored to you or, using less of your data, display non-personalized ads. Please see our Privacy Policy for details
- Personalized ads
- Non-personalized ads
- I am over 18 years old
- Yes, personalized ads
- Yes, non-personalized ads
- Advanced
- Appearance & Behavior
- Notifications
- Synchronization
- Advertisements
- Grades
- Dashboard
- Tiles visibility
- Attendance
- Timetable
- Grades
- Calculated average
- Messages
- Appearance & Behavior
- Languages, themes, subjects sorting
- App notifications, fix problems
- Notifications
- Synchronization
- Automatic update, synchronization interval
- Plus and minus values, average calculation
- Advanced
- App version, contributors, social portals
- Displaying advertisements, project support
-
- New grades
- New homework
- New conferences
- New exams
- Lucky number
- New messages
- New notes
- New school announcements
- Push notifications
- Upcoming lessons
- Debug
- Timetable change
- New attendance
-
- Black
- Red
- Blue
- Green
- Purple
- No color
-
- Download of updates has started…
- An update has just been downloaded.
- Restart
- Update failed! Wulkanowy may not function properly. Consider updating
-
- No internet connection
- An error occurred. Check your device clock
- Connection to register failed. Servers can be overloaded. Please try again later
- Loading data failed. Please try again later
- Register password change required
- Maintenance underway UONET + register. Try again later
- Unknown UONET + register error. Try again later
- Unknown application error. Please try again later
- An unexpected error occurred
- Feature disabled by your school
- Feature not available. Login in a mode other than Mobile API
- This field is required
-
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index f7b8e7c4d..4dfeee4f6 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -55,7 +55,7 @@
Ungültige symbol
Schüler nicht gefunden. Überprüfen Sie das Symbol und die gewählte Variation des UONET+ Registers
Ausgewählter Student ist bereits angemeldet.
- The symbol can be found on the register page in Uczeń → Dostęp Mobilny → Wygeneruj kod dostępu.\n\nMake sure that you have set the appropriate register variant in the UONET+ register variant field on the first login screen
+ Das Symbol kann auf der Registerseite in Uczeń→ Dostęp Mobilny → Zarejestruj urządzenie mobilnegefunden werden.\n\nStellen Sie sicher, dass Sie die entsprechende Registervariante im Feld UONET+ Registervariante auf dem vorherigen Bildschirm festgelegt haben
Wählen Sie die Studenten aus, die sich bei der Anwendung anmelden sollen
Andere Optionen
In diesem Modus funktioniert eine Glücknummer, eine Klassenstatistik, eine Zusammenfassung der Anwesenheit, eine Entschuldigung für die Abwesenheit, abgeschlossene Lektionen, Schulinformationen und eine Vorschau der Liste der registrierten Geräte nicht
@@ -72,14 +72,6 @@
Wiederherstellen
Student ist bereits angemeldet
Standard
- Other search locations
- No active students found
- Enter a different symbol
-
- Enable notifications
- Enable notifications so you don\'t miss message from teacher or new grade
- Skip
- Enable
Kundenbetreuer
Anmelden
@@ -283,11 +275,9 @@
Nachricht nicht vorhanden
Sie müssen mindestens 1 Empfänger auswählen.
Der Inhalt der Nachricht muss mindestens 3 Zeichen lang sein.
- Alle postfächer
Nur ungelesen
Nur mit Anhängen
Lesen: %s
- Read by: %1$d of %2$d people
- %1$d Nachricht
- %1$d Nachrichten
@@ -307,7 +297,6 @@
- %1$d ausgewählt
Nachrichten gelöscht
- Postfach auswählen
Keine Informationen über Eintragen
Punkte
@@ -421,8 +410,6 @@
Teilnahme an einem Meeting
Agenda
- Place
- Topic
Schulankündigungen
Keine schulankündigungen
@@ -645,10 +632,10 @@
Antwort mit Nachrichtenhistorie
Arithmetisches Mittel anzeigen, wenn keine Gewichte angegeben sind
Unterstützung
- Datenschutz-Bestimmungen
- Vereinbarungen
- Zustimmung zur Verarbeitung von Daten im Zusammenhang mit Anzeigen
- Anzeigen in der App anzeigen
+ Privacy Policy
+ Agreements
+ Consent to processing of data related to ads
+ Show ads in app
Einzelanzeige ansehen, um Projekt zu unterstützen
Einwilligung in die Datenverarbeitung
Um eine Anzeige zu sehen, müssen Sie mit den Datenverarbeitungsbedingungen unserer Datenschutzerklärung einverstanden sein
@@ -660,9 +647,9 @@
Sie können Ihre Wahl jederzeit in den App-Einstellungen ändern. Wir verwenden Ihre Daten, um auf Sie zugeschnittene Anzeigen anzuzeigen oder unter Verwendung weniger Ihrer Daten nicht personalisierte Werbung anzuzeigen. Bitte lesen Sie unsere Datenschutzerklärung für Details
Personalisierte Werbung
keine personalisierte Werbung
- Ich bin über 18 Jahre alt
- Ja, personalisierte Werbung
- Ja, nicht personalisierte Werbung
+ I am over 18 years old
+ Yes, personalized ads
+ Yes, non-personalized ads
Erweitert
Aussehen & Verhalten
Benachrichtigungen
diff --git a/app/src/main/res/values-es-rES/preferences_values.xml b/app/src/main/res/values-es-rES/preferences_values.xml
deleted file mode 100644
index ac2b6e9e5..000000000
--- a/app/src/main/res/values-es-rES/preferences_values.xml
+++ /dev/null
@@ -1,65 +0,0 @@
-
-
-
- - Light
- - Dark
- - Black (AMOLED)
-
-
- - System language
- - Polski
- - English
- - Pусский
- - Українська
- - Deutsch
- - Čeština
- - Slovenčina
-
-
- - 15 minutes
- - 30 minutes
- - 1 hour
- - 2 hours
- - 6 hours
- - 12 hours
- - 24 hours
-
-
- - 0,00
- - 0,25
- - 0,33
- - 0,5
- - 0,75
-
-
- - Alphabetically
- - By date
- - By average
-
-
- - Dzienniczek+
- - Wulkanowy
- - Grade colors in register
-
-
- - Up to 1 at once
- - Always expanded
- - Unlimited expansions
-
-
- - Average of grades only from selected semester
- - Average of averages from both semesters
- - Average of grades from the whole year
-
-
- - Lucky number
- - Unread messages
- - Attendance
- - Lessons
- - Grades
- - Homework
- - School announcements
- - Exams
- - Conferences
-
-
diff --git a/app/src/main/res/values-es-rES/strings.xml b/app/src/main/res/values-es-rES/strings.xml
deleted file mode 100644
index 667231274..000000000
--- a/app/src/main/res/values-es-rES/strings.xml
+++ /dev/null
@@ -1,728 +0,0 @@
-
-
-
- Login
- Wulkanowy
- Grades
- Attendance
- Exams
- Timetable
- Settings
- More
- About
- Log viewer
- Debug
- Notification debug
- Contributors
- Licenses
- Messages
- New message
- New homework
- Notes and achievements
- Homework
- Accounts manager
- Select account
- Account details
- Student info
- Dashboard
- Notifications center
-
- Semester %1$d, %2$d/%3$d
-
- Sign in with the student or parent account
- Enter the symbol from the register page for account: <b>%1$s</b>
- Username
- Email
- Login, PESEL or e-mail
- Password
- UONET+ register variant
- Mobile API
- Scraper
- Hybrid
- Token
- PIN
- Symbol
- Sign in
- Password too short
- Login details are incorrect
- %1$s. Make sure the correct UONET+ register variation is selected below
- Invalid PIN
- Invalid token
- Token expired
- Invalid email
- Use the assigned login instead of email
- Use the assigned login or email in @%1$s
- Invalid symbol
- Student not found. Validate the symbol and the chosen variation of the UONET+ register
- Selected student is already logged in
- The symbol can be found on the register page in Uczeń → Dostęp Mobilny → Wygeneruj kod dostępu.\n\nMake sure that you have set the appropriate register variant in the UONET+ register variant field on the first login screen
- Select students to log in to the application
- Other options
- In this mode, a lucky number does not work, a class grade stats, summary of attendance, excuse for absence, completed lessons, school information and preview of the list of registered devices
- This mode displays the same data as it appears on the register website
- The combination of the best features of the other two modes. It works faster than scraper and provides features not available in the Mobile API mode. It is in the experimental phase
- Privacy policy
- Trouble signing in? Contact us!
- Email
- Discord
- Send email
- Make sure you select the correct UONET+ register variation!
- I forgot my password
- Recover your account
- Recover
- Student is already signed in
- Standard
- Other search locations
- No active students found
- Enter a different symbol
-
- Enable notifications
- Enable notifications so you don\'t miss message from teacher or new grade
- Skip
- Enable
-
- Account manager
- Log in
- Session expired
- Session expired, log in again
- Application support
- Do you like this app? Support its development by enabling non-invasive ads that you can disable at any time
- Enable ads
-
- Grade
- Semester %d
- Change semester
- No grades
- Weight
- Weight: %s
- Comment
- Number of new ratings: %1$d
- Average: %1$.2f
- Points: %s
- No average
- Total points
- Final grade
- Predicted grade
- Calculated average
- How does Calculated Average work?
- The Calculated Average is the arithmetic average calculated from the subjects averages. It allows you to know the approximate final average. It is calculated in a way selected by the user in the application settings. It is recommended that you choose the appropriate option. This is because the calculation of school averages differs. Additionally, if your school reports the average of the subjects on the Vulcan page, the application downloads them and does not calculate these averages. This can be changed by forcing the calculation of the average in the application settings.\n\nAverage of grades only from selected semester:\n1. Calculating the weighted average for each subject in a given semester\n2.Adding calculated averages\n3. Calculation of the arithmetic average of the summed averages\n\nAverage of averages from both semesters:\n1.Calculating the weighted average for each subject in semester 1 and 2\n2. Calculating the arithmetic average of the calculated averages for semesters 1 and 2 for each subject.\n3. Adding calculated averages\n4. Calculation of the arithmetic average of the summed averages\n\nAverage of grades from the whole year:\n1. Calculating weighted average over the year for each subject. The final average in the 1st semester is irrelevant.\n2. Adding calculated averages\n3. Calculating the arithmetic average of summed averages
- How does the Final Average work?
- The Final Average is the arithmetic average calculated from all currently available final grades in the given semester.\n\nThe calculation scheme consists of the following steps:\n1. Summing up the final grades given by teachers\n2. Divide by the number of subjects that have already been graded
- Final average
- from %1$d of %2$d subjects
- Summary
- Class
- Mark as read
- Partial
- Semester
- Points
- Legend
- Class average: %1$s
- Your average: %1$s
- Your grade: %1$s
- Class
- Student
-
- - %d grade
- - %d grades
-
-
- - 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
-
-
- Lesson
- Room
- Group
- Hours
- Changes
- No lessons this day
- %s min
- %s sec
- %1$s left
- in %1$s
- Finished
- Now: %s
- Next: %s
- Later: %s
- %1$s lesson %2$d - %3$s
- Change of room from %1$s to %2$s
- Change of teacher from %1$s to %2$s
- Change of subject from %1$s to %2$s
-
- - Timetable change
- - Timetable changes
-
-
- - %1$s - %2$d change in timetable
- - %1$s - %2$d changes in timetable
-
-
- - %1$d change in timetable
- - %1$d changes in timetable
-
-
- - %d change
- - %d changes
-
-
- Completed lessons
- Show completed lessons
- No info about completed lessons
- Topic
- Absence
- Resources
-
- Additional lessons
- Show additional lessons
- No info about additional lessons
- New lesson
- New additional lesson
- Additional lesson added successfully
- Additional lesson deleted successfully
- Repeat weekly
- Delete additional lesson
- Just this lesson
- All in the series
- Start time
- End time
- End time must be greater than start time
-
- Attendance summary
- Absent for school reasons
- Excused absence
- Unexcused absence
- Exemption
- Excused lateness
- Unexcused lateness
- Present
- Deleted
- Unknown
- Number of lesson
- No entries
- Absence reason (optional)
- Send
- Absence excuse request sent successfully!
- You must select at least one absence!
- Excuse
-
- - New attendance
- - New attendance
-
-
- - %1$d new attendance
- - %1$d attendance
-
-
- - %d attendance
- - %d attendance
-
-
- Total
-
- No exams this week
- Type
- Entry date
-
- - New exam
- - New exams
-
-
- - %d new exam
- - %d new exams
-
-
- - %d exam
- - %d exams
-
-
- Inbox
- Sent
- Trash
- (no subject)
- No messages
- From:
- To:
- Date: %1$s
- Reply
- Forward
- Select all
- Unselect all
- Move to trash
- Delete permanently
- Message deleted successfully
- student
- parent
- guardian
- employee
- Share
- Print
- Subject
- Content
- Message sent successfully
- Message does not exist
- You need to choose at least 1 recipient
- The message content must be at least 3 characters
- All mailboxes
- Only unread
- Only with attachments
- Read: %s
- Read by: %1$d of %2$d people
-
- - %1$d message
- - %1$d messages
-
-
- - New message
- - New messages
-
- Do you want to restore draft message?
- Do you want to restore draft message with recipients: %s?
-
- - You received %1$d message
- - You received %1$d messages
-
-
- - %1$d selected
- - %1$d selected
-
- Messages deleted
- Choose mailbox
-
- No info about notes
- Points
-
- - %d note
- - %d notes
-
-
- - New note
- - New notes
-
-
- - You received %1$d note
- - You received %1$d notes
-
-
-
- - %d praise
- - %d praises
-
-
- - New praise
- - New praises
-
-
- - You received %1$d praise
- - You received %1$d praises
-
-
-
- - %d neutral note
- - %d neutral notes
-
-
- - New neutral note
- - New neutral notes
-
-
- - You received %1$d neutral note
- - You received %1$d neutral notes
-
-
- No info about homework
- Mark as done
- Mark as undone
- Add homework
- Homework added successfully
- Homework deleted successfully
- Attachments
-
- - New homework
- - New homework
-
-
- - You received %d new homework
- - You received %d new homework
-
-
- - %d homework
- - %d homework
-
-
- Lucky number
- Today\'s lucky number is
- No info about the lucky number
- Lucky number for today
- Today\'s lucky number is: %s
- Show history
-
- Lucky number history
- No info about lucky numbers
-
- Mobile devices
- No devices
- Deregister
- Device removed
- QR code
- Token
- Symbol
- PIN
-
- School and teachers
-
- School
- No info about school
- School name
- School address
- Telephone
- Name of headmaster
- Name of pedagogue
- Show on map
- Call
-
- Teachers
- No info about teachers
- No subject
-
- Conferences
- No info about conferences
-
- - %d conference
- - %d conferences
-
-
- - New conference
- - New conferences
-
-
- - You have %1$d new conference
- - You have %1$d new conferences
-
- Present at conference
- Agenda
- Place
- Topic
-
- School announcements
- No school announcements
-
- - %d school announcement
- - %d school announcements
-
-
- - New school announcement
- - New school announcements
-
-
- - You have %1$d new school announcement
- - You have %1$d new school announcements
-
-
- Add account
- Logout
- Do you want to log out this student?
- Student logout
- Student account
- Parent account
- Edit data
- Accounts manager
- Select student
- Family
- Contact
- Residence details
- Personal information
-
- App version
- Contributors
- List of Wulkanowy developers
- Report a bug
- Send a bug report via e-mail
- FAQ
- Read Frequently Asked Questions
- Discord server
- Join the Wulkanowy community
- Facebook fanpage
- Twitter page
- Follow us on twitter
- Like our facebook fanpage
- Privacy policy
- Rules for collecting personal data
- System settings
- Open system settings
- Homepage
- Visit the website and help develop the application
- Licenses
- Licenses of libraries used in the application
-
- License
-
- Avatar
- See more on GitHub
-
- No info about student or student family
- Name
- Second name
- Gender
- Polish citizenship
- Family name
- Mother\'s and father\'s names
- Phone
- Cellphone
- E-mail
- Address of residence
- Address of registration
- Correspondence address
- Surname and first name
- Degree of kinship
- Address
- Phones
- Male
- Female
- Last name
- Guardian
-
- Nick
- Add nick
- Choose avatar color
-
- Share logs
- Refresh
-
- Lessons
- (Tomorrow)
- (Today and tomorrow)
- In a moment:
- Soon:
- First:
- Now:
- End of lessons
- Next:
- Later:
-
- - %1$d more lesson
- - %1$d more lessons
-
- until %1$s
- No upcoming lessons
- An error occurred while loading the lessons
- Homework
- No homework to do
- An error occurred while loading the homework
-
- - %1$d more homework
- - %1$d more homework
-
- due %1$s
- Last grades
- No new grades
- An error occurred while loading the grades
- School announcements
- No current announcements
- An error occurred while loading the announcements
-
- - %1$d more announcement
- - %1$d more announcements
-
- Exams
- No upcoming exams
- An error occurred while loading the exams
-
- - %1$d more exam
- - %1$d more exams
-
- Conferences
- No upcoming conferences
- An error occurred while loading the conferences
-
- - %1$d more conference
- - %1$d more conferences
-
- An error occurred while loading data
- None
-
- Check for updates
- Before reporting a bug, check first if an update with the bug fix is available
-
- Content
- Retry
- Description
- No description
- Teacher
- Date
- Entry date
- Color
- Details
- Category
- Close
- No data
- Subject
- Prev
- Next
- Search
- Search…
- Yes
- No
- Save
- Title
- Add
- Copied
- Undo
- Change
- Add to calendar
-
- No lessons
- Choose theme
- Light
- Dark
- System Theme
-
- App
- Default view
- Calculated average options
- Force average calculation by app
- Show presence
- Theme
- Grades expanding
- Mark current lesson
- Show groups next to subjects
- Show chart list in class grades
- Show subjects without grades
- Grades color scheme
- Subjects sorting
- Language
- Notifications
- Other
- Show notifications
- Show upcoming lesson notifications
- Make upcoming lesson notification persistent
- Turn off when notification is not showing in your watch/band
- Open system notification settings
- 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.
- Show debug notifications
- Synchronization is disabled
- Official app notifications
- Capture official app notifications
- Remove official app notifications after capture
- Capture notifications
- With this feature you can gain a substitute of push notifications like in the official app. All you need to do is allow Wulkanowy to receive all notifications in your system settings.\n\nHow it works?\nWhen you get a notification in Dziennik VULCAN, Wulkanowy will be notified (that\'s what these extra permissions are for) and will trigger a sync so that can send its own notification.\n\nFOR ADVANCED USERS ONLY
- Upcoming lesson notifications
- You must allow the Wulkanowy app to set alarms and reminders in your system settings to use this feature.
- Go to settings
- Synchronization
- Automatic update
- Suspended on holidays
- Updates interval
- Wi-Fi only
- Sync now
- Synced!
- Sync failed
- Sync in progress
- Last full sync: %s
- Value of the plus
- Value of the minus
- Reply with message history
- Show arithmetic average when no weights provided
- Support
- Privacy Policy
- Agreements
- Consent to processing of data related to ads
- Show ads in app
- Watch single ad to support project
- Consent to data processing
- To view an advertisement you must agree to the data processing terms of our Privacy Policy
- Agree
- Privacy policy
- Ad is loading
- Thank you for your support, come back later for more ads
- Can we use your data to display ads?
- You can change your choice anytime in the app settings. We may use your data to display ads tailored to you or, using less of your data, display non-personalized ads. Please see our Privacy Policy for details
- Personalized ads
- Non-personalized ads
- I am over 18 years old
- Yes, personalized ads
- Yes, non-personalized ads
- Advanced
- Appearance & Behavior
- Notifications
- Synchronization
- Advertisements
- Grades
- Dashboard
- Tiles visibility
- Attendance
- Timetable
- Grades
- Calculated average
- Messages
- Appearance & Behavior
- Languages, themes, subjects sorting
- App notifications, fix problems
- Notifications
- Synchronization
- Automatic update, synchronization interval
- Plus and minus values, average calculation
- Advanced
- App version, contributors, social portals
- Displaying advertisements, project support
-
- New grades
- New homework
- New conferences
- New exams
- Lucky number
- New messages
- New notes
- New school announcements
- Push notifications
- Upcoming lessons
- Debug
- Timetable change
- New attendance
-
- Black
- Red
- Blue
- Green
- Purple
- No color
-
- Download of updates has started…
- An update has just been downloaded.
- Restart
- Update failed! Wulkanowy may not function properly. Consider updating
-
- No internet connection
- An error occurred. Check your device clock
- Connection to register failed. Servers can be overloaded. Please try again later
- Loading data failed. Please try again later
- Register password change required
- Maintenance underway UONET + register. Try again later
- Unknown UONET + register error. Try again later
- Unknown application error. Please try again later
- An unexpected error occurred
- Feature disabled by your school
- Feature not available. Login in a mode other than Mobile API
- This field is required
-
diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml
index 4891015d2..c9abbd022 100644
--- a/app/src/main/res/values-pl/strings.xml
+++ b/app/src/main/res/values-pl/strings.xml
@@ -55,7 +55,7 @@
Nieprawidłowy symbol
Nie znaleziono ucznia. Sprawdź poprawność symbolu i wybranej odmiany dziennika UONET+
Wybrany uczeń jest już zalogowany
- Symbol można znaleźć na stronie dziennika w Uczeń→ Dostęp Mobilny → Wygeneruj kod dostępu.\n\nUpewnij się, że ustawiłeś odpowiednią odmianę dziennika w polu Odmiana dziennika UONET+ na pierwszym ekranie logowania
+ Symbol znajdziesz na stronie dziennika w Uczeń → Dostęp Mobilny → Zarejestruj urządzenie mobilne.\n\nUpewnij się, że w polu Dziennik UONET+ na poprzednim ekranie została ustawiona odpowiednia odmiana dziennika
Wybierz uczniów do zalogowania w aplikacji
Inne opcje
W tym trybie nie działa szczęśliwy numerek, uczeń na tle klasy, podsumowanie frekwencji, usprawiedliwianie nieobecności, lekcje zrealizowane, informacje o szkole i podgląd listy zarejestrowanych urządzeń
@@ -72,14 +72,6 @@
Przywróć
Uczeń jest już zalogowany
Standardowa
- Inne lokalizacje wyszukiwania
- Nie znaleziono aktywnych uczniów
- Wprowadź inny symbol
-
- Włącz powiadomienia
- Włącz powiadomienia, aby nie przegapić wiadomości od nauczyciela lub nowej oceny
- Pomiń
- Włącz
Menadżer kont
Zaloguj się
@@ -317,11 +309,9 @@
Wiadomość nie istnieje
Musisz wybrać co najmniej 1 adresata
Treść wiadomości musi zawierać co najmniej 3 znaki
- Wszystkie skrzynki
Tylko nieprzeczytane
Tylko z załącznikami
Przeczytana: %s
- Przeczytana przez: %1$d z %2$d osób
- %1$d wiadomość
- %1$d wiadomości
@@ -349,7 +339,6 @@
- %1$d wybranych
Wiadomości zostały usunięte
- Wybierz skrzynkę
Brak informacji o uwagach
Punkty
@@ -493,8 +482,6 @@
Obecność na zebraniu
Agenda
- Miejsce
- Temat
Ogłoszenia szkolne
Brak ogłoszeń szkolnych
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index 01e43183f..e1abb0293 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -55,7 +55,7 @@
Неверный symbol
Ученик не найден. Проверьте symbol и выбранный тип дненика UONET+
Данный ученик уже авторизован
- The symbol can be found on the register page in Uczeń → Dostęp Mobilny → Wygeneruj kod dostępu.\n\nMake sure that you have set the appropriate register variant in the UONET+ register variant field on the first login screen
+ Symbol можно найти на странице регистрации в Uczeń → Dostęp Mobilny → Zarejestruj urządzenie mobilne.\n\nУбедитесь, что вы выбрали соответствующий тип дневника в поле Тип дневника UONET+ на предыдущем экране
Выберите учеников для авторизации в приложении
Другие варианты
В этом режиме не работают: счастливый номер, статистика класса по оценкам, статистика посещаемости и уроков, информация о школе и список зарегистрированных устройств
@@ -72,22 +72,14 @@
Восстановить
Ученик уже авторизован
Стандартный
- Other search locations
- No active students found
- Enter a different symbol
-
- Enable notifications
- Enable notifications so you don\'t miss message from teacher or new grade
- Skip
- Enable
Менеджер аккаунтов
Войти
Сеанс истёк
Сеанс истёк, авторизуйтесь снова
- Поддержка приложения
- Вам нравится это приложение? Поддержите его разработку, включив неинвазивную рекламу, которую можно отключить в любое время
- Включить рекламу
+ Application support
+ Do you like this app? Support its development by enabling non-invasive ads that you can disable at any time
+ Enable ads
Оценка
%d семестр
@@ -105,7 +97,7 @@
Ожидаемая оценка
Рассчитанная средняя оценка
Как работает \"Рассчитанная средняя оценка\"?
- Рассчитанная средняя оценка - это среднее арифметическое, рассчитанное на основе средних оценок по предметам. Это позволяет узнать приблизительную итоговую среднюю оценку. Она рассчитывается способом, выбранным пользователем в настройках приложения. Рекомендуется выбрать подходящий вариант, так как каждая школа по разному считает среднюю оценку. Кроме того, если ваша школа выставляет средние оценки по предметам на странице Vulcan, приложение просто загрузит их. Это можно изменить, заставив приложение считать среднюю оценку в настройках.\n\nСредняя из оценок выбранного семестра:\n1. Вычисление средневзвешенного значения по каждому предмету за семестр\n2.Суммирование вычисленных значений\n3. Вычисление среднего арифметического суммированных значений\n\nСредняя из средних оценок семестров:\n1.Расчет средневзвешенного значения для каждого предмета в семестрах. \n2. Вычисление среднего арифметического из средневзвешенных значений для каждого предмета в семестрах.\n3. Суммирование средних арифметических\n4. Вычисление среднего арифматического из суммированных значений\n\nСредняя из оценок со всего года:\n1. Расчет средневзвешенного значения по каждому предмету за год. Итоговое среднее значение за 1 семестр не имеет значения.\n2. Суммирование вычисленных средних\n3. Расчет среднего арифметического суммированных чисел
+ The Calculated Average is the arithmetic average calculated from the subjects averages. It allows you to know the approximate final average. It is calculated in a way selected by the user in the application settings. It is recommended that you choose the appropriate option. This is because the calculation of school averages differs. Additionally, if your school reports the average of the subjects on the Vulcan page, the application downloads them and does not calculate these averages. This can be changed by forcing the calculation of the average in the application settings.\n\nAverage of grades only from selected semester:\n1. Calculating the weighted average for each subject in a given semester\n2.Adding calculated averages\n3. Calculation of the arithmetic average of the summed averages\n\nAverage of averages from both semesters:\n1.Calculating the weighted average for each subject in semester 1 and 2\n2. Calculating the arithmetic average of the calculated averages for semesters 1 and 2 for each subject.\n3. Adding calculated averages\n4. Calculation of the arithmetic average of the summed averages\n\nAverage of grades from the whole year:\n1. Calculating weighted average over the year for each subject. The final average in the 1st semester is irrelevant.\n2. Adding calculated averages\n3. Calculating the arithmetic average of summed averages
Как работает \"Итоговая средняя оценка\"?
Итоговая средняя оценка - это среднее арифметическое, рассчитанное из всех имеющихся на данный момент итоговых оценок в семестре.\n\nРассчет происходит следующим образом:\n1. Суммирование итоговых оценок, выставленных преподавателями\n2. Полученная сумма делится на число предметов, по которым выставлены оценки
Итоговая средняя оценка
@@ -305,10 +297,10 @@
Перенести в корзину
Удалить навсегда
Письмо успешно удалено
- ученик
- родитель
- опекун
- работник
+ student
+ parent
+ guardian
+ employee
Поделиться
Печать
Тема
@@ -317,11 +309,9 @@
Письма не существует
Вы должны выбрать как минимум одного получателя
Текст сообщения должен содержать как минимум 3 знака
- Все почтовые ящики
Только непрочитанные
Только с вложениями
Прочитано: %s
- Прочитано: %1$d из %2$d человек
- %1$d сообщение
- %1$d сообщения
@@ -349,7 +339,6 @@
- %1$d выбрано
Сообщение удалено
- Выбрать почтовый ящик
Нет записей о замечаниях и свершениях
Баллы
@@ -493,8 +482,6 @@
Присутствует на встрече
Повестка дня
- Place
- Topic
Объявления школы
Нет школьных объявлений
@@ -733,10 +720,10 @@
Отвечать с историей сообщений
Показывать среднее арифметическое при отсутствии стоимости
Поддержка
- Политика приватности
- Соглашения
- Согласие на обработку данных, связанных с объявлениями
- Показать рекламу в приложении
+ Privacy Policy
+ Agreements
+ Consent to processing of data related to ads
+ Show ads in app
Посмотреть рекламу для поддержки проекта
Согласие на обработку данных
Для просмотра рекламы вы должны согласиться с условиями обработки данных нашей Политики конфиденциальности
@@ -744,13 +731,13 @@
Политика конфиденциальности
Реклама загружается
Спасибо за вашу поддержку, возвращайтесь позже для дополнительной рекламы
- Можем ли мы использовать ваши данные для показа рекламы?
- Вы можете изменить свой выбор в любое время в настройках приложения. Мы можем использовать ваши данные для показа объявлений в соответствии с вашими пожеланиями или, используя меньше данных, отображать неперсональную рекламу. Пожалуйста, ознакомьтесь с нашей политикой конфиденциальности для подробностей
- Персонализированная реклама
- Неперсонализированная реклама
- Я старше 18 лет
- Да, персонализировать рекламу
- Да, не персонализировать рекламу
+ Can we use your data to display ads?
+ You can change your choice anytime in the app settings. We may use your data to display ads tailored to you or, using less of your data, display non-personalized ads. Please see our Privacy Policy for details
+ Personalized ads
+ Non-personalized ads
+ I am over 18 years old
+ Yes, personalized ads
+ Yes, non-personalized ads
Расширенные
Внешний вид и поведение
Уведомления
diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml
index 4189c5349..1c6eae8c0 100644
--- a/app/src/main/res/values-sk/strings.xml
+++ b/app/src/main/res/values-sk/strings.xml
@@ -35,7 +35,7 @@
Email
Prihlásenie, číslo PESEL alebo e-mail
Heslo
- Variácia denníka UONET+
+ Variácie denníka UONET+
Mobile API
Scraper
Hybridné
@@ -55,7 +55,7 @@
Neplatný symbol
Žiak nebol nájdený. Skontrolujte správnosť symbolu a vybrané varianty denníka UONET+
Vybraný žiak už je prihlásený
- Symbol nájdete na stránke denníka v Uczeń→ Dostęp Mobilny → Wygeneruj kod dostępu.\n\nUistite sa, že ste nastavili správny variant denníka v poli Variácia denníka UONET+ na prvej prihlasovacej obrazovke
+ Symbol nájdete na stránke denníka v Uczeń→ Dostęp Mobilny → Zarejestruj urządzenie mobilne.\n\nUistite sa, že ste na predchádzajúcu obrazovke nastaviť správny variant denníka do poľa Variácie denníka UONET+
Vyberte žiakov, ktorí sa majú do aplikácie prihlásiť
Iné možnosti
V tomto režime nefungujú nasledovné: šťastné číslo, štatistiky triedy, zhrnutie frekvencií, ospravedlnenie neprítomnosti, dokončené lekcie, informácie o škole a prezeranie zoznamu registrovaných zariadení
@@ -72,14 +72,6 @@
Obnoviť
Žiak je už prihlásený
Štandardná
- Iné miesta vyhľadávania
- Neboli nájdení žiadni aktívni žiaci
- Zadajte iný symbol
-
- Povoliť oznámenia
- Povoliť oznámenia, aby ste nezmeškali správu od učiteľa alebo o novej známke
- Preskočiť
- Zapnúť
Manažér účtov
Prihlásiť sa
@@ -317,11 +309,9 @@
Správa neexistuje
Musíte vybrať aspoň 1 príjemca
Obsah správy musí mať aspoň 3 znaky
- Všetky poštové schránky
Iba neprečítané
Iba s prílohami
Prečítaná: %s
- Prečítaná cez: %1$d z %2$d osôb
- %1$d správa
- %1$d správy
@@ -349,7 +339,6 @@
- %1$d vybraných
Správy odstránené
- Vyberte poštovú schránku
Žiadne informácie o poznámkach
Body
@@ -493,8 +482,6 @@
Prítomnosť na stretnutí
Agenda
- Miesto
- Téma
Školské oznámenia
Žiadne školské oznámenia
@@ -748,7 +735,7 @@
Voľbu môžete kedykoľvek zmeniť v nastavení aplikácie. Môžeme použiť vaše údaje na zobrazenie reklám šitých pre vás alebo pomocou menej vašich dát zobrazovať neprispôsobené reklamy. Podrobnosti nájdete v našich Zásadách ochrany osobných údajov
Prispôsobené reklamy
Neprispôsobené reklamy
- Mám viac ako 18 rokov
+ Mám ukončené 18 rokov
Áno, prispôsobené reklamy
Áno, neprispôsobené reklamy
Pokročilé
diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml
index 99c340650..f90e78e7d 100644
--- a/app/src/main/res/values-uk/strings.xml
+++ b/app/src/main/res/values-uk/strings.xml
@@ -55,7 +55,7 @@
Неправильний symbol
Студента не знайдено. Перевірте symbol та обранний тип щоденника UONET+
Цього учня вже авторизовано
- The symbol can be found on the register page in Uczeń → Dostęp Mobilny → Wygeneruj kod dostępu.\n\nMake sure that you have set the appropriate register variant in the UONET+ register variant field on the first login screen
+ Symbol можна знайти на сторінці реєстрації в Uczeń→ Dostęp Mobilny → Zarejestruj urządzenie mobilne.\n\nПереконайтесь, що ви встановили відповідний тип щоденника в полі Тип щоденника UONET+ на попередньому екрані
Виберіть учнів для авторизації в додатку
Інші варіанти
У цьому режимі не працюють: щасливий номер, статистика класу по оцінкам, статистика відвідуваності та уроків, інформація про школу та список зареєстрованих пристроїв
@@ -72,22 +72,14 @@
Відновити
Учня вже авторизовано
Стандартний
- Other search locations
- No active students found
- Enter a different symbol
-
- Enable notifications
- Enable notifications so you don\'t miss message from teacher or new grade
- Skip
- Enable
Змінити облікові записи
Увійти
Минув термін дії сесії
Минув термін дії сесії, авторизуйтеся знову
- Підтримка додатку
- Вам подобається цей додаток? Підтримайте його розвиток, увімкнувши неінвазивну рекламу, яку ви можете відключити в будь-який час
- Увімкнути рекламу
+ Application support
+ Do you like this app? Support its development by enabling non-invasive ads that you can disable at any time
+ Enable ads
Оцінка
%d семестр
@@ -105,7 +97,7 @@
Передбачувана оцінка
Розрахована середня оцінка
Як працює \"Розрахована середня оцінка\"?
- Розрахована середня оцінка - це середнє арифметичне, обчислене з середніх оцінок з предметів. Це дозволяє дізнатися приблизну кінцеву середню оцінку. Вона розраховується спосібом, обраним користувачем у налаштуваннях програми. Рекомендується вибрати відповідний варіант, тому що кожна школа по різному розраховує середню оцінку. Крім того, якщо у вашій школі повідомляється середня оцінка з предметів на сторінці Vulcan, програма тільки завантажує ці оцінки і не розраховує їх самостійно. Це можна змінити шляхом примусового розрахунку середньоЇ оцінки в налаштуваннях програми.\n\nСередні оцінки тільки за обраний семестр:\n1. Розрахунок середньозваженого числа для кожного предмета в даному семестрі\n2. Сумування розрахованих числ\n3. Розрахунок середнього арифметичного з сумованих чисел\n\nСереднє значення з обох семестрів:\n1. Обчислення середньозваженого числа для кожного предмета у 1 та 2 семестрі\n2. Обчислення середнього арифметичного з розрахованих середньозважених числ за 1 та 2 семестри для кожного предмета.\n3. Додавання розрахованих середніх\n4. Розрахунок середнього арифметичного підсумованих середніх значень\n\nСереднє значення оцінок за весь рік: \n1. Розрахунок середньозваженого числа за рік для кожного предмета. Підсумковий середній показник у 1-му семестрі не має значення.\n2. Сумування розрахованих середніх\n3. Обчислення середнього арифметичного з суммованих середніх
+ The Calculated Average is the arithmetic average calculated from the subjects averages. It allows you to know the approximate final average. It is calculated in a way selected by the user in the application settings. It is recommended that you choose the appropriate option. This is because the calculation of school averages differs. Additionally, if your school reports the average of the subjects on the Vulcan page, the application downloads them and does not calculate these averages. This can be changed by forcing the calculation of the average in the application settings.\n\nAverage of grades only from selected semester:\n1. Calculating the weighted average for each subject in a given semester\n2.Adding calculated averages\n3. Calculation of the arithmetic average of the summed averages\n\nAverage of averages from both semesters:\n1.Calculating the weighted average for each subject in semester 1 and 2\n2. Calculating the arithmetic average of the calculated averages for semesters 1 and 2 for each subject.\n3. Adding calculated averages\n4. Calculation of the arithmetic average of the summed averages\n\nAverage of grades from the whole year:\n1. Calculating weighted average over the year for each subject. The final average in the 1st semester is irrelevant.\n2. Adding calculated averages\n3. Calculating the arithmetic average of summed averages
Як працює \"Підсумкова середня оцінка\"?
Підсумкове середнє значення - це середнє арифметичне, обчислене з усіх наявних наразі підсумкових оцінок у даному семестрі. \n\nСхема обчислення складається з таких кроків:\n1. Сумування підсумкових оцінок, виставленних викладачами\n2. Ділення на кількість предметів, з яких виставлені ці оцінки
Підсумкова середня оцінка
@@ -228,7 +220,7 @@
Всі в серії
Час початку
Час завершення
- Час завершення має бути пізніше часу початку
+ Час завершення має бути більшим, ніж час початку
Підсумок відвідуваності
Відсутність зі шкільних причин
@@ -305,10 +297,10 @@
Перемістити до кошика
Видалити назавжди
Лист було успішно видалено
- учень
- родич
- опікун
- працівник
+ student
+ parent
+ guardian
+ employee
Поділитись
Друк
Тема
@@ -317,11 +309,9 @@
Такого листа не існує
Необхідно обрати принаймні 1 адресата
Зміст листа повинен складатися принаймні з 3 знаків
- Усі поштові скриньки
Лише непрочитані
Тільки з вкладеннями
Прочитаний: %s
- Прочитано: %1$d з %2$d осіб
- %1$d лист
- %1$d листи
@@ -348,8 +338,7 @@
- %1$d вибрано
- %1$d вибрано
- Листи видалено
- Вибрати поштову скриньку
+ Листи видалені
Немає інформації о зауваженнях
Бали
@@ -493,8 +482,6 @@
Присутність на зустрічі
Порядок денний
- Place
- Topic
Оголошення школи
Немає шкільних оголошень
@@ -733,10 +720,10 @@
Відповісти з історією повідомлень
Вилічити середню аритметичну, якщо оцінка немає вартості
Підтримка
- Політика конфіденційності
- Угоди
- Згода на обробку даних, пов\'язаних з рекламою
- Показувати рекламу в додатку
+ Privacy Policy
+ Agreements
+ Consent to processing of data related to ads
+ Show ads in app
Подивіться одну рекламу для підтримки проєкту
Згода в обробці даних
Щоб переглянути рекламу, ви повинні погодитися з умовами обробки даних нашої Політики конфіденційності
@@ -744,13 +731,13 @@
Політика конфіденційності
Реклама завантажується
Дякуємо за вашу підтримку, повертайтеся пізніше для більшої кількості реклам
- Чи можемо ми використовувати ваші дані для висвітлювання реклами?
- Ви можете змінити свій вибір в будь-який час в налаштуваннях додатку. Ми можемо використовувати ваші дані для висвітлювання реклами, адаптованої до вас або, використовуючи менше ваших даних, висвітлювати неперсоналізовану рекламу. Перегляньте нашу Політику конфіденційності для подробиць
- Персоналізована реклама
- Неперсоналізована реклама
- Мені більше 18 років
- Так, персоналізована реклама
- Так, неперсоналізована реклама
+ Can we use your data to display ads?
+ You can change your choice anytime in the app settings. We may use your data to display ads tailored to you or, using less of your data, display non-personalized ads. Please see our Privacy Policy for details
+ Personalized ads
+ Non-personalized ads
+ I am over 18 years old
+ Yes, personalized ads
+ Yes, non-personalized ads
Додатково
Вигляд та поведінка
Сповіщення
diff --git a/app/src/main/res/values/api_hosts.xml b/app/src/main/res/values/api_hosts.xml
index 04f4a12bf..8413d68e4 100644
--- a/app/src/main/res/values/api_hosts.xml
+++ b/app/src/main/res/values/api_hosts.xml
@@ -6,9 +6,8 @@
- Gdańska Platforma Edukacyjna
- Lubelski Portal Oświatowy
- EduNet Miasta Tarnowa
- - Platforma Edukacyjna Koszalina
- - Gmina-miasto Tomaszów Mazowiecki - System zarządzania oświatą
- ResMan Rzeszów
+ - Platforma Edukacyjna Koszalina
- Rawa Mazowiecka - Platforma vEdukacja
- Zduńska Wola - e-Urząd
- Sieradz - Portal oświatowy
@@ -28,6 +27,7 @@
- https://edu.gdansk.pl
- https://edu.lublin.eu
- https://umt.tarnow.pl
+ - https://resman.pl
- https://eduportal.koszalin.pl
- https://vulcan.net.pl/?login
- https://vulcan.net.pl/?login
@@ -40,9 +40,7 @@
- https://vulcan.net.pl/?login
- https://vulcan.net.pl/?login
- https://vulcan.net.pl/?login
- - https://vulcan.net.pl/?login
- - https://vulcan.net.pl/?login
- - https://fakelog.cf/?email
+ - http://fakelog.cf/?email
- Default
@@ -50,9 +48,8 @@
- gdansk
- lublin
- tarnow
+ - rzeszow
- koszalin
- - tomaszowmazowieckiprojekt
- - rzeszowprojekt
- rawamazowiecka
- zdunskawola
- sieradz
diff --git a/app/src/main/res/values/api_symbols.xml b/app/src/main/res/values/api_symbols.xml
index 4b61db48d..6f9b1739d 100644
--- a/app/src/main/res/values/api_symbols.xml
+++ b/app/src/main/res/values/api_symbols.xml
@@ -4,11 +4,13 @@
- Andrychów
- Augustów
- Baranów Sandomierski
+ - Bartoszyce
- Będzin
- Bełchatów
- Bełżyce
- Biała Podlaska
- Biała Rawska
+ - Białogard
- Biały Bór
- Białystok
- Biecz
@@ -16,9 +18,11 @@
- Bielsko-Biała
- Bierawa
- Bierutów
+ - Biskupice
- Blachownia
- Błaszki
- Błonie
+ - Bochnia
- Bogatynia
- Boguchwała
- Boguty-Pianki
@@ -41,7 +45,6 @@
- Chełmża
- Chocianów
- Chodzież
- - Chojnice
- Chojnów
- Chorzów
- Ciechanów
@@ -55,9 +58,7 @@
- Dąbrowa Górnicza
- Dąbrowa Tarnowska
- Dębica
- - Dębno
- Dobrzeń Wielki
- - Dobrzeń Wielki 2
- Dobrzyń Nad Wisłą
- Dolnośląskie
- Duszniki-Zdrój
@@ -75,9 +76,6 @@
- Głogów Małopolski
- Głowno
- Głubczyce
- - Głubczyce 2
- - Głuchołazy
- - Gmina Abramów
- Gmina Adamówka
- Gmina Aleksandrów Kujawski
- Gmina Aleksandrów Łódzki
@@ -89,17 +87,14 @@
- Gmina Bądkowo
- Gmina Bałtów
- Gmina Baranów
+ - Gmina Barciany
- Gmina Barcin
- - Gmina Barczewo
- Gmina Baruchowo
- - Gmina Batorz
- Gmina Będzino
- Gmina Bełchatów
- - Gmina Besko
- Gmina Białaczów
- Gmina Białe Błota
- - Gmina Białopole
- - Gmina Bielsk
+ - Gmina Bielsk Podlaski
- Gmina Bircza
- Gmina Błażowa
- Gmina Błędów
@@ -109,6 +104,7 @@
- Gmina Bobrowniki
- Gmina Bodzentyn
- Gmina Bogoria
+ - Gmina Bojanów
- Gmina Bojanowo
- Gmina Bojszowy
- Gmina Bolesławiec
@@ -117,14 +113,10 @@
- Gmina Borów
- Gmina Borowa
- Gmina Borzęcin
- - Gmina Borzytuchom
- - Gmina Bralin
- Gmina Branice
- Gmina Braniewo
- - Gmina Brańszczyk
- Gmina Brąszewice
- Gmina Brenna
- - Gmina Brok
- Gmina Brzeg Dolny
- Gmina Brzeziny
- Gmina Brzeźnio
@@ -133,14 +125,13 @@
- Gmina Brzuze
- Gmina Brzyska
- Gmina Buczek
+ - Gmina Buczkowice
- Gmina Budzów
- Gmina Budzyń
- - Gmina Bukowina Tatrzańska
- Gmina Bukowsko
- Gmina Byczyna
- Gmina Bystra-Sidzina
- - Gmina Cegłów
- - Gmina Cekcyn
+ - Gmina Bytoń
- Gmina Ceków-Kolonia
- Gmina Celestynów
- Gmina Cewice
@@ -148,25 +139,16 @@
- Gmina Chełm
- Gmina Chełmiec
- Gmina Chełmno
- - Gmina Chłopice
- Gmina Chmielnik
- - Gmina Chociwel
- Gmina Chocz
- Gmina Chodel
- - Gmina Chodów
- Gmina Chojnice
- Gmina Chojnów
- - Gmina Chotcza
- - Gmina Chrząstowice
- Gmina Chrzypsko Wielkie
- Gmina Chybie
- Gmina Ciasna
- - Gmina Ciechanów
- Gmina Ciechocin
- - Gmina Cielądz
- - Gmina Cieszanów
- Gmina Ciężkowice
- - Gmina Cisek
- Gmina Cisna
- Gmina Cmolas
- Gmina Cyców
@@ -174,26 +156,19 @@
- Gmina Czarna
- Gmina Czarnków
- Gmina Czarny Dunajec
- - Gmina Czastary
- Gmina Czechowice-Dziedzice
- Gmina Czernichów
- Gmina Czerniejewo
- - Gmina Czerniewice
- - Gmina Czernikowo
- Gmina Czerwionka-Leszczyny
- - Gmina Czerwonak
+ - Gmina Czerwonka
- Gmina Człuchów
- Gmina Czosnów
- - Gmina Dąbrowa Zielona
- - Gmina Dąbrowice
- Gmina Damasławek
- Gmina Damnica
- Gmina Darłowo
- Gmina Dębe Wielkie
- Gmina Dębica
- Gmina Dębno
- - Gmina Dębowa Kłoda
- - Gmina Debrzno
- Gmina Dłutów
- Gmina Dobczyce
- Gmina Dobra
@@ -201,31 +176,19 @@
- Gmina Dobrodzień
- Gmina Dobroń
- Gmina Dobrzany
- - Gmina Dobrzyca
- Gmina Dobrzyniewo Duże
- - Gmina Dolsk
- Gmina Dominowo
- Gmina Dorohusk
- - Gmina Doruchów
- - Gmina Dragacz
- - Gmina Drawsko
- - Gmina Drużbice
- Gmina Drzewica
- Gmina Dubiecko
- - Gmina Dubienka
- Gmina Dukla
- Gmina Dwikozy
- - Gmina Dydnia
- Gmina Dynów
- Gmina Dziadowa Kłoda
- Gmina Działoszyce
- - Gmina Dziemiany
- Gmina Dzierżoniów
- - Gmina Dzwola
- Gmina Elbląg
- - Gmina Ełk
- - Gmina Fredropol
- - Gmina Garbatka-Letnisko
+ - Gmina Fajsławice
- Gmina Garbów
- Gmina Garwolin
- Gmina Gąsawa
@@ -235,37 +198,29 @@
- Gmina Gdów
- Gmina Gielniów
- Gmina Gierałtowice
+ - Gmina Glinojeck
- Gmina Głogów
- - Gmina Głogówek
- Gmina Głuchów
- - Gmina Głusk
- Gmina Głuszyca
- Gmina Gniew
- - Gmina Gniewino
- Gmina Gniewoszów
- Gmina Gniezno
- Gmina Goczałkowice-Zdrój
- Gmina Godkowo
- Gmina Godów
- Gmina Godziesze Wielkie
- - Gmina Godziszów
- Gmina Gołańcz
- - Gmina Gołcza
- Gmina Goleszów
- Gmina Golina
- Gmina Golub-Dobrzyń
- - Gmina Gołuchów
- - Gmina Gomunice
- Gmina Goraj
- Gmina Gorlice
- Gmina Górno
- - Gmina Górzyca
- Gmina Gościeradów
- Gmina Gostyń
- Gmina Gostynin
- Gmina Goszczyn
- Gmina Gózd
- - Gmina Grabica
- Gmina Grabów
- Gmina Grabowiec
- Gmina Grabów Nad Pilicą
@@ -284,52 +239,45 @@
- Gmina Grudziądz
- Gmina Gruta
- Gmina Grybów
- - Gmina Gryfice
- - Gmina Grzmiąca
- Gmina Haczów
- Gmina Halinów
- Gmina Hańsk
- Gmina Harasiuki
- Gmina Hażlach
- Gmina Herby
- - Gmina Horodło
- Gmina Hrubieszów
- Gmina Huszlew
- Gmina Hyżne
- Gmina Imielno
- Gmina Inowrocław
- - Gmina Irządze
- Gmina Istebna
- - Gmina Iwanowice
- Gmina Iwierzyce
- Gmina Iwonicz-Zdrój
- Gmina Izabelin
- Gmina Izbica
- - Gmina Izbicko
- - Gmina Jabłoń
+ - Gmina Jadów
- Gmina Jaktorów
- - Gmina Jakubów
- Gmina Janikowo
- - Gmina Janów
- Gmina Janowiec
- Gmina Janów Podlaski
- - Gmina Jarczów
+ - Gmina Jaraczewo
- Gmina Jarocin
- Gmina Jasienica Rosielna
- - Gmina Jaśliska
- Gmina Jasło
- Gmina Jastków
- Gmina Jastrowie
- Gmina Jastrząb
- Gmina Jedlicze
+ - Gmina Jedlińsk
+ - Gmina Jedlnia-Letnisko
- Gmina Jejkowice
- Gmina Jemielnica
+ - Gmina Jemielno
- Gmina Jerzmanowa
- Gmina Jeżewo
- Gmina Jeziora Wielkie
- Gmina Jeziorzany
- Gmina Jeżowe
- - Gmina Joniec
- Gmina Jordanów
- Gmina Józefów
- Gmina Józefów Nad Wisłą
@@ -337,18 +285,14 @@
- Gmina Kąkolewnica
- Gmina Kamień
- Gmina Kamienica
- - Gmina Kamiennik
+ - Gmina Kamieniec
- Gmina Kamionka
- Gmina Karczmiska
- Gmina Kargowa
- - Gmina Karlino
- - Gmina Karniewo
- Gmina Kawęczyn
- Gmina Kazimierz Biskupi
- Gmina Kępice
- - Gmina Kęsowo
- Gmina Kiełczygłów
- - Gmina Kietrz
- Gmina Kikół
- Gmina Kiszkowo
- Gmina Kleczew
@@ -363,30 +307,22 @@
- Gmina Klucze
- Gmina Kluczewsko
- Gmina Kobiele Wielkie
- - Gmina Kobylanka
- Gmina Kochanowice
- Gmina Kock
- Gmina Kodrąb
- Gmina Kołaczyce
- Gmina Kołbaskowo
- - Gmina Kołbiel
- Gmina Kołczygłowy
- - Gmina Kołobrzeg
- Gmina Koluszki
- Gmina Komańcza
- - Gmina Komarówka Podlaska
- Gmina Komorniki
- Gmina Komprachcice
- Gmina Konarzyny
- Gmina Kondratowice
- - Gmina Koneck
- Gmina Koniusza
- Gmina Konopiska
- Gmina Końskowola
- - Gmina Konstantynów
- Gmina Koprzywnica
- - Gmina Korfantów
- - Gmina Kórnik
- Gmina Korsze
- Gmina Korycin
- Gmina Korzenna
@@ -396,14 +332,10 @@
- Gmina Kościerzyna
- Gmina Kosów Lacki
- Gmina Kostrzyn
- - Gmina Koszęcin
+ - Gmina Koszyce
- Gmina Kotla
- Gmina Kotuń
- - Gmina Kowiesy
- - Gmina Koziegłowy
- Gmina Kozłów
- - Gmina Kramsk
- - Gmina Kraśniczyn
- Gmina Kraśnik
- Gmina Krasnobród
- Gmina Krasnystaw
@@ -413,16 +345,12 @@
- Gmina Krośnice
- Gmina Krupski Młyn
- Gmina Kruszwica
- - Gmina Krynice
- Gmina Krynki
- Gmina Krzanowice
- Gmina Krzemieniewo
- - Gmina Krzeszów
- Gmina Krzymów
- - Gmina Krzywcza
- Gmina Krzywiń
- Gmina Krzyżanowice
- - Gmina Ksawerów
- Gmina Książ Wielki
- Gmina Kunice
- Gmina Kunów
@@ -432,19 +360,15 @@
- Gmina Kwilcz
- Gmina Łabowa
- Gmina Łabunie
- - Gmina Łączna
- - Gmina Lądek
- Gmina Łambinowice
- Gmina Lanckorona
- - Gmina Łańcut
- - Gmina Łapanów
- Gmina Łapsze Niżne
- Gmina Łasin
- Gmina Łaskarzew
- Gmina Lasowice Wielkie
- Gmina Łaszczów
+ - Gmina Laszki
- Gmina Latowicz
- - Gmina Łaziska
- Gmina Łazy
- Gmina Łęczyca
- Gmina Łęczyce
@@ -454,14 +378,11 @@
- Gmina Lelów
- Gmina Leśna
- Gmina Leśna Podlaska
- - Gmina Leśniowice
- Gmina Lesznowola
- Gmina Leżajsk
- Gmina Lichnowy
- Gmina Limanowa
- Gmina Linia
- - Gmina Liniewo
- - Gmina Lipiany
- Gmina Lipinki
- Gmina Lipnik
- Gmina Lipowa
@@ -469,51 +390,43 @@
- Gmina Liszki
- Gmina Liw
- Gmina Łobez
- - Gmina Łochów
- Gmina Łodygowice
- Gmina Łomazy
- - Gmina Łomianki
- - Gmina Łoniów
- Gmina Łopiennik Górny
- Gmina Łopuszno
- - Gmina Łosice
- Gmina Lubań
- Gmina Lubartów
- Gmina Lubasz
- - Gmina Lubawka
- Gmina Lubenia
- Gmina Łubianka
- Gmina Lubicz
- - Gmina Lubień
- Gmina Lubiewo
- Gmina Lubin
- Gmina Łubniany
- Gmina Lubochnia
+ - Gmina Lubomia
- Gmina Luboń
- - Gmina Lubsza
- - Gmina Lubycza Królewska
- Gmina Łuków
- Gmina Łukowica
- Gmina Lutowiska
- - Gmina Lututów
- Gmina Luzino
- Gmina Łużna
- Gmina Łysomice
- - Gmina Maciejowice
- Gmina Magnuszew
- - Gmina Majdan Królewski
- Gmina Maków Podhalański
+ - Gmina Mała Wieś
- Gmina Malbork
- Gmina Małdyty
- Gmina Małkinia Górna
- Gmina Marcinowice
- Gmina Margonin
- Gmina Marianowo
- - Gmina Markuszów
- - Gmina Męcinka
+ - Gmina Markusy
+ - Gmina Masłów
- Gmina Medyka
- Gmina Mełgiew
- Gmina Michałów
+ - Gmina Michałowo
- Gmina Miedziana Góra
- Gmina Miedźna
- Gmina Miedźno
@@ -522,10 +435,7 @@
- Gmina Międzyrzec Podlaski
- Gmina Międzyzdroje
- Gmina Miejsce Piastowe
- - Gmina Miękinia
- Gmina Mielec
- - Gmina Mielno
- - Gmina Mieszkowice
- Gmina Milanów
- Gmina Milejów
- Gmina Milicz
@@ -534,26 +444,21 @@
- Gmina Miłosław
- Gmina Milówka
- Gmina Mińsk Mazowiecki
- - Gmina Mirów
- Gmina Mirsk
- Gmina Młynary
- - Gmina Modliborzyce
- Gmina Mogielnica
- Gmina Mogilany
- - Gmina Mogilno
- - Gmina Morawica
- Gmina Mordy
- Gmina Moryń
- Gmina Mrocza
- Gmina Mrozy
- - Gmina Mściwojów
- - Gmina Mstów
- Gmina Mszana
- Gmina Mszana Dolna
- Gmina Murów
- Gmina Mycielin
- - Gmina Mykanów
+ - Gmina Mysłakowice
- Gmina Myślibórz
+ - Gmina Nadarzyn
- Gmina Namysłów
- Gmina Nasielsk
- Gmina Nawojowa
@@ -564,25 +469,23 @@
- Gmina Niedrzwica Duża
- Gmina Niedźwiada
- Gmina Niedźwiedź
- - Gmina Nowa Karczma
+ - Gmina Niegosławice
+ - Gmina Niwiska
- Gmina Nowa Ruda
- Gmina Nowa Wieś Lęborska
- - Gmina Nowe
- Gmina Nowe Miasto
- Gmina Nowe Miasto Nad Wartą
- - Gmina Nowogród
+ - Gmina Nowogród Bobrzański
- Gmina Nowosolna
- Gmina Nowy Kawęczyn
- - Gmina Nowy Korczyn
- Gmina Nowy Staw
- Gmina Nowy Targ
- Gmina Nowy Tomyśl
- - Gmina Nozdrzec
- Gmina Nur
- Gmina Obrazów
- Gmina Ochotnica Dolna
- Gmina Ogrodzieniec
- - Gmina Olszanica
+ - Gmina Olecko
- Gmina Olsztynek
- Gmina Olszyna
- Gmina Opatowiec
@@ -592,15 +495,11 @@
- Gmina Osiek Jasielski
- Gmina Osiek Mały
- Gmina Osielsko
- - Gmina Osina
- - Gmina Osjaków
- - Gmina Ostroróg
- Gmina Ostrów
- Gmina Ostrówek
- Gmina Ostrów Lubelski
- Gmina Ostrów Mazowiecka
- Gmina Ostrów Wielkopolski
- - Gmina Otmuchów
- Gmina Otyń
- Gmina Ożarów
- Gmina Ożarowice
@@ -608,32 +507,27 @@
- Gmina Ozorków
- Gmina Pabianice
- Gmina Pacanów
- - Gmina Pacyna
- Gmina Paczków
- Gmina Padew Narodowa
+ - Gmina Pajęczno
- Gmina Pakosław
- Gmina Pakosławice
- Gmina Pałecznica
- Gmina Panki
- Gmina Parchowo
- Gmina Parczew
- - Gmina Pasłęk
- - Gmina Pątnów
+ - Gmina Pawłosiów
- Gmina Pawłowice
- Gmina Pawłowiczki
- - Gmina Pawonków
- Gmina Pęcław
- Gmina Pelplin
- - Gmina Pępowo
- Gmina Piaski
- Gmina Piątnica
+ - Gmina Piecki
- Gmina Piekoszów
- - Gmina Pieniężno
- Gmina Pilchowice
- - Gmina Pińczów
- Gmina Pionki
- - Gmina Płaska
- - Gmina Platerówka
+ - Gmina Piotrków Trybunalski
- Gmina Pleśna
- Gmina Pleszew
- Gmina Płońsk
@@ -641,7 +535,6 @@
- Gmina Poczesna
- Gmina Podedwórze
- Gmina Podegrodzie
- - Gmina Podgórzyn
- Gmina Pokój
- Gmina Połajewo
- Gmina Połaniec
@@ -650,18 +543,16 @@
- Gmina Police
- Gmina Polkowice
- Gmina Pomiechówek
- - Gmina Poniatowa
- Gmina Popielów
- Gmina Popów
+ - Gmina Poraj
- Gmina Potęgowo
- - Gmina Potok Wielki
- Gmina Praszka
+ - Gmina Prażmów
- Gmina Prochowice
- Gmina Promna
- Gmina Prószków
- - Gmina Prusice
- Gmina Pruszcz Gdański
- - Gmina Przechlewo
- Gmina Przecław
- Gmina Przedecz
- Gmina Przemęt
@@ -671,9 +562,7 @@
- Gmina Przodkowo
- Gmina Przykona
- Gmina Przyłęk
- - Gmina Przyrów
- Gmina Przystajń
- - Gmina Przytoczna
- Gmina Puchaczów
- Gmina Puck
- Gmina Puławy
@@ -681,10 +570,10 @@
- Gmina Puszcza Mariańska
- Gmina Pysznica
- Gmina Pyzdry
- - Gmina Raba Wyżna
- Gmina Rachanie
- Gmina Raciechowice
- - Gmina Radgoszcz
+ - Gmina Racławice
+ - Gmina Radecznica
- Gmina Radków
- Gmina Radłów
- Gmina Radomin
@@ -692,29 +581,16 @@
- Gmina Radomyśl Nad Sanem
- Gmina Radoszyce
- Gmina Radwanice
- - Gmina Radymno
- - Gmina Radziejów
- Gmina Radziłów
- - Gmina Rajgród
- - Gmina Raków
- - Gmina Rakszawa
- Gmina Rawa Mazowiecka
- - Gmina Regnów
- Gmina Reńska Wieś
- - Gmina Rogóźno
- - Gmina Rokitno
- - Gmina Ropa
- Gmina Rossosz
- Gmina Rozprza
- Gmina Ruciane-Nida
- Gmina Ruda-Huta
- Gmina Rudna
- Gmina Rudniki
- - Gmina Rudnik Nad Sanem
- - Gmina Rudziniec
- Gmina Rusiec
- - Gmina Rusinów
- - Gmina Rybczewice
- Gmina Rychliki
- Gmina Rychtal
- Gmina Ryczywół
@@ -722,39 +598,32 @@
- Gmina Rypin
- Gmina Rytro
- Gmina Rytwiany
+ - Gmina Rząśnia
- Gmina Rzeczyca
- Gmina Rzepiennik Strzyżewski
- Gmina Rzepin
- - Gmina Rzezawa
- Gmina Rzgów
- Gmina Sadki
- Gmina Sadowne
- Gmina Samborzec
- Gmina Sanok
- - Gmina Sawin
- Gmina Ścinawa
- Gmina Sędziejowice
- - Gmina Sejny
- - Gmina Sękowa
- Gmina Sępopol
- Gmina Serokomla
- Gmina Sianów
- Gmina Sicienko
- Gmina Sieciechów
- Gmina Siedlce
- - Gmina Siedliszcze
- Gmina Siemiatycze
- - Gmina Siemień
- Gmina Siemyśl
- Gmina Siennica
- Gmina Siennica Różana
- Gmina Sienno
- Gmina Siepraw
- Gmina Sieradz
- - Gmina Sieraków
- Gmina Sierakowice
- Gmina Siewierz
- - Gmina Sitkówka-Nowiny
- Gmina Sitno
- Gmina Skarżysko Kościelne
- Gmina Skępe
@@ -762,22 +631,16 @@
- Gmina Skoczów
- Gmina Skoki
- Gmina Skołyszyn
- - Gmina Skrwilno
- Gmina Skrzyszów
- Gmina Skulsk
- - Gmina Skwierzyna
- Gmina Sława
- - Gmina Śliwice
- Gmina Słopnice
- - Gmina Słubice
- Gmina Słupca
- Gmina Słupia
- - Gmina Słupia (Konecka)
- - Gmina Śmigiel
- Gmina Sobienie-Jeziory
- - Gmina Sobolew
- Gmina Sobótka
- Gmina Sokółka
+ - Gmina Sokoły
- Gmina Solina
- Gmina Sośnicowice
- Gmina Sośnie
@@ -792,16 +655,11 @@
- Gmina Stare Miasto
- Gmina Stare Pole
- Gmina Starogard Gdański
- - Gmina Stary Brus
- - Gmina Stary Dzierzgoń
- - Gmina Stary Targ
- Gmina Stawiszyn
- - Gmina Stepnica
- Gmina Stoczek Łukowski
- Gmina Stopnica
- Gmina Strawczyn
- Gmina Stryków
- - Gmina Stryszawa
- Gmina Stryszów
- Gmina Strzałkowo
- Gmina Strzelce Opolskie
@@ -810,43 +668,38 @@
- Gmina Strzyżewice
- Gmina Stupsk
- Gmina Subkowy
- - Gmina Suchań
- Gmina Suchedniów
- Gmina Suchożebry
- Gmina Suchy Las
- Gmina Sulechów
- Gmina Sulęcin
- - Gmina Sulejów
- Gmina Sulików
- Gmina Sulmierzyce
- Gmina Sułów
- Gmina Susiec
- - Gmina Świercze
- - Gmina Świerczów
- - Gmina Świerklany
+ - Gmina Świerklaniec
- Gmina Świerzawa
- Gmina Świeszyno
- Gmina Świlcza
- Gmina Szadek
- Gmina Szaflary
- Gmina Szastarka
- - Gmina Szczawin Kościelny
- Gmina Szczebrzeszyn
- Gmina Szczekociny
- Gmina Szczerców
+ - Gmina Szczutowo
- Gmina Szczytna
- Gmina Szczytniki
- - Gmina Szczytno
+ - Gmina Szemud
- Gmina Szerzyny
- Gmina Szlichtyngowa
- - Gmina Szreńsk
- - Gmina Szudziałowo
- Gmina Szydłów
- Gmina Tarłów
- Gmina Tarnów
- Gmina Tarnowiec
- Gmina Tarnów Opolski
- Gmina Teresin
+ - Gmina Terespol
- Gmina Tereszpol
- Gmina Tłuchowo
- Gmina Tłuszcz
@@ -856,15 +709,12 @@
- Gmina Toszek
- Gmina Trąbki Wielkie
- Gmina Trzebiatów
- - Gmina Trzebielino
- Gmina Trzebinia
+ - Gmina Trzeszczany
- Gmina Trzyciąż
- - Gmina Trzydnik Duży
- Gmina Tuchów
- - Gmina Tułowice
- Gmina Turośń Kościelna
- Gmina Tuszów Narodowy
- - Gmina Tworóg
- Gmina Tyczyn
- Gmina Tymbark
- Gmina Tyrawa Wołoska
@@ -873,21 +723,15 @@
- Gmina Ulan-Majorat
- Gmina Ulanów
- Gmina Ułęż
- - Gmina Ulhówek
- Gmina Urszulin
- Gmina Urzędów
- - Gmina Uście Gorlickie
- Gmina Uścimów
- Gmina Wąchock
- - Gmina Wądroże Wielkie
- Gmina Wągrowiec
- - Gmina Walce
- Gmina Wąpielsk
- Gmina Wasilków
- - Gmina Wąsosz
- Gmina Wąwolnica
- Gmina Wejherowo
- - Gmina Werbkowice
- Gmina Wiązów
- Gmina Wiązowna
- Gmina Wicko
@@ -895,21 +739,16 @@
- Gmina Wielbark
- Gmina Wieleń
- Gmina Wielgie
- - Gmina Wielgomłyny
- Gmina Wieliszew
- Gmina Wielka Nieszawka
- Gmina Wieniawa
- Gmina Wieprz
- Gmina Wieruszów
- - Gmina Wierzbinek
- Gmina Wierzbno
- - Gmina Wierzchlas
- Gmina Wierzchosławice
- Gmina Wietrzychowice
- Gmina Wijewo
- - Gmina Wilczyce
- Gmina Wilczyn
- - Gmina Wilkołaz
- Gmina Wilków
- Gmina Wilkowice
- Gmina Winnica
@@ -920,14 +759,12 @@
- Gmina Witkowo
- Gmina Władysławów
- Gmina Wleń
- - Gmina Włocławek
- Gmina Włodawa
- Gmina Włoszczowa
- Gmina Wodzierady
- Gmina Wodzisław
- Gmina Wojcieszków
- Gmina Wojnicz
- - Gmina Wojsławice
- Gmina Wola Krzysztoporska
- Gmina Wolanów
- Gmina Wolbrom
@@ -938,18 +775,15 @@
- Gmina Wręczyca Wielka
- Gmina Wronki
- Gmina Wyrzysk
- - Gmina Wysokie
+ - Gmina Zabierzów
- Gmina Żabno
- Gmina Żagań
- - Gmina Zagórów
+ - Gmina Zagórz
- Gmina Zaklików
- Gmina Zakroczym
- Gmina Zakrzówek
- - Gmina Zalesie
- Gmina Zaleszany
- - Gmina Załuski
- Gmina Zamość
- - Gmina Żarnów
- Gmina Żarnowiec
- Gmina Żarów
- Gmina Zarszyn
@@ -961,26 +795,20 @@
- Gmina Zbójno
- Gmina Zbrosławice
- Gmina Zduńska Wola
+ - Gmina Zduny
- Gmina Zdzieszowice
- - Gmina Zębowice
- Gmina Zebrzydowice
- - Gmina Żegocina
- Gmina Żelazków
- - Gmina Zembrzyce
- Gmina Zgierz
- Gmina Zgorzelec
- Gmina Ziębice
- Gmina Zielonki
- Gmina Zławieś Wielka
- - Gmina Złota
- - Gmina Złotniki Kujawskie
- Gmina Żmudź
- Gmina Żnin
- Gmina Żółkiewka
- Gmina Żołynia
- Gmina Żukowice
- - Gmina Żurawica
- - Gmina Żyraków
- Gmina Żyrzyn
- Gmina Żytno
- Gniezno
@@ -989,19 +817,19 @@
- Góra
- Góra Kalwaria
- Gorlice
- - Górzno
- Gorzów Śląski
- Gorzów Wielkopolski
- Gostynin
- Grajewo
- Grodzisk Mazowiecki
+ - Gronowo Elbląskie
- Grudziądz
- - Grybów
- Gryfino
- Gryfów Śląski
- Hel
- Hrubieszów
- Inowrocław
+ - Iwanowice
- Izbica Kujawska
- Jabłonowo Pomorskie
- Janowiec Wielkopolski
@@ -1011,6 +839,7 @@
- Jasło
- Jastrzębie-Zdrój
- Jawor
+ - Jaworzno
- Jedlina-Zdrój
- Jelcz-Laskowice
- Jelenia Góra
@@ -1031,9 +860,9 @@
- Kępno
- Kętrzyn
- Kielce
+ - Kiełczygłów
- Kłodawa
- Kłodzko
- - Kluczbork
- Knurów
- Kobyłka
- Koło
@@ -1063,13 +892,11 @@
- Krzeszowice
- Krzyż Wielkopolski
- Książ Wielkopolski
+ - Kudowa-Zdrój
- Kujawsko-Pomorskie
- - Kutno
- Kuźnia Raciborska
- - Kwidzyn
- Łabiszyn
- Lądek-Zdrój
- - Łańcut
- Łapy
- Łask
- Łaskarzew
@@ -1081,10 +908,10 @@
- Legnica
- Leszno
- Lewin Brzeski
- - Lewin Brzeski 2
- Leżajsk
- Limanowa
- Lipno
+ - Lipsko
- Łódź
- Łódzkie
- Łowicz
@@ -1101,8 +928,11 @@
- Lwówek Śląski
- Malbork
- Małopolskie
+ - Marciszów
- Marki
+ - Masłowice
- Mazowieckie
+ - Miastko
- Michałowice
- Miechów
- Międzyrzec Podlaski
@@ -1110,7 +940,6 @@
- Mielec
- Milanówek
- Mińsk Mazowiecki
- - Mniszków
- Mosina
- Mrągowo
- Mrągowski
@@ -1120,17 +949,18 @@
- Mysłowice
- Myszków
- Nakło Nad Notecią
+ - Nasielsk
- Niemodlin
- Niepołomice
- Nisko
- Nowa Dęba
- Nowa Sarzyna
- - Nowa Sól
- Nowe Miasteczko
- Nowe Skalmierzyce
- Nowogard
- Nowogród Bobrzański
- Nowogrodziec
+ - Nowosolna
- Nowy Dwór Mazowiecki
- Nowy Sącz
- Nowy Targ
@@ -1144,8 +974,6 @@
- Opoczno
- Opole
- Opole Lubelskie
- - Opolskie
- - Orzesze
- Osieczna
- Osiecznica
- Ostróda
@@ -1163,16 +991,13 @@
- Piekary Śląskie
- Pieńsk
- Piła
- - Pilzno
- Piotrków Trybunalski
- Pisz
- Płock
- Płońsk
- Pniewy
- - Pobiedziska
- Podkarpackie
- Podkowa Leśna
- - Podlaskie
- Połczyn-Zdrój
- Pomorskie
- Poniec
@@ -1181,7 +1006,7 @@
- Powiat augustowski
- Powiat będziński
- Powiat bełchatowski
- - Powiat białostocki
+ - Powiat białobrzeski
- Powiat bialski
- Powiat bielski
- Powiat bieszczadzki
@@ -1207,7 +1032,6 @@
- Powiat człuchowski
- Powiat dąbrowski
- Powiat dębicki
- - Powiat drawski
- Powiat działdowski
- Powiat dzierżoniowski
- Powiat elbląski
@@ -1222,11 +1046,10 @@
- Powiat goleniowski
- Powiat golubsko-dobrzyński
- Powiat gorlicki
- - Powiat górowski
- Powiat gorzowski
- Powiat gostyński
- - Powiat grajewski
- Powiat grójecki
+ - Powiat grudziądzki
- Powiat gryficki
- Powiat gryfiński
- Powiat hajnowski
@@ -1241,7 +1064,6 @@
- Powiat jędrzejowski
- Powiat jeleniogórski
- Powiat kaliski
- - Powiat kamiennogórski
- Powiat kamieński
- Powiat kartuski
- Powiat kazimierski
@@ -1266,7 +1088,6 @@
- Powiat krośnieński
- Powiat krotoszyński
- Powiat kutnowski
- - Powiat łańcucki
- Powiat łaski
- Powiat lęborski
- Powiat łęczycki
@@ -1281,7 +1102,6 @@
- Powiat lipski
- Powiat łobeski
- Powiat łódzki wschodni
- - Powiat łosicki
- Powiat łowicki
- Powiat lubaczowski
- Powiat lubański
@@ -1302,11 +1122,9 @@
- Powiat myślenicki
- Powiat myszkowski
- Powiat nakielski
- - Powiat namysłowski
- Powiat nidzicki
- Powiat niżański
- Powiat nowodworski
- - Powiat nowomiejski
- Powiat nowosądecki
- Powiat nowosolski
- Powiat nowotarski
@@ -1342,6 +1160,7 @@
- Powiat proszowicki
- Powiat prudnicki
- Powiat pruszkowski
+ - Powiat przasnyski
- Powiat przemyski
- Powiat przeworski
- Powiat przysuski
@@ -1364,7 +1183,6 @@
- Powiat rzeszowski
- Powiat sandomierski
- Powiat sanocki
- - Powiat sejneński
- Powiat sępoleński
- Powiat siedlecki
- Powiat siemiatycki
@@ -1392,7 +1210,6 @@
- Powiat świdnicki
- Powiat świdwiński
- Powiat świebodziński
- - Powiat świecki
- Powiat szamotulski
- Powiat szczycieński
- Powiat sztumski
@@ -1411,7 +1228,6 @@
- Powiat wągrowiecki
- Powiat wałecki
- Powiat warszawski zachodni
- - Powiat węgorzewski
- Powiat węgrowski
- Powiat wejherowski
- Powiat wielicki
@@ -1431,6 +1247,7 @@
- Powiat wyszkowski
- Powiat ząbkowicki
- Powiat żagański
+ - Powiat zambrowski
- Powiat zamojski
- Powiat żarski
- Powiat zawierciański
@@ -1441,33 +1258,34 @@
- Powiat złotoryjski
- Powiat złotowski
- Powiat żniński
+ - Powiat żuromiński
- Powiat żyrardowski
- Powiat żywiecki
- Poznań
+ - Prostki
- Proszowice
- Prudnik
- - Pruszcz Gdański
- Pruszków
- Przasnysz
- Przemyśl
- Przeworsk
- Przysucha
- Pszczyna
+ - Pszów
- Puck
- Puławy
- - Pułtusk
- - Puszczykowo
- Pyskowice
- Rabka-Zdrój
- Raciąż
- Racibórz
+ - Raciechowice
- Radom
- Radomsko
- - Radomyśl Wielki
- Radymno
- Radziejów
- Radzionków
- Radzyń Podlaski
+ - Raków
- Rawa Mazowiecka
- Rawicz
- Reda
@@ -1481,7 +1299,6 @@
- Rymanów
- Rypin
- Rzeszów
- - Rzeszów projekt
- Sandomierz
- Sanok
- Sędziszów Małopolski
@@ -1489,6 +1306,7 @@
- Siedlce
- Siemianowice Śląskie
- Siemiatycze
+ - Sieniawa
- Sieradz
- Skarżysko-Kamienna
- Skawina
@@ -1507,15 +1325,17 @@
- Środa Śląska
- Środa Wielkopolska
- Starachowice
- - Stargard
- Starogard Gdański
- Stary Sącz
- Staszów
- Stronie Śląskie
+ - Strzegom
- Strzyżów
+ - Suchy Las
- Sulejówek
- Sułkowice
- Sulmierzyce
+ - Suwalski
- Swarzędz
- Świdnica
- Świdnik
@@ -1538,10 +1358,8 @@
- Terespol
- Tomaszów Lubelski
- Tomaszów Mazowiecki
- - Tomaszów Mazowiecki projekt
- Toruń
- Trzcianka
- - Trzcińsko-Zdrój
- Trzebnica
- Trzemeszno
- Tuliszków
@@ -1554,7 +1372,7 @@
- Ustrzyki Dolne
- Wadowice
- Wągrowiec
- - Wałcz
+ - Wałbrzych
- Warmińsko-Mazurskie
- Warszawa
- Wąsosz
@@ -1563,7 +1381,7 @@
- Więcbork
- Wieliczka
- Wielkopolskie
- - Wieluń
+ - Wizna
- Władysławowo
- Włocławek
- Włodawa
@@ -1592,7 +1410,6 @@
- Zielona Góra
- Zielonka
- Złotoryja
- - Złotów
- Żory
- Zwoleń
- Żyrardów
@@ -1601,11 +1418,13 @@
- andrychow
- augustow
- baranowsandomierski
+ - bartoszyce
- bedzin
- belchatow
- belzyce
- bialapodlaska
- bialarawska
+ - bialogard
- bialybor
- bialystok
- biecz
@@ -1613,9 +1432,11 @@
- bielskobiala
- bierawa
- bierutow
+ - biskupice
- blachownia
- blaszki
- blonie
+ - bochnia
- bogatynia
- boguchwala
- bogutypianki
@@ -1638,7 +1459,6 @@
- chelmza
- chocianow
- chodziez
- - chojnice
- chojnow
- chorzow
- ciechanow
@@ -1652,9 +1472,7 @@
- dabrowagornicza
- dabrowatarnowska
- debica
- - debno
- dobrzenwielki
- - dobrzenwielki2
- dobrzynnadwisla
- dolnoslaskie
- dusznikizdroj
@@ -1672,9 +1490,6 @@
- glogowmalopolski
- glowno
- glubczyce
- - glubczyce2
- - glucholazy
- - gminaabramow
- gminaadamowka
- gminaaleksandrowkujawski
- gminaaleksandrowlodzki
@@ -1686,17 +1501,14 @@
- gminabadkowo
- gminabaltow
- gminabaranow
+ - gminabarciany
- gminabarcin
- - gminabarczewo
- gminabaruchowo
- - gminabatorz
- gminabedzino
- gminabelchatow
- - gminabesko
- gminabialaczow
- gminabialeblota
- - gminabialopole
- - gminabielsk
+ - gminabielskpodlaski
- gminabircza
- gminablazowa
- gminabledow
@@ -1706,6 +1518,7 @@
- gminabobrowniki
- gminabodzentyn
- gminabogoria
+ - gminabojanow
- gminabojanowo
- gminabojszowy
- gminaboleslawiec
@@ -1714,14 +1527,10 @@
- gminaborow
- gminaborowa
- gminaborzecin
- - gminaborzytuchom
- - gminabralin
- gminabranice
- gminabraniewo
- - gminabranszczyk
- gminabraszewice
- gminabrenna
- - gminabrok
- gminabrzegdolny
- gminabrzeziny
- gminabrzeznio
@@ -1730,14 +1539,13 @@
- gminabrzuze
- gminabrzyska
- gminabuczek
+ - gminabuczkowice
- gminabudzow
- gminabudzyn
- - gminabukowinatatrzanska
- gminabukowsko
- gminabyczyna
- gminabystrasidzina
- - gminaceglow
- - gminacekcyn
+ - gminabyton
- gminacekowkolonia
- gminacelestynow
- gminacewice
@@ -1745,25 +1553,16 @@
- gminachelm
- gminachelmiec
- gminachelmno
- - gminachlopice
- gminachmielnik
- - gminachociwel
- gminachocz
- gminachodel
- - gminachodow
- gminachojnice
- gminachojnow
- - gminachotcza
- - gminachrzastowice
- gminachrzypskowielkie
- gminachybie
- gminaciasna
- - gminaciechanow
- gminaciechocin
- - gminacieladz
- - gminacieszanow
- gminaciezkowice
- - gminacisek
- gminacisna
- gminacmolas
- gminacycow
@@ -1771,26 +1570,19 @@
- gminaczarna
- gminaczarnkow
- gminaczarnydunajec
- - gminaczastary
- gminaczechowicedziedzice
- gminaczernichow
- gminaczerniejewo
- - gminaczerniewice
- - gminaczernikowo
- gminaczerwionkaleszczyny
- - gminaczerwonak
+ - gminaczerwonka
- gminaczluchow
- gminaczosnow
- - gminadabrowazielona
- - gminadabrowice
- gminadamaslawek
- gminadamnica
- gminadarlowo
- gminadebewielkie
- gminadebica
- gminadebno
- - gminadebowakloda
- - gminadebrzno
- gminadlutow
- gminadobczyce
- gminadobra
@@ -1798,31 +1590,19 @@
- gminadobrodzien
- gminadobron
- gminadobrzany
- - gminadobrzyca
- gminadobrzyniewoduze
- - gminadolsk
- gminadominowo
- gminadorohusk
- - gminadoruchow
- - gminadragacz
- - gminadrawsko
- - gminadruzbice
- gminadrzewica
- gminadubiecko
- - gminadubienka
- gminadukla
- gminadwikozy
- - gminadydnia
- gminadynow
- gminadziadowakloda
- gminadzialoszyce
- - gminadziemiany
- gminadzierzoniow
- - gminadzwola
- gminaelblag
- - gminaelk
- - gminafredropol
- - gminagarbatkaletnisko
+ - gminafajslawice
- gminagarbow
- gminagarwolin
- gminagasawa
@@ -1832,37 +1612,29 @@
- gminagdow
- gminagielniow
- gminagieraltowice
+ - gminaglinojeck
- gminaglogow
- - gminaglogowek
- gminagluchow
- - gminaglusk
- gminagluszyca
- gminagniew
- - gminagniewino
- gminagniewoszow
- gminagniezno
- gminagoczalkowicezdroj
- gminagodkowo
- gminagodow
- gminagodzieszewielkie
- - gminagodziszow
- gminagolancz
- - gminagolcza
- gminagoleszow
- gminagolina
- gminagolubdobrzyn
- - gminagoluchow
- - gminagomunice
- gminagoraj
- gminagorlice
- gminagorno
- - gminagorzyca
- gminagoscieradow
- gminagostyn
- gminagostynin
- gminagoszczyn
- gminagozd
- - gminagrabica
- gminagrabow
- gminagrabowiec
- gminagrabownadpilica
@@ -1881,52 +1653,45 @@
- gminagrudziadz
- gminagruta
- gminagrybow
- - gminagryfice
- - gminagrzmiaca
- gminahaczow
- gminahalinow
- gminahansk
- gminaharasiuki
- gminahazlach
- gminaherby
- - gminahorodlo
- gminahrubieszow
- gminahuszlew
- gminahyzne
- gminaimielno
- gminainowroclaw
- - gminairzadze
- gminaistebna
- - gminaiwanowice
- gminaiwierzyce
- gminaiwoniczzdroj
- gminaizabelin
- gminaizbica
- - gminaizbicko
- - gminajablon
+ - gminajadow
- gminajaktorow
- - gminajakubow
- gminajanikowo
- - gminajanow
- gminajanowiec
- gminajanowpodlaski
- - gminajarczow
+ - gminajaraczewo
- gminajarocin
- gminajasienicarosielna
- - gminajasliska
- gminajaslo
- gminajastkow
- gminajastrowie
- gminajastrzab
- gminajedlicze
+ - gminajedlinsk
+ - gminajedlnialetnisko
- gminajejkowice
- gminajemielnica
+ - gminajemielno
- gminajerzmanowa
- gminajezewo
- gminajeziorawielkie
- gminajeziorzany
- gminajezowe
- - gminajoniec
- gminajordanow
- gminajozefow
- gminajozefownadwisla
@@ -1934,18 +1699,14 @@
- gminakakolewnica
- gminakamien
- gminakamienica
- - gminakamiennik
+ - gminakamieniec
- gminakamionka
- gminakarczmiska
- gminakargowa
- - gminakarlino
- - gminakarniewo
- gminakaweczyn
- gminakazimierzbiskupi
- gminakepice
- - gminakesowo
- gminakielczyglow
- - gminakietrz
- gminakikol
- gminakiszkowo
- gminakleczew
@@ -1960,30 +1721,22 @@
- gminaklucze
- gminakluczewsko
- gminakobielewielkie
- - gminakobylanka
- gminakochanowice
- gminakock
- gminakodrab
- gminakolaczyce
- gminakolbaskowo
- - gminakolbiel
- gminakolczyglowy
- - gminakolobrzeg
- gminakoluszki
- gminakomancza
- - gminakomarowkapodlaska
- gminakomorniki
- gminakomprachcice
- gminakonarzyny
- gminakondratowice
- - gminakoneck
- gminakoniusza
- gminakonopiska
- gminakonskowola
- - gminakonstantynow
- gminakoprzywnica
- - gminakorfantow
- - gminakornik
- gminakorsze
- gminakorycin
- gminakorzenna
@@ -1993,14 +1746,10 @@
- gminakoscierzyna
- gminakosowlacki
- gminakostrzyn
- - gminakoszecin
+ - gminakoszyce
- gminakotla
- gminakotun
- - gminakowiesy
- - gminakozieglowy
- gminakozlow
- - gminakramsk
- - gminakrasniczyn
- gminakrasnik
- gminakrasnobrod
- gminakrasnystaw
@@ -2010,16 +1759,12 @@
- gminakrosnice
- gminakrupskimlyn
- gminakruszwica
- - gminakrynice
- gminakrynki
- gminakrzanowice
- gminakrzemieniewo
- - gminakrzeszow
- gminakrzymow
- - gminakrzywcza
- gminakrzywin
- gminakrzyzanowice
- - gminaksawerow
- gminaksiazwielki
- gminakunice
- gminakunow
@@ -2029,19 +1774,15 @@
- gminakwilcz
- gminalabowa
- gminalabunie
- - gminalaczna
- - gminaladek
- gminalambinowice
- gminalanckorona
- - gminalancut
- - gminalapanow
- gminalapszenizne
- gminalasin
- gminalaskarzew
- gminalasowicewielkie
- gminalaszczow
+ - gminalaszki
- gminalatowicz
- - gminalaziska
- gminalazy
- gminaleczyca
- gminaleczyce
@@ -2051,14 +1792,11 @@
- gminalelow
- gminalesna
- gminalesnapodlaska
- - gminalesniowice
- gminalesznowola
- gminalezajsk
- gminalichnowy
- gminalimanowa
- gminalinia
- - gminaliniewo
- - gminalipiany
- gminalipinki
- gminalipnik
- gminalipowa
@@ -2066,51 +1804,43 @@
- gminaliszki
- gminaliw
- gminalobez
- - gminalochow
- gminalodygowice
- gminalomazy
- - gminalomianki
- - gminaloniow
- gminalopiennikgorny
- gminalopuszno
- - gminalosice
- gminaluban
- gminalubartow
- gminalubasz
- - gminalubawka
- gminalubenia
- gminalubianka
- gminalubicz
- - gminalubien
- gminalubiewo
- gminalubin
- gminalubniany
- gminalubochnia
+ - gminalubomia
- gminalubon
- - gminalubsza
- - gminalubyczakrolewska
- gminalukow
- gminalukowica
- gminalutowiska
- - gminalututow
- gminaluzino
- gminaluzna
- gminalysomice
- - gminamaciejowice
- gminamagnuszew
- - gminamajdankrolewski
- gminamakowpodhalanski
+ - gminamalawies
- gminamalbork
- gminamaldyty
- gminamalkiniagorna
- gminamarcinowice
- gminamargonin
- gminamarianowo
- - gminamarkuszow
- - gminamecinka
+ - gminamarkusy
+ - gminamaslow
- gminamedyka
- gminamelgiew
- gminamichalow
+ - gminamichalowo
- gminamiedzianagora
- gminamiedzna
- gminamiedzno
@@ -2119,10 +1849,7 @@
- gminamiedzyrzecpodlaski
- gminamiedzyzdroje
- gminamiejscepiastowe
- - gminamiekinia
- gminamielec
- - gminamielno
- - gminamieszkowice
- gminamilanow
- gminamilejow
- gminamilicz
@@ -2131,26 +1858,21 @@
- gminamiloslaw
- gminamilowka
- gminaminskmazowiecki
- - gminamirow
- gminamirsk
- gminamlynary
- - gminamodliborzyce
- gminamogielnica
- gminamogilany
- - gminamogilno
- - gminamorawica
- gminamordy
- gminamoryn
- gminamrocza
- gminamrozy
- - gminamsciwojow
- - gminamstow
- gminamszana
- gminamszanadolna
- gminamurow
- gminamycielin
- - gminamykanow
+ - gminamyslakowice
- gminamysliborz
+ - gminanadarzyn
- gminanamyslow
- gminanasielsk
- gminanawojowa
@@ -2161,25 +1883,23 @@
- gminaniedrzwicaduza
- gminaniedzwiada
- gminaniedzwiedz
- - gminanowakarczma
+ - gminaniegoslawice
+ - gminaniwiska
- gminanowaruda
- gminanowawiesleborska
- - gminanowe
- gminanowemiasto
- gminanowemiastonadwarta
- - gminanowogrod
+ - gminanowogrodbobrzanski
- gminanowosolna
- gminanowykaweczyn
- - gminanowykorczyn
- gminanowystaw
- gminanowytarg
- gminanowytomysl
- - gminanozdrzec
- gminanur
- gminaobrazow
- gminaochotnicadolna
- gminaogrodzieniec
- - gminaolszanica
+ - gminaolecko
- gminaolsztynek
- gminaolszyna
- gminaopatowiec
@@ -2189,15 +1909,11 @@
- gminaosiekjasielski
- gminaosiekmaly
- gminaosielsko
- - gminaosina
- - gminaosjakow
- - gminaostrorog
- gminaostrow
- gminaostrowek
- gminaostrowlubelski
- gminaostrowmazowiecka
- gminaostrowwielkopolski
- - gminaotmuchow
- gminaotyn
- gminaozarow
- gminaozarowice
@@ -2205,32 +1921,27 @@
- gminaozorkow
- gminapabianice
- gminapacanow
- - gminapacyna
- gminapaczkow
- gminapadewnarodowa
+ - gminapajeczno
- gminapakoslaw
- gminapakoslawice
- gminapalecznica
- gminapanki
- gminaparchowo
- gminaparczew
- - gminapaslek
- - gminapatnow
+ - gminapawlosiow
- gminapawlowice
- gminapawlowiczki
- - gminapawonkow
- gminapeclaw
- gminapelplin
- - gminapepowo
- gminapiaski
- gminapiatnica
+ - gminapiecki
- gminapiekoszow
- - gminapieniezno
- gminapilchowice
- - gminapinczow
- gminapionki
- - gminaplaska
- - gminaplaterowka
+ - gminapiotrkowtrybunalski
- gminaplesna
- gminapleszew
- gminaplonsk
@@ -2238,7 +1949,6 @@
- gminapoczesna
- gminapodedworze
- gminapodegrodzie
- - gminapodgorzyn
- gminapokoj
- gminapolajewo
- gminapolaniec
@@ -2247,18 +1957,16 @@
- gminapolice
- gminapolkowice
- gminapomiechowek
- - gminaponiatowa
- gminapopielow
- gminapopow
+ - gminaporaj
- gminapotegowo
- - gminapotokwielki
- gminapraszka
+ - gminaprazmow
- gminaprochowice
- gminapromna
- gminaproszkow
- - gminaprusice
- gminapruszczgdanski
- - gminaprzechlewo
- gminaprzeclaw
- gminaprzedecz
- gminaprzemet
@@ -2268,9 +1976,7 @@
- gminaprzodkowo
- gminaprzykona
- gminaprzylek
- - gminaprzyrow
- gminaprzystajn
- - gminaprzytoczna
- gminapuchaczow
- gminapuck
- gminapulawy
@@ -2278,10 +1984,10 @@
- gminapuszczamarianska
- gminapysznica
- gminapyzdry
- - gminarabawyzna
- gminarachanie
- gminaraciechowice
- - gminaradgoszcz
+ - gminaraclawice
+ - gminaradecznica
- gminaradkow
- gminaradlow
- gminaradomin
@@ -2289,29 +1995,16 @@
- gminaradomyslnadsanem
- gminaradoszyce
- gminaradwanice
- - gminaradymno
- - gminaradziejow
- gminaradzilow
- - gminarajgrod
- - gminarakow
- - gminarakszawa
- gminarawamazowiecka
- - gminaregnow
- gminarenskawies
- - gminarogozno
- - gminarokitno
- - gminaropa
- gminarossosz
- gminarozprza
- gminarucianenida
- gminarudahuta
- gminarudna
- gminarudniki
- - gminarudniknadsanem
- - gminarudziniec
- gminarusiec
- - gminarusinow
- - gminarybczewice
- gminarychliki
- gminarychtal
- gminaryczywol
@@ -2319,39 +2012,32 @@
- gminarypin
- gminarytro
- gminarytwiany
+ - gminarzasnia
- gminarzeczyca
- gminarzepiennikstrzyzewski
- gminarzepin
- - gminarzezawa
- gminarzgow
- gminasadki
- gminasadowne
- gminasamborzec
- gminasanok
- - gminasawin
- gminascinawa
- gminasedziejowice
- - gminasejny
- - gminasekowa
- gminasepopol
- gminaserokomla
- gminasianow
- gminasicienko
- gminasieciechow
- gminasiedlce
- - gminasiedliszcze
- gminasiemiatycze
- - gminasiemien
- gminasiemysl
- gminasiennica
- gminasiennicarozana
- gminasienno
- gminasiepraw
- gminasieradz
- - gminasierakow
- gminasierakowice
- gminasiewierz
- - gminasitkowkanowiny
- gminasitno
- gminaskarzyskokoscielne
- gminaskepe
@@ -2359,22 +2045,16 @@
- gminaskoczow
- gminaskoki
- gminaskolyszyn
- - gminaskrwilno
- gminaskrzyszow
- gminaskulsk
- - gminaskwierzyna
- gminaslawa
- - gminasliwice
- gminaslopnice
- - gminaslubice
- gminaslupca
- gminaslupia
- - gminaslupiakonecka
- - gminasmigiel
- gminasobieniejeziory
- - gminasobolew
- gminasobotka
- gminasokolka
+ - gminasokoly
- gminasolina
- gminasosnicowice
- gminasosnie
@@ -2389,16 +2069,11 @@
- gminastaremiasto
- gminastarepole
- gminastarogardgdanski
- - gminastarybrus
- - gminastarydzierzgon
- - gminastarytarg
- gminastawiszyn
- - gminastepnica
- gminastoczeklukowski
- gminastopnica
- gminastrawczyn
- gminastrykow
- - gminastryszawa
- gminastryszow
- gminastrzalkowo
- gminastrzelceopolskie
@@ -2407,43 +2082,38 @@
- gminastrzyzewice
- gminastupsk
- gminasubkowy
- - gminasuchan
- gminasuchedniow
- gminasuchozebry
- gminasuchylas
- gminasulechow
- gminasulecin
- - gminasulejow
- gminasulikow
- gminasulmierzyce
- gminasulow
- gminasusiec
- - gminaswiercze
- - gminaswierczow
- - gminaswierklany
+ - gminaswierklaniec
- gminaswierzawa
- gminaswieszyno
- gminaswilcza
- gminaszadek
- gminaszaflary
- gminaszastarka
- - gminaszczawinkoscielny
- gminaszczebrzeszyn
- gminaszczekociny
- gminaszczercow
+ - gminaszczutowo
- gminaszczytna
- gminaszczytniki
- - gminaszczytno
+ - gminaszemud
- gminaszerzyny
- gminaszlichtyngowa
- - gminaszrensk
- - gminaszudzialowo
- gminaszydlow
- gminatarlow
- gminatarnow
- gminatarnowiec
- gminatarnowopolski
- gminateresin
+ - gminaterespol
- gminatereszpol
- gminatluchowo
- gminatluszcz
@@ -2453,15 +2123,12 @@
- gminatoszek
- gminatrabkiwielkie
- gminatrzebiatow
- - gminatrzebielino
- gminatrzebinia
+ - gminatrzeszczany
- gminatrzyciaz
- - gminatrzydnikduzy
- gminatuchow
- - gminatulowice
- gminaturosnkoscielna
- gminatuszownarodowy
- - gminatworog
- gminatyczyn
- gminatymbark
- gminatyrawawoloska
@@ -2470,21 +2137,15 @@
- gminaulanmajorat
- gminaulanow
- gminaulez
- - gminaulhowek
- gminaurszulin
- gminaurzedow
- - gminausciegorlickie
- gminauscimow
- gminawachock
- - gminawadrozewielkie
- gminawagrowiec
- - gminawalce
- gminawapielsk
- gminawasilkow
- - gminawasosz
- gminawawolnica
- gminawejherowo
- - gminawerbkowice
- gminawiazow
- gminawiazowna
- gminawicko
@@ -2492,21 +2153,16 @@
- gminawielbark
- gminawielen
- gminawielgie
- - gminawielgomlyny
- gminawieliszew
- gminawielkanieszawka
- gminawieniawa
- gminawieprz
- gminawieruszow
- - gminawierzbinek
- gminawierzbno
- - gminawierzchlas
- gminawierzchoslawice
- gminawietrzychowice
- gminawijewo
- - gminawilczyce
- gminawilczyn
- - gminawilkolaz
- gminawilkow
- gminawilkowice
- gminawinnica
@@ -2517,14 +2173,12 @@
- gminawitkowo
- gminawladyslawow
- gminawlen
- - gminawloclawek
- gminawlodawa
- gminawloszczowa
- gminawodzierady
- gminawodzislaw
- gminawojcieszkow
- gminawojnicz
- - gminawojslawice
- gminawolakrzysztoporska
- gminawolanow
- gminawolbrom
@@ -2535,18 +2189,15 @@
- gminawreczycawielka
- gminawronki
- gminawyrzysk
- - gminawysokie
+ - gminazabierzow
- gminazabno
- gminazagan
- - gminazagorow
+ - gminazagorz
- gminazaklikow
- gminazakroczym
- gminazakrzowek
- - gminazalesie
- gminazaleszany
- - gminazaluski
- gminazamosc
- - gminazarnow
- gminazarnowiec
- gminazarow
- gminazarszyn
@@ -2558,26 +2209,20 @@
- gminazbojno
- gminazbroslawice
- gminazdunskawola
+ - gminazduny
- gminazdzieszowice
- - gminazebowice
- gminazebrzydowice
- - gminazegocina
- gminazelazkow
- - gminazembrzyce
- gminazgierz
- gminazgorzelec
- gminaziebice
- gminazielonki
- gminazlawieswielka
- - gminazlota
- - gminazlotnikikujawskie
- gminazmudz
- gminaznin
- gminazolkiewka
- gminazolynia
- gminazukowice
- - gminazurawica
- - gminazyrakow
- gminazyrzyn
- gminazytno
- gniezno
@@ -2586,19 +2231,19 @@
- gora
- gorakalwaria
- gorlice
- - gorzno
- gorzowslaski
- gorzowwielkopolski
- gostynin
- grajewo
- grodziskmazowiecki
+ - gronowoelblaskie
- grudziadz
- - grybow
- gryfino
- gryfowslaski
- hel
- hrubieszow
- inowroclaw
+ - iwanowice
- izbicakujawska
- jablonowopomorskie
- janowiecwielkopolski
@@ -2608,6 +2253,7 @@
- jaslo
- jastrzebiezdroj
- jawor
+ - jaworzno
- jedlinazdroj
- jelczlaskowice
- jeleniagora
@@ -2628,9 +2274,9 @@
- kepno
- ketrzyn
- kielce
+ - kielczyglow
- klodawa
- klodzko
- - kluczbork
- knurow
- kobylka
- kolo
@@ -2660,13 +2306,11 @@
- krzeszowice
- krzyzwielkopolski
- ksiazwielkopolski
+ - kudowazdroj
- kujawskopomorskie
- - kutno
- kuzniaraciborska
- - kwidzyn
- labiszyn
- ladekzdroj
- - lancut
- lapy
- lask
- laskarzew
@@ -2678,10 +2322,10 @@
- legnica
- leszno
- lewinbrzeski
- - lewinbrzeski2
- lezajsk
- limanowa
- lipno
+ - lipsko
- lodz
- lodzkie
- lowicz
@@ -2698,8 +2342,11 @@
- lwowekslaski
- malbork
- malopolskie
+ - marciszow
- marki
+ - maslowice
- mazowieckie
+ - miastko
- michalowice
- miechow
- miedzyrzecpodlaski
@@ -2707,7 +2354,6 @@
- mielec
- milanowek
- minskmazowiecki
- - mniszkow
- mosina
- mragowo
- mragowski
@@ -2717,17 +2363,18 @@
- myslowice
- myszkow
- naklonadnotecia
+ - nasielsk
- niemodlin
- niepolomice
- nisko
- nowadeba
- nowasarzyna
- - nowasol
- nowemiasteczko
- noweskalmierzyce
- nowogard
- nowogrodbobrzanski
- nowogrodziec
+ - nowosolna
- nowydwormazowiecki
- nowysacz
- nowytarg
@@ -2741,8 +2388,6 @@
- opoczno
- opole
- opolelubelskie
- - opolskie
- - orzesze
- osieczna
- osiecznica
- ostroda
@@ -2760,16 +2405,13 @@
- piekaryslaskie
- piensk
- pila
- - pilzno
- piotrkowtrybunalski
- pisz
- plock
- plonsk
- pniewy
- - pobiedziska
- podkarpackie
- podkowalesna
- - podlaskie
- polczynzdroj
- pomorskie
- poniec
@@ -2778,7 +2420,7 @@
- powiataugustowski
- powiatbedzinski
- powiatbelchatowski
- - powiatbialostocki
+ - powiatbialobrzeski
- powiatbialski
- powiatbielski
- powiatbieszczadzki
@@ -2804,7 +2446,6 @@
- powiatczluchowski
- powiatdabrowski
- powiatdebicki
- - powiatdrawski
- powiatdzialdowski
- powiatdzierzoniowski
- powiatelblaski
@@ -2819,11 +2460,10 @@
- powiatgoleniowski
- powiatgolubskodobrzynski
- powiatgorlicki
- - powiatgorowski
- powiatgorzowski
- powiatgostynski
- - powiatgrajewski
- powiatgrojecki
+ - powiatgrudziadzki
- powiatgryficki
- powiatgryfinski
- powiathajnowski
@@ -2838,7 +2478,6 @@
- powiatjedrzejowski
- powiatjeleniogorski
- powiatkaliski
- - powiatkamiennogorski
- powiatkamienski
- powiatkartuski
- powiatkazimierski
@@ -2863,7 +2502,6 @@
- powiatkrosnienski
- powiatkrotoszynski
- powiatkutnowski
- - powiatlancucki
- powiatlaski
- powiatleborski
- powiatleczycki
@@ -2878,7 +2516,6 @@
- powiatlipski
- powiatlobeski
- powiatlodzkiwschodni
- - powiatlosicki
- powiatlowicki
- powiatlubaczowski
- powiatlubanski
@@ -2899,11 +2536,9 @@
- powiatmyslenicki
- powiatmyszkowski
- powiatnakielski
- - powiatnamyslowski
- powiatnidzicki
- powiatnizanski
- powiatnowodworski
- - powiatnowomiejski
- powiatnowosadecki
- powiatnowosolski
- powiatnowotarski
@@ -2939,6 +2574,7 @@
- powiatproszowicki
- powiatprudnicki
- powiatpruszkowski
+ - powiatprzasnyski
- powiatprzemyski
- powiatprzeworski
- powiatprzysuski
@@ -2961,7 +2597,6 @@
- powiatrzeszowski
- powiatsandomierski
- powiatsanocki
- - powiatsejnenski
- powiatsepolenski
- powiatsiedlecki
- powiatsiemiatycki
@@ -2989,7 +2624,6 @@
- powiatswidnicki
- powiatswidwinski
- powiatswiebodzinski
- - powiatswiecki
- powiatszamotulski
- powiatszczycienski
- powiatsztumski
@@ -3008,7 +2642,6 @@
- powiatwagrowiecki
- powiatwalecki
- powiatwarszawskizachodni
- - powiatwegorzewski
- powiatwegrowski
- powiatwejherowski
- powiatwielicki
@@ -3028,6 +2661,7 @@
- powiatwyszkowski
- powiatzabkowicki
- powiatzaganski
+ - powiatzambrowski
- powiatzamojski
- powiatzarski
- powiatzawiercianski
@@ -3038,33 +2672,34 @@
- powiatzlotoryjski
- powiatzlotowski
- powiatzninski
+ - powiatzurominski
- powiatzyrardowski
- powiatzywiecki
- poznan
+ - prostki
- proszowice
- prudnik
- - pruszczgdanski
- pruszkow
- przasnysz
- przemysl
- przeworsk
- przysucha
- pszczyna
+ - pszow
- puck
- pulawy
- - pultusk
- - puszczykowo
- pyskowice
- rabkazdroj
- raciaz
- raciborz
+ - raciechowice
- radom
- radomsko
- - radomyslwielki
- radymno
- radziejow
- radzionkow
- radzynpodlaski
+ - rakow
- rawamazowiecka
- rawicz
- reda
@@ -3078,7 +2713,6 @@
- rymanow
- rypin
- rzeszow
- - rzeszowprojekt
- sandomierz
- sanok
- sedziszowmalopolski
@@ -3086,6 +2720,7 @@
- siedlce
- siemianowiceslaskie
- siemiatycze
+ - sieniawa
- sieradz
- skarzyskokamienna
- skawina
@@ -3104,15 +2739,17 @@
- srodaslaska
- srodawielkopolska
- starachowice
- - stargard
- starogardgdanski
- starysacz
- staszow
- stronieslaskie
+ - strzegom
- strzyzow
+ - suchylas
- sulejowek
- sulkowice
- sulmierzyce
+ - suwalski
- swarzedz
- swidnica
- swidnik
@@ -3135,10 +2772,8 @@
- terespol
- tomaszowlubelski
- tomaszowmazowiecki
- - tomaszowmazowieckiprojekt
- torun
- trzcianka
- - trzcinskozdroj
- trzebnica
- trzemeszno
- tuliszkow
@@ -3151,7 +2786,7 @@
- ustrzykidolne
- wadowice
- wagrowiec
- - walcz
+ - walbrzych
- warminskomazurskie
- warszawa
- wasosz
@@ -3160,7 +2795,7 @@
- wiecbork
- wieliczka
- wielkopolskie
- - wielun
+ - wizna
- wladyslawowo
- wloclawek
- wlodawa
@@ -3189,7 +2824,6 @@
- zielonagora
- zielonka
- zlotoryja
- - zlotow
- zory
- zwolen
- zyrardow
diff --git a/app/src/main/res/values/preferences_keys.xml b/app/src/main/res/values/preferences_keys.xml
index 80a71bc71..f29080b33 100644
--- a/app/src/main/res/values/preferences_keys.xml
+++ b/app/src/main/res/values/preferences_keys.xml
@@ -31,7 +31,8 @@
homework_fullscreen
subjects_without_grades
optional_arithmetic_average
- message_draft
+ message_send_is_draft
+ message_send_recipients
last_sync_date
notifications_piggyback
notifications_piggyback_cancel_original
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 38997054f..e4542547d 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -26,11 +26,15 @@
Student info
Dashboard
Notifications center
+
+
Semester %1$d, %2$d/%3$d
+
+
Sign in with the student or parent account
- Enter the symbol from the register page for account: <b>%1$s</b>
+ Enter the symbol from the register page for account: <b>%1$s</b>
Username
Email
Login, PESEL or e-mail
@@ -55,7 +59,7 @@
Invalid symbol
Student not found. Validate the symbol and the chosen variation of the UONET+ register
Selected student is already logged in
- The symbol can be found on the register page in Uczeń → Dostęp Mobilny → Wygeneruj kod dostępu.\n\nMake sure that you have set the appropriate register variant in the UONET+ register variant field on the first login screen
+ The symbol can be found on the register page in Uczeń → Dostęp Mobilny → Zarejestruj urządzenie mobilne.\n\nMake sure that you have set the appropriate register variant in the UONET+ register variant field on the previous screen
Select students to log in to the application
Other options
In this mode, a lucky number does not work, a class grade stats, summary of attendance, excuse for absence, completed lessons, school information and preview of the list of registered devices
@@ -67,21 +71,15 @@
Discord
Send email
Zgłoszenie: Problemy z logowaniem
- Informacje o aplikacji:\n\nUrządzenie: %1$s\nWersja SDK: %2$s\nWersja aplikacji: %3$s\nDodatkowe informacje: %4$s\nIdentyfikator instalacji: %5$s\nOstatni błąd: %6$s\n\nNazwa szkoły i miejscowość:
+ Informacje o aplikacji:\n\nUrządzenie: %1$s\nWersja SDK: %2$s\nWersja aplikacji: %3$s\nDodatkowe informacje: %4$s\nOstatni błąd: %5$s\n\nNazwa szkoły i miejscowość:
Make sure you select the correct UONET+ register variation!
I forgot my password
Recover your account
Recover
Student is already signed in
Standard
- Other search locations
- No active students found
- Enter a different symbol
-
- Enable notifications
- Enable notifications so you don\'t miss message from teacher or new grade
- Skip
- Enable
+
+
Account manager
Log in
@@ -90,6 +88,8 @@
Application support
Do you like this app? Support its development by enabling non-invasive ads that you can disable at any time
Enable ads
+
+
Grade
Semester %d
@@ -152,6 +152,8 @@
- You received %1$d final grade
- You received %1$d final grades
+
+
Lesson
Room
@@ -187,6 +189,8 @@
- %d change
- %d changes
+
+
Completed lessons
Show completed lessons
@@ -194,6 +198,8 @@
Topic
Absence
Resources
+
+
Additional lessons
Show additional lessons
@@ -209,6 +215,8 @@
Start time
End time
End time must be greater than start time
+
+
Attendance summary
Absent for school reasons
@@ -241,8 +249,12 @@
- %d attendance
- %d attendance
+
+
Total
+
+
No exams this week
Type
@@ -259,6 +271,8 @@
- %d exam
- %d exams
+
+
Inbox
Sent
@@ -287,11 +301,9 @@
Message does not exist
You need to choose at least 1 recipient
The message content must be at least 3 characters
- All mailboxes
Only unread
Only with attachments
Read: %s
- Read by: %1$d of %2$d people
- %1$d message
- %1$d messages
@@ -311,7 +323,8 @@
- %1$d selected
Messages deleted
- Choose mailbox
+
+
No info about notes
Points
@@ -327,6 +340,7 @@
- You received %1$d note
- You received %1$d notes
+
- %d praise
@@ -340,6 +354,7 @@
- You received %1$d praise
- You received %1$d praises
+
- %d neutral note
@@ -353,6 +368,8 @@
- You received %1$d neutral note
- You received %1$d neutral notes
+
+
No info about homework
Mark as done
@@ -373,6 +390,8 @@
- %d homework
- %d homework
+
+
Lucky number
Today\'s lucky number is
@@ -380,9 +399,13 @@
Lucky number for today
Today\'s lucky number is: %s
Show history
+
+
Lucky number history
No info about lucky numbers
+
+
Mobile devices
No devices
@@ -392,8 +415,12 @@
Token
Symbol
PIN
+
+
School and teachers
+
+
School
No info about school
@@ -404,10 +431,14 @@
Name of pedagogue
Show on map
Call
+
+
Teachers
No info about teachers
No subject
+
+
Conferences
No info about conferences
@@ -425,8 +456,7 @@
Present at conference
Agenda
- Place
- Topic
+
School announcements
No school announcements
@@ -442,6 +472,8 @@
- You have %1$d new school announcement
- You have %1$d new school announcements
+
+
Add account
Logout
@@ -456,6 +488,8 @@
Contact
Residence details
Personal information
+
+
App version
Contributors
@@ -478,12 +512,18 @@
Visit the website and help develop the application
Licenses
Licenses of libraries used in the application
- Informacje o aplikacji:\n\nUrządzenie: %1$s\nWersja SDK: %2$s\nWersja aplikacji: %3$s\nIdentyfikator instalacji: %4$s\nTreść zgłoszenia:
+ Informacje o aplikacji:\n\nUrządzenie: %1$s\nWersja SDK: %2$s\nWersja aplikacji: %3$s\n\nTreść zgłoszenia:
+
+
License
+
+
Avatar
See more on GitHub
+
+
No info about student or student family
Name
@@ -506,13 +546,19 @@
Female
Last name
Guardian
+
+
Nick
Add nick
Choose avatar color
+
+
Share logs
Refresh
+
+
Lessons
(Tomorrow)
@@ -531,6 +577,7 @@
until %1$s
No upcoming lessons
An error occurred while loading the lessons
+
Homework
No homework to do
An error occurred while loading the homework
@@ -539,9 +586,11 @@
- %1$d more homework
due %1$s
+
Last grades
No new grades
An error occurred while loading the grades
+
School announcements
No current announcements
An error occurred while loading the announcements
@@ -549,6 +598,7 @@
- %1$d more announcement
- %1$d more announcements
+
Exams
No upcoming exams
An error occurred while loading the exams
@@ -556,6 +606,7 @@
- %1$d more exam
- %1$d more exams
+
Conferences
No upcoming conferences
An error occurred while loading the conferences
@@ -563,11 +614,16 @@
- %1$d more conference
- %1$d more conferences
+
An error occurred while loading data
None
+
+
Check for updates
Before reporting a bug, check first if an update with the bug fix is available
+
+
Content
Retry
@@ -595,12 +651,16 @@
Undo
Change
Add to calendar
+
+
No lessons
Choose theme
Light
Dark
System Theme
+
+
App
Default view
@@ -616,6 +676,7 @@
Grades color scheme
Subjects sorting
Language
+
Notifications
Other
Show notifications
@@ -635,6 +696,7 @@
Upcoming lesson notifications
You must allow the Wulkanowy app to set alarms and reminders in your system settings to use this feature.
Go to settings
+
Synchronization
Automatic update
Suspended on holidays
@@ -645,10 +707,12 @@
Sync failed
Sync in progress
Last full sync: %s
+
Value of the plus
Value of the minus
Reply with message history
Show arithmetic average when no weights provided
+
Support
Privacy Policy
Agreements
@@ -668,11 +732,13 @@
I am over 18 years old
Yes, personalized ads
Yes, non-personalized ads
+
Advanced
Appearance & Behavior
Notifications
Synchronization
Advertisements
+
Grades
Dashboard
Tiles visibility
@@ -681,6 +747,7 @@
Grades
Calculated average
Messages
+
Appearance & Behavior
Languages, themes, subjects sorting
App notifications, fix problems
@@ -691,6 +758,8 @@
Advanced
App version, contributors, social portals
Displaying advertisements, project support
+
+
New grades
New homework
@@ -705,6 +774,8 @@
Debug
Timetable change
New attendance
+
+
Black
Red
@@ -712,11 +783,15 @@
Green
Purple
No color
+
+
Download of updates has started…
An update has just been downloaded.
Restart
Update failed! Wulkanowy may not function properly. Consider updating
+
+
No internet connection
An error occurred. Check your device clock
diff --git a/app/src/main/res/xml/data_extraction_rules.xml b/app/src/main/res/xml/data_extraction_rules.xml
deleted file mode 100644
index 418b6d4c4..000000000
--- a/app/src/main/res/xml/data_extraction_rules.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/main/res/xml/network_security_config.xml b/app/src/main/res/xml/network_security_config.xml
index 17fac4d1e..84ff05a04 100644
--- a/app/src/main/res/xml/network_security_config.xml
+++ b/app/src/main/res/xml/network_security_config.xml
@@ -1,5 +1,6 @@
+
diff --git a/app/src/play/java/io/github/wulkanowy/ui/modules/settings/ads/AdsPresenter.kt b/app/src/play/java/io/github/wulkanowy/ui/modules/settings/ads/AdsPresenter.kt
index 28c98e3c3..772d616d7 100644
--- a/app/src/play/java/io/github/wulkanowy/ui/modules/settings/ads/AdsPresenter.kt
+++ b/app/src/play/java/io/github/wulkanowy/ui/modules/settings/ads/AdsPresenter.kt
@@ -31,22 +31,13 @@ class AdsPresenter @Inject constructor(
view?.showLoadingSupportAd(true)
presenterScope.launch {
runCatching { adsHelper.getSupportAd() }
- .onFailure {
- errorHandler.dispatch(it)
+ .onFailure(errorHandler::dispatch)
+ .onSuccess { it?.let { view?.showAd(it) } }
- view?.run {
- showLoadingSupportAd(false)
- showWatchAdOncePerVisit(false)
- }
- }
- .onSuccess {
- it?.let { view?.showAd(it) }
-
- view?.run {
- showLoadingSupportAd(false)
- showWatchAdOncePerVisit(true)
- }
- }
+ view?.run {
+ showLoadingSupportAd(false)
+ showWatchAdOncePerVisit(true)
+ }
}
}
diff --git a/app/src/play/java/io/github/wulkanowy/utils/AdsHelper.kt b/app/src/play/java/io/github/wulkanowy/utils/AdsHelper.kt
index d5f65b46d..c536e2218 100644
--- a/app/src/play/java/io/github/wulkanowy/utils/AdsHelper.kt
+++ b/app/src/play/java/io/github/wulkanowy/utils/AdsHelper.kt
@@ -1,12 +1,8 @@
package io.github.wulkanowy.utils
import android.content.Context
-import android.net.ConnectivityManager
-import android.net.NetworkCapabilities
-import android.os.Build
import android.os.Bundle
import android.view.View
-import androidx.core.content.getSystemService
import com.google.ads.mediation.admob.AdMobAdapter
import com.google.android.gms.ads.*
import com.google.android.gms.ads.rewardedinterstitial.RewardedInterstitialAd
@@ -14,7 +10,6 @@ import com.google.android.gms.ads.rewardedinterstitial.RewardedInterstitialAdLoa
import dagger.hilt.android.qualifiers.ApplicationContext
import io.github.wulkanowy.BuildConfig
import io.github.wulkanowy.data.repositories.PreferencesRepository
-import java.net.UnknownHostException
import javax.inject.Inject
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
@@ -33,10 +28,6 @@ class AdsHelper @Inject constructor(
}
suspend fun getSupportAd(): RewardedInterstitialAd? {
- if (!context.isInternetConnected()) {
- throw UnknownHostException()
- }
-
val extra = Bundle().apply { putString("npa", "1") }
val adRequest = AdRequest.Builder()
.apply {
@@ -93,18 +84,4 @@ class AdsHelper @Inject constructor(
}
}
-@Suppress("DEPRECATION")
-private fun Context.isInternetConnected(): Boolean {
- val connectivityManager = getSystemService() ?: return false
-
- return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- val currentNetwork = connectivityManager.activeNetwork
- val networkCapabilities = connectivityManager.getNetworkCapabilities(currentNetwork)
-
- networkCapabilities?.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED) == true
- } else {
- connectivityManager.activeNetworkInfo?.isConnected == true
- }
-}
-
data class AdBanner(val view: View)
diff --git a/app/src/play/java/io/github/wulkanowy/utils/AnalyticsHelper.kt b/app/src/play/java/io/github/wulkanowy/utils/AnalyticsHelper.kt
index 3215fa20c..b65325790 100644
--- a/app/src/play/java/io/github/wulkanowy/utils/AnalyticsHelper.kt
+++ b/app/src/play/java/io/github/wulkanowy/utils/AnalyticsHelper.kt
@@ -4,37 +4,25 @@ import android.app.Activity
import android.content.Context
import android.os.Bundle
import com.google.firebase.analytics.FirebaseAnalytics
-import com.google.firebase.crashlytics.FirebaseCrashlytics
import dagger.hilt.android.qualifiers.ApplicationContext
-import io.github.wulkanowy.data.repositories.PreferencesRepository
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class AnalyticsHelper @Inject constructor(
- @ApplicationContext private val context: Context,
- preferencesRepository: PreferencesRepository,
- appInfo: AppInfo,
+ @ApplicationContext private val context: Context
) {
private val analytics by lazy { FirebaseAnalytics.getInstance(context) }
- private val crashlytics by lazy { FirebaseCrashlytics.getInstance() }
-
- init {
- if (!appInfo.isDebug) {
- crashlytics.setUserId(preferencesRepository.installationId)
- }
- }
-
fun logEvent(name: String, vararg params: Pair) {
Bundle().apply {
- params.forEach { (key, value) ->
- if (value == null) return@forEach
- when (value) {
- is String -> putString(key, value)
- is Int -> putInt(key, value)
- is Boolean -> putBoolean(key, value)
+ params.forEach {
+ if (it.second == null) return@forEach
+ when (it.second) {
+ is String, is String? -> putString(it.first, it.second.toString())
+ is Int, is Int? -> putInt(it.first, it.second as Int)
+ is Boolean, is Boolean? -> putBoolean(it.first, it.second as Boolean)
}
}
analytics.logEvent(name, this)
diff --git a/app/src/play/java/io/github/wulkanowy/utils/CrashlyticsUtils.kt b/app/src/play/java/io/github/wulkanowy/utils/CrashlyticsUtils.kt
index f980bc4bb..410fddf16 100644
--- a/app/src/play/java/io/github/wulkanowy/utils/CrashlyticsUtils.kt
+++ b/app/src/play/java/io/github/wulkanowy/utils/CrashlyticsUtils.kt
@@ -23,6 +23,9 @@ class CrashLogExceptionTree : FormatterPriorityTree(Log.ERROR, ExceptionFilter)
override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
if (skipLog(priority, tag, message, t)) return
+ crashlytics.setCustomKey("priority", priority)
+ crashlytics.setCustomKey("tag", tag.orEmpty())
+ crashlytics.setCustomKey("message", message)
if (t != null) {
crashlytics.recordException(t)
} else {
diff --git a/app/src/test/java/io/github/wulkanowy/TestEnityCreator.kt b/app/src/test/java/io/github/wulkanowy/TestEnityCreator.kt
index 84a0cb405..ff0a53135 100644
--- a/app/src/test/java/io/github/wulkanowy/TestEnityCreator.kt
+++ b/app/src/test/java/io/github/wulkanowy/TestEnityCreator.kt
@@ -27,9 +27,7 @@ fun getMailboxEntity() = Mailbox(
globalKey = "v4",
fullName = "",
userName = "",
- email = "test",
- symbol = "powiatwulkanowy",
- schoolId = "123456",
+ userLoginId = 0,
studentName = "",
schoolNameShort = "",
type = MailboxType.UNKNOWN,
diff --git a/app/src/test/java/io/github/wulkanowy/data/db/migrations/AbstractMigrationTest.kt b/app/src/test/java/io/github/wulkanowy/data/db/migrations/AbstractMigrationTest.kt
index 18249ba8b..cc31d8933 100644
--- a/app/src/test/java/io/github/wulkanowy/data/db/migrations/AbstractMigrationTest.kt
+++ b/app/src/test/java/io/github/wulkanowy/data/db/migrations/AbstractMigrationTest.kt
@@ -3,7 +3,6 @@ package io.github.wulkanowy.data.db.migrations
import android.content.Context
import androidx.preference.PreferenceManager
import androidx.room.Room
-import androidx.room.migration.Migration
import androidx.room.testing.MigrationTestHelper
import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory
import androidx.test.core.app.ApplicationProvider
@@ -17,7 +16,7 @@ abstract class AbstractMigrationTest {
val dbName = "migration-test"
- private val context: Context get() = ApplicationProvider.getApplicationContext()
+ val context: Context get() = ApplicationProvider.getApplicationContext()
@get:Rule
val helper: MigrationTestHelper = MigrationTestHelper(
@@ -26,10 +25,6 @@ abstract class AbstractMigrationTest {
FrameworkSQLiteOpenHelperFactory()
)
- fun runMigrationsAndValidate(migration: Migration) {
- helper.runMigrationsAndValidate(dbName, migration.endVersion, true, migration).close()
- }
-
fun getMigratedRoomDatabase(): AppDatabase {
val database = Room.databaseBuilder(
ApplicationProvider.getApplicationContext(),
diff --git a/app/src/test/java/io/github/wulkanowy/data/db/migrations/Migration12Test.kt b/app/src/test/java/io/github/wulkanowy/data/db/migrations/Migration12Test.kt
index f614c8ca9..a02904733 100644
--- a/app/src/test/java/io/github/wulkanowy/data/db/migrations/Migration12Test.kt
+++ b/app/src/test/java/io/github/wulkanowy/data/db/migrations/Migration12Test.kt
@@ -33,7 +33,7 @@ class Migration12Test : AbstractMigrationTest() {
close()
}
- runMigrationsAndValidate(Migration12())
+ helper.runMigrationsAndValidate(dbName, 12, true, Migration12())
val db = getMigratedRoomDatabase()
val students = runBlocking { db.studentDao.loadAll() }
@@ -49,7 +49,6 @@ class Migration12Test : AbstractMigrationTest() {
assertEquals(2, studentId)
assertEquals(6, classId)
}
- db.close()
}
@Test
@@ -63,7 +62,7 @@ class Migration12Test : AbstractMigrationTest() {
close()
}
- runMigrationsAndValidate(Migration12())
+ helper.runMigrationsAndValidate(dbName, 12, true, Migration12())
val db = getMigratedRoomDatabase()
val students = runBlocking { db.studentDao.loadAll() }
@@ -74,7 +73,6 @@ class Migration12Test : AbstractMigrationTest() {
assertEquals(2, studentId)
assertEquals(1, classId)
}
- db.close()
}
@Test
@@ -90,7 +88,7 @@ class Migration12Test : AbstractMigrationTest() {
close()
}
- runMigrationsAndValidate(Migration12())
+ helper.runMigrationsAndValidate(dbName, 12, true, Migration12())
val db = getMigratedRoomDatabase()
val students = runBlocking { db.studentDao.loadAll() }
@@ -109,7 +107,6 @@ class Migration12Test : AbstractMigrationTest() {
assertEquals(studentId, 3)
assertEquals(true, isCurrent)
}
- db.close()
}
private fun createStudent(db: SupportSQLiteDatabase, studentId: Int, isCurrent: Boolean) {
diff --git a/app/src/test/java/io/github/wulkanowy/data/db/migrations/Migration13Test.kt b/app/src/test/java/io/github/wulkanowy/data/db/migrations/Migration13Test.kt
index b0c03fb11..bdfb4137d 100644
--- a/app/src/test/java/io/github/wulkanowy/data/db/migrations/Migration13Test.kt
+++ b/app/src/test/java/io/github/wulkanowy/data/db/migrations/Migration13Test.kt
@@ -57,8 +57,6 @@ class Migration13Test : AbstractMigrationTest() {
assertEquals("C", className)
assertEquals("Publiczna szkoła Wulkanowego-fejka nr 2 w fakelog.cf", schoolName)
}
-
- db.close()
}
@Test
@@ -87,8 +85,6 @@ class Migration13Test : AbstractMigrationTest() {
assertEquals("", className)
assertEquals("Publiczna szkoła Wulkanowego-fejka nr 1 w fakelog.cf", schoolName)
}
-
- db.close()
}
@Test
@@ -152,7 +148,6 @@ class Migration13Test : AbstractMigrationTest() {
assertFalse(semesters[2].second)
assertTrue(semesters[3].second)
}
- db.close()
}
private fun getSemesters(db: SupportSQLiteDatabase, query: String): List> {
diff --git a/app/src/test/java/io/github/wulkanowy/data/db/migrations/Migration27Test.kt b/app/src/test/java/io/github/wulkanowy/data/db/migrations/Migration27Test.kt
index 19eda9ba8..8e744f27a 100644
--- a/app/src/test/java/io/github/wulkanowy/data/db/migrations/Migration27Test.kt
+++ b/app/src/test/java/io/github/wulkanowy/data/db/migrations/Migration27Test.kt
@@ -27,7 +27,7 @@ class Migration27Test : AbstractMigrationTest() {
close()
}
- runMigrationsAndValidate(Migration27())
+ helper.runMigrationsAndValidate(dbName, 27, true, Migration27())
val db = getMigratedRoomDatabase()
val students = runBlocking { db.studentDao.loadAll() }
@@ -39,8 +39,6 @@ class Migration27Test : AbstractMigrationTest() {
assertEquals(123, userLoginId)
assertEquals("Student Jan", userName)
}
-
- db.close()
}
@Test
@@ -51,7 +49,7 @@ class Migration27Test : AbstractMigrationTest() {
close()
}
- runMigrationsAndValidate(Migration27())
+ helper.runMigrationsAndValidate(dbName, 27, true, Migration27())
val db = getMigratedRoomDatabase()
val students = runBlocking { db.studentDao.loadAll() }
@@ -63,8 +61,6 @@ class Migration27Test : AbstractMigrationTest() {
assertEquals(2, userLoginId)
assertEquals("Unit Jan", userName)
}
-
- db.close()
}
@Test
@@ -77,7 +73,7 @@ class Migration27Test : AbstractMigrationTest() {
close()
}
- runMigrationsAndValidate(Migration27())
+ helper.runMigrationsAndValidate(dbName, 27, true, Migration27())
val db = getMigratedRoomDatabase()
val students = runBlocking { db.studentDao.loadAll() }
@@ -94,8 +90,6 @@ class Migration27Test : AbstractMigrationTest() {
assertEquals(333, userLoginId)
assertEquals("Unit Tomasz", userName)
}
-
- db.close()
}
private fun createStudent(db: SupportSQLiteDatabase, id: Long, userLoginId: Int, studentName: String) {
diff --git a/app/src/test/java/io/github/wulkanowy/data/db/migrations/Migration35Test.kt b/app/src/test/java/io/github/wulkanowy/data/db/migrations/Migration35Test.kt
index 79c24f2e6..883cdb81c 100644
--- a/app/src/test/java/io/github/wulkanowy/data/db/migrations/Migration35Test.kt
+++ b/app/src/test/java/io/github/wulkanowy/data/db/migrations/Migration35Test.kt
@@ -29,7 +29,7 @@ class Migration35Test : AbstractMigrationTest() {
close()
}
- runMigrationsAndValidate(Migration35(AppInfo()))
+ helper.runMigrationsAndValidate(dbName, 35, true, Migration35(AppInfo()))
val db = getMigratedRoomDatabase()
val students = runBlocking { db.studentDao.loadAll() }
@@ -38,8 +38,6 @@ class Migration35Test : AbstractMigrationTest() {
assertTrue { students[0].avatarColor in AppInfo().defaultColorsForAvatar }
assertTrue { students[1].avatarColor in AppInfo().defaultColorsForAvatar }
-
- db.close()
}
private fun createStudent(db: SupportSQLiteDatabase, id: Long) {
diff --git a/app/src/test/java/io/github/wulkanowy/data/db/migrations/Migration54Test.kt b/app/src/test/java/io/github/wulkanowy/data/db/migrations/Migration54Test.kt
deleted file mode 100644
index 1855e0d50..000000000
--- a/app/src/test/java/io/github/wulkanowy/data/db/migrations/Migration54Test.kt
+++ /dev/null
@@ -1,130 +0,0 @@
-package io.github.wulkanowy.data.db.migrations
-
-import android.content.ContentValues
-import android.database.sqlite.SQLiteDatabase
-import android.os.Build
-import androidx.sqlite.db.SupportSQLiteDatabase
-import dagger.hilt.android.testing.HiltAndroidTest
-import dagger.hilt.android.testing.HiltTestApplication
-import io.github.wulkanowy.sdk.Sdk
-import io.github.wulkanowy.sdk.Sdk.ScrapperLoginType.*
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.test.runTest
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.robolectric.RobolectricTestRunner
-import org.robolectric.annotation.Config
-import kotlin.random.Random
-import kotlin.test.assertEquals
-
-@HiltAndroidTest
-@RunWith(RobolectricTestRunner::class)
-@OptIn(ExperimentalCoroutinesApi::class)
-@Config(sdk = [Build.VERSION_CODES.O_MR1], application = HiltTestApplication::class)
-class Migration54Test : AbstractMigrationTest() {
-
- @Test
- fun `don't touch unrelated students`() = runTest {
- with(helper.createDatabase(dbName, 53)) {
- createStudent(1, STANDARD, "vulcan.net.pl", "rzeszow", "Jan Michniewicz")
- createStudent(2, ADFSLight, "umt.tarnow.pl", "tarnow", "Joanna Marcinkiewicz")
- close()
- }
-
- runMigrationsAndValidate(Migration54())
- val db = getMigratedRoomDatabase()
- val students = db.studentDao.loadAll()
-
- assertEquals(2, students.size)
- with(students[0]) {
- assertEquals(STANDARD.name, loginType)
- assertEquals("https://vulcan.net.pl", scrapperBaseUrl)
- assertEquals("rzeszow", symbol)
- }
- with(students[1]) {
- assertEquals(ADFSLight.name, loginType)
- assertEquals("https://umt.tarnow.pl", scrapperBaseUrl)
- assertEquals("tarnow", symbol)
- }
- db.close()
- }
-
- @Test
- fun `remove tomaszow mazowiecki students`() = runTest {
- with(helper.createDatabase(dbName, 53)) {
- createStudent(1, STANDARD, "vulcan.net.pl", "rzeszow", "Jan Michniewicz")
- createStudent(2, STANDARD, "vulcan.net.pl", "tomaszowmazowiecki", "Joanna Stec")
- createStudent(3, STANDARD, "vulcan.net.pl", "tomaszowmazowiecki", "Kacper Morawiecki")
- close()
- }
-
- runMigrationsAndValidate(Migration54())
- val db = getMigratedRoomDatabase()
- val students = db.studentDao.loadAll()
- assertEquals(1, students.size)
- with(students[0]) {
- assertEquals("rzeszow", symbol)
- }
- db.close()
- }
-
- @Test
- fun `migrate resman students`() = runTest {
- with(helper.createDatabase(dbName, 53)) {
- createStudent(1, ADFSLight, "resman.pl", "rzeszow", "Joanna Stec")
- createStudent(2, ADFSLight, "resman.pl", "rzeszow", "Kacper Morawiecki")
- createStudent(3, STANDARD, "vulcan.net.pl", "rzeszow", "Jan Michniewicz")
- close()
- }
- runMigrationsAndValidate(Migration54())
- val db = getMigratedRoomDatabase()
- val students = db.studentDao.loadAll()
- assertEquals(3, students.size)
- with(students[0]) {
- assertEquals(ADFSLightScoped.name, loginType)
- assertEquals("https://vulcan.net.pl", scrapperBaseUrl)
- assertEquals("rzeszowprojekt", symbol)
- }
- with(students[1]) {
- assertEquals(ADFSLightScoped.name, loginType)
- assertEquals("https://vulcan.net.pl", scrapperBaseUrl)
- assertEquals("rzeszowprojekt", symbol)
- }
- db.close()
- }
-
- private fun SupportSQLiteDatabase.createStudent(
- id: Long,
- loginType: Sdk.ScrapperLoginType,
- host: String,
- symbol: String,
- studentName: String,
- ) {
- insert("Students", SQLiteDatabase.CONFLICT_FAIL, ContentValues().apply {
- put("scrapper_base_url", "https://$host")
- put("mobile_base_url", "")
- put("login_type", loginType.name)
- put("login_mode", "SCRAPPER")
- put("certificate_key", "")
- put("private_key", "")
- put("is_parent", false)
- put("email", "jan@fakelog.cf")
- put("password", "******")
- put("symbol", symbol)
- put("student_id", Random.nextInt())
- put("user_login_id", id)
- put("user_name", studentName)
- put("student_name", studentName)
- put("school_id", "123")
- put("school_short", "")
- put("school_name", "")
- put("class_name", "")
- put("class_id", Random.nextInt())
- put("is_current", false)
- put("registration_date", "0")
- put("id", id)
- put("nick", "")
- put("avatar_color", "")
- })
- }
-}
diff --git a/app/src/test/java/io/github/wulkanowy/data/mappers/AttendanceMapperKtTest.kt b/app/src/test/java/io/github/wulkanowy/data/mappers/AttendanceMapperKtTest.kt
deleted file mode 100644
index a35e5d303..000000000
--- a/app/src/test/java/io/github/wulkanowy/data/mappers/AttendanceMapperKtTest.kt
+++ /dev/null
@@ -1,143 +0,0 @@
-package io.github.wulkanowy.data.mappers
-
-import io.github.wulkanowy.data.db.entities.Semester
-import io.github.wulkanowy.data.db.entities.Timetable
-import io.github.wulkanowy.sdk.pojo.Attendance
-import io.github.wulkanowy.sdk.scrapper.attendance.SentExcuse
-import org.junit.Test
-import java.time.Instant
-import java.time.LocalDate
-import kotlin.test.assertEquals
-
-class AttendanceMapperTest {
-
- @Test
- fun `map attendance when fallback is not necessary`() {
- val attendance = listOf(
- getSdkAttendance(1, LocalDate.of(2022, 11, 17), "Oryginalna 1"),
- getSdkAttendance(2, LocalDate.of(2022, 11, 17), "Oryginalna 2"),
- )
- val lessons = listOf(
- getEntityTimetable(1, LocalDate.of(2022, 11, 17), "Pierwsza"),
- getEntityTimetable(2, LocalDate.of(2022, 11, 17), "Druga"),
- )
-
- val result = attendance.mapToEntities(getEntitySemester(), lessons)
- assertEquals("Oryginalna 1", result[0].subject)
- assertEquals("Oryginalna 2", result[1].subject)
- }
-
- @Test
- fun `map attendance when fallback is not always necessary`() {
- val attendance = listOf(
- getSdkAttendance(1, LocalDate.of(2022, 11, 17), "Oryginalna 1"),
- getSdkAttendance(2, LocalDate.of(2022, 11, 17), ""),
- )
- val lessons = listOf(
- getEntityTimetable(1, LocalDate.of(2022, 11, 17), "Pierwsza"),
- getEntityTimetable(2, LocalDate.of(2022, 11, 17), "Druga"),
- )
-
- val result = attendance.mapToEntities(getEntitySemester(), lessons)
- assertEquals("Oryginalna 1", result[0].subject)
- assertEquals("Druga", result[1].subject)
- }
-
- @Test
- fun `map attendance when fallback is sometimes empty`() {
- val attendance = listOf(
- getSdkAttendance(1, LocalDate.of(2022, 11, 17), "Oryginalna 1"),
- getSdkAttendance(2, LocalDate.of(2022, 11, 17), ""),
- )
- val lessons = listOf(
- getEntityTimetable(1, LocalDate.of(2022, 11, 17), "Pierwsza"),
- )
-
- val result = attendance.mapToEntities(getEntitySemester(), lessons)
- assertEquals("Oryginalna 1", result[0].subject)
- assertEquals("", result[1].subject)
- }
-
- @Test
- fun `map attendance when fallback is empty`() {
- val attendance = listOf(
- getSdkAttendance(1, LocalDate.of(2022, 11, 17), ""),
- getSdkAttendance(2, LocalDate.of(2022, 11, 17), ""),
- )
- val lessons = listOf(
- getEntityTimetable(1, LocalDate.of(2022, 11, 18), "Pierwsza"),
- getEntityTimetable(2, LocalDate.of(2022, 10, 17), "Druga"),
- )
-
- val result = attendance.mapToEntities(getEntitySemester(), lessons)
- assertEquals("", result[0].subject)
- assertEquals("", result[1].subject)
- }
-
- @Test
- fun `map attendance with all subject fallback`() {
- val attendance = listOf(
- getSdkAttendance(1, LocalDate.of(2022, 11, 17)),
- getSdkAttendance(2, LocalDate.of(2022, 11, 17)),
- )
- val lessons = listOf(
- getEntityTimetable(1, LocalDate.of(2022, 11, 17), "Pierwsza"),
- getEntityTimetable(2, LocalDate.of(2022, 11, 17), "Druga"),
- )
-
- val result = attendance.mapToEntities(getEntitySemester(), lessons)
- assertEquals("Pierwsza", result[0].subject)
- assertEquals("Druga", result[1].subject)
- }
-
- private fun getSdkAttendance(number: Int, date: LocalDate, subject: String = "") = Attendance(
- number = number,
- name = "ABSENCE",
- subject = subject,
- date = date,
- timeId = 1,
- categoryId = 1,
- deleted = false,
- excuseStatus = SentExcuse.Status.WAITING,
- excusable = false,
- absence = false,
- excused = false,
- exemption = false,
- lateness = false,
- presence = false,
- )
-
- private fun getEntityTimetable(number: Int, date: LocalDate, subject: String = "") = Timetable(
- number = number,
- start = Instant.now(),
- end = Instant.now(),
- date = date,
- subject = subject,
- subjectOld = "",
- group = "",
- room = "",
- roomOld = "",
- teacher = "",
- teacherOld = "",
- info = "",
- changes = false,
- canceled = false,
- studentId = 0,
- diaryId = 0,
- isStudentPlan = false,
- )
-
- private fun getEntitySemester() = Semester(
- studentId = 0,
- diaryId = 0,
- kindergartenDiaryId = 0,
- diaryName = "",
- schoolYear = 0,
- semesterId = 0,
- semesterName = 0,
- start = LocalDate.now(),
- end = LocalDate.now(),
- classId = 0,
- unitId = 0
- )
-}
diff --git a/app/src/test/java/io/github/wulkanowy/data/repositories/AttendanceRepositoryTest.kt b/app/src/test/java/io/github/wulkanowy/data/repositories/AttendanceRepositoryTest.kt
index 896491ef0..7d22f7265 100644
--- a/app/src/test/java/io/github/wulkanowy/data/repositories/AttendanceRepositoryTest.kt
+++ b/app/src/test/java/io/github/wulkanowy/data/repositories/AttendanceRepositoryTest.kt
@@ -2,7 +2,6 @@ package io.github.wulkanowy.data.repositories
import io.github.wulkanowy.data.dataOrNull
import io.github.wulkanowy.data.db.dao.AttendanceDao
-import io.github.wulkanowy.data.db.dao.TimetableDao
import io.github.wulkanowy.data.errorOrNull
import io.github.wulkanowy.data.mappers.mapToEntities
import io.github.wulkanowy.data.toFirstResult
@@ -30,9 +29,6 @@ class AttendanceRepositoryTest {
@MockK
private lateinit var attendanceDb: AttendanceDao
- @MockK
- private lateinit var timetableDb: TimetableDao
-
@MockK(relaxUnitFun = true)
private lateinit var refreshHelper: AutoRefreshHelper
@@ -55,9 +51,8 @@ class AttendanceRepositoryTest {
fun setUp() {
MockKAnnotations.init(this)
every { refreshHelper.shouldBeRefreshed(any()) } returns false
- coEvery { timetableDb.load(any(), any(), any(), any()) } returns emptyList()
- attendanceRepository = AttendanceRepository(attendanceDb, timetableDb, sdk, refreshHelper)
+ attendanceRepository = AttendanceRepository(attendanceDb, sdk, refreshHelper)
}
@Test
@@ -65,8 +60,8 @@ class AttendanceRepositoryTest {
// prepare
coEvery { sdk.getAttendance(startDate, endDate, 1) } returns remoteList
coEvery { attendanceDb.loadAll(1, 1, startDate, endDate) } returnsMany listOf(
- flowOf(remoteList.mapToEntities(semester, emptyList())),
- flowOf(remoteList.mapToEntities(semester, emptyList()))
+ flowOf(remoteList.mapToEntities(semester)),
+ flowOf(remoteList.mapToEntities(semester))
)
coEvery { attendanceDb.insertAll(any()) } returns listOf(1, 2, 3)
coEvery { attendanceDb.deleteAll(any()) } just Runs
@@ -88,9 +83,9 @@ class AttendanceRepositoryTest {
// prepare
coEvery { sdk.getAttendance(startDate, endDate, 1) } returns remoteList
coEvery { attendanceDb.loadAll(1, 1, startDate, endDate) } returnsMany listOf(
- flowOf(remoteList.dropLast(1).mapToEntities(semester, emptyList())),
- flowOf(remoteList.dropLast(1).mapToEntities(semester, emptyList())), // after fetch end before save result
- flowOf(remoteList.mapToEntities(semester, emptyList()))
+ flowOf(remoteList.dropLast(1).mapToEntities(semester)),
+ flowOf(remoteList.dropLast(1).mapToEntities(semester)), // after fetch end before save result
+ flowOf(remoteList.mapToEntities(semester))
)
coEvery { attendanceDb.insertAll(any()) } returns listOf(1, 2, 3)
coEvery { attendanceDb.deleteAll(any()) } just Runs
@@ -105,7 +100,7 @@ class AttendanceRepositoryTest {
coVerify { attendanceDb.loadAll(1, 1, startDate, endDate) }
coVerify {
attendanceDb.insertAll(match {
- it.size == 1 && it[0] == remoteList.mapToEntities(semester, emptyList())[1]
+ it.size == 1 && it[0] == remoteList.mapToEntities(semester)[1]
})
}
coVerify { attendanceDb.deleteAll(match { it.isEmpty() }) }
@@ -116,9 +111,9 @@ class AttendanceRepositoryTest {
// prepare
coEvery { sdk.getAttendance(startDate, endDate, 1) } returns remoteList.dropLast(1)
coEvery { attendanceDb.loadAll(1, 1, startDate, endDate) } returnsMany listOf(
- flowOf(remoteList.mapToEntities(semester, emptyList())),
- flowOf(remoteList.mapToEntities(semester, emptyList())), // after fetch end before save result
- flowOf(remoteList.dropLast(1).mapToEntities(semester, emptyList()))
+ flowOf(remoteList.mapToEntities(semester)),
+ flowOf(remoteList.mapToEntities(semester)), // after fetch end before save result
+ flowOf(remoteList.dropLast(1).mapToEntities(semester))
)
coEvery { attendanceDb.insertAll(any()) } returns listOf(1, 2, 3)
coEvery { attendanceDb.deleteAll(any()) } just Runs
@@ -134,7 +129,7 @@ class AttendanceRepositoryTest {
coVerify { attendanceDb.insertAll(match { it.isEmpty() }) }
coVerify {
attendanceDb.deleteAll(match {
- it.size == 1 && it[0] == remoteList.mapToEntities(semester, emptyList())[1]
+ it.size == 1 && it[0] == remoteList.mapToEntities(semester)[1]
})
}
}
diff --git a/app/src/test/java/io/github/wulkanowy/data/repositories/MessageRepositoryTest.kt b/app/src/test/java/io/github/wulkanowy/data/repositories/MessageRepositoryTest.kt
index 9a2c22fd6..24306bfeb 100644
--- a/app/src/test/java/io/github/wulkanowy/data/repositories/MessageRepositoryTest.kt
+++ b/app/src/test/java/io/github/wulkanowy/data/repositories/MessageRepositoryTest.kt
@@ -3,7 +3,6 @@ package io.github.wulkanowy.data.repositories
import android.content.Context
import io.github.wulkanowy.data.dataOrNull
import io.github.wulkanowy.data.db.SharedPrefProvider
-import io.github.wulkanowy.data.db.dao.MailboxDao
import io.github.wulkanowy.data.db.dao.MessageAttachmentDao
import io.github.wulkanowy.data.db.dao.MessagesDao
import io.github.wulkanowy.data.db.entities.Message
@@ -11,7 +10,6 @@ import io.github.wulkanowy.data.db.entities.MessageWithAttachment
import io.github.wulkanowy.data.enums.MessageFolder
import io.github.wulkanowy.data.errorOrNull
import io.github.wulkanowy.data.toFirstResult
-import io.github.wulkanowy.domain.messages.GetMailboxByStudentUseCase
import io.github.wulkanowy.getMailboxEntity
import io.github.wulkanowy.getStudentEntity
import io.github.wulkanowy.sdk.Sdk
@@ -57,12 +55,6 @@ class MessageRepositoryTest {
@MockK
private lateinit var sharedPrefProvider: SharedPrefProvider
- @MockK
- private lateinit var mailboxDao: MailboxDao
-
- @MockK
- private lateinit var getMailboxByStudentUseCase: GetMailboxByStudentUseCase
-
private val student = getStudentEntity()
private val mailbox = getMailboxEntity()
@@ -82,33 +74,26 @@ class MessageRepositoryTest {
refreshHelper = refreshHelper,
sharedPrefProvider = sharedPrefProvider,
json = Json,
- mailboxDao = mailboxDao,
- getMailboxByStudentUseCase = getMailboxByStudentUseCase,
)
}
@Test
fun `get messages when fetched completely new message without notify`() = runBlocking {
- coEvery { mailboxDao.loadAll(any()) } returns listOf(mailbox)
- every { messageDb.loadAll(mailbox.globalKey, any()) } returns flowOf(emptyList())
+ every { messageDb.loadAll(any(), any()) } returns flowOf(emptyList())
coEvery { sdk.getMessages(Folder.RECEIVED, any()) } returns listOf(
- getMessageDto().copy(
- unreadBy = 5,
- readBy = 10,
- )
+ getMessageDto()
)
coEvery { messageDb.deleteAll(any()) } just Runs
coEvery { messageDb.insertAll(any()) } returns listOf()
- val res = repository.getMessages(
+ repository.getMessages(
student = student,
mailbox = mailbox,
folder = MessageFolder.RECEIVED,
forceRefresh = true,
notify = false,
- ).toFirstResult()
+ ).toFirstResult().dataOrNull.orEmpty()
- assertEquals(null, res.errorOrNull)
coVerify(exactly = 1) { messageDb.deleteAll(withArg { checkEquals(emptyList()) }) }
coVerify {
messageDb.insertAll(withArg {
@@ -156,7 +141,7 @@ class MessageRepositoryTest {
messageDb.loadMessageWithAttachment("v4")
} returnsMany listOf(flowOf(mWa), flowOf(mWaWithContent))
coEvery {
- sdk.getMessageDetails("v4", any())
+ sdk.getMessageDetails("v4")
} returns mockk {
every { sender } returns ""
every { recipients } returns listOf("")
@@ -202,16 +187,13 @@ class MessageRepositoryTest {
) = Message(
messageGlobalKey = "v4",
mailboxKey = "",
- email = "",
correspondents = "",
messageId = messageId,
subject = "",
date = Instant.EPOCH,
folderId = 1,
unread = unread,
- readBy = 1,
- unreadBy = 1,
- hasAttachments = false,
+ hasAttachments = false
).apply {
this.content = content
}
@@ -227,8 +209,6 @@ class MessageRepositoryTest {
dateZoned = Instant.EPOCH.atZone(ZoneOffset.UTC),
folderId = 1,
unread = true,
- readBy = 1,
- unreadBy = 1,
hasAttachments = false,
)
}
diff --git a/app/src/test/java/io/github/wulkanowy/domain/GetMailboxByStudentUseCaseTest.kt b/app/src/test/java/io/github/wulkanowy/domain/GetMailboxByStudentUseCaseTest.kt
deleted file mode 100644
index 6db16d2f5..000000000
--- a/app/src/test/java/io/github/wulkanowy/domain/GetMailboxByStudentUseCaseTest.kt
+++ /dev/null
@@ -1,225 +0,0 @@
-package io.github.wulkanowy.domain
-
-import io.github.wulkanowy.data.db.dao.MailboxDao
-import io.github.wulkanowy.data.db.entities.Mailbox
-import io.github.wulkanowy.data.db.entities.MailboxType
-import io.github.wulkanowy.data.db.entities.Student
-import io.github.wulkanowy.domain.messages.GetMailboxByStudentUseCase
-import io.github.wulkanowy.sdk.Sdk
-import io.mockk.MockKAnnotations
-import io.mockk.Runs
-import io.mockk.coEvery
-import io.mockk.impl.annotations.MockK
-import io.mockk.just
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.test.runTest
-import org.junit.Before
-import org.junit.Test
-import java.time.Instant
-import kotlin.test.assertEquals
-import kotlin.test.assertNull
-
-@OptIn(ExperimentalCoroutinesApi::class)
-class GetMailboxByStudentUseCaseTest {
-
- @MockK
- private lateinit var mailboxDao: MailboxDao
-
- private lateinit var systemUnderTest: GetMailboxByStudentUseCase
-
- @Before
- fun setUp() {
- MockKAnnotations.init(this)
-
- coEvery { mailboxDao.deleteAll(any()) } just Runs
- coEvery { mailboxDao.insertAll(any()) } returns emptyList()
- coEvery { mailboxDao.loadAll(any()) } returns emptyList()
-
- systemUnderTest = GetMailboxByStudentUseCase(mailboxDao = mailboxDao)
- }
-
- @Test
- fun `get mailbox that doesn't exist`() = runTest {
- val student = getStudentEntity(
- userName = "Stanisław Kowalski",
- studentName = "Jan Kowalski",
- )
- coEvery { mailboxDao.loadAll(any()) } returns emptyList()
-
- assertNull(systemUnderTest(student))
- }
-
- @Test
- fun `get mailbox for user with additional spaces`() = runTest {
- val student = getStudentEntity(
- userName = " Stanisław Kowalski ",
- studentName = " Jan Kowalski ",
- )
- val expectedMailbox = getMailboxEntity("Jan Kowalski ")
- coEvery { mailboxDao.loadAll(any()) } returns listOf(
- expectedMailbox,
- )
-
- val selectedMailbox = systemUnderTest(student)
- assertEquals(expectedMailbox, selectedMailbox)
- }
-
- @Test
- fun `get mailbox for user with reversed name`() = runTest {
- val student = getStudentEntity(
- userName = "Kowalski Jan",
- studentName = "Jan Kowalski",
- )
- val expectedMailbox = getMailboxEntity("Kowalski Jan")
- coEvery { mailboxDao.loadAll(any()) } returns listOf(expectedMailbox)
-
- assertEquals(expectedMailbox, systemUnderTest(student))
- }
-
- @Test
- fun `get mailbox for unique non-authorized student`() = runTest {
- val student = getStudentEntity(
- userName = "Stanisław Kowalski",
- studentName = "J** K*******",
- )
- val expectedMailbox = getMailboxEntity("Jan Kowalski")
- coEvery { mailboxDao.loadAll(any()) } returns listOf(
- expectedMailbox,
- )
-
- assertEquals(expectedMailbox, systemUnderTest(student))
- }
-
- @Test
- fun `get mailbox for unique non-authorized student but with spaces`() = runTest {
- val student = getStudentEntity(
- userName = "Stanisław Kowalski",
- studentName = "J** K*******",
- )
- val expectedMailbox = getMailboxEntity("Jan Kowalski")
- coEvery { mailboxDao.loadAll(any()) } returns listOf(
- expectedMailbox,
- )
-
- assertEquals(expectedMailbox, systemUnderTest(student))
- }
-
- @Test
- fun `get mailbox for not-unique non-authorized student`() = runTest {
- val student = getStudentEntity(
- userName = "Stanisław Kowalski",
- studentName = "J** K*******",
- )
- coEvery { mailboxDao.loadAll(any()) } returns listOf(
- getMailboxEntity("Jan Kowalski"),
- getMailboxEntity("Jan Kurowski"),
- )
-
- assertNull(systemUnderTest(student))
- }
-
- @Test
- fun `get mailbox for student with uppercase name`() = runTest {
- val student = getStudentEntity(
- userName = "Mochoń Julia",
- studentName = "KLAUDIA MOCHOŃ",
- )
- val expectedMailbox = getMailboxEntity("Klaudia Mochoń")
- coEvery { mailboxDao.loadAll(any()) } returns listOf(
- expectedMailbox,
- )
-
- assertEquals(expectedMailbox, systemUnderTest(student))
- }
-
- @Test
- fun `get mailbox for student with second name`() = runTest {
- val student = getStudentEntity(
- userName = "Fistaszek Karolina",
- studentName = "Julia Fistaszek",
- )
- val expectedMailbox = getMailboxEntity("Julia Maria Fistaszek")
- coEvery { mailboxDao.loadAll(any()) } returns listOf(
- expectedMailbox,
- )
-
- assertEquals(expectedMailbox, systemUnderTest(student))
- }
-
- @Test
- fun `get mailbox for student with second name and uppercase`() = runTest {
- val student = getStudentEntity(
- userName = "BEDNAREK KAMIL",
- studentName = "ALEKSANDRA BEDNAREK",
- )
- val expectedMailbox = getMailboxEntity("Aleksandra Anna Bednarek")
- coEvery { mailboxDao.loadAll(any()) } returns listOf(
- expectedMailbox,
- )
-
- assertEquals(expectedMailbox, systemUnderTest(student))
- }
-
- @Test
- fun `get mailbox for student with mailboxes from two different schools`() = runTest {
- val student = getStudentEntity(
- userName = "Kamil Bednarek",
- studentName = "Kamil Bednarek",
- schoolShortName = "CKZiU",
- )
- val mailbox1 = getMailboxEntity(
- studentName = "Kamil Bednarek",
- schoolShortName = "ZSTiO",
- )
- val mailbox2 = getMailboxEntity(
- studentName = "Kamil Bednarek",
- schoolShortName = "CKZiU",
- )
- coEvery { mailboxDao.loadAll(any()) } returns listOf(mailbox1, mailbox2)
-
- assertEquals(mailbox2, systemUnderTest(student))
- }
-
- private fun getMailboxEntity(
- studentName: String,
- schoolShortName: String = "test",
- ) = Mailbox(
- globalKey = "",
- fullName = "",
- userName = "",
- email = "",
- schoolId = "",
- symbol = "",
- studentName = studentName,
- schoolNameShort = schoolShortName,
- type = MailboxType.STUDENT,
- )
-
- private fun getStudentEntity(
- studentName: String,
- userName: String,
- schoolShortName: String = "test",
- ) = Student(
- scrapperBaseUrl = "http://fakelog.cf",
- email = "jan@fakelog.cf",
- certificateKey = "",
- classId = 0,
- className = "",
- isCurrent = false,
- isParent = false,
- loginMode = Sdk.Mode.API.name,
- loginType = Sdk.ScrapperLoginType.STANDARD.name,
- mobileBaseUrl = "",
- password = "",
- privateKey = "",
- registrationDate = Instant.now(),
- schoolName = "",
- schoolShortName = schoolShortName,
- schoolSymbol = "",
- studentId = 1,
- studentName = studentName,
- symbol = "",
- userLoginId = 1,
- userName = userName,
- )
-}
diff --git a/app/src/test/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenterTest.kt b/app/src/test/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenterTest.kt
index bf2d9f2cc..9bcfb8b6c 100644
--- a/app/src/test/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenterTest.kt
+++ b/app/src/test/java/io/github/wulkanowy/ui/modules/login/form/LoginFormPresenterTest.kt
@@ -1,9 +1,9 @@
package io.github.wulkanowy.ui.modules.login.form
import io.github.wulkanowy.MainCoroutineRule
-import io.github.wulkanowy.data.pojos.RegisterUser
+import io.github.wulkanowy.data.db.entities.Student
+import io.github.wulkanowy.data.db.entities.StudentWithSemesters
import io.github.wulkanowy.data.repositories.StudentRepository
-import io.github.wulkanowy.sdk.scrapper.Scrapper
import io.github.wulkanowy.ui.modules.login.LoginErrorHandler
import io.github.wulkanowy.utils.AnalyticsHelper
import io.mockk.*
@@ -12,6 +12,7 @@ import org.junit.Before
import org.junit.Rule
import org.junit.Test
import java.io.IOException
+import java.time.Instant
class LoginFormPresenterTest {
@@ -32,15 +33,6 @@ class LoginFormPresenterTest {
private lateinit var presenter: LoginFormPresenter
- private val registerUser = RegisterUser(
- email = "",
- password = "",
- login = "",
- baseUrl = "",
- loginType = Scrapper.LoginType.AUTO,
- symbols = listOf(),
- )
-
@Before
fun setUp() {
MockKAnnotations.init(this)
@@ -112,9 +104,32 @@ class LoginFormPresenterTest {
@Test
fun loginTest() {
- coEvery {
- repository.getUserSubjectsFromScrapper(any(), any(), any(), any())
- } returns registerUser
+ val studentTest = Student(
+ email = "test@",
+ password = "123",
+ scrapperBaseUrl = "https://fakelog.cf/?email",
+ loginType = "AUTO",
+ studentName = "",
+ schoolSymbol = "",
+ schoolName = "",
+ studentId = 0,
+ classId = 1,
+ isCurrent = false,
+ symbol = "",
+ registrationDate = Instant.now(),
+ className = "",
+ mobileBaseUrl = "",
+ privateKey = "",
+ certificateKey = "",
+ loginMode = "",
+ userLoginId = 0,
+ schoolShortName = "",
+ isParent = false,
+ userName = ""
+ )
+ coEvery { repository.getStudentsScrapper(any(), any(), any(), any()) } returns listOf(
+ StudentWithSemesters(studentTest, emptyList())
+ )
every { loginFormView.formUsernameValue } returns "@"
every { loginFormView.formPassValue } returns "123456"
@@ -131,9 +146,7 @@ class LoginFormPresenterTest {
@Test
fun loginEmptyTest() {
- coEvery {
- repository.getUserSubjectsFromScrapper(any(), any(), any(), any())
- } returns registerUser
+ coEvery { repository.getStudentsScrapper(any(), any(), any(), any()) } returns listOf()
every { loginFormView.formUsernameValue } returns "@"
every { loginFormView.formPassValue } returns "123456"
every { loginFormView.formHostValue } returns "https://fakelog.cf/?email"
@@ -149,9 +162,7 @@ class LoginFormPresenterTest {
@Test
fun loginEmptyTwiceTest() {
- coEvery {
- repository.getUserSubjectsFromScrapper(any(), any(), any(), any())
- } returns registerUser
+ coEvery { repository.getStudentsScrapper(any(), any(), any(), any()) } returns listOf()
every { loginFormView.formUsernameValue } returns "@"
every { loginFormView.formPassValue } returns "123456"
every { loginFormView.formHostValue } returns "https://fakelog.cf/?email"
@@ -169,14 +180,7 @@ class LoginFormPresenterTest {
@Test
fun loginErrorTest() {
val testException = IOException("test")
- coEvery {
- repository.getUserSubjectsFromScrapper(
- any(),
- any(),
- any(),
- any()
- )
- } throws testException
+ coEvery { repository.getStudentsScrapper(any(), any(), any(), any()) } throws testException
every { loginFormView.formUsernameValue } returns "@"
every { loginFormView.formPassValue } returns "123456"
every { loginFormView.formHostValue } returns "https://fakelog.cf/?email"
diff --git a/app/src/test/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectPresenterTest.kt b/app/src/test/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectPresenterTest.kt
index cf426a50b..e52ec3ae2 100644
--- a/app/src/test/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectPresenterTest.kt
+++ b/app/src/test/java/io/github/wulkanowy/ui/modules/login/studentselect/LoginStudentSelectPresenterTest.kt
@@ -1,22 +1,18 @@
package io.github.wulkanowy.ui.modules.login.studentselect
import io.github.wulkanowy.MainCoroutineRule
-import io.github.wulkanowy.data.pojos.RegisterStudent
-import io.github.wulkanowy.data.pojos.RegisterSymbol
-import io.github.wulkanowy.data.pojos.RegisterUnit
-import io.github.wulkanowy.data.pojos.RegisterUser
+import io.github.wulkanowy.data.db.entities.Student
+import io.github.wulkanowy.data.db.entities.StudentWithSemesters
import io.github.wulkanowy.data.repositories.StudentRepository
-import io.github.wulkanowy.sdk.scrapper.Scrapper
import io.github.wulkanowy.services.sync.SyncManager
-import io.github.wulkanowy.ui.modules.login.LoginData
import io.github.wulkanowy.ui.modules.login.LoginErrorHandler
import io.github.wulkanowy.utils.AnalyticsHelper
-import io.github.wulkanowy.utils.AppInfo
import io.mockk.*
import io.mockk.impl.annotations.MockK
import org.junit.Before
import org.junit.Rule
import org.junit.Test
+import java.time.Instant
class LoginStudentSelectPresenterTest {
@@ -26,7 +22,7 @@ class LoginStudentSelectPresenterTest {
@MockK(relaxed = true)
lateinit var errorHandler: LoginErrorHandler
- @MockK
+ @MockK(relaxed = true)
lateinit var loginStudentSelectView: LoginStudentSelectView
@MockK
@@ -38,55 +34,33 @@ class LoginStudentSelectPresenterTest {
@MockK(relaxed = true)
lateinit var syncManager: SyncManager
- private val appInfo = AppInfo()
-
private lateinit var presenter: LoginStudentSelectPresenter
- private val loginData = LoginData(
- login = "",
- password = "",
- baseUrl = "",
- symbol = null,
- )
-
- private val subject = RegisterStudent(
- studentId = 0,
- studentName = "",
- studentSecondName = "",
- studentSurname = "",
- className = "",
- classId = 0,
- isParent = false,
- semesters = listOf(),
- )
-
- private val school = RegisterUnit(
- userLoginId = 0,
- schoolId = "",
- schoolName = "",
- schoolShortName = "",
- parentIds = listOf(),
- studentIds = listOf(),
- employeeIds = listOf(),
- error = null,
- students = listOf(subject)
- )
-
- private val symbol = RegisterSymbol(
- symbol = "",
- error = null,
- userName = "",
- schools = listOf(school),
- )
-
- private val registerUser = RegisterUser(
- email = "",
- password = "",
- login = "",
- baseUrl = "",
- loginType = Scrapper.LoginType.AUTO,
- symbols = listOf(symbol),
- )
+ private val testStudent by lazy {
+ Student(
+ email = "test",
+ password = "test123",
+ scrapperBaseUrl = "https://fakelog.cf",
+ loginType = "AUTO",
+ symbol = "",
+ isCurrent = false,
+ studentId = 0,
+ schoolName = "",
+ schoolSymbol = "",
+ classId = 1,
+ studentName = "",
+ registrationDate = Instant.now(),
+ className = "",
+ loginMode = "",
+ certificateKey = "",
+ privateKey = "",
+ mobileBaseUrl = "",
+ schoolShortName = "",
+ userLoginId = 1,
+ isParent = false,
+ userName = ""
+ )
+ }
private val testException by lazy { RuntimeException("Problem") }
@@ -95,62 +69,46 @@ class LoginStudentSelectPresenterTest {
MockKAnnotations.init(this)
clearMocks(studentRepository, loginStudentSelectView)
-
- coEvery { studentRepository.getSavedStudents(false) } returns emptyList()
-
every { loginStudentSelectView.initView() } just Runs
- every { loginStudentSelectView.symbols } returns emptyMap()
-
+ every { loginStudentSelectView.showContact(any()) } just Runs
every { loginStudentSelectView.enableSignIn(any()) } just Runs
every { loginStudentSelectView.showProgress(any()) } just Runs
every { loginStudentSelectView.showContent(any()) } just Runs
- presenter = LoginStudentSelectPresenter(
- studentRepository = studentRepository,
- loginErrorHandler = errorHandler,
- syncManager = syncManager,
- analytics = analytics,
- appInfo = appInfo,
- )
+ presenter = LoginStudentSelectPresenter(studentRepository, errorHandler, syncManager, analytics)
+ presenter.onAttachView(loginStudentSelectView, emptyList())
}
@Test
fun initViewTest() {
- presenter.onAttachView(loginStudentSelectView, loginData, registerUser)
verify { loginStudentSelectView.initView() }
}
@Test
fun onSelectedStudentTest() {
- val itemsSlot = slot>()
- every { loginStudentSelectView.updateData(capture(itemsSlot)) } just Runs
- presenter.onAttachView(loginStudentSelectView, loginData, registerUser)
+ coEvery {
+ studentRepository.saveStudents(listOf(StudentWithSemesters(testStudent, emptyList())))
+ } just Runs
- coEvery { studentRepository.saveStudents(any()) } just Runs
+ every { loginStudentSelectView.openMainView() } just Runs
- every { loginStudentSelectView.navigateToNext() } just Runs
-
- itemsSlot.captured.filterIsInstance().first().let {
- it.onClick(it)
- }
+ presenter.onItemSelected(StudentWithSemesters(testStudent, emptyList()), false)
presenter.onSignIn()
verify { loginStudentSelectView.showContent(false) }
verify { loginStudentSelectView.showProgress(true) }
- verify { loginStudentSelectView.navigateToNext() }
+ verify { loginStudentSelectView.openMainView() }
}
@Test
fun onSelectedStudentErrorTest() {
- val itemsSlot = slot>()
- every { loginStudentSelectView.updateData(capture(itemsSlot)) } just Runs
- presenter.onAttachView(loginStudentSelectView, loginData, registerUser)
+ coEvery {
+ studentRepository.saveStudents(listOf(StudentWithSemesters(testStudent, emptyList())))
+ } throws testException
- coEvery { studentRepository.saveStudents(any()) } throws testException
+ coEvery { studentRepository.logoutStudent(testStudent) } just Runs
- itemsSlot.captured.filterIsInstance().first().let {
- it.onClick(it)
- }
+ presenter.onItemSelected(StudentWithSemesters(testStudent, emptyList()), false)
presenter.onSignIn()
verify { loginStudentSelectView.showContent(false) }
diff --git a/app/src/test/java/io/github/wulkanowy/utils/SemesterExtensionKtTest.kt b/app/src/test/java/io/github/wulkanowy/utils/SemesterExtensionKtTest.kt
deleted file mode 100644
index b7d3ecc94..000000000
--- a/app/src/test/java/io/github/wulkanowy/utils/SemesterExtensionKtTest.kt
+++ /dev/null
@@ -1,72 +0,0 @@
-package io.github.wulkanowy.utils
-
-import io.github.wulkanowy.data.db.entities.Semester
-import io.github.wulkanowy.getSemesterEntity
-import org.junit.Test
-import java.time.LocalDate
-import kotlin.test.assertEquals
-
-class SemesterExtensionKtTest {
-
- @Test(expected = IllegalArgumentException::class)
- fun `get current semester when current is doubled`() {
- val semesters = listOf(
- getSemesterEntity(1, 1, LocalDate.now(), LocalDate.now()),
- getSemesterEntity(1, 1, LocalDate.now(), LocalDate.now())
- )
-
- semesters.getCurrentOrLast()
- }
-
- @Test(expected = RuntimeException::class)
- fun `get current semester when there is empty list`() {
- val semesters = listOf()
-
- semesters.getCurrentOrLast()
- }
-
- @Test
- fun `get current kindergarten semester when there is no any current`() {
- val semesters = listOf(
- createSemesterEntity(
- kindergartenDiaryId = 281,
- schoolYear = 2020,
- semesterId = 0,
- start = LocalDate.of(2020, 9, 1),
- end = LocalDate.of(2021, 8, 31),
- ),
- createSemesterEntity(
- kindergartenDiaryId = 342,
- schoolYear = 2021,
- semesterId = 0,
- start = LocalDate.of(2021, 9, 1),
- end = LocalDate.of(2022, 8, 31),
- ),
- )
-
- val res = semesters.getCurrentOrLast()
-
- assertEquals(2021, res.schoolYear)
- }
-
- private fun createSemesterEntity(
- diaryId: Int = 0,
- kindergartenDiaryId: Int = 0,
- semesterId: Int = 0,
- schoolYear: Int = 0,
- start: LocalDate = LocalDate.now(),
- end: LocalDate = LocalDate.now().plusMonths(6),
- ) = Semester(
- studentId = 1,
- diaryId = diaryId,
- kindergartenDiaryId = kindergartenDiaryId,
- semesterId = semesterId,
- diaryName = "$semesterId",
- schoolYear = schoolYear,
- classId = 0,
- semesterName = semesterId,
- unitId = 1,
- start = start,
- end = end
- )
-}
diff --git a/build.gradle b/build.gradle
index 87e201acb..98c9dfb84 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,8 +1,8 @@
buildscript {
ext {
- kotlin_version = '1.7.21'
- about_libraries = '10.5.2'
- hilt_version = "2.44.2"
+ kotlin_version = '1.7.10'
+ about_libraries = '10.4.0'
+ hilt_version = "2.43.2"
}
repositories {
mavenCentral()
@@ -13,14 +13,14 @@ buildscript {
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
- classpath 'com.android.tools.build:gradle:7.3.1'
+ classpath 'com.android.tools.build:gradle:7.2.2'
classpath "com.google.dagger:hilt-android-gradle-plugin:$hilt_version"
- classpath 'com.google.gms:google-services:4.3.14'
- classpath 'com.huawei.agconnect:agcp:1.7.3.302'
- classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.2'
+ classpath 'com.google.gms:google-services:4.3.13'
+ classpath 'com.huawei.agconnect:agcp:1.7.1.300'
+ classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.1'
classpath "com.github.triplet.gradle:play-publisher:3.6.0"
classpath "ru.cian:huawei-publish-gradle-plugin:1.3.4"
- classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:3.5.0.2730"
+ classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:3.4.0.2513"
classpath "gradle.plugin.com.star-zero.gradle:githook:1.2.0"
classpath "com.mikepenz.aboutlibraries.plugin:aboutlibraries-plugin:$about_libraries"
}
@@ -31,7 +31,6 @@ allprojects {
mavenCentral()
google()
maven { url "https://jitpack.io" }
- maven { url "https://s01.oss.sonatype.org/content/repositories/snapshots/" }
maven { url "https://developer.huawei.com/repo/" }
}
}
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index 41d9927a4..7454180f2 100644
Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index f42e62f37..d7e66b5c6 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.1-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists