1
0

Compare commits

...

78 Commits

Author SHA1 Message Date
4f60673e4e Merge branch 'release/0.14.0' 2019-12-25 16:52:28 +01:00
7bd4fd7cbd Version 0.14.0 2019-12-25 16:52:17 +01:00
65995cdc6c Change Wulkanowy API link to SDK in README (#626) 2019-12-24 16:51:35 +01:00
9d27723f30 Don't copy teacher from previous lesson with changes if new one… (#622) 2019-12-22 20:19:31 +01:00
2e7d2b66f8 Fix lucky number empty screen (#623) 2019-12-22 20:18:48 +01:00
304c49d61e Migration to Wulkanowy SDK (#336) 2019-12-22 00:14:46 +01:00
826ea32fc0 Bump room from 2.2.2 to 2.2.3 (#618) 2019-12-20 10:18:00 +00:00
d70c4fa9fe Bump work_manager from 2.3.0-beta01 to 2.3.0-beta02 (#620) 2019-12-20 09:46:28 +00:00
bc43359467 Bump mockito-inline from 3.2.0 to 3.2.4 (#621) 2019-12-20 09:44:18 +00:00
cf286f3c23 Bump mockito-android from 3.2.0 to 3.2.4 (#619) 2019-12-20 09:27:14 +00:00
57abd43214 Bump fragment-ktx from 1.2.0-rc03 to 1.2.0-rc04 (#617) 2019-12-20 09:24:51 +00:00
90bdc9d157 Bump material from 1.1.0-beta02 to 1.1.0-rc01 (#616) 2019-12-20 09:13:34 +00:00
93bce685bd Bump dagger from 2.25.2 to 2.25.3 (#614) 2019-12-20 09:07:39 +00:00
4639a075b0 Bump rxjava from 2.2.15 to 2.2.16 (#615) 2019-12-20 09:06:52 +00:00
91f63da6d0 Fixed capitalization in the about tab (en) (#613) 2019-12-09 17:35:18 +01:00
3894c9d48e Fixed letter capitalization in the About tab (pl) (#612) 2019-12-09 17:34:58 +01:00
fb40701962 Merge tag '0.13.0' into develop
Version 0.13.0
2019-12-07 23:04:39 +01:00
ff1e794820 Merge branch 'release/0.13.0' 2019-12-07 23:04:26 +01:00
ceba5f7fe8 Version 0.13.0 2019-12-07 23:04:17 +01:00
f570acbed6 Add FAQ link (#611) 2019-12-07 22:06:15 +01:00
2a7a472d90 Bump fragment-ktx from 1.2.0-rc02 to 1.2.0-rc03 (#610) 2019-12-07 16:07:36 +00:00
138fbe5bf5 Bump activity-ktx from 1.1.0-rc02 to 1.1.0-rc03 (#608) 2019-12-07 12:51:40 +00:00
ad99cc75eb Bump gradle from 3.5.2 to 3.5.3 (#609) 2019-12-07 12:51:24 +00:00
f6606e7a4f Bump coordinatorlayout from 1.1.0-rc01 to 1.1.0 (#607) 2019-12-07 12:51:09 +00:00
3690deef1e Bump mockito-android from 3.1.0 to 3.2.0 (#605) 2019-12-02 16:19:20 +00:00
cd1438587d Bump kotlin_version from 1.3.60 to 1.3.61 (#606) 2019-12-02 16:18:56 +00:00
8193a57227 Bump mockito-inline from 3.1.0 to 3.2.0 (#604) 2019-12-02 16:18:27 +00:00
8467f39ad9 Add russian language (#595) 2019-11-29 20:43:37 +01:00
0fc293f47a Bump assisted-inject-processor-dagger2 from 0.5.1 to 0.5.2 (#601) 2019-11-25 17:15:23 +00:00
9b063edb0b Bump rxjava from 2.2.14 to 2.2.15 (#603) 2019-11-25 16:48:56 +00:00
5d852eee87 Bump assisted-inject-annotations-dagger2 from 0.5.1 to 0.5.2 (#602) 2019-11-25 16:48:07 +00:00
54ab408135 Add error view showing on first loading in fragment view (#590) 2019-11-24 17:05:09 +01:00
41aa326f42 Add 0,00 grade modifier (#596) 2019-11-21 17:41:41 +01:00
24f605c71c Bump work_manager from 2.3.0-alpha03 to 2.3.0-beta01 (#600) 2019-11-21 11:00:11 +00:00
5c52dcc74f Bump room from 2.2.1 to 2.2.2 (#599) 2019-11-21 10:31:14 +00:00
667659fbe6 Bump core-ktx from 1.2.0-beta02 to 1.2.0-rc01 (#598) 2019-11-21 10:30:51 +00:00
d467bf096f Bump recyclerview from 1.1.0-rc01 to 1.1.0 (#597) 2019-11-21 10:28:54 +00:00
98d556bcd5 Bump kotlin_version from 1.3.50 to 1.3.60 (#594) 2019-11-18 10:57:50 +01:00
8c730be635 Bump google-services from 4.3.2 to 4.3.3 (#591) 2019-11-18 08:58:17 +00:00
377d24fbb4 Bump sonarqube-gradle-plugin from 2.8 to 2.8.0.1969 (#593) 2019-11-18 08:26:46 +00:00
bde810e031 Fix screens loading state (#589) 2019-11-17 01:07:43 +01:00
2f18d42c86 Update material design components (#587) 2019-11-10 16:45:53 +01:00
c708b0c20e Bump activity-ktx from 1.1.0-rc01 to 1.1.0-rc02 (#586) 2019-11-09 13:35:59 +00:00
ff8d55d4f8 Bump fragment-ktx from 1.2.0-rc01 to 1.2.0-rc02 (#585) 2019-11-09 13:08:02 +00:00
49bf911c84 Bump core-ktx from 1.2.0-beta01 to 1.2.0-beta02 (#584) 2019-11-09 13:07:27 +00:00
9e33ef419f Fix LuckyNumberWidget not showing ThemeDialog (#583) 2019-11-09 13:59:33 +01:00
40e95eac1e Add BaseDao interface (#581) 2019-11-06 23:52:14 +01:00
19e76a0b5d Bump rxjava from 2.2.13 to 2.2.14 (#580) 2019-11-04 19:23:50 +00:00
5feafe3907 Update gradle wrapper (#579) 2019-11-03 15:07:32 +01:00
b7206ed714 Add DatePicker to Timetable and Attendance modules. (#522) 2019-11-03 14:52:35 +01:00
38370d647d Add language change settings (#577) 2019-11-03 12:37:03 +01:00
323bc188b1 Bump assisted-inject-annotations-dagger2 from 0.5.0 to 0.5.1 (#576) 2019-11-01 20:20:09 +00:00
b17356591a Bump assisted-inject-processor-dagger2 from 0.5.0 to 0.5.1 (#575) 2019-11-01 19:50:28 +00:00
a02c444cf5 Merge tag '0.12.0' into develop
0.12.0
2019-10-29 00:25:17 +01:00
87a133beb9 Merge branch 'release/0.12.0' 2019-10-29 00:25:12 +01:00
1f4a208857 Version 0.12.0 2019-10-29 00:25:03 +01:00
a7c472989c Add support for edu.lublin.eu (#571) 2019-10-28 21:10:58 +01:00
747696e386 Bump firebase-core from 17.2.0 to 17.2.1 (#572) 2019-10-28 14:58:10 +00:00
a71a183160 Add school quick actions (#570) 2019-10-27 00:36:39 +02:00
125a010f03 Fix restoring state in exposed dropdown menu (#569) 2019-10-24 22:56:49 +02:00
5c5993cc2a Change FAB to extended FAB in messages (#536) 2019-10-24 18:45:05 +02:00
f234b71932 Bump dagger from 2.24 to 2.25.2 (#564) 2019-10-24 18:24:22 +02:00
497a3391d4 Bump fragment-ktx from 1.2.0-beta02 to 1.2.0-rc01 (#568) 2019-10-24 06:58:42 +00:00
a72c743c6f Bump work_manager from 2.3.0-alpha02 to 2.3.0-alpha03 (#563) 2019-10-24 06:37:24 +00:00
98fdfd001a Bump recyclerview from 1.1.0-beta05 to 1.1.0-rc01 (#566) 2019-10-24 06:17:11 +00:00
994b162ae3 Bump activity-ktx from 1.1.0-beta01 to 1.1.0-rc01 (#567) 2019-10-24 06:16:51 +00:00
90c60f399b Bump coordinatorlayout from 1.1.0-beta01 to 1.1.0-rc01 (#565) 2019-10-24 06:15:58 +00:00
b16b225a1a Bump room from 2.2.0 to 2.2.1 (#562) 2019-10-24 05:55:08 +00:00
7a4cf694ca Add school info (#557)
* Add db layer to school info

* Add base classes

* Add database migration

* Add base view

* Update icon

* Fix textviews height

* Handle error and empty results

* Improve school info look

* Add strings

* Fix action bar elevation in school fragment

* Add missing blank lines

* Reorganize strings

* Make field title first in order

* Make fields views selectable

* Rename SchoolInfo to School
2019-10-21 21:25:15 +02:00
1b492d50fe Bump aboutlibraries from 7.0.3 to 7.0.4 (#559) 2019-10-21 19:23:41 +00:00
d9b5e000f8 Bump gradle from 1.31.1 to 1.31.2 (#560) 2019-10-21 19:23:13 +00:00
7e30524876 Contact info after failed login (#556) 2019-10-20 19:10:32 +02:00
ce9b12eb93 Add system theme setting for Android 10 (#554) 2019-10-16 22:27:16 +02:00
b602657d55 Move default preferences values to separate file (#555) 2019-10-16 20:10:24 +02:00
360dfbcdb5 Update androidx dependencies (#553) 2019-10-15 19:15:28 +02:00
f466497970 Bump recyclerview from 1.1.0-beta04 to 1.1.0-beta05 (#551) 2019-10-11 21:56:19 +00:00
184a7ab200 Bump room from 2.2.0-rc01 to 2.2.0 (#552) 2019-10-11 21:55:28 +00:00
2e5ef7dfa2 Merge tag '0.11.0' into develop
Version 0.11.0
2019-10-07 00:11:59 +02:00
285 changed files with 8906 additions and 1173 deletions

View File

@ -14,7 +14,7 @@ cache:
branches: branches:
only: only:
- develop - develop
- 0.11.0 - 0.14.0
android: android:
licenses: licenses:

View File

@ -46,7 +46,7 @@ You can also download a [development version](https://wulkanowy.github.io/#downl
## Built With ## Built With
* [Wulkanowy API](https://github.com/wulkanowy/api) * [Wulkanowy SDK](https://github.com/wulkanowy/sdk)
* [RxJava 2](https://github.com/ReactiveX/RxJava) * [RxJava 2](https://github.com/ReactiveX/RxJava)
* [Dagger 2](https://github.com/google/dagger) * [Dagger 2](https://github.com/google/dagger)
* [Room](https://developer.android.com/topic/libraries/architecture/room) * [Room](https://developer.android.com/topic/libraries/architecture/room)

View File

@ -47,7 +47,7 @@ Możesz także pobrać [wersję rozwojową](https://wulkanowy.github.io/#downloa
## Zbudowana za pomocą ## Zbudowana za pomocą
* [Wulkanowy API](https://github.com/wulkanowy/api) * [Wulkanowy SDK](https://github.com/wulkanowy/SDK)
* [RxJava 2](https://github.com/ReactiveX/RxJava) * [RxJava 2](https://github.com/ReactiveX/RxJava)
* [Dagger 2](https://github.com/google/dagger) * [Dagger 2](https://github.com/google/dagger)
* [Room](https://developer.android.com/topic/libraries/architecture/room) * [Room](https://developer.android.com/topic/libraries/architecture/room)

View File

@ -17,8 +17,8 @@ android {
testApplicationId "io.github.tests.wulkanowy" testApplicationId "io.github.tests.wulkanowy"
minSdkVersion 16 minSdkVersion 16
targetSdkVersion 29 targetSdkVersion 29
versionCode 46 versionCode 49
versionName "0.11.0" versionName "0.14.0"
multiDexEnabled true multiDexEnabled true
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true vectorDrawables.useSupportLibrary = true
@ -110,37 +110,36 @@ play {
} }
ext { ext {
work_manager = "2.2.0" work_manager = "2.3.0-beta02"
room = "2.2.0-rc01" room = "2.2.3"
dagger = "2.24" dagger = "2.25.3"
chucker = "2.0.4" chucker = "2.0.4"
mockk = "1.9.2" mockk = "1.9.2"
} }
configurations.all { configurations.all {
resolutionStrategy.force "androidx.constraintlayout:constraintlayout:1.1.3" resolutionStrategy.force "androidx.constraintlayout:constraintlayout:1.1.3"
resolutionStrategy.force "com.google.android.material:material:1.1.0-alpha07"
} }
dependencies { dependencies {
implementation "io.github.wulkanowy:api:0.11.0" implementation "io.github.wulkanowy:sdk:0.14.0"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation "androidx.core:core-ktx:1.1.0" implementation "androidx.core:core-ktx:1.2.0-rc01"
implementation "androidx.activity:activity-ktx:1.0.0" implementation "androidx.activity:activity-ktx:1.1.0-rc03"
implementation "androidx.appcompat:appcompat:1.1.0" implementation "androidx.appcompat:appcompat:1.1.0"
implementation "androidx.appcompat:appcompat-resources:1.1.0" implementation "androidx.appcompat:appcompat-resources:1.1.0"
implementation "androidx.fragment:fragment-ktx:1.1.0" implementation "androidx.fragment:fragment-ktx:1.2.0-rc04"
implementation "androidx.annotation:annotation:1.1.0" implementation "androidx.annotation:annotation:1.1.0"
implementation "androidx.multidex:multidex:2.0.1" implementation "androidx.multidex:multidex:2.0.1"
implementation "androidx.preference:preference-ktx:1.1.0" implementation "androidx.preference:preference-ktx:1.1.0"
implementation "androidx.recyclerview:recyclerview:1.1.0-beta04" implementation "androidx.recyclerview:recyclerview:1.1.0"
implementation "androidx.viewpager:viewpager:1.0.0" implementation "androidx.viewpager:viewpager:1.0.0"
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0" implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0-alpha03"
implementation "androidx.constraintlayout:constraintlayout:1.1.3" implementation "androidx.constraintlayout:constraintlayout:1.1.3"
implementation "androidx.coordinatorlayout:coordinatorlayout:1.1.0-beta01" implementation "androidx.coordinatorlayout:coordinatorlayout:1.1.0"
implementation "com.google.android.material:material:1.1.0-alpha07" implementation "com.google.android.material:material:1.1.0-rc01"
implementation "com.github.wulkanowy:material-chips-input:2.0.1" implementation "com.github.wulkanowy:material-chips-input:2.0.1"
implementation "com.github.PhilJay:MPAndroidChart:v3.1.0" implementation "com.github.PhilJay:MPAndroidChart:v3.1.0"
implementation "me.zhanghai.android.materialprogressbar:library:1.6.1" implementation "me.zhanghai.android.materialprogressbar:library:1.6.1"
@ -157,26 +156,28 @@ dependencies {
implementation "com.google.dagger:dagger-android-support:$dagger" implementation "com.google.dagger:dagger-android-support:$dagger"
kapt "com.google.dagger:dagger-compiler:$dagger" kapt "com.google.dagger:dagger-compiler:$dagger"
kapt "com.google.dagger:dagger-android-processor:$dagger" kapt "com.google.dagger:dagger-android-processor:$dagger"
implementation "com.squareup.inject:assisted-inject-annotations-dagger2:0.5.0" implementation "com.squareup.inject:assisted-inject-annotations-dagger2:0.5.2"
kapt "com.squareup.inject:assisted-inject-processor-dagger2:0.5.0" kapt "com.squareup.inject:assisted-inject-processor-dagger2:0.5.2"
implementation "eu.davidea:flexible-adapter:5.1.0" implementation "eu.davidea:flexible-adapter:5.1.0"
implementation "eu.davidea:flexible-adapter-ui:1.0.0" implementation "eu.davidea:flexible-adapter-ui:1.0.0"
implementation "com.aurelhubert:ahbottomnavigation:2.3.4" implementation "com.aurelhubert:ahbottomnavigation:2.3.4"
implementation "com.ncapdevi:frag-nav:3.3.0" implementation "com.ncapdevi:frag-nav:3.3.0"
implementation "com.github.YarikSOffice:lingver:1.1.0"
implementation "com.github.pwittchen:reactivenetwork-rx2:3.0.6" implementation "com.github.pwittchen:reactivenetwork-rx2:3.0.6"
implementation "io.reactivex.rxjava2:rxandroid:2.1.1" implementation "io.reactivex.rxjava2:rxandroid:2.1.1"
implementation "io.reactivex.rxjava2:rxjava:2.2.13" implementation "io.reactivex.rxjava2:rxjava:2.2.16"
implementation "com.google.code.gson:gson:2.8.6" implementation "com.google.code.gson:gson:2.8.6"
implementation "com.jakewharton.threetenabp:threetenabp:1.2.1" implementation "com.jakewharton.threetenabp:threetenabp:1.2.1"
implementation "com.jakewharton.timber:timber:4.7.1" implementation "com.jakewharton.timber:timber:4.7.1"
implementation "at.favre.lib:slf4j-timber:1.0.1" implementation "at.favre.lib:slf4j-timber:1.0.1"
implementation "com.squareup.okhttp3:logging-interceptor:3.12.6" implementation "com.squareup.okhttp3:logging-interceptor:3.12.6"
implementation "com.mikepenz:aboutlibraries:7.0.3" implementation "com.mikepenz:aboutlibraries:7.0.4"
implementation 'com.wdullaer:materialdatetimepicker:4.2.3'
playImplementation "com.google.firebase:firebase-core:17.2.0" playImplementation "com.google.firebase:firebase-core:17.2.1"
playImplementation "com.crashlytics.sdk.android:crashlytics:2.10.1" playImplementation "com.crashlytics.sdk.android:crashlytics:2.10.1"
releaseImplementation "fr.o80.chucker:library-no-op:$chucker" releaseImplementation "fr.o80.chucker:library-no-op:$chucker"
@ -187,7 +188,7 @@ dependencies {
testImplementation "junit:junit:4.12" testImplementation "junit:junit:4.12"
testImplementation "io.mockk:mockk:$mockk" testImplementation "io.mockk:mockk:$mockk"
testImplementation "org.threeten:threetenbp:1.4.0" testImplementation "org.threeten:threetenbp:1.4.0"
testImplementation "org.mockito:mockito-inline:3.1.0" testImplementation "org.mockito:mockito-inline:3.2.4"
androidTestImplementation "androidx.test:core:1.2.0" androidTestImplementation "androidx.test:core:1.2.0"
androidTestImplementation "androidx.test:runner:1.2.0" androidTestImplementation "androidx.test:runner:1.2.0"
@ -195,7 +196,7 @@ dependencies {
androidTestImplementation "io.mockk:mockk-android:$mockk" androidTestImplementation "io.mockk:mockk-android:$mockk"
androidTestImplementation "androidx.room:room-testing:$room" androidTestImplementation "androidx.room:room-testing:$room"
androidTestImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin_version" androidTestImplementation "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
androidTestImplementation "org.mockito:mockito-android:3.1.0" androidTestImplementation "org.mockito:mockito-android:3.2.4"
} }
apply plugin: 'com.google.gms.google-services' apply plugin: 'com.google.gms.google-services'

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,11 +1,13 @@
package io.github.wulkanowy.data.db.migrations package io.github.wulkanowy.data.db.migrations
import androidx.preference.PreferenceManager
import androidx.room.Room import androidx.room.Room
import androidx.room.testing.MigrationTestHelper import androidx.room.testing.MigrationTestHelper
import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory
import androidx.test.core.app.ApplicationProvider import androidx.test.core.app.ApplicationProvider
import androidx.test.platform.app.InstrumentationRegistry import androidx.test.platform.app.InstrumentationRegistry
import io.github.wulkanowy.data.db.AppDatabase import io.github.wulkanowy.data.db.AppDatabase
import io.github.wulkanowy.data.db.SharedPrefProvider
import org.junit.Rule import org.junit.Rule
abstract class AbstractMigrationTest { abstract class AbstractMigrationTest {
@ -22,7 +24,9 @@ abstract class AbstractMigrationTest {
fun getMigratedRoomDatabase(): AppDatabase { fun getMigratedRoomDatabase(): AppDatabase {
val database = Room.databaseBuilder(ApplicationProvider.getApplicationContext(), val database = Room.databaseBuilder(ApplicationProvider.getApplicationContext(),
AppDatabase::class.java, dbName) AppDatabase::class.java, dbName)
.addMigrations(*AppDatabase.getMigrations()) .addMigrations(*AppDatabase.getMigrations(SharedPrefProvider(PreferenceManager
.getDefaultSharedPreferences(ApplicationProvider.getApplicationContext())))
)
.build() .build()
// close the database and release any stream resources when the test finishes // close the database and release any stream resources when the test finishes
helper.closeWhenFinished(database) helper.closeWhenFinished(database)

View File

@ -6,15 +6,18 @@ import androidx.test.core.app.ApplicationProvider.getApplicationContext
import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SdkSuppress import androidx.test.filters.SdkSuppress
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
import io.github.wulkanowy.api.Api import io.github.wulkanowy.data.SdkHelper
import io.github.wulkanowy.data.db.AppDatabase import io.github.wulkanowy.data.db.AppDatabase
import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.repositories.TestInternetObservingStrategy import io.github.wulkanowy.data.repositories.TestInternetObservingStrategy
import io.github.wulkanowy.sdk.Sdk
import io.mockk.MockKAnnotations import io.mockk.MockKAnnotations
import io.mockk.every import io.mockk.every
import io.mockk.impl.annotations.MockK import io.mockk.impl.annotations.MockK
import io.mockk.impl.annotations.SpyK import io.mockk.impl.annotations.SpyK
import io.mockk.just
import io.mockk.runs
import io.reactivex.Single import io.reactivex.Single
import org.junit.After import org.junit.After
import org.junit.Before import org.junit.Before
@ -25,14 +28,13 @@ import org.threeten.bp.LocalDateTime
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.assertFalse import kotlin.test.assertFalse
import kotlin.test.assertTrue import kotlin.test.assertTrue
import io.github.wulkanowy.api.grades.Grade as GradeApi
@SdkSuppress(minSdkVersion = P) @SdkSuppress(minSdkVersion = P)
@RunWith(AndroidJUnit4::class) @RunWith(AndroidJUnit4::class)
class GradeRepositoryTest { class GradeRepositoryTest {
@SpyK @MockK
private var mockApi = Api() private lateinit var mockSdk: Sdk
private val settings = InternetObservingSettings.builder() private val settings = InternetObservingSettings.builder()
.strategy(TestInternetObservingStrategy()) .strategy(TestInternetObservingStrategy())
@ -55,13 +57,14 @@ class GradeRepositoryTest {
MockKAnnotations.init(this) MockKAnnotations.init(this)
testDb = Room.inMemoryDatabaseBuilder(getApplicationContext(), AppDatabase::class.java).build() testDb = Room.inMemoryDatabaseBuilder(getApplicationContext(), AppDatabase::class.java).build()
gradeLocal = GradeLocal(testDb.gradeDao) gradeLocal = GradeLocal(testDb.gradeDao)
gradeRemote = GradeRemote(mockApi) gradeRemote = GradeRemote(mockSdk)
every { mockApi.diaryId } returns 1
every { studentMock.registrationDate } returns LocalDateTime.of(2019, 2, 27, 12, 0) every { studentMock.registrationDate } returns LocalDateTime.of(2019, 2, 27, 12, 0)
every { semesterMock.studentId } returns 1 every { semesterMock.studentId } returns 1
every { semesterMock.semesterId } returns 1
every { semesterMock.diaryId } returns 1 every { semesterMock.diaryId } returns 1
every { semesterMock.schoolYear } returns 2019
every { semesterMock.semesterId } returns 1
every { mockSdk.switchDiary(any(), any()) } returns mockSdk
} }
@After @After
@ -71,7 +74,7 @@ class GradeRepositoryTest {
@Test @Test
fun markOlderThanRegisterDateAsRead() { fun markOlderThanRegisterDateAsRead() {
every { mockApi.getGrades(1) } returns Single.just(listOf( every { mockSdk.getGrades(1) } returns Single.just(listOf(
createGradeApi(5, 4.0, of(2019, 2, 25), "Ocena pojawiła się"), createGradeApi(5, 4.0, of(2019, 2, 25), "Ocena pojawiła się"),
createGradeApi(5, 4.0, of(2019, 2, 26), "przed zalogowanie w aplikacji"), createGradeApi(5, 4.0, of(2019, 2, 26), "przed zalogowanie w aplikacji"),
createGradeApi(5, 4.0, of(2019, 2, 27), "Ocena z dnia logowania"), createGradeApi(5, 4.0, of(2019, 2, 27), "Ocena z dnia logowania"),
@ -95,7 +98,7 @@ class GradeRepositoryTest {
createGradeLocal(3, 5.0, of(2019, 2, 27), "Trzecia") createGradeLocal(3, 5.0, of(2019, 2, 27), "Trzecia")
)) ))
every { mockApi.getGrades(1) } returns Single.just(listOf( every { mockSdk.getGrades(1) } returns Single.just(listOf(
createGradeApi(5, 2.0, of(2019, 2, 25), "Ocena ma datę, jest inna, ale nie zostanie powiadomiona"), createGradeApi(5, 2.0, of(2019, 2, 25), "Ocena ma datę, jest inna, ale nie zostanie powiadomiona"),
createGradeApi(4, 3.0, of(2019, 2, 26), "starszą niż ostatnia lokalnie"), createGradeApi(4, 3.0, of(2019, 2, 26), "starszą niż ostatnia lokalnie"),
createGradeApi(3, 4.0, of(2019, 2, 27), "Ta jest z tego samego dnia co ostatnia lokalnie"), createGradeApi(3, 4.0, of(2019, 2, 27), "Ta jest z tego samego dnia co ostatnia lokalnie"),
@ -119,7 +122,7 @@ class GradeRepositoryTest {
createGradeLocal(3, 5.0, of(2019, 2, 26), "Jakaś inna ocena") createGradeLocal(3, 5.0, of(2019, 2, 26), "Jakaś inna ocena")
)) ))
every { mockApi.getGrades(1) } returns Single.just(listOf( every { mockSdk.getGrades(1) } returns Single.just(listOf(
createGradeApi(5, 3.0, of(2019, 2, 25), "Taka sama ocena"), createGradeApi(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
createGradeApi(3, 5.0, of(2019, 2, 26), "Jakaś inna ocena") createGradeApi(3, 5.0, of(2019, 2, 26), "Jakaś inna ocena")
)) ))
@ -137,7 +140,7 @@ class GradeRepositoryTest {
createGradeLocal(3, 5.0, of(2019, 2, 26), "Jakaś inna ocena") createGradeLocal(3, 5.0, of(2019, 2, 26), "Jakaś inna ocena")
)) ))
every { mockApi.getGrades(1) } returns Single.just(listOf( every { mockSdk.getGrades(1) } returns Single.just(listOf(
createGradeApi(5, 3.0, of(2019, 2, 25), "Taka sama ocena"), createGradeApi(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
createGradeApi(5, 3.0, of(2019, 2, 25), "Taka sama ocena"), createGradeApi(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
createGradeApi(3, 5.0, of(2019, 2, 26), "Jakaś inna ocena") createGradeApi(3, 5.0, of(2019, 2, 26), "Jakaś inna ocena")
@ -153,7 +156,7 @@ class GradeRepositoryTest {
fun emptyLocal() { fun emptyLocal() {
gradeLocal.saveGrades(listOf()) gradeLocal.saveGrades(listOf())
every { mockApi.getGrades(1) } returns Single.just(listOf( every { mockSdk.getGrades(1) } returns Single.just(listOf(
createGradeApi(5, 3.0, of(2019, 2, 25), "Taka sama ocena"), createGradeApi(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
createGradeApi(5, 3.0, of(2019, 2, 25), "Taka sama ocena"), createGradeApi(5, 3.0, of(2019, 2, 25), "Taka sama ocena"),
createGradeApi(3, 5.0, of(2019, 2, 26), "Jakaś inna ocena") createGradeApi(3, 5.0, of(2019, 2, 26), "Jakaś inna ocena")
@ -172,7 +175,7 @@ class GradeRepositoryTest {
createGradeLocal(3, 5.0, of(2019, 2, 26), "Jakaś inna ocena") createGradeLocal(3, 5.0, of(2019, 2, 26), "Jakaś inna ocena")
)) ))
every { mockApi.getGrades(1) } returns Single.just(listOf()) every { mockSdk.getGrades(1) } returns Single.just(listOf())
val grades = GradeRepository(settings, gradeLocal, gradeRemote) val grades = GradeRepository(settings, gradeLocal, gradeRemote)
.getGrades(studentMock, semesterMock, true).blockingGet() .getGrades(studentMock, semesterMock, true).blockingGet()

View File

@ -1,8 +1,7 @@
package io.github.wulkanowy.data.repositories.grade package io.github.wulkanowy.data.repositories.grade
import io.github.wulkanowy.api.toDate
import org.threeten.bp.LocalDate import org.threeten.bp.LocalDate
import io.github.wulkanowy.api.grades.Grade as GradeRemote import io.github.wulkanowy.sdk.pojo.Grade as GradeRemote
import io.github.wulkanowy.data.db.entities.Grade as GradeLocal import io.github.wulkanowy.data.db.entities.Grade as GradeLocal
fun createGradeLocal(value: Int, weight: Double, date: LocalDate, desc: String, semesterId: Int = 1): GradeLocal { fun createGradeLocal(value: Int, weight: Double, date: LocalDate, desc: String, semesterId: Int = 1): GradeLocal {
@ -18,17 +17,25 @@ fun createGradeLocal(value: Int, weight: Double, date: LocalDate, desc: String,
description = desc, description = desc,
entry = "", entry = "",
gradeSymbol = "", gradeSymbol = "",
value = value, value = value.toDouble(),
weight = "", weight = "",
weightValue = weight weightValue = weight
) )
} }
fun createGradeApi(value: Int, weight: Double, date: LocalDate, desc: String): GradeRemote { fun createGradeApi(value: Int, weight: Double, date: LocalDate, desc: String): GradeRemote {
return GradeRemote().apply { return GradeRemote(
this.value = value subject = "",
this.weightValue = weight color = "",
this.date = date.toDate() comment = "",
this.description = desc date = date,
} description = desc,
entry = "",
modifier = .0,
symbol = "",
teacher = "",
value = value.toDouble(),
weight = weight.toString(),
weightValue = weight
)
} }

View File

@ -42,7 +42,7 @@ class RecipientLocalTest {
)) ))
val recipients = recipientLocal.getRecipients( val recipients = recipientLocal.getRecipients(
Student("fakelog.cf", "AUTO", "", "", "", 1, "", "", "", "", 1, true, LocalDateTime.now()), Student("fakelog.cf", "AUTO", "", "", "", "", false, "", "", "", 1, 0, "", "", "", "", 1, true, LocalDateTime.now()),
2, 2,
ReportingUnit(1, 4, "", 0, "", emptyList()) ReportingUnit(1, 4, "", 0, "", emptyList())
).blockingGet() ).blockingGet()

View File

@ -39,7 +39,7 @@ class StudentLocalTest {
@Test @Test
fun saveAndReadTest() { fun saveAndReadTest() {
studentLocal.saveStudents(listOf(Student(email = "test", password = "test123", schoolSymbol = "23", endpoint = "fakelog.cf", loginType = "AUTO", isCurrent = true, studentName = "", schoolName = "", studentId = 0, classId = 1, symbol = "", registrationDate = now(), className = ""))) studentLocal.saveStudents(listOf(Student(email = "test", password = "test123", schoolSymbol = "23", scrapperBaseUrl = "fakelog.cf", loginType = "AUTO", isCurrent = true, studentName = "", schoolName = "", studentId = 0, classId = 1, symbol = "", registrationDate = now(), className = "", loginMode = "API", certificateKey = "", privateKey = "", mobileBaseUrl = "", userLoginId = 0, isParent = false)))
.blockingGet() .blockingGet()
val student = studentLocal.getCurrentStudent(true).blockingGet() val student = studentLocal.getCurrentStudent(true).blockingGet()

View File

@ -1,13 +1,11 @@
package io.github.wulkanowy.data.repositories.timetable package io.github.wulkanowy.data.repositories.timetable
import io.github.wulkanowy.api.toDate
import io.github.wulkanowy.utils.toDate
import org.threeten.bp.LocalDateTime import org.threeten.bp.LocalDateTime
import org.threeten.bp.LocalDateTime.now import org.threeten.bp.LocalDateTime.now
import io.github.wulkanowy.api.timetable.Timetable as TimetableRemote import io.github.wulkanowy.sdk.pojo.Timetable as TimetableRemote
import io.github.wulkanowy.data.db.entities.Timetable as TimetableLocal import io.github.wulkanowy.data.db.entities.Timetable as TimetableLocal
fun createTimetableLocal(number: Int, start: LocalDateTime, room: String = "", subject: String = "", teacher: String = "", changes: Boolean = false): TimetableLocal { fun createTimetableLocal(start: LocalDateTime, number: Int, room: String = "", subject: String = "", teacher: String = "", changes: Boolean = false): TimetableLocal {
return TimetableLocal( return TimetableLocal(
studentId = 1, studentId = 1,
diaryId = 2, diaryId = 2,
@ -28,18 +26,22 @@ fun createTimetableLocal(number: Int, start: LocalDateTime, room: String = "", s
) )
} }
fun createTimetableRemote(number: Int, start: LocalDateTime, room: String, subject: String = "", teacher: String = "", changes: Boolean = false): TimetableRemote { fun createTimetableRemote(start: LocalDateTime, number: Int = 1, room: String = "", subject: String = "", teacher: String = "", changes: Boolean = false): TimetableRemote {
return TimetableRemote( return TimetableRemote(
number = number, number = number,
start = start.toDate(), start = start,
end = start.plusMinutes(45).toDate(), end = start.plusMinutes(45),
date = start.toLocalDate().toDate(), date = start.toLocalDate(),
subject = subject, subject = subject,
group = "", group = "",
room = room, room = room,
teacher = teacher, teacher = teacher,
info = "", info = "",
changes = changes, changes = changes,
canceled = false canceled = false,
roomOld = "",
subjectOld = "",
teacherOld = "",
studentPlan = true
) )
} }

View File

@ -35,9 +35,9 @@ class TimetableLocalTest {
@Test @Test
fun saveAndReadTest() { fun saveAndReadTest() {
timetableDb.saveTimetable(listOf( timetableDb.saveTimetable(listOf(
createTimetableLocal(1, of(2018, 9, 10, 0, 0, 0)), createTimetableLocal(of(2018, 9, 10, 0, 0, 0), 1),
createTimetableLocal(1, of(2018, 9, 14, 0, 0, 0)), createTimetableLocal(of(2018, 9, 14, 0, 0, 0), 1),
createTimetableLocal(1, of(2018, 9, 17, 0, 0, 0)) createTimetableLocal(of(2018, 9, 17, 0, 0, 0), 1)
)) ))
val exams = timetableDb.getTimetable( val exams = timetableDb.getTimetable(

View File

@ -6,14 +6,13 @@ import androidx.test.core.app.ApplicationProvider.getApplicationContext
import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SdkSuppress import androidx.test.filters.SdkSuppress
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
import io.github.wulkanowy.api.Api
import io.github.wulkanowy.data.db.AppDatabase import io.github.wulkanowy.data.db.AppDatabase
import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.repositories.TestInternetObservingStrategy import io.github.wulkanowy.data.repositories.TestInternetObservingStrategy
import io.github.wulkanowy.sdk.Sdk
import io.mockk.MockKAnnotations import io.mockk.MockKAnnotations
import io.mockk.every import io.mockk.every
import io.mockk.impl.annotations.MockK import io.mockk.impl.annotations.MockK
import io.mockk.impl.annotations.SpyK
import io.reactivex.Single import io.reactivex.Single
import org.junit.After import org.junit.After
import org.junit.Before import org.junit.Before
@ -27,8 +26,8 @@ import kotlin.test.assertEquals
@RunWith(AndroidJUnit4::class) @RunWith(AndroidJUnit4::class)
class TimetableRepositoryTest { class TimetableRepositoryTest {
@SpyK @MockK
private var mockApi = Api() private lateinit var mockSdk: Sdk
private val settings = InternetObservingSettings.builder() private val settings = InternetObservingSettings.builder()
.strategy(TestInternetObservingStrategy()) .strategy(TestInternetObservingStrategy())
@ -48,10 +47,13 @@ class TimetableRepositoryTest {
MockKAnnotations.init(this) MockKAnnotations.init(this)
testDb = Room.inMemoryDatabaseBuilder(getApplicationContext(), AppDatabase::class.java).build() testDb = Room.inMemoryDatabaseBuilder(getApplicationContext(), AppDatabase::class.java).build()
timetableLocal = TimetableLocal(testDb.timetableDao) timetableLocal = TimetableLocal(testDb.timetableDao)
timetableRemote = TimetableRemote(mockApi) timetableRemote = TimetableRemote(mockSdk)
every { semesterMock.studentId } returns 1 every { semesterMock.studentId } returns 1
every { semesterMock.diaryId } returns 2 every { semesterMock.diaryId } returns 2
every { semesterMock.schoolYear } returns 2019
every { semesterMock.semesterId } returns 1
every { mockSdk.switchDiary(any(), any()) } returns mockSdk
} }
@After @After
@ -62,17 +64,17 @@ class TimetableRepositoryTest {
@Test @Test
fun copyRoomToCompletedFromPrevious() { fun copyRoomToCompletedFromPrevious() {
timetableLocal.saveTimetable(listOf( timetableLocal.saveTimetable(listOf(
createTimetableLocal(1, of(2019, 3, 5, 8, 0), "123", "Przyroda"), createTimetableLocal(of(2019, 3, 5, 8, 0), 1, "123", "Przyroda"),
createTimetableLocal(2, of(2019, 3, 5, 8, 50), "321", "Religia"), createTimetableLocal(of(2019, 3, 5, 8, 50), 2, "321", "Religia"),
createTimetableLocal(3, of(2019, 3, 5, 9, 40), "213", "W-F"), createTimetableLocal(of(2019, 3, 5, 9, 40), 3, "213", "W-F"),
createTimetableLocal(4, of(2019, 3, 5, 10, 30), "213", "W-F", "Jan Kowalski") createTimetableLocal(of(2019, 3, 5, 10, 30),3, "213", "W-F", "Jan Kowalski")
)) ))
every { mockApi.getTimetable(any(), any()) } returns Single.just(listOf( every { mockSdk.getTimetable(any(), any()) } returns Single.just(listOf(
createTimetableRemote(1, of(2019, 3, 5, 8, 0), "", "Przyroda"), createTimetableRemote(of(2019, 3, 5, 8, 0), 1, "", "Przyroda"),
createTimetableRemote(2, of(2019, 3, 5, 8, 50), "", "Religia"), createTimetableRemote(of(2019, 3, 5, 8, 50), 2, "", "Religia"),
createTimetableRemote(3, of(2019, 3, 5, 9, 40), "", "W-F"), createTimetableRemote(of(2019, 3, 5, 9, 40), 3, "", "W-F"),
createTimetableRemote(4, of(2019, 3, 5, 10, 30), "", "W-F") createTimetableRemote(of(2019, 3, 5, 10, 30), 4, "", "W-F")
)) ))
val lessons = TimetableRepository(settings, timetableLocal, timetableRemote) val lessons = TimetableRepository(settings, timetableLocal, timetableRemote)
@ -88,27 +90,58 @@ class TimetableRepositoryTest {
@Test @Test
fun copyTeacherToCompletedFromPrevious() { fun copyTeacherToCompletedFromPrevious() {
timetableLocal.saveTimetable(listOf( timetableLocal.saveTimetable(listOf(
createTimetableLocal(1, of(2019, 3, 5, 8, 0), "123", "Przyroda", "Jan Garnkiewicz", false), createTimetableLocal(of(2019, 12, 23, 8, 0), 1, "123", "Matematyka", "Paweł Poniedziałkowski", false),
createTimetableLocal(2, of(2019, 3, 5, 8, 50), "321", "Religia", "Paweł Jumper", false), createTimetableLocal(of(2019, 12, 23, 8, 50), 2, "124", "Matematyka", "Paweł Poniedziałkowski", false),
createTimetableLocal(3, of(2019, 3, 5, 9, 40), "213", "W-F", "", true), createTimetableLocal(of(2019, 12, 23, 9, 40), 3, "125", "Język polski", "Joanna Wtorkowska", true),
createTimetableLocal(4, of(2019, 3, 5, 10, 30), "213", "W-F", "", false) createTimetableLocal(of(2019, 12, 23, 10, 40), 4, "126", "Język polski", "Joanna Wtorkowska", true),
createTimetableLocal(of(2019, 12, 24, 8, 0), 1, "123", "Język polski", "Joanna Wtorkowska", false),
createTimetableLocal(of(2019, 12, 24, 8, 50), 2, "124", "Język polski", "Joanna Wtorkowska", false),
createTimetableLocal(of(2019, 12, 24, 9, 40), 3, "125", "Język polski", "Joanna Środowska", true),
createTimetableLocal(of(2019, 12, 24, 10, 40), 4, "126", "Język polski", "Joanna Środowska", true),
createTimetableLocal(of(2019, 12, 25, 8, 0), 1, "123", "Matematyka", "", false),
createTimetableLocal(of(2019, 12, 25, 8, 50), 2, "124", "Matematyka", "", false),
createTimetableLocal(of(2019, 12, 25, 9, 40), 3, "125", "Matematyka", "", true),
createTimetableLocal(of(2019, 12, 25, 10, 40), 4, "126", "Matematyka", "", true)
)) ))
every { mockApi.getTimetable(any(), any()) } returns Single.just(listOf( every { mockSdk.getTimetable(any(), any()) } returns Single.just(listOf(
createTimetableRemote(1, of(2019, 3, 5, 8, 0), "", "Przyroda", "", true), // should override local createTimetableRemote(of(2019, 12, 23, 8, 0), 1, "123", "Matematyka", "Paweł Poniedziałkowski", false),
createTimetableRemote(2, of(2019, 3, 5, 8, 50), "", "Religia", "", false), createTimetableRemote(of(2019, 12, 23, 8, 50), 2, "124", "Matematyka", "Jakub Wtorkowski", true),
createTimetableRemote(3, of(2019, 3, 5, 9, 40), "", "W-F", "Jan Garnkiewicz", false), createTimetableRemote(of(2019, 12, 23, 9, 40), 3, "125", "Język polski", "Joanna Poniedziałkowska", false),
createTimetableRemote(4, of(2019, 3, 5, 10, 30), "", "W-F", "Paweł Jumper", false) createTimetableRemote(of(2019, 12, 23, 10, 40), 4, "126", "Język polski", "Joanna Wtorkowska", true),
createTimetableRemote(of(2019, 12, 24, 8, 0), 1, "123", "Język polski", "", false),
createTimetableRemote(of(2019, 12, 24, 8, 50), 2, "124", "Język polski", "", true),
createTimetableRemote(of(2019, 12, 24, 9, 40), 3, "125", "Język polski", "", false),
createTimetableRemote(of(2019, 12, 24, 10, 40), 4, "126", "Język polski", "", true),
createTimetableRemote(of(2019, 12, 25, 8, 0), 1, "123", "Matematyka", "Paweł Środowski", false),
createTimetableRemote(of(2019, 12, 25, 8, 50), 2, "124", "Matematyka", "Paweł Czwartkowski", true),
createTimetableRemote(of(2019, 12, 25, 9, 40), 3, "125", "Matematyka", "Paweł Środowski", false),
createTimetableRemote(of(2019, 12, 25, 10, 40), 4, "126", "Matematyka", "Paweł Czwartkowski", true)
)) ))
val lessons = TimetableRepository(settings, timetableLocal, timetableRemote) val lessons = TimetableRepository(settings, timetableLocal, timetableRemote)
.getTimetable(semesterMock, LocalDate.of(2019, 3, 5), LocalDate.of(2019, 3, 5), true) .getTimetable(semesterMock, LocalDate.of(2019, 12, 23), LocalDate.of(2019, 12, 25), true)
.blockingGet() .blockingGet()
assertEquals(4, lessons.size) assertEquals(12, lessons.size)
assertEquals("", lessons[0].teacher)
assertEquals("Paweł Jumper", lessons[1].teacher) assertEquals("Paweł Poniedziałkowski", lessons[0].teacher)
assertEquals("Jan Garnkiewicz", lessons[2].teacher) assertEquals("Jakub Wtorkowski", lessons[1].teacher)
assertEquals("Paweł Jumper", lessons[3].teacher) assertEquals("Joanna Poniedziałkowska", lessons[2].teacher)
assertEquals("Joanna Wtorkowska", lessons[3].teacher)
assertEquals("Joanna Wtorkowska", lessons[4].teacher)
assertEquals("", lessons[5].teacher)
assertEquals("", lessons[6].teacher)
assertEquals("", lessons[7].teacher)
assertEquals("Paweł Środowski", lessons[8].teacher)
assertEquals("Paweł Czwartkowski", lessons[9].teacher)
assertEquals("Paweł Środowski", lessons[10].teacher)
assertEquals("Paweł Czwartkowski", lessons[11].teacher)
} }
} }

View File

@ -1,3 +0,0 @@
<resources>
<string name="app_name">Wulkanowy DEV</string>
</resources>

View File

@ -6,6 +6,7 @@ import android.util.Log.VERBOSE
import androidx.multidex.MultiDex import androidx.multidex.MultiDex
import androidx.work.Configuration import androidx.work.Configuration
import com.jakewharton.threetenabp.AndroidThreeTen import com.jakewharton.threetenabp.AndroidThreeTen
import com.yariksoffice.lingver.Lingver
import dagger.android.AndroidInjector import dagger.android.AndroidInjector
import dagger.android.support.DaggerApplication import dagger.android.support.DaggerApplication
import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.FlexibleAdapter
@ -44,6 +45,7 @@ class WulkanowyApp : DaggerApplication(), Configuration.Provider {
super.onCreate() super.onCreate()
AndroidThreeTen.init(this) AndroidThreeTen.init(this)
RxJavaPlugins.setErrorHandler(::onError) RxJavaPlugins.setErrorHandler(::onError)
Lingver.init(this)
themeManager.applyDefaultTheme() themeManager.applyDefaultTheme()
initLogging() initLogging()

View File

@ -1,35 +0,0 @@
package io.github.wulkanowy.data
import io.github.wulkanowy.api.Api
import io.github.wulkanowy.data.db.entities.Student
import java.net.URL
import javax.inject.Inject
class ApiHelper @Inject constructor(private val api: Api) {
fun initApi(student: Student) {
api.apply {
email = student.email
password = student.password
symbol = student.symbol
schoolSymbol = student.schoolSymbol
studentId = student.studentId
classId = student.classId
host = URL(student.endpoint).run { host + ":$port".removeSuffix(":-1") }
ssl = student.endpoint.startsWith("https")
loginType = Api.LoginType.valueOf(student.loginType)
useNewStudent = true
}
}
fun initApi(email: String, password: String, symbol: String, endpoint: String) {
api.apply {
this.email = email
this.password = password
this.symbol = symbol
host = URL(endpoint).run { host + ":$port".removeSuffix(":-1") }
ssl = endpoint.startsWith("https")
useNewStudent = true
}
}
}

View File

@ -11,12 +11,10 @@ import com.readystatesoftware.chuck.api.ChuckInterceptor
import com.readystatesoftware.chuck.api.RetentionManager import com.readystatesoftware.chuck.api.RetentionManager
import dagger.Module import dagger.Module
import dagger.Provides import dagger.Provides
import io.github.wulkanowy.api.Api
import io.github.wulkanowy.data.db.AppDatabase import io.github.wulkanowy.data.db.AppDatabase
import io.github.wulkanowy.data.db.SharedPrefProvider
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
import okhttp3.logging.HttpLoggingInterceptor import io.github.wulkanowy.sdk.Sdk
import okhttp3.logging.HttpLoggingInterceptor.Level.BASIC
import okhttp3.logging.HttpLoggingInterceptor.Level.NONE
import timber.log.Timber import timber.log.Timber
import javax.inject.Singleton import javax.inject.Singleton
@ -33,15 +31,14 @@ internal class RepositoryModule {
@Singleton @Singleton
@Provides @Provides
fun provideApi(chuckCollector: ChuckCollector, context: Context): Api { fun provideSdk(chuckCollector: ChuckCollector, context: Context): Sdk {
return Api().apply { return Sdk().apply {
logLevel = NONE
androidVersion = android.os.Build.VERSION.RELEASE androidVersion = android.os.Build.VERSION.RELEASE
buildTag = android.os.Build.MODEL buildTag = android.os.Build.MODEL
setInterceptor(HttpLoggingInterceptor(HttpLoggingInterceptor.Logger { Timber.d(it) }).setLevel(BASIC)) setSimpleHttpLogger { Timber.d(it) }
// for debug only // for debug only
setInterceptor(ChuckInterceptor(context, chuckCollector).maxContentLength(250000L), true, 0) addInterceptor(ChuckInterceptor(context, chuckCollector).maxContentLength(250000L), true)
} }
} }
@ -55,7 +52,7 @@ internal class RepositoryModule {
@Singleton @Singleton
@Provides @Provides
fun provideDatabase(context: Context) = AppDatabase.newInstance(context) fun provideDatabase(context: Context, sharedPrefProvider: SharedPrefProvider) = AppDatabase.newInstance(context, sharedPrefProvider)
@Singleton @Singleton
@Provides @Provides
@ -144,4 +141,8 @@ internal class RepositoryModule {
@Singleton @Singleton
@Provides @Provides
fun provideTeacherDao(database: AppDatabase) = database.teacherDao fun provideTeacherDao(database: AppDatabase) = database.teacherDao
@Singleton
@Provides
fun provideSchoolInfoDao(database: AppDatabase) = database.schoolDao
} }

View File

@ -0,0 +1,30 @@
package io.github.wulkanowy.data
import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.sdk.Sdk
import javax.inject.Inject
class SdkHelper @Inject constructor(private val sdk: Sdk) {
fun init(student: Student) {
sdk.apply {
email = student.email
password = student.password
symbol = student.symbol
schoolSymbol = student.schoolSymbol
studentId = student.studentId
classId = student.classId
if (Sdk.Mode.valueOf(student.loginMode) != Sdk.Mode.API) {
scrapperBaseUrl = student.scrapperBaseUrl
loginType = Sdk.ScrapperLoginType.valueOf(student.loginType)
}
loginId = student.userLoginId
mode = Sdk.Mode.valueOf(student.loginMode)
mobileBaseUrl = student.mobileBaseUrl
certKey = student.certificateKey
privateKey = student.privateKey
}
}
}

View File

@ -22,6 +22,7 @@ import io.github.wulkanowy.data.db.dao.MobileDeviceDao
import io.github.wulkanowy.data.db.dao.NoteDao import io.github.wulkanowy.data.db.dao.NoteDao
import io.github.wulkanowy.data.db.dao.RecipientDao import io.github.wulkanowy.data.db.dao.RecipientDao
import io.github.wulkanowy.data.db.dao.ReportingUnitDao import io.github.wulkanowy.data.db.dao.ReportingUnitDao
import io.github.wulkanowy.data.db.dao.SchoolDao
import io.github.wulkanowy.data.db.dao.SemesterDao import io.github.wulkanowy.data.db.dao.SemesterDao
import io.github.wulkanowy.data.db.dao.StudentDao import io.github.wulkanowy.data.db.dao.StudentDao
import io.github.wulkanowy.data.db.dao.SubjectDao import io.github.wulkanowy.data.db.dao.SubjectDao
@ -42,6 +43,7 @@ import io.github.wulkanowy.data.db.entities.MobileDevice
import io.github.wulkanowy.data.db.entities.Note import io.github.wulkanowy.data.db.entities.Note
import io.github.wulkanowy.data.db.entities.Recipient import io.github.wulkanowy.data.db.entities.Recipient
import io.github.wulkanowy.data.db.entities.ReportingUnit import io.github.wulkanowy.data.db.entities.ReportingUnit
import io.github.wulkanowy.data.db.entities.School
import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.db.entities.Subject import io.github.wulkanowy.data.db.entities.Subject
@ -55,6 +57,8 @@ import io.github.wulkanowy.data.db.migrations.Migration14
import io.github.wulkanowy.data.db.migrations.Migration15 import io.github.wulkanowy.data.db.migrations.Migration15
import io.github.wulkanowy.data.db.migrations.Migration16 import io.github.wulkanowy.data.db.migrations.Migration16
import io.github.wulkanowy.data.db.migrations.Migration17 import io.github.wulkanowy.data.db.migrations.Migration17
import io.github.wulkanowy.data.db.migrations.Migration18
import io.github.wulkanowy.data.db.migrations.Migration19
import io.github.wulkanowy.data.db.migrations.Migration2 import io.github.wulkanowy.data.db.migrations.Migration2
import io.github.wulkanowy.data.db.migrations.Migration3 import io.github.wulkanowy.data.db.migrations.Migration3
import io.github.wulkanowy.data.db.migrations.Migration4 import io.github.wulkanowy.data.db.migrations.Migration4
@ -87,7 +91,8 @@ import javax.inject.Singleton
ReportingUnit::class, ReportingUnit::class,
Recipient::class, Recipient::class,
MobileDevice::class, MobileDevice::class,
Teacher::class Teacher::class,
School::class
], ],
version = AppDatabase.VERSION_SCHEMA, version = AppDatabase.VERSION_SCHEMA,
exportSchema = true exportSchema = true
@ -96,9 +101,9 @@ import javax.inject.Singleton
abstract class AppDatabase : RoomDatabase() { abstract class AppDatabase : RoomDatabase() {
companion object { companion object {
const val VERSION_SCHEMA = 17 const val VERSION_SCHEMA = 19
fun getMigrations(): Array<Migration> { fun getMigrations(sharedPrefProvider: SharedPrefProvider): Array<Migration> {
return arrayOf( return arrayOf(
Migration2(), Migration2(),
Migration3(), Migration3(),
@ -115,16 +120,18 @@ abstract class AppDatabase : RoomDatabase() {
Migration14(), Migration14(),
Migration15(), Migration15(),
Migration16(), Migration16(),
Migration17() Migration17(),
Migration18(),
Migration19(sharedPrefProvider)
) )
} }
fun newInstance(context: Context): AppDatabase { fun newInstance(context: Context, sharedPrefProvider: SharedPrefProvider): AppDatabase {
return Room.databaseBuilder(context, AppDatabase::class.java, "wulkanowy_database") return Room.databaseBuilder(context, AppDatabase::class.java, "wulkanowy_database")
.setJournalMode(TRUNCATE) .setJournalMode(TRUNCATE)
.fallbackToDestructiveMigrationFrom(VERSION_SCHEMA + 1) .fallbackToDestructiveMigrationFrom(VERSION_SCHEMA + 1)
.fallbackToDestructiveMigrationOnDowngrade() .fallbackToDestructiveMigrationOnDowngrade()
.addMigrations(*getMigrations()) .addMigrations(*getMigrations(sharedPrefProvider))
.build() .build()
} }
} }
@ -168,4 +175,6 @@ abstract class AppDatabase : RoomDatabase() {
abstract val mobileDeviceDao: MobileDeviceDao abstract val mobileDeviceDao: MobileDeviceDao
abstract val teacherDao: TeacherDao abstract val teacherDao: TeacherDao
abstract val schoolDao: SchoolDao
} }

View File

@ -8,12 +8,22 @@ import javax.inject.Singleton
@Singleton @Singleton
class SharedPrefProvider @Inject constructor(private val sharedPref: SharedPreferences) { class SharedPrefProvider @Inject constructor(private val sharedPref: SharedPreferences) {
companion object {
const val APP_VERSION_CODE_KEY = "app_version_code"
}
fun putLong(key: String, value: Long, sync: Boolean = false) { fun putLong(key: String, value: Long, sync: Boolean = false) {
sharedPref.edit(sync) { putLong(key, value) } sharedPref.edit(sync) { putLong(key, value) }
} }
fun getLong(key: String, defaultValue: Long) = sharedPref.getLong(key, defaultValue) fun getLong(key: String, defaultValue: Long) = sharedPref.getLong(key, defaultValue)
fun getString(key: String, defaultValue: String): String = sharedPref.getString(key, defaultValue) ?: defaultValue
fun putString(key: String, value: String, sync: Boolean = false) {
sharedPref.edit(sync) { putString(key, value) }
}
fun delete(key: String) { fun delete(key: String) {
sharedPref.edit().remove(key).apply() sharedPref.edit().remove(key).apply()
} }

View File

@ -1,8 +1,6 @@
package io.github.wulkanowy.data.db.dao package io.github.wulkanowy.data.db.dao
import androidx.room.Dao import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query import androidx.room.Query
import io.github.wulkanowy.data.db.entities.Attendance import io.github.wulkanowy.data.db.entities.Attendance
import io.reactivex.Maybe import io.reactivex.Maybe
@ -11,13 +9,7 @@ import javax.inject.Singleton
@Singleton @Singleton
@Dao @Dao
interface AttendanceDao { interface AttendanceDao : BaseDao<Attendance> {
@Insert
fun insertAll(exams: List<Attendance>): List<Long>
@Delete
fun deleteAll(exams: List<Attendance>)
@Query("SELECT * FROM Attendance WHERE diary_id = :diaryId AND student_id = :studentId AND date >= :from AND date <= :end") @Query("SELECT * FROM Attendance WHERE diary_id = :diaryId AND student_id = :studentId AND date >= :from AND date <= :end")
fun loadAll(diaryId: Int, studentId: Int, from: LocalDate, end: LocalDate): Maybe<List<Attendance>> fun loadAll(diaryId: Int, studentId: Int, from: LocalDate, end: LocalDate): Maybe<List<Attendance>>

View File

@ -1,20 +1,12 @@
package io.github.wulkanowy.data.db.dao package io.github.wulkanowy.data.db.dao
import androidx.room.Dao import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query import androidx.room.Query
import io.github.wulkanowy.data.db.entities.AttendanceSummary import io.github.wulkanowy.data.db.entities.AttendanceSummary
import io.reactivex.Maybe import io.reactivex.Maybe
@Dao @Dao
interface AttendanceSummaryDao { interface AttendanceSummaryDao : BaseDao<AttendanceSummary> {
@Insert
fun insertAll(exams: List<AttendanceSummary>): List<Long>
@Delete
fun deleteAll(exams: List<AttendanceSummary>)
@Query("SELECT * FROM AttendanceSummary WHERE diary_id = :diaryId AND student_id = :studentId AND subject_id = :subjectId") @Query("SELECT * FROM AttendanceSummary WHERE diary_id = :diaryId AND student_id = :studentId AND subject_id = :subjectId")
fun loadAll(diaryId: Int, studentId: Int, subjectId: Int): Maybe<List<AttendanceSummary>> fun loadAll(diaryId: Int, studentId: Int, subjectId: Int): Maybe<List<AttendanceSummary>>

View File

@ -0,0 +1,17 @@
package io.github.wulkanowy.data.db.dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Update
interface BaseDao<T> {
@Insert
fun insertAll(items: List<T>): List<Long>
@Update
fun updateAll(items: List<T>)
@Delete
fun deleteAll(items: List<T>)
}

View File

@ -1,8 +1,6 @@
package io.github.wulkanowy.data.db.dao package io.github.wulkanowy.data.db.dao
import androidx.room.Dao import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query import androidx.room.Query
import io.github.wulkanowy.data.db.entities.CompletedLesson import io.github.wulkanowy.data.db.entities.CompletedLesson
import io.reactivex.Maybe import io.reactivex.Maybe
@ -11,13 +9,7 @@ import javax.inject.Singleton
@Singleton @Singleton
@Dao @Dao
interface CompletedLessonsDao { interface CompletedLessonsDao : BaseDao<CompletedLesson> {
@Insert
fun insertAll(exams: List<CompletedLesson>)
@Delete
fun deleteAll(exams: List<CompletedLesson>)
@Query("SELECT * FROM CompletedLesson WHERE diary_id = :diaryId AND student_id = :studentId AND date >= :from AND date <= :end") @Query("SELECT * FROM CompletedLesson WHERE diary_id = :diaryId AND student_id = :studentId AND date >= :from AND date <= :end")
fun loadAll(diaryId: Int, studentId: Int, from: LocalDate, end: LocalDate): Maybe<List<CompletedLesson>> fun loadAll(diaryId: Int, studentId: Int, from: LocalDate, end: LocalDate): Maybe<List<CompletedLesson>>

View File

@ -1,8 +1,6 @@
package io.github.wulkanowy.data.db.dao package io.github.wulkanowy.data.db.dao
import androidx.room.Dao import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query import androidx.room.Query
import io.github.wulkanowy.data.db.entities.Exam import io.github.wulkanowy.data.db.entities.Exam
import io.reactivex.Maybe import io.reactivex.Maybe
@ -11,13 +9,7 @@ import javax.inject.Singleton
@Singleton @Singleton
@Dao @Dao
interface ExamDao { interface ExamDao : BaseDao<Exam> {
@Insert
fun insertAll(exams: List<Exam>): List<Long>
@Delete
fun deleteAll(exams: List<Exam>)
@Query("SELECT * FROM Exams WHERE diary_id = :diaryId AND student_id = :studentId AND date >= :from AND date <= :end") @Query("SELECT * FROM Exams WHERE diary_id = :diaryId AND student_id = :studentId AND date >= :from AND date <= :end")
fun loadAll(diaryId: Int, studentId: Int, from: LocalDate, end: LocalDate): Maybe<List<Exam>> fun loadAll(diaryId: Int, studentId: Int, from: LocalDate, end: LocalDate): Maybe<List<Exam>>

View File

@ -1,26 +1,14 @@
package io.github.wulkanowy.data.db.dao package io.github.wulkanowy.data.db.dao
import androidx.room.Dao import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query import androidx.room.Query
import androidx.room.Update
import io.github.wulkanowy.data.db.entities.Grade import io.github.wulkanowy.data.db.entities.Grade
import io.reactivex.Maybe import io.reactivex.Maybe
import javax.inject.Singleton import javax.inject.Singleton
@Singleton @Singleton
@Dao @Dao
interface GradeDao { interface GradeDao : BaseDao<Grade> {
@Insert
fun insertAll(grades: List<Grade>)
@Update
fun updateAll(grade: List<Grade>)
@Delete
fun deleteAll(grades: List<Grade>)
@Query("SELECT * FROM Grades WHERE semester_id = :semesterId AND student_id = :studentId") @Query("SELECT * FROM Grades WHERE semester_id = :semesterId AND student_id = :studentId")
fun loadAll(semesterId: Int, studentId: Int): Maybe<List<Grade>> fun loadAll(semesterId: Int, studentId: Int): Maybe<List<Grade>>

View File

@ -1,8 +1,6 @@
package io.github.wulkanowy.data.db.dao package io.github.wulkanowy.data.db.dao
import androidx.room.Dao import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query import androidx.room.Query
import io.github.wulkanowy.data.db.entities.GradePointsStatistics import io.github.wulkanowy.data.db.entities.GradePointsStatistics
import io.reactivex.Maybe import io.reactivex.Maybe
@ -10,13 +8,7 @@ import javax.inject.Singleton
@Singleton @Singleton
@Dao @Dao
interface GradePointsStatisticsDao { interface GradePointsStatisticsDao : BaseDao<GradePointsStatistics> {
@Insert
fun insertAll(gradesStatistics: List<GradePointsStatistics>)
@Delete
fun deleteAll(gradesStatistics: List<GradePointsStatistics>)
@Query("SELECT * FROM GradesPointsStatistics WHERE student_id = :studentId AND semester_id = :semesterId AND subject = :subjectName") @Query("SELECT * FROM GradesPointsStatistics WHERE student_id = :studentId AND semester_id = :semesterId AND subject = :subjectName")
fun loadSubject(semesterId: Int, studentId: Int, subjectName: String): Maybe<GradePointsStatistics> fun loadSubject(semesterId: Int, studentId: Int, subjectName: String): Maybe<GradePointsStatistics>

View File

@ -1,8 +1,6 @@
package io.github.wulkanowy.data.db.dao package io.github.wulkanowy.data.db.dao
import androidx.room.Dao import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query import androidx.room.Query
import io.github.wulkanowy.data.db.entities.GradeStatistics import io.github.wulkanowy.data.db.entities.GradeStatistics
import io.reactivex.Maybe import io.reactivex.Maybe
@ -10,13 +8,7 @@ import javax.inject.Singleton
@Singleton @Singleton
@Dao @Dao
interface GradeStatisticsDao { interface GradeStatisticsDao : BaseDao<GradeStatistics> {
@Insert
fun insertAll(gradesStatistics: List<GradeStatistics>)
@Delete
fun deleteAll(gradesStatistics: List<GradeStatistics>)
@Query("SELECT * FROM GradesStatistics WHERE student_id = :studentId AND semester_id = :semesterId AND subject = :subjectName AND is_semester = :isSemester") @Query("SELECT * FROM GradesStatistics WHERE student_id = :studentId AND semester_id = :semesterId AND subject = :subjectName AND is_semester = :isSemester")
fun loadSubject(semesterId: Int, studentId: Int, subjectName: String, isSemester: Boolean): Maybe<List<GradeStatistics>> fun loadSubject(semesterId: Int, studentId: Int, subjectName: String, isSemester: Boolean): Maybe<List<GradeStatistics>>

View File

@ -1,8 +1,6 @@
package io.github.wulkanowy.data.db.dao package io.github.wulkanowy.data.db.dao
import androidx.room.Dao import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query import androidx.room.Query
import io.github.wulkanowy.data.db.entities.GradeSummary import io.github.wulkanowy.data.db.entities.GradeSummary
import io.reactivex.Maybe import io.reactivex.Maybe
@ -10,13 +8,7 @@ import javax.inject.Singleton
@Singleton @Singleton
@Dao @Dao
interface GradeSummaryDao { interface GradeSummaryDao : BaseDao<GradeSummary> {
@Insert
fun insertAll(gradesSummary: List<GradeSummary>)
@Delete
fun deleteAll(gradesSummary: List<GradeSummary>)
@Query("SELECT * FROM GradesSummary WHERE student_id = :studentId AND semester_id = :semesterId") @Query("SELECT * FROM GradesSummary WHERE student_id = :studentId AND semester_id = :semesterId")
fun loadAll(semesterId: Int, studentId: Int): Maybe<List<GradeSummary>> fun loadAll(semesterId: Int, studentId: Int): Maybe<List<GradeSummary>>

View File

@ -1,8 +1,6 @@
package io.github.wulkanowy.data.db.dao package io.github.wulkanowy.data.db.dao
import androidx.room.Dao import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query import androidx.room.Query
import io.github.wulkanowy.data.db.entities.Homework import io.github.wulkanowy.data.db.entities.Homework
import io.reactivex.Maybe import io.reactivex.Maybe
@ -11,13 +9,7 @@ import javax.inject.Singleton
@Singleton @Singleton
@Dao @Dao
interface HomeworkDao { interface HomeworkDao : BaseDao<Homework> {
@Insert
fun insertAll(homework: List<Homework>)
@Delete
fun deleteAll(homework: List<Homework>)
@Query("SELECT * FROM Homework WHERE semester_id = :semesterId AND student_id = :studentId AND date >= :from AND date <= :end") @Query("SELECT * FROM Homework WHERE semester_id = :semesterId AND student_id = :studentId AND date >= :from AND date <= :end")
fun loadAll(semesterId: Int, studentId: Int, from: LocalDate, end: LocalDate): Maybe<List<Homework>> fun loadAll(semesterId: Int, studentId: Int, from: LocalDate, end: LocalDate): Maybe<List<Homework>>

View File

@ -1,10 +1,7 @@
package io.github.wulkanowy.data.db.dao package io.github.wulkanowy.data.db.dao
import androidx.room.Dao import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query import androidx.room.Query
import androidx.room.Update
import io.github.wulkanowy.data.db.entities.LuckyNumber import io.github.wulkanowy.data.db.entities.LuckyNumber
import io.reactivex.Maybe import io.reactivex.Maybe
import org.threeten.bp.LocalDate import org.threeten.bp.LocalDate
@ -12,18 +9,8 @@ import javax.inject.Singleton
@Singleton @Singleton
@Dao @Dao
interface LuckyNumberDao { interface LuckyNumberDao : BaseDao<LuckyNumber> {
@Insert
fun insert(luckyNumber: LuckyNumber)
@Update
fun update(luckyNumber: LuckyNumber)
@Delete
fun delete(luckyNumber: LuckyNumber)
@Query("SELECT * FROM LuckyNumbers WHERE student_id = :studentId AND date = :date") @Query("SELECT * FROM LuckyNumbers WHERE student_id = :studentId AND date = :date")
fun load(studentId: Int, date: LocalDate): Maybe<LuckyNumber> fun load(studentId: Int, date: LocalDate): Maybe<LuckyNumber>
} }

View File

@ -1,24 +1,12 @@
package io.github.wulkanowy.data.db.dao package io.github.wulkanowy.data.db.dao
import androidx.room.Dao import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query import androidx.room.Query
import androidx.room.Update
import io.github.wulkanowy.data.db.entities.Message import io.github.wulkanowy.data.db.entities.Message
import io.reactivex.Maybe import io.reactivex.Maybe
@Dao @Dao
interface MessagesDao { interface MessagesDao : BaseDao<Message> {
@Insert
fun insertAll(messages: List<Message>)
@Delete
fun deleteAll(messages: List<Message>)
@Update
fun updateAll(messages: List<Message>)
@Query("SELECT * FROM Messages WHERE student_id = :studentId AND folder_id = :folder AND removed = 0 ORDER BY date DESC") @Query("SELECT * FROM Messages WHERE student_id = :studentId AND folder_id = :folder AND removed = 0 ORDER BY date DESC")
fun loadAll(studentId: Int, folder: Int): Maybe<List<Message>> fun loadAll(studentId: Int, folder: Int): Maybe<List<Message>>

View File

@ -1,20 +1,12 @@
package io.github.wulkanowy.data.db.dao package io.github.wulkanowy.data.db.dao
import androidx.room.Dao import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query import androidx.room.Query
import io.github.wulkanowy.data.db.entities.MobileDevice import io.github.wulkanowy.data.db.entities.MobileDevice
import io.reactivex.Maybe import io.reactivex.Maybe
@Dao @Dao
interface MobileDeviceDao { interface MobileDeviceDao : BaseDao<MobileDevice> {
@Insert
fun insertAll(devices: List<MobileDevice>)
@Delete
fun deleteAll(devices: List<MobileDevice>)
@Query("SELECT * FROM MobileDevices WHERE student_id = :studentId ORDER BY date DESC") @Query("SELECT * FROM MobileDevices WHERE student_id = :studentId ORDER BY date DESC")
fun loadAll(studentId: Int): Maybe<List<MobileDevice>> fun loadAll(studentId: Int): Maybe<List<MobileDevice>>

View File

@ -1,28 +1,15 @@
package io.github.wulkanowy.data.db.dao package io.github.wulkanowy.data.db.dao
import androidx.room.Dao import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query import androidx.room.Query
import androidx.room.Update
import io.github.wulkanowy.data.db.entities.Note import io.github.wulkanowy.data.db.entities.Note
import io.reactivex.Maybe import io.reactivex.Maybe
import javax.inject.Singleton import javax.inject.Singleton
@Singleton @Singleton
@Dao @Dao
interface NoteDao { interface NoteDao : BaseDao<Note> {
@Insert
fun insertAll(notes: List<Note>)
@Update
fun updateAll(notes: List<Note>)
@Delete
fun deleteAll(notes: List<Note>)
@Query("SELECT * FROM Notes WHERE student_id = :studentId") @Query("SELECT * FROM Notes WHERE student_id = :studentId")
fun loadAll(studentId: Int): Maybe<List<Note>> fun loadAll(studentId: Int): Maybe<List<Note>>
} }

View File

@ -1,8 +1,6 @@
package io.github.wulkanowy.data.db.dao package io.github.wulkanowy.data.db.dao
import androidx.room.Dao import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query import androidx.room.Query
import io.github.wulkanowy.data.db.entities.Recipient import io.github.wulkanowy.data.db.entities.Recipient
import io.reactivex.Maybe import io.reactivex.Maybe
@ -10,13 +8,7 @@ import javax.inject.Singleton
@Singleton @Singleton
@Dao @Dao
interface RecipientDao { interface RecipientDao : BaseDao<Recipient> {
@Insert
fun insertAll(messages: List<Recipient>)
@Delete
fun deleteAll(messages: List<Recipient>)
@Query("SELECT * FROM Recipients WHERE student_id = :studentId AND role = :role AND unit_id = :unitId") @Query("SELECT * FROM Recipients WHERE student_id = :studentId AND role = :role AND unit_id = :unitId")
fun load(studentId: Int, role: Int, unitId: Int): Maybe<List<Recipient>> fun load(studentId: Int, role: Int, unitId: Int): Maybe<List<Recipient>>

View File

@ -1,8 +1,6 @@
package io.github.wulkanowy.data.db.dao package io.github.wulkanowy.data.db.dao
import androidx.room.Dao import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query import androidx.room.Query
import io.github.wulkanowy.data.db.entities.ReportingUnit import io.github.wulkanowy.data.db.entities.ReportingUnit
import io.reactivex.Maybe import io.reactivex.Maybe
@ -10,13 +8,7 @@ import javax.inject.Singleton
@Singleton @Singleton
@Dao @Dao
interface ReportingUnitDao { interface ReportingUnitDao : BaseDao<ReportingUnit> {
@Insert
fun insertAll(reportingUnits: List<ReportingUnit>)
@Delete
fun deleteAll(reportingUnits: List<ReportingUnit>)
@Query("SELECT * FROM ReportingUnits WHERE student_id = :studentId") @Query("SELECT * FROM ReportingUnits WHERE student_id = :studentId")
fun load(studentId: Int): Maybe<List<ReportingUnit>> fun load(studentId: Int): Maybe<List<ReportingUnit>>

View File

@ -0,0 +1,15 @@
package io.github.wulkanowy.data.db.dao
import androidx.room.Dao
import androidx.room.Query
import io.github.wulkanowy.data.db.entities.School
import io.reactivex.Maybe
import javax.inject.Singleton
@Singleton
@Dao
interface SchoolDao : BaseDao<School> {
@Query("SELECT * FROM School WHERE student_id = :studentId AND class_id = :classId")
fun load(studentId: Int, classId: Int): Maybe<School>
}

View File

@ -1,8 +1,6 @@
package io.github.wulkanowy.data.db.dao package io.github.wulkanowy.data.db.dao
import androidx.room.Dao import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query import androidx.room.Query
import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Semester
import io.reactivex.Maybe import io.reactivex.Maybe
@ -10,13 +8,7 @@ import javax.inject.Singleton
@Singleton @Singleton
@Dao @Dao
interface SemesterDao { interface SemesterDao : BaseDao<Semester> {
@Insert
fun insertAll(semester: List<Semester>)
@Delete
fun deleteAll(semester: List<Semester>)
@Query("SELECT * FROM Semesters WHERE student_id = :studentId AND class_id = :classId") @Query("SELECT * FROM Semesters WHERE student_id = :studentId AND class_id = :classId")
fun loadAll(studentId: Int, classId: Int): Maybe<List<Semester>> fun loadAll(studentId: Int, classId: Int): Maybe<List<Semester>>

View File

@ -1,20 +1,12 @@
package io.github.wulkanowy.data.db.dao package io.github.wulkanowy.data.db.dao
import androidx.room.Dao import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query import androidx.room.Query
import io.github.wulkanowy.data.db.entities.Subject import io.github.wulkanowy.data.db.entities.Subject
import io.reactivex.Maybe import io.reactivex.Maybe
@Dao @Dao
interface SubjectDao { interface SubjectDao : BaseDao<Subject> {
@Insert
fun insertAll(subjects: List<Subject>): List<Long>
@Delete
fun deleteAll(subjects: List<Subject>)
@Query("SELECT * FROM Subjects WHERE diary_id = :diaryId AND student_id = :studentId") @Query("SELECT * FROM Subjects WHERE diary_id = :diaryId AND student_id = :studentId")
fun loadAll(diaryId: Int, studentId: Int): Maybe<List<Subject>> fun loadAll(diaryId: Int, studentId: Int): Maybe<List<Subject>>

View File

@ -1,8 +1,6 @@
package io.github.wulkanowy.data.db.dao package io.github.wulkanowy.data.db.dao
import androidx.room.Dao import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query import androidx.room.Query
import io.github.wulkanowy.data.db.entities.Teacher import io.github.wulkanowy.data.db.entities.Teacher
import io.reactivex.Maybe import io.reactivex.Maybe
@ -10,13 +8,7 @@ import javax.inject.Singleton
@Singleton @Singleton
@Dao @Dao
interface TeacherDao { interface TeacherDao : BaseDao<Teacher> {
@Insert
fun insertAll(devices: List<Teacher>)
@Delete
fun deleteAll(devices: List<Teacher>)
@Query("SELECT * FROM Teachers WHERE student_id = :studentId AND class_id = :classId") @Query("SELECT * FROM Teachers WHERE student_id = :studentId AND class_id = :classId")
fun loadAll(studentId: Int, classId: Int): Maybe<List<Teacher>> fun loadAll(studentId: Int, classId: Int): Maybe<List<Teacher>>

View File

@ -1,8 +1,6 @@
package io.github.wulkanowy.data.db.dao package io.github.wulkanowy.data.db.dao
import androidx.room.Dao import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query import androidx.room.Query
import io.github.wulkanowy.data.db.entities.Timetable import io.github.wulkanowy.data.db.entities.Timetable
import io.reactivex.Maybe import io.reactivex.Maybe
@ -11,13 +9,7 @@ import javax.inject.Singleton
@Singleton @Singleton
@Dao @Dao
interface TimetableDao { interface TimetableDao : BaseDao<Timetable> {
@Insert
fun insertAll(exams: List<Timetable>): List<Long>
@Delete
fun deleteAll(exams: List<Timetable>)
@Query("SELECT * FROM Timetable WHERE diary_id = :diaryId AND student_id = :studentId AND date >= :from AND date <= :end") @Query("SELECT * FROM Timetable WHERE diary_id = :diaryId AND student_id = :studentId AND date >= :from AND date <= :end")
fun loadAll(diaryId: Int, studentId: Int, from: LocalDate, end: LocalDate): Maybe<List<Timetable>> fun loadAll(diaryId: Int, studentId: Int, from: LocalDate, end: LocalDate): Maybe<List<Timetable>>

View File

@ -19,7 +19,7 @@ data class Grade(
val entry: String, val entry: String,
val value: Int, val value: Double,
val modifier: Double, val modifier: Double,

View File

@ -29,6 +29,8 @@ data class Message(
val subject: String, val subject: String,
var content: String,
val date: LocalDateTime, val date: LocalDateTime,
@ColumnInfo(name = "folder_id") @ColumnInfo(name = "folder_id")
@ -50,6 +52,4 @@ data class Message(
@ColumnInfo(name = "is_notified") @ColumnInfo(name = "is_notified")
var isNotified: Boolean = true var isNotified: Boolean = true
var content: String? = null
} }

View File

@ -0,0 +1,30 @@
package io.github.wulkanowy.data.db.entities
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
import java.io.Serializable
@Entity(tableName = "School")
data class School(
@ColumnInfo(name = "student_id")
val studentId: Int,
@ColumnInfo(name = "class_id")
val classId: Int,
val name: String,
val address: String,
val contact: String,
val headmaster: String,
val pedagogue: String
) : Serializable {
@PrimaryKey(autoGenerate = true)
var id: Long = 0
}

View File

@ -10,10 +10,27 @@ import java.io.Serializable
@Entity(tableName = "Students", indices = [Index(value = ["email", "symbol", "student_id", "school_id", "class_id"], unique = true)]) @Entity(tableName = "Students", indices = [Index(value = ["email", "symbol", "student_id", "school_id", "class_id"], unique = true)])
data class Student( data class Student(
val endpoint: String, @ColumnInfo(name = "scrapper_base_url")
val scrapperBaseUrl: String,
@ColumnInfo(name = "mobile_base_url")
val mobileBaseUrl: String,
@ColumnInfo(name = "login_type")
val loginType: String, val loginType: String,
@ColumnInfo(name = "login_mode")
val loginMode: String,
@ColumnInfo(name = "certificate_key")
val certificateKey: String,
@ColumnInfo(name = "private_key")
val privateKey: String,
@ColumnInfo(name = "is_parent")
val isParent: Boolean,
val email: String, val email: String,
var password: String, var password: String,
@ -23,6 +40,9 @@ data class Student(
@ColumnInfo(name = "student_id") @ColumnInfo(name = "student_id")
val studentId: Int, val studentId: Int,
@ColumnInfo(name = "user_login_id")
val userLoginId: Int,
@ColumnInfo(name = "student_name") @ColumnInfo(name = "student_name")
val studentName: String, val studentName: String,

View File

@ -0,0 +1,22 @@
package io.github.wulkanowy.data.db.migrations
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
class Migration18 : Migration(17, 18) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("""
CREATE TABLE IF NOT EXISTS School (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
student_id INTEGER NOT NULL,
class_id INTEGER NOT NULL,
name TEXT NOT NULL,
address TEXT NOT NULL,
contact TEXT NOT NULL,
headmaster TEXT NOT NULL,
pedagogue TEXT NOT NULL
)
""")
}
}

View File

@ -0,0 +1,119 @@
package io.github.wulkanowy.data.db.migrations
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
import io.github.wulkanowy.data.db.SharedPrefProvider
class Migration19(private val sharedPrefProvider: SharedPrefProvider) : Migration(18, 19) {
override fun migrate(database: SupportSQLiteDatabase) {
migrateMessages(database)
migrateGrades(database)
migrateStudents(database)
migrateSharedPreferences()
}
private fun migrateMessages(database: SupportSQLiteDatabase) {
database.execSQL("DROP TABLE Messages")
database.execSQL("""
CREATE TABLE IF NOT EXISTS Messages (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
is_notified INTEGER NOT NULL,
student_id INTEGER NOT NULL,
real_id INTEGER NOT NULL,
message_id INTEGER NOT NULL,
sender_name TEXT NOT NULL,
sender_id INTEGER NOT NULL,
recipient_name TEXT NOT NULL,
subject TEXT NOT NULL,
content TEXT NOT NULL,
date INTEGER NOT NULL,
folder_id INTEGER NOT NULL,
unread INTEGER NOT NULL,
unread_by INTEGER NOT NULL,
read_by INTEGER NOT NULL,
removed INTEGER NOT NULL
)
""")
}
private fun migrateGrades(database: SupportSQLiteDatabase) {
database.execSQL("DROP TABLE Grades")
database.execSQL("""
CREATE TABLE IF NOT EXISTS Grades (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
is_read INTEGER NOT NULL,
is_notified INTEGER NOT NULL,
semester_id INTEGER NOT NULL,
student_id INTEGER NOT NULL,
subject TEXT NOT NULL,
entry TEXT NOT NULL,
value REAL NOT NULL,
modifier REAL NOT NULL,
comment TEXT NOT NULL,
color TEXT NOT NULL,
grade_symbol TEXT NOT NULL,
description TEXT NOT NULL,
weight TEXT NOT NULL,
weightValue REAL NOT NULL,
date INTEGER NOT NULL,
teacher TEXT NOT NULL
)
""")
}
private fun migrateStudents(database: SupportSQLiteDatabase) {
database.execSQL("""
CREATE TABLE IF NOT EXISTS Students_tmp (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
scrapper_base_url TEXT NOT NULL,
mobile_base_url TEXT NOT NULL,
is_parent INTEGER NOT NULL,
login_type TEXT NOT NULL,
login_mode TEXT NOT NULL,
certificate_key TEXT NOT NULL,
private_key TEXT NOT NULL,
email TEXT NOT NULL,
password TEXT NOT NULL,
symbol TEXT NOT NULL,
student_id INTEGER NOT NULL,
user_login_id INTEGER NOT NULL,
student_name TEXT NOT NULL,
school_id TEXT NOT NULL,
school_name TEXT NOT NULL,
class_name TEXT NOT NULL,
class_id INTEGER NOT NULL,
is_current INTEGER NOT NULL,
registration_date INTEGER NOT NULL
)
""")
database.execSQL("ALTER TABLE Students ADD COLUMN scrapperBaseUrl TEXT NOT NULL DEFAULT \"\";")
database.execSQL("ALTER TABLE Students ADD COLUMN apiBaseUrl TEXT NOT NULL DEFAULT \"\";")
database.execSQL("ALTER TABLE Students ADD COLUMN is_parent INT NOT NULL DEFAULT 0;")
database.execSQL("ALTER TABLE Students ADD COLUMN loginMode TEXT NOT NULL DEFAULT \"\";")
database.execSQL("ALTER TABLE Students ADD COLUMN certificateKey TEXT NOT NULL DEFAULT \"\";")
database.execSQL("ALTER TABLE Students ADD COLUMN privateKey TEXT NOT NULL DEFAULT \"\";")
database.execSQL("ALTER TABLE Students ADD COLUMN user_login_id INTEGER NOT NULL DEFAULT 0;")
database.execSQL("""
INSERT INTO Students_tmp(
id, scrapper_base_url, mobile_base_url, is_parent, login_type, login_mode, certificate_key, private_key, email, password, symbol, student_id, user_login_id, student_name, school_id, school_name, school_id, school_name, class_name, class_id, is_current, registration_date)
SELECT
id, endpoint, apiBaseUrl, is_parent, loginType, "SCRAPPER", certificateKey, privateKey, email, password, symbol, student_id, user_login_id, student_name, school_id, school_name, school_id, school_name, class_name, class_id, is_current, registration_date
FROM Students
""")
database.execSQL("DROP TABLE Students")
database.execSQL("ALTER TABLE Students_tmp RENAME TO Students")
database.execSQL("CREATE UNIQUE INDEX index_Students_email_symbol_student_id_school_id_class_id ON Students (email, symbol, student_id, school_id, class_id)")
}
private fun migrateSharedPreferences() {
if (sharedPrefProvider.getString("grade_modifier_plus", "0.0") == "0.0") {
sharedPrefProvider.putString("grade_modifier_plus", "0.33")
}
if (sharedPrefProvider.getString("grade_modifier_minus", "0.0") == "0.0") {
sharedPrefProvider.putString("grade_modifier_minus", "0.33")
}
}
}

View File

@ -1,25 +1,24 @@
package io.github.wulkanowy.data.repositories.attendance package io.github.wulkanowy.data.repositories.attendance
import io.github.wulkanowy.api.Api
import io.github.wulkanowy.data.db.entities.Attendance import io.github.wulkanowy.data.db.entities.Attendance
import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.utils.toLocalDate import io.github.wulkanowy.sdk.Sdk
import io.reactivex.Single import io.reactivex.Single
import org.threeten.bp.LocalDate import org.threeten.bp.LocalDate
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
@Singleton @Singleton
class AttendanceRemote @Inject constructor(private val api: Api) { class AttendanceRemote @Inject constructor(private val sdk: Sdk) {
fun getAttendance(semester: Semester, startDate: LocalDate, endDate: LocalDate): Single<List<Attendance>> { fun getAttendance(semester: Semester, startDate: LocalDate, endDate: LocalDate): Single<List<Attendance>> {
return Single.just(api.apply { diaryId = semester.diaryId }) return sdk.switchDiary(semester.diaryId, semester.schoolYear).getAttendance(startDate, endDate, semester.semesterId)
.flatMap { it.getAttendance(startDate, endDate) }.map { attendance -> .map { attendance ->
attendance.map { attendance.map {
Attendance( Attendance(
studentId = semester.studentId, studentId = semester.studentId,
diaryId = semester.diaryId, diaryId = semester.diaryId,
date = it.date.toLocalDate(), date = it.date,
number = it.number, number = it.number,
subject = it.subject, subject = it.subject,
name = it.name, name = it.name,

View File

@ -1,18 +1,18 @@
package io.github.wulkanowy.data.repositories.attendancesummary package io.github.wulkanowy.data.repositories.attendancesummary
import io.github.wulkanowy.api.Api
import io.github.wulkanowy.data.db.entities.AttendanceSummary import io.github.wulkanowy.data.db.entities.AttendanceSummary
import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.sdk.Sdk
import io.reactivex.Single import io.reactivex.Single
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
@Singleton @Singleton
class AttendanceSummaryRemote @Inject constructor(private val api: Api) { class AttendanceSummaryRemote @Inject constructor(private val sdk: Sdk) {
fun getAttendanceSummary(semester: Semester, subjectId: Int): Single<List<AttendanceSummary>> { fun getAttendanceSummary(semester: Semester, subjectId: Int): Single<List<AttendanceSummary>> {
return Single.just(api.apply { diaryId = semester.diaryId }) return sdk.switchDiary(semester.diaryId, semester.schoolYear).getAttendanceSummary(subjectId)
.flatMap { api.getAttendanceSummary(subjectId) }.map { attendance -> .map { attendance ->
attendance.map { attendance.map {
AttendanceSummary( AttendanceSummary(
studentId = semester.studentId, studentId = semester.studentId,

View File

@ -1,27 +1,25 @@
package io.github.wulkanowy.data.repositories.completedlessons package io.github.wulkanowy.data.repositories.completedlessons
import io.github.wulkanowy.api.Api
import io.github.wulkanowy.api.toLocalDate
import io.github.wulkanowy.data.db.entities.CompletedLesson import io.github.wulkanowy.data.db.entities.CompletedLesson
import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.sdk.Sdk
import io.reactivex.Single import io.reactivex.Single
import org.threeten.bp.LocalDate import org.threeten.bp.LocalDate
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
@Singleton @Singleton
class CompletedLessonsRemote @Inject constructor(private val api: Api) { class CompletedLessonsRemote @Inject constructor(private val sdk: Sdk) {
fun getCompletedLessons(semester: Semester, startDate: LocalDate, endDate: LocalDate): Single<List<CompletedLesson>> { fun getCompletedLessons(semester: Semester, startDate: LocalDate, endDate: LocalDate): Single<List<CompletedLesson>> {
return Single.just(api.apply { diaryId = semester.diaryId }) return sdk.switchDiary(semester.diaryId, semester.schoolYear).getCompletedLessons(startDate, endDate)
.flatMap { it.getCompletedLessons(startDate, endDate) }
.map { lessons -> .map { lessons ->
lessons.map { lessons.map {
it.absence it.absence
CompletedLesson( CompletedLesson(
studentId = semester.studentId, studentId = semester.studentId,
diaryId = semester.diaryId, diaryId = semester.diaryId,
date = it.date.toLocalDate(), date = it.date,
number = it.number, number = it.number,
subject = it.subject, subject = it.subject,
topic = it.topic, topic = it.topic,

View File

@ -1,26 +1,25 @@
package io.github.wulkanowy.data.repositories.exam package io.github.wulkanowy.data.repositories.exam
import io.github.wulkanowy.api.Api
import io.github.wulkanowy.data.db.entities.Exam import io.github.wulkanowy.data.db.entities.Exam
import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.utils.toLocalDate import io.github.wulkanowy.sdk.Sdk
import io.reactivex.Single import io.reactivex.Single
import org.threeten.bp.LocalDate import org.threeten.bp.LocalDate
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
@Singleton @Singleton
class ExamRemote @Inject constructor(private val api: Api) { class ExamRemote @Inject constructor(private val sdk: Sdk) {
fun getExams(semester: Semester, startDate: LocalDate, endDate: LocalDate): Single<List<Exam>> { fun getExams(semester: Semester, startDate: LocalDate, endDate: LocalDate): Single<List<Exam>> {
return Single.just(api.apply { diaryId = semester.diaryId }) return sdk.switchDiary(semester.diaryId, semester.schoolYear).getExams(startDate, endDate, semester.semesterId)
.flatMap { it.getExams(startDate, endDate) }.map { exams -> .map { exams ->
exams.map { exams.map {
Exam( Exam(
studentId = semester.studentId, studentId = semester.studentId,
diaryId = semester.diaryId, diaryId = semester.diaryId,
date = it.date.toLocalDate(), date = it.date,
entryDate = it.entryDate.toLocalDate(), entryDate = it.entryDate,
subject = it.subject, subject = it.subject,
group = it.group, group = it.group,
type = it.type, type = it.type,

View File

@ -1,35 +1,33 @@
package io.github.wulkanowy.data.repositories.grade package io.github.wulkanowy.data.repositories.grade
import io.github.wulkanowy.api.Api
import io.github.wulkanowy.data.db.entities.Grade import io.github.wulkanowy.data.db.entities.Grade
import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.utils.toLocalDate import io.github.wulkanowy.sdk.Sdk
import io.reactivex.Single import io.reactivex.Single
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
@Singleton @Singleton
class GradeRemote @Inject constructor(private val api: Api) { class GradeRemote @Inject constructor(private val sdk: Sdk) {
fun getGrades(semester: Semester): Single<List<Grade>> { fun getGrades(semester: Semester): Single<List<Grade>> {
return Single.just(api.apply { diaryId = semester.diaryId }) return sdk.switchDiary(semester.diaryId, semester.schoolYear).getGrades(semester.semesterId)
.flatMap { it.getGrades(semester.semesterId) }
.map { grades -> .map { grades ->
grades.map { grades.map {
Grade( Grade(
semesterId = semester.semesterId,
studentId = semester.studentId, studentId = semester.studentId,
semesterId = semester.semesterId,
subject = it.subject, subject = it.subject,
entry = it.entry, entry = it.entry,
value = it.value, value = it.value,
modifier = it.modifier, modifier = it.modifier,
comment = it.comment, comment = it.comment,
color = it.color, color = it.color,
gradeSymbol = it.symbol.orEmpty(), gradeSymbol = it.symbol,
description = it.description.orEmpty(), description = it.description,
weight = it.weight, weight = it.weight,
weightValue = it.weightValue, weightValue = it.weightValue,
date = it.date.toLocalDate(), date = it.date,
teacher = it.teacher teacher = it.teacher
) )
} }

View File

@ -1,24 +1,23 @@
package io.github.wulkanowy.data.repositories.gradessummary package io.github.wulkanowy.data.repositories.gradessummary
import io.github.wulkanowy.api.Api
import io.github.wulkanowy.data.db.entities.GradeSummary import io.github.wulkanowy.data.db.entities.GradeSummary
import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.sdk.Sdk
import io.reactivex.Single import io.reactivex.Single
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
@Singleton @Singleton
class GradeSummaryRemote @Inject constructor(private val api: Api) { class GradeSummaryRemote @Inject constructor(private val sdk: Sdk) {
fun getGradeSummary(semester: Semester): Single<List<GradeSummary>> { fun getGradeSummary(semester: Semester): Single<List<GradeSummary>> {
return Single.just(api.apply { diaryId = semester.diaryId }) return sdk.switchDiary(semester.diaryId, semester.schoolYear).getGradesSummary(semester.semesterId)
.flatMap { it.getGradesSummary(semester.semesterId) }
.map { gradesSummary -> .map { gradesSummary ->
gradesSummary.map { gradesSummary.map {
GradeSummary( GradeSummary(
semesterId = semester.semesterId, semesterId = semester.semesterId,
studentId = semester.studentId, studentId = semester.studentId,
position = it.order, position = 0,
subject = it.name, subject = it.name,
predictedGrade = it.predicted, predictedGrade = it.predicted,
finalGrade = it.final, finalGrade = it.final,

View File

@ -1,39 +1,36 @@
package io.github.wulkanowy.data.repositories.gradestatistics package io.github.wulkanowy.data.repositories.gradestatistics
import io.github.wulkanowy.api.Api
import io.github.wulkanowy.data.db.entities.GradePointsStatistics import io.github.wulkanowy.data.db.entities.GradePointsStatistics
import io.github.wulkanowy.data.db.entities.GradeStatistics import io.github.wulkanowy.data.db.entities.GradeStatistics
import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.sdk.Sdk
import io.reactivex.Single import io.reactivex.Single
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
@Singleton @Singleton
class GradeStatisticsRemote @Inject constructor(private val api: Api) { class GradeStatisticsRemote @Inject constructor(private val sdk: Sdk) {
fun getGradeStatistics(semester: Semester, isSemester: Boolean): Single<List<GradeStatistics>> { fun getGradeStatistics(semester: Semester, isSemester: Boolean): Single<List<GradeStatistics>> {
return Single.just(api.apply { diaryId = semester.diaryId }) return sdk.switchDiary(semester.diaryId, semester.schoolYear).let {
.flatMap { if (isSemester) it.getGradesAnnualStatistics(semester.semesterId)
if (isSemester) it.getGradesAnnualStatistics(semester.semesterId) else it.getGradesPartialStatistics(semester.semesterId)
else it.getGradesPartialStatistics(semester.semesterId) }.map { gradeStatistics ->
} gradeStatistics.map {
.map { gradeStatistics -> GradeStatistics(
gradeStatistics.map { semesterId = semester.semesterId,
GradeStatistics( studentId = semester.studentId,
semesterId = semester.semesterId, subject = it.subject,
studentId = semester.studentId, grade = it.gradeValue,
subject = it.subject, amount = it.amount,
grade = it.gradeValue, semester = isSemester
amount = it.amount ?: 0, )
semester = isSemester
)
}
} }
}
} }
fun getGradePointsStatistics(semester: Semester): Single<List<GradePointsStatistics>> { fun getGradePointsStatistics(semester: Semester): Single<List<GradePointsStatistics>> {
return Single.just(api.apply { diaryId = semester.diaryId }) return sdk.switchDiary(semester.diaryId, semester.schoolYear).getGradesPointsStatistics(semester.semesterId)
.flatMap { it.getGradesPointsStatistics(semester.semesterId) }
.map { gradePointsStatistics -> .map { gradePointsStatistics ->
gradePointsStatistics.map { gradePointsStatistics.map {
GradePointsStatistics( GradePointsStatistics(

View File

@ -1,27 +1,25 @@
package io.github.wulkanowy.data.repositories.homework package io.github.wulkanowy.data.repositories.homework
import io.github.wulkanowy.api.Api
import io.github.wulkanowy.data.db.entities.Homework import io.github.wulkanowy.data.db.entities.Homework
import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.utils.toLocalDate import io.github.wulkanowy.sdk.Sdk
import io.reactivex.Single import io.reactivex.Single
import org.threeten.bp.LocalDate import org.threeten.bp.LocalDate
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
@Singleton @Singleton
class HomeworkRemote @Inject constructor(private val api: Api) { class HomeworkRemote @Inject constructor(private val sdk: Sdk) {
fun getHomework(semester: Semester, startDate: LocalDate, endDate: LocalDate): Single<List<Homework>> { fun getHomework(semester: Semester, startDate: LocalDate, endDate: LocalDate): Single<List<Homework>> {
return Single.just(api.apply { diaryId = semester.diaryId }) return sdk.switchDiary(semester.diaryId, semester.schoolYear).getHomework(startDate, endDate)
.flatMap { it.getHomework(startDate, endDate) }
.map { homework -> .map { homework ->
homework.map { homework.map {
Homework( Homework(
semesterId = semester.semesterId, semesterId = semester.semesterId,
studentId = semester.studentId, studentId = semester.studentId,
date = it.date.toLocalDate(), date = it.date,
entryDate = it.entryDate.toLocalDate(), entryDate = it.entryDate,
subject = it.subject, subject = it.subject,
content = it.content, content = it.content,
teacher = it.teacher, teacher = it.teacher,

View File

@ -12,15 +12,15 @@ import javax.inject.Singleton
class LuckyNumberLocal @Inject constructor(private val luckyNumberDb: LuckyNumberDao) { class LuckyNumberLocal @Inject constructor(private val luckyNumberDb: LuckyNumberDao) {
fun saveLuckyNumber(luckyNumber: LuckyNumber) { fun saveLuckyNumber(luckyNumber: LuckyNumber) {
luckyNumberDb.insert(luckyNumber) luckyNumberDb.insertAll(listOf(luckyNumber))
} }
fun updateLuckyNumber(luckyNumber: LuckyNumber) { fun updateLuckyNumber(luckyNumber: LuckyNumber) {
luckyNumberDb.update(luckyNumber) luckyNumberDb.updateAll(listOf(luckyNumber))
} }
fun deleteLuckyNumber(luckyNumber: LuckyNumber) { fun deleteLuckyNumber(luckyNumber: LuckyNumber) {
luckyNumberDb.delete(luckyNumber) luckyNumberDb.deleteAll(listOf(luckyNumber))
} }
fun getLuckyNumber(semester: Semester, date: LocalDate): Maybe<LuckyNumber> { fun getLuckyNumber(semester: Semester, date: LocalDate): Maybe<LuckyNumber> {

View File

@ -1,20 +1,18 @@
package io.github.wulkanowy.data.repositories.luckynumber package io.github.wulkanowy.data.repositories.luckynumber
import io.github.wulkanowy.api.Api
import io.github.wulkanowy.data.db.entities.LuckyNumber import io.github.wulkanowy.data.db.entities.LuckyNumber
import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.sdk.Sdk
import io.reactivex.Maybe import io.reactivex.Maybe
import io.reactivex.Single
import org.threeten.bp.LocalDate import org.threeten.bp.LocalDate
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
@Singleton @Singleton
class LuckyNumberRemote @Inject constructor(private val api: Api) { class LuckyNumberRemote @Inject constructor(private val sdk: Sdk) {
fun getLuckyNumber(semester: Semester): Maybe<LuckyNumber> { fun getLuckyNumber(semester: Semester): Maybe<LuckyNumber> {
return Single.just(api.apply { diaryId = semester.diaryId }) return sdk.getLuckyNumber()
.flatMapMaybe { it.getLuckyNumber() }
.map { .map {
LuckyNumber( LuckyNumber(
studentId = semester.studentId, studentId = semester.studentId,

View File

@ -1,24 +1,23 @@
package io.github.wulkanowy.data.repositories.message package io.github.wulkanowy.data.repositories.message
import io.github.wulkanowy.api.Api
import io.github.wulkanowy.api.messages.Folder
import io.github.wulkanowy.api.messages.SentMessage
import io.github.wulkanowy.data.db.entities.Message import io.github.wulkanowy.data.db.entities.Message
import io.github.wulkanowy.data.db.entities.Recipient import io.github.wulkanowy.data.db.entities.Recipient
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.utils.toLocalDateTime import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.sdk.pojo.Folder
import io.github.wulkanowy.sdk.pojo.SentMessage
import io.reactivex.Single import io.reactivex.Single
import org.threeten.bp.LocalDateTime.now import org.threeten.bp.LocalDateTime.now
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
import io.github.wulkanowy.api.messages.Message as ApiMessage import io.github.wulkanowy.sdk.pojo.Recipient as SdkRecipient
import io.github.wulkanowy.api.messages.Recipient as ApiRecipient
@Singleton @Singleton
class MessageRemote @Inject constructor(private val api: Api) { class MessageRemote @Inject constructor(private val sdk: Sdk) {
fun getMessages(student: Student, folder: MessageFolder): Single<List<Message>> { fun getMessages(student: Student, semester: Semester, folder: MessageFolder): Single<List<Message>> {
return api.getMessages(Folder.valueOf(folder.name)).map { messages -> return sdk.getMessages(Folder.valueOf(folder.name), semester.start.atStartOfDay(), semester.end.atStartOfDay()).map { messages ->
messages.map { messages.map {
Message( Message(
studentId = student.id.toInt(), studentId = student.id.toInt(),
@ -28,7 +27,8 @@ class MessageRemote @Inject constructor(private val api: Api) {
senderId = it.senderId ?: 0, senderId = it.senderId ?: 0,
recipient = it.recipient.orEmpty(), recipient = it.recipient.orEmpty(),
subject = it.subject.trim(), subject = it.subject.trim(),
date = it.date?.toLocalDateTime() ?: now(), date = it.date ?: now(),
content = it.content.orEmpty(),
folderId = it.folderId, folderId = it.folderId,
unread = it.unread ?: false, unread = it.unread ?: false,
unreadBy = it.unreadBy ?: 0, unreadBy = it.unreadBy ?: 0,
@ -40,27 +40,28 @@ class MessageRemote @Inject constructor(private val api: Api) {
} }
fun getMessagesContent(message: Message, markAsRead: Boolean = false): Single<String> { fun getMessagesContent(message: Message, markAsRead: Boolean = false): Single<String> {
return api.getMessageContent(message.messageId, message.folderId, markAsRead, message.realId) return sdk.getMessageContent(message.messageId, message.folderId, markAsRead, message.realId)
} }
fun sendMessage(subject: String, content: String, recipients: List<Recipient>): Single<SentMessage> { fun sendMessage(subject: String, content: String, recipients: List<Recipient>): Single<SentMessage> {
return api.sendMessage( return sdk.sendMessage(
subject = subject, subject = subject,
content = content, content = content,
recipients = recipients.map { recipients = recipients.map {
ApiRecipient( SdkRecipient(
id = it.realId, id = it.realId,
name = it.realName, name = it.realName,
loginId = it.loginId, loginId = it.loginId,
reportingUnitId = it.unitId, reportingUnitId = it.unitId,
role = it.role, role = it.role,
hash = it.hash hash = it.hash,
shortName = it.name
) )
} }
) )
} }
fun deleteMessage(message: Message): Single<Boolean> { fun deleteMessage(message: Message): Single<Boolean> {
return api.deleteMessages(listOf(Pair(message.realId, message.folderId))) return sdk.deleteMessages(listOf(Pair(message.realId, message.folderId)))
} }
} }

View File

@ -2,12 +2,13 @@ package io.github.wulkanowy.data.repositories.message
import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
import io.github.wulkanowy.api.messages.SentMessage import io.github.wulkanowy.data.SdkHelper
import io.github.wulkanowy.data.ApiHelper
import io.github.wulkanowy.data.db.entities.Message import io.github.wulkanowy.data.db.entities.Message
import io.github.wulkanowy.data.db.entities.Recipient import io.github.wulkanowy.data.db.entities.Recipient
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.repositories.message.MessageFolder.RECEIVED import io.github.wulkanowy.data.repositories.message.MessageFolder.RECEIVED
import io.github.wulkanowy.sdk.pojo.SentMessage
import io.github.wulkanowy.utils.uniqueSubtract import io.github.wulkanowy.utils.uniqueSubtract
import io.reactivex.Completable import io.reactivex.Completable
import io.reactivex.Maybe import io.reactivex.Maybe
@ -21,16 +22,16 @@ class MessageRepository @Inject constructor(
private val settings: InternetObservingSettings, private val settings: InternetObservingSettings,
private val local: MessageLocal, private val local: MessageLocal,
private val remote: MessageRemote, private val remote: MessageRemote,
private val apiHelper: ApiHelper private val sdkHelper: SdkHelper
) { ) {
fun getMessages(student: Student, folder: MessageFolder, forceRefresh: Boolean = false, notify: Boolean = false): Single<List<Message>> { fun getMessages(student: Student, semester: Semester, folder: MessageFolder, forceRefresh: Boolean = false, notify: Boolean = false): Single<List<Message>> {
return Single.just(apiHelper.initApi(student)) return Single.just(sdkHelper.init(student))
.flatMap { _ -> .flatMap { _ ->
local.getMessages(student, folder).filter { !forceRefresh } local.getMessages(student, folder).filter { !forceRefresh }
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings) .switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
.flatMap { .flatMap {
if (it) remote.getMessages(student, folder) if (it) remote.getMessages(student, semester, folder)
else Single.error(UnknownHostException()) else Single.error(UnknownHostException())
}.flatMap { new -> }.flatMap { new ->
local.getMessages(student, folder).toSingle(emptyList()) local.getMessages(student, folder).toSingle(emptyList())
@ -47,10 +48,10 @@ class MessageRepository @Inject constructor(
} }
fun getMessage(student: Student, messageDbId: Long, markAsRead: Boolean = false): Single<Message> { fun getMessage(student: Student, messageDbId: Long, markAsRead: Boolean = false): Single<Message> {
return Single.just(apiHelper.initApi(student)) return Single.just(sdkHelper.init(student))
.flatMap { _ -> .flatMap { _ ->
local.getMessage(messageDbId) local.getMessage(messageDbId)
.filter { !it.content.isNullOrEmpty() } .filter { it.content.isNotEmpty() }
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings) .switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
.flatMap { .flatMap {
if (it) local.getMessage(messageDbId).toSingle() if (it) local.getMessage(messageDbId).toSingle()
@ -60,7 +61,7 @@ class MessageRepository @Inject constructor(
remote.getMessagesContent(dbMessage, markAsRead).doOnSuccess { remote.getMessagesContent(dbMessage, markAsRead).doOnSuccess {
local.updateMessages(listOf(dbMessage.copy(unread = false).apply { local.updateMessages(listOf(dbMessage.copy(unread = false).apply {
id = dbMessage.id id = dbMessage.id
content = it content = content.ifBlank { it }
})) }))
} }
}.flatMap { }.flatMap {

View File

@ -3,7 +3,6 @@ package io.github.wulkanowy.data.repositories.mobiledevice
import io.github.wulkanowy.data.db.dao.MobileDeviceDao import io.github.wulkanowy.data.db.dao.MobileDeviceDao
import io.github.wulkanowy.data.db.entities.MobileDevice import io.github.wulkanowy.data.db.entities.MobileDevice
import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student
import io.reactivex.Maybe import io.reactivex.Maybe
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton

View File

@ -1,25 +1,23 @@
package io.github.wulkanowy.data.repositories.mobiledevice package io.github.wulkanowy.data.repositories.mobiledevice
import io.github.wulkanowy.api.Api
import io.github.wulkanowy.data.db.entities.MobileDevice import io.github.wulkanowy.data.db.entities.MobileDevice
import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.pojos.MobileDeviceToken import io.github.wulkanowy.data.pojos.MobileDeviceToken
import io.github.wulkanowy.utils.toLocalDateTime import io.github.wulkanowy.sdk.Sdk
import io.reactivex.Single import io.reactivex.Single
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
@Singleton @Singleton
class MobileDeviceRemote @Inject constructor(private val api: Api) { class MobileDeviceRemote @Inject constructor(private val sdk: Sdk) {
fun getDevices(semester: Semester): Single<List<MobileDevice>> { fun getDevices(semester: Semester): Single<List<MobileDevice>> {
return Single.just(api.apply { diaryId = semester.diaryId }) return sdk.switchDiary(semester.diaryId, semester.schoolYear).getRegisteredDevices()
.flatMap { api.getRegisteredDevices() }
.map { devices -> .map { devices ->
devices.map { devices.map {
MobileDevice( MobileDevice(
studentId = semester.studentId, studentId = semester.studentId,
date = it.date.toLocalDateTime(), date = it.date,
deviceId = it.id, deviceId = it.id,
name = it.name name = it.name
) )
@ -28,13 +26,11 @@ class MobileDeviceRemote @Inject constructor(private val api: Api) {
} }
fun unregisterDevice(semester: Semester, device: MobileDevice): Single<Boolean> { fun unregisterDevice(semester: Semester, device: MobileDevice): Single<Boolean> {
return Single.just(api.apply { diaryId = semester.diaryId }) return sdk.switchDiary(semester.diaryId, semester.schoolYear).unregisterDevice(device.deviceId)
.flatMap { api.unregisterDevice(device.deviceId) }
} }
fun getToken(semester: Semester): Single<MobileDeviceToken> { fun getToken(semester: Semester): Single<MobileDeviceToken> {
return Single.just(api.apply { diaryId = semester.diaryId }) return sdk.switchDiary(semester.diaryId, semester.schoolYear).getToken()
.flatMap { api.getToken() }
.map { .map {
MobileDeviceToken( MobileDeviceToken(
token = it.token, token = it.token,

View File

@ -1,24 +1,22 @@
package io.github.wulkanowy.data.repositories.note package io.github.wulkanowy.data.repositories.note
import io.github.wulkanowy.api.Api
import io.github.wulkanowy.data.db.entities.Note import io.github.wulkanowy.data.db.entities.Note
import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.utils.toLocalDate import io.github.wulkanowy.sdk.Sdk
import io.reactivex.Single import io.reactivex.Single
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
@Singleton @Singleton
class NoteRemote @Inject constructor(private val api: Api) { class NoteRemote @Inject constructor(private val sdk: Sdk) {
fun getNotes(semester: Semester): Single<List<Note>> { fun getNotes(semester: Semester): Single<List<Note>> {
return Single.just(api.apply { diaryId = semester.diaryId }) return sdk.switchDiary(semester.diaryId, semester.schoolYear).getNotes(semester.semesterId)
.flatMap { it.getNotes() }
.map { notes -> .map { notes ->
notes.map { notes.map {
Note( Note(
studentId = semester.studentId, studentId = semester.studentId,
date = it.date.toLocalDate(), date = it.date,
teacher = it.teacher, teacher = it.teacher,
category = it.category, category = it.category,
content = it.content content = it.content

View File

@ -12,52 +12,64 @@ class PreferencesRepository @Inject constructor(
val context: Context val context: Context
) { ) {
val startMenuIndex: Int val startMenuIndex: Int
get() = sharedPref.getString(context.getString(R.string.pref_key_start_menu), "0")?.toIntOrNull() ?: 0 get() = getString(R.string.pref_key_start_menu, R.string.pref_default_startup).toInt()
val isShowPresent: Boolean val isShowPresent: Boolean
get() = sharedPref.getBoolean(context.getString(R.string.pref_key_attendance_present), true) get() = getBoolean(R.string.pref_key_attendance_present, R.bool.pref_default_attendance_present)
val gradeAverageMode: String val gradeAverageMode: String
get() = sharedPref.getString(context.getString(R.string.pref_key_grade_average_mode), "only_one_semester") ?: "only_one_semester" get() = getString(R.string.pref_key_grade_average_mode, R.string.pref_default_grade_average_mode)
val gradeAverageForceCalc: Boolean val gradeAverageForceCalc: Boolean
get() = sharedPref.getBoolean(context.getString(R.string.pref_key_grade_average_force_calc), false) get() = getBoolean(R.string.pref_key_grade_average_force_calc, R.bool.pref_default_grade_average_force_calc)
val isGradeExpandable: Boolean val isGradeExpandable: Boolean
get() = !sharedPref.getBoolean(context.getString(R.string.pref_key_expand_grade), false) get() = !getBoolean(R.string.pref_key_expand_grade, R.bool.pref_default_expand_grade)
val appThemeKey: String = context.getString(R.string.pref_key_app_theme) val appThemeKey = context.getString(R.string.pref_key_app_theme)
val appTheme: String val appTheme: String
get() = sharedPref.getString(appThemeKey, "light") ?: "light" get() = getString(appThemeKey, R.string.pref_default_app_theme)
val gradeColorTheme: String val gradeColorTheme: String
get() = sharedPref.getString(context.getString(R.string.pref_key_grade_color_scheme), "vulcan") ?: "vulcan" get() = getString(R.string.pref_key_grade_color_scheme, R.string.pref_default_grade_color_scheme)
val serviceEnableKey: String = context.getString(R.string.pref_key_services_enable) val appLanguageKey = context.getString(R.string.pref_key_app_language)
val appLanguage
get() = getString(appLanguageKey, R.string.pref_default_app_language)
val serviceEnableKey = context.getString(R.string.pref_key_services_enable)
val isServiceEnabled: Boolean val isServiceEnabled: Boolean
get() = sharedPref.getBoolean(serviceEnableKey, true) get() = getBoolean(serviceEnableKey, R.bool.pref_default_services_enable)
val servicesIntervalKey: String = context.getString(R.string.pref_key_services_interval) val servicesIntervalKey = context.getString(R.string.pref_key_services_interval)
val servicesInterval: Long val servicesInterval: Long
get() = sharedPref.getString(servicesIntervalKey, "60")?.toLongOrNull() ?: 60 get() = getString(servicesIntervalKey, R.string.pref_default_services_interval).toLong()
val servicesOnlyWifiKey: String = context.getString(R.string.pref_key_services_wifi_only) val servicesOnlyWifiKey = context.getString(R.string.pref_key_services_wifi_only)
val isServicesOnlyWifi: Boolean val isServicesOnlyWifi: Boolean
get() = sharedPref.getBoolean(servicesOnlyWifiKey, false) get() = getBoolean(servicesOnlyWifiKey, R.bool.pref_default_services_wifi_only)
val isNotificationsEnable: Boolean val isNotificationsEnable: Boolean
get() = sharedPref.getBoolean(context.getString(R.string.pref_key_notifications_enable), true) get() = getBoolean(R.string.pref_key_notifications_enable, R.bool.pref_default_notifications_enable)
val isDebugNotificationEnableKey: String = context.getString(R.string.pref_key_notification_debug) val isDebugNotificationEnableKey = context.getString(R.string.pref_key_notification_debug)
val isDebugNotificationEnable: Boolean val isDebugNotificationEnable: Boolean
get() = sharedPref.getBoolean(isDebugNotificationEnableKey, false) get() = getBoolean(isDebugNotificationEnableKey, R.bool.pref_default_notification_debug)
val gradePlusModifier: Double val gradePlusModifier: Double
get() = sharedPref.getString(context.getString(R.string.pref_key_grade_modifier_plus), "0.0")?.toDouble() ?: 0.0 get() = getString(R.string.pref_key_grade_modifier_plus, R.string.pref_default_grade_modifier_plus).toDouble()
val gradeMinusModifier: Double val gradeMinusModifier: Double
get() = sharedPref.getString(context.getString(R.string.pref_key_grade_modifier_minus), "0.0")?.toDouble() ?: 0.0 get() = getString(R.string.pref_key_grade_modifier_minus, R.string.pref_default_grade_modifier_minus).toDouble()
val fillMessageContent: Boolean val fillMessageContent: Boolean
get() = sharedPref.getBoolean(context.getString(R.string.pref_key_fill_message_content), true) get() = getBoolean(R.string.pref_key_fill_message_content, R.bool.pref_default_fill_message_content)
private fun getString(id: Int, default: Int) = getString(context.getString(id), default)
private fun getString(id: String, default: Int) = sharedPref.getString(id, context.getString(default)) ?: context.getString(default)
private fun getBoolean(id: Int, default: Int) = getBoolean(context.getString(id), default)
private fun getBoolean(id: String, default: Int) = sharedPref.getBoolean(id, context.resources.getBoolean(default))
} }

View File

@ -15,7 +15,7 @@ class RecipientLocal @Inject constructor(private val recipientDb: RecipientDao)
return recipientDb.load(student.studentId, role, unit.realId).filter { !it.isEmpty() } return recipientDb.load(student.studentId, role, unit.realId).filter { !it.isEmpty() }
} }
fun saveRecipients(recipients: List<Recipient>) { fun saveRecipients(recipients: List<Recipient>): List<Long> {
return recipientDb.insertAll(recipients) return recipientDb.insertAll(recipients)
} }

View File

@ -1,34 +1,34 @@
package io.github.wulkanowy.data.repositories.recipient package io.github.wulkanowy.data.repositories.recipient
import io.github.wulkanowy.api.Api
import io.github.wulkanowy.data.db.entities.Message import io.github.wulkanowy.data.db.entities.Message
import io.github.wulkanowy.data.db.entities.Recipient import io.github.wulkanowy.data.db.entities.Recipient
import io.github.wulkanowy.data.db.entities.ReportingUnit import io.github.wulkanowy.data.db.entities.ReportingUnit
import io.github.wulkanowy.sdk.Sdk
import io.reactivex.Single import io.reactivex.Single
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
import io.github.wulkanowy.api.messages.Recipient as ApiRecipient import io.github.wulkanowy.sdk.pojo.Recipient as SdkRecipient
@Singleton @Singleton
class RecipientRemote @Inject constructor(private val api: Api) { class RecipientRemote @Inject constructor(private val sdk: Sdk) {
fun getRecipients(role: Int, unit: ReportingUnit): Single<List<Recipient>> { fun getRecipients(role: Int, unit: ReportingUnit): Single<List<Recipient>> {
return api.getRecipients(unit.realId, role) return sdk.getRecipients(unit.realId, role)
.map { recipients -> .map { recipients ->
recipients.map { it.toRecipient() } recipients.map { it.toRecipient() }
} }
} }
fun getMessageRecipients(message: Message): Single<List<Recipient>> { fun getMessageRecipients(message: Message): Single<List<Recipient>> {
return api.getMessageRecipients(message.messageId, message.senderId) return sdk.getMessageRecipients(message.messageId, message.senderId)
.map { recipients -> .map { recipients ->
recipients.map { it.toRecipient() } recipients.map { it.toRecipient() }
} }
} }
private fun ApiRecipient.toRecipient(): Recipient { private fun SdkRecipient.toRecipient(): Recipient {
return Recipient( return Recipient(
studentId = api.studentId, studentId = sdk.studentId,
realId = id, realId = id,
realName = name, realName = name,
name = shortName, name = shortName,

View File

@ -2,7 +2,7 @@ package io.github.wulkanowy.data.repositories.recipient
import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
import io.github.wulkanowy.data.ApiHelper import io.github.wulkanowy.data.SdkHelper
import io.github.wulkanowy.data.db.entities.Message import io.github.wulkanowy.data.db.entities.Message
import io.github.wulkanowy.data.db.entities.Recipient import io.github.wulkanowy.data.db.entities.Recipient
import io.github.wulkanowy.data.db.entities.ReportingUnit import io.github.wulkanowy.data.db.entities.ReportingUnit
@ -18,11 +18,11 @@ class RecipientRepository @Inject constructor(
private val settings: InternetObservingSettings, private val settings: InternetObservingSettings,
private val local: RecipientLocal, private val local: RecipientLocal,
private val remote: RecipientRemote, private val remote: RecipientRemote,
private val apiHelper: ApiHelper private val sdkHelper: SdkHelper
) { ) {
fun getRecipients(student: Student, role: Int, unit: ReportingUnit, forceRefresh: Boolean = false): Single<List<Recipient>> { fun getRecipients(student: Student, role: Int, unit: ReportingUnit, forceRefresh: Boolean = false): Single<List<Recipient>> {
return Single.just(apiHelper.initApi(student)) return Single.just(sdkHelper.init(student))
.flatMap { _ -> .flatMap { _ ->
local.getRecipients(student, role, unit).filter { !forceRefresh } local.getRecipients(student, role, unit).filter { !forceRefresh }
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings) .switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
@ -43,7 +43,7 @@ class RecipientRepository @Inject constructor(
} }
fun getMessageRecipients(student: Student, message: Message): Single<List<Recipient>> { fun getMessageRecipients(student: Student, message: Message): Single<List<Recipient>> {
return Single.just(apiHelper.initApi(student)) return Single.just(sdkHelper.init(student))
.flatMap { ReactiveNetwork.checkInternetConnectivity(settings) } .flatMap { ReactiveNetwork.checkInternetConnectivity(settings) }
.flatMap { .flatMap {
if (it) remote.getMessageRecipients(message) if (it) remote.getMessageRecipients(message)

View File

@ -18,7 +18,7 @@ class ReportingUnitLocal @Inject constructor(private val reportingUnitDb: Report
return reportingUnitDb.loadOne(student.studentId, unitId) return reportingUnitDb.loadOne(student.studentId, unitId)
} }
fun saveReportingUnits(reportingUnits: List<ReportingUnit>) { fun saveReportingUnits(reportingUnits: List<ReportingUnit>): List<Long> {
return reportingUnitDb.insertAll(reportingUnits) return reportingUnitDb.insertAll(reportingUnits)
} }

View File

@ -1,19 +1,19 @@
package io.github.wulkanowy.data.repositories.reportingunit package io.github.wulkanowy.data.repositories.reportingunit
import io.github.wulkanowy.api.Api
import io.github.wulkanowy.data.db.entities.ReportingUnit import io.github.wulkanowy.data.db.entities.ReportingUnit
import io.github.wulkanowy.sdk.Sdk
import io.reactivex.Single import io.reactivex.Single
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
@Singleton @Singleton
class ReportingUnitRemote @Inject constructor(private val api: Api) { class ReportingUnitRemote @Inject constructor(private val sdk: Sdk) {
fun getReportingUnits(): Single<List<ReportingUnit>> { fun getReportingUnits(): Single<List<ReportingUnit>> {
return api.getReportingUnits().map { return sdk.getReportingUnits().map {
it.map { unit -> it.map { unit ->
ReportingUnit( ReportingUnit(
studentId = api.studentId, studentId = sdk.studentId,
realId = unit.id, realId = unit.id,
roles = unit.roles, roles = unit.roles,
senderId = unit.senderId, senderId = unit.senderId,

View File

@ -2,7 +2,7 @@ package io.github.wulkanowy.data.repositories.reportingunit
import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
import io.github.wulkanowy.data.ApiHelper import io.github.wulkanowy.data.SdkHelper
import io.github.wulkanowy.data.db.entities.ReportingUnit import io.github.wulkanowy.data.db.entities.ReportingUnit
import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.utils.uniqueSubtract import io.github.wulkanowy.utils.uniqueSubtract
@ -17,11 +17,11 @@ class ReportingUnitRepository @Inject constructor(
private val settings: InternetObservingSettings, private val settings: InternetObservingSettings,
private val local: ReportingUnitLocal, private val local: ReportingUnitLocal,
private val remote: ReportingUnitRemote, private val remote: ReportingUnitRemote,
private val apiHelper: ApiHelper private val sdkHelper: SdkHelper
) { ) {
fun getReportingUnits(student: Student, forceRefresh: Boolean = false): Single<List<ReportingUnit>> { fun getReportingUnits(student: Student, forceRefresh: Boolean = false): Single<List<ReportingUnit>> {
return Single.just(apiHelper.initApi(student)) return Single.just(sdkHelper.init(student))
.flatMap { _ -> .flatMap { _ ->
local.getReportingUnits(student).filter { !forceRefresh } local.getReportingUnits(student).filter { !forceRefresh }
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings) .switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
@ -40,7 +40,7 @@ class ReportingUnitRepository @Inject constructor(
} }
fun getReportingUnit(student: Student, unitId: Int): Maybe<ReportingUnit> { fun getReportingUnit(student: Student, unitId: Int): Maybe<ReportingUnit> {
return Maybe.just(apiHelper.initApi(student)) return Maybe.just(sdkHelper.init(student))
.flatMap { _ -> .flatMap { _ ->
local.getReportingUnit(student, unitId) local.getReportingUnit(student, unitId)
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings) .switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)

View File

@ -0,0 +1,22 @@
package io.github.wulkanowy.data.repositories.school
import io.github.wulkanowy.data.db.dao.SchoolDao
import io.github.wulkanowy.data.db.entities.School
import io.github.wulkanowy.data.db.entities.Semester
import io.reactivex.Maybe
import javax.inject.Inject
class SchoolLocal @Inject constructor(private val schoolDb: SchoolDao) {
fun saveSchool(school: School) {
schoolDb.insertAll(listOf(school))
}
fun deleteSchool(school: School) {
schoolDb.deleteAll(listOf(school))
}
fun getSchool(semester: Semester): Maybe<School> {
return schoolDb.load(semester.studentId, semester.classId)
}
}

View File

@ -0,0 +1,25 @@
package io.github.wulkanowy.data.repositories.school
import io.github.wulkanowy.data.db.entities.School
import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.sdk.Sdk
import io.reactivex.Single
import javax.inject.Inject
class SchoolRemote @Inject constructor(private val sdk: Sdk) {
fun getSchoolInfo(semester: Semester): Single<School> {
return sdk.switchDiary(semester.diaryId, semester.schoolYear).getSchool()
.map {
School(
studentId = semester.studentId,
classId = semester.classId,
name = it.name,
address = it.address,
contact = it.contact,
headmaster = it.headmaster,
pedagogue = it.pedagogue
)
}
}
}

View File

@ -0,0 +1,41 @@
package io.github.wulkanowy.data.repositories.school
import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
import io.github.wulkanowy.data.db.entities.School
import io.github.wulkanowy.data.db.entities.Semester
import io.reactivex.Maybe
import io.reactivex.Single
import java.net.UnknownHostException
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class SchoolRepository @Inject constructor(
private val settings: InternetObservingSettings,
private val local: SchoolLocal,
private val remote: SchoolRemote
) {
fun getSchoolInfo(semester: Semester, forceRefresh: Boolean = false): Maybe<School> {
return local.getSchool(semester).filter { !forceRefresh }
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
.flatMap {
if (it) remote.getSchoolInfo(semester)
else Single.error(UnknownHostException())
}.flatMapMaybe { new ->
local.getSchool(semester)
.doOnSuccess { old ->
if (new != old) {
local.deleteSchool(old)
local.saveSchool(new)
}
}
.doOnComplete {
local.saveSchool(new)
}
}.flatMap({ local.getSchool(semester) }, { Maybe.error(it) },
{ local.getSchool(semester) })
)
}
}

View File

@ -1,35 +1,32 @@
package io.github.wulkanowy.data.repositories.semester package io.github.wulkanowy.data.repositories.semester
import io.github.wulkanowy.api.Api
import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.sdk.Sdk
import io.reactivex.Single import io.reactivex.Single
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
@Singleton @Singleton
class SemesterRemote @Inject constructor(private val api: Api) { class SemesterRemote @Inject constructor(private val sdk: Sdk) {
fun getSemesters(student: Student): Single<List<Semester>> { fun getSemesters(student: Student): Single<List<Semester>> {
return api.getSemesters().map { semesters -> return sdk.getSemesters().map { semesters ->
semesters.map { semester -> semesters.map {
Semester( Semester(
studentId = student.studentId, studentId = student.studentId,
diaryId = semester.diaryId, diaryId = it.diaryId,
diaryName = semester.diaryName, diaryName = it.diaryName,
schoolYear = semester.schoolYear, schoolYear = it.schoolYear,
semesterId = semester.semesterId, semesterId = it.semesterId,
semesterName = semester.semesterNumber, semesterName = it.semesterNumber,
isCurrent = semester.current, isCurrent = it.current,
start = semester.start, start = it.start,
end = semester.end, end = it.end,
classId = semester.classId, classId = it.classId,
unitId = semester.unitId unitId = it.unitId
) )
} }
} }
} }
} }

View File

@ -2,7 +2,7 @@ package io.github.wulkanowy.data.repositories.semester
import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
import io.github.wulkanowy.data.ApiHelper import io.github.wulkanowy.data.SdkHelper
import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.utils.uniqueSubtract import io.github.wulkanowy.utils.uniqueSubtract
@ -18,11 +18,11 @@ class SemesterRepository @Inject constructor(
private val remote: SemesterRemote, private val remote: SemesterRemote,
private val local: SemesterLocal, private val local: SemesterLocal,
private val settings: InternetObservingSettings, private val settings: InternetObservingSettings,
private val apiHelper: ApiHelper private val sdkHelper: SdkHelper
) { ) {
fun getSemesters(student: Student, forceRefresh: Boolean = false): Single<List<Semester>> { fun getSemesters(student: Student, forceRefresh: Boolean = false): Single<List<Semester>> {
return Maybe.just(apiHelper.initApi(student)) return Maybe.just(sdkHelper.init(student))
.flatMap { local.getSemesters(student).filter { !forceRefresh } } .flatMap { local.getSemesters(student).filter { !forceRefresh } }
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings) .switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
.flatMap { .flatMap {

View File

@ -3,6 +3,7 @@ package io.github.wulkanowy.data.repositories.student
import android.content.Context import android.content.Context
import io.github.wulkanowy.data.db.dao.StudentDao import io.github.wulkanowy.data.db.dao.StudentDao
import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.utils.security.decrypt import io.github.wulkanowy.utils.security.decrypt
import io.github.wulkanowy.utils.security.encrypt import io.github.wulkanowy.utils.security.encrypt
import io.reactivex.Completable import io.reactivex.Completable
@ -18,17 +19,26 @@ class StudentLocal @Inject constructor(
) { ) {
fun saveStudents(students: List<Student>): Single<List<Long>> { fun saveStudents(students: List<Student>): Single<List<Long>> {
return Single.fromCallable { studentDb.insertAll(students.map { it.copy(password = encrypt(it.password, context)) }) } return Single.fromCallable {
studentDb.insertAll(students.map {
if (Sdk.Mode.valueOf(it.loginMode) != Sdk.Mode.API) it.copy(password = encrypt(it.password, context))
else it
})
}
} }
fun getStudents(decryptPass: Boolean): Maybe<List<Student>> { fun getStudents(decryptPass: Boolean): Maybe<List<Student>> {
return studentDb.loadAll() return studentDb.loadAll()
.map { list -> list.map { it.apply { if (decryptPass) password = decrypt(password) } } } .map { list -> list.map { it.apply { if (decryptPass) password = decrypt(password) } } }
.filter { !it.isEmpty() } .filter { it.isNotEmpty() }
} }
fun getCurrentStudent(decryptPass: Boolean): Maybe<Student> { fun getCurrentStudent(decryptPass: Boolean): Maybe<Student> {
return studentDb.loadCurrent().map { it.apply { if (decryptPass) password = decrypt(password) } } return studentDb.loadCurrent().map {
it.apply {
if (decryptPass && Sdk.Mode.valueOf(loginMode) != Sdk.Mode.API) password = decrypt(password)
}
}
} }
fun setCurrentStudent(student: Student): Completable { fun setCurrentStudent(student: Student): Completable {

View File

@ -1,34 +1,51 @@
package io.github.wulkanowy.data.repositories.student package io.github.wulkanowy.data.repositories.student
import io.github.wulkanowy.api.Api
import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.sdk.Sdk
import io.reactivex.Single import io.reactivex.Single
import org.threeten.bp.LocalDateTime.now import org.threeten.bp.LocalDateTime.now
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
import io.github.wulkanowy.sdk.pojo.Student as SdkStudent
@Singleton @Singleton
class StudentRemote @Inject constructor(private val api: Api) { class StudentRemote @Inject constructor(private val sdk: Sdk) {
fun getStudents(email: String, password: String, endpoint: String): Single<List<Student>> { private fun mapStudents(students: List<SdkStudent>, email: String, password: String): List<Student> {
return api.getStudents().map { students -> return students.map { student ->
students.map { student -> Student(
Student( email = email,
email = email, password = password,
password = password, isParent = student.isParent,
symbol = student.symbol, symbol = student.symbol,
studentId = student.studentId, studentId = student.studentId,
studentName = student.studentName, userLoginId = student.userLoginId,
schoolSymbol = student.schoolSymbol, studentName = student.studentName,
schoolName = student.schoolName, schoolSymbol = student.schoolSymbol,
className = student.className, schoolName = student.schoolName,
classId = student.classId, className = student.className,
endpoint = endpoint, classId = student.classId,
loginType = student.loginType.name, scrapperBaseUrl = student.scrapperBaseUrl,
isCurrent = false, loginType = student.loginType.name,
registrationDate = now() isCurrent = false,
) registrationDate = now(),
} mobileBaseUrl = student.mobileBaseUrl,
privateKey = student.privateKey,
certificateKey = student.certificateKey,
loginMode = student.loginMode.name
)
} }
} }
fun getStudentsMobileApi(token: String, pin: String, symbol: String): Single<List<Student>> {
return sdk.getStudentsFromMobileApi(token, pin, symbol).map { mapStudents(it, "", "") }
}
fun getStudentsScrapper(email: String, password: String, scrapperBaseUrl: String, symbol: String): Single<List<Student>> {
return sdk.getStudentsFromScrapper(email, password, scrapperBaseUrl, symbol).map { mapStudents(it, email, password) }
}
fun getStudentsHybrid(email: String, password: String, scrapperBaseUrl: String, symbol: String): Single<List<Student>> {
return sdk.getStudentsHybrid(email, password, scrapperBaseUrl, symbol).map { mapStudents(it, email, password) }
}
} }

View File

@ -2,7 +2,6 @@ package io.github.wulkanowy.data.repositories.student
import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork import com.github.pwittchen.reactivenetwork.library.rx2.ReactiveNetwork
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
import io.github.wulkanowy.data.ApiHelper
import io.github.wulkanowy.data.db.entities.Student import io.github.wulkanowy.data.db.entities.Student
import io.github.wulkanowy.data.exceptions.NoCurrentStudentException import io.github.wulkanowy.data.exceptions.NoCurrentStudentException
import io.reactivex.Completable import io.reactivex.Completable
@ -16,21 +15,32 @@ import javax.inject.Singleton
class StudentRepository @Inject constructor( class StudentRepository @Inject constructor(
private val local: StudentLocal, private val local: StudentLocal,
private val remote: StudentRemote, private val remote: StudentRemote,
private val settings: InternetObservingSettings, private val settings: InternetObservingSettings
private val apiHelper: ApiHelper
) { ) {
fun isStudentSaved(): Single<Boolean> = local.getStudents(false).isEmpty.map { !it } fun isStudentSaved(): Single<Boolean> = local.getStudents(false).isEmpty.map { !it }
fun isCurrentStudentSet(): Single<Boolean> = local.getCurrentStudent(false).isEmpty.map { !it } fun isCurrentStudentSet(): Single<Boolean> = local.getCurrentStudent(false).isEmpty.map { !it }
fun getStudents(email: String, password: String, endpoint: String, symbol: String = ""): Single<List<Student>> { fun getStudentsApi(pin: String, symbol: String, token: String): Single<List<Student>> {
return ReactiveNetwork.checkInternetConnectivity(settings) return ReactiveNetwork.checkInternetConnectivity(settings).flatMap {
.flatMap { if (it) remote.getStudentsMobileApi(token, pin, symbol)
apiHelper.initApi(email, password, symbol, endpoint) else Single.error(UnknownHostException("No internet connection"))
if (it) remote.getStudents(email, password, endpoint) }
else Single.error(UnknownHostException("No internet connection")) }
}
fun getStudentsScrapper(email: String, password: String, endpoint: String, symbol: String = ""): Single<List<Student>> {
return ReactiveNetwork.checkInternetConnectivity(settings).flatMap {
if (it) remote.getStudentsScrapper(email, password, endpoint, symbol)
else Single.error(UnknownHostException("No internet connection"))
}
}
fun getStudentsHybrid(email: String, password: String, endpoint: String, symbol: String): Single<List<Student>> {
return ReactiveNetwork.checkInternetConnectivity(settings).flatMap {
if (it) remote.getStudentsHybrid(email, password, endpoint, symbol)
else Single.error(UnknownHostException("No internet connection"))
}
} }
fun getSavedStudents(decryptPass: Boolean = true): Single<List<Student>> { fun getSavedStudents(decryptPass: Boolean = true): Single<List<Student>> {

View File

@ -1,25 +1,24 @@
package io.github.wulkanowy.data.repositories.subject package io.github.wulkanowy.data.repositories.subject
import io.github.wulkanowy.api.Api
import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Subject import io.github.wulkanowy.data.db.entities.Subject
import io.github.wulkanowy.sdk.Sdk
import io.reactivex.Single import io.reactivex.Single
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
@Singleton @Singleton
class SubjectRemote @Inject constructor(private val api: Api) { class SubjectRemote @Inject constructor(private val sdk: Sdk) {
fun getSubjects(semester: Semester): Single<List<Subject>> { fun getSubjects(semester: Semester): Single<List<Subject>> {
return Single.just(api.apply { diaryId = semester.diaryId }) return sdk.switchDiary(semester.diaryId, semester.schoolYear).getSubjects()
.flatMap { api.getSubjects() }
.map { subjects -> .map { subjects ->
subjects.map { subjects.map {
Subject( Subject(
studentId = semester.studentId, studentId = semester.studentId,
diaryId = semester.diaryId, diaryId = semester.diaryId,
name = it.name, name = it.name,
realId = it.value realId = it.id
) )
} }
} }

View File

@ -6,7 +6,8 @@ import io.github.wulkanowy.data.db.entities.Teacher
import io.reactivex.Maybe import io.reactivex.Maybe
import javax.inject.Inject import javax.inject.Inject
class TeacherLocal @Inject constructor(private val teacherDb: TeacherDao) { class TeacherLocal @Inject constructor(private val teacherDb: TeacherDao) {
fun saveTeachers(teachers: List<Teacher>) { fun saveTeachers(teachers: List<Teacher>) {
teacherDb.insertAll(teachers) teacherDb.insertAll(teachers)
} }

View File

@ -1,18 +1,17 @@
package io.github.wulkanowy.data.repositories.teacher package io.github.wulkanowy.data.repositories.teacher
import io.github.wulkanowy.api.Api
import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Teacher import io.github.wulkanowy.data.db.entities.Teacher
import io.github.wulkanowy.sdk.Sdk
import io.reactivex.Single import io.reactivex.Single
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
@Singleton @Singleton
class TeacherRemote @Inject constructor(private val api: Api) { class TeacherRemote @Inject constructor(private val sdk: Sdk) {
fun getTeachers(semester: Semester): Single<List<Teacher>> { fun getTeachers(semester: Semester): Single<List<Teacher>> {
return Single.just(api.apply { diaryId = semester.diaryId }) return sdk.switchDiary(semester.diaryId, semester.schoolYear).getTeachers(semester.semesterId)
.flatMap { it.getTeachers() }
.map { teachers -> .map { teachers ->
teachers.map { teachers.map {
Teacher( Teacher(

View File

@ -16,6 +16,7 @@ class TeacherRepository @Inject constructor(
private val local: TeacherLocal, private val local: TeacherLocal,
private val remote: TeacherRemote private val remote: TeacherRemote
) { ) {
fun getTeachers(semester: Semester, forceRefresh: Boolean = false): Single<List<Teacher>> { fun getTeachers(semester: Semester, forceRefresh: Boolean = false): Single<List<Teacher>> {
return local.getTeachers(semester).filter { !forceRefresh } return local.getTeachers(semester).filter { !forceRefresh }
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings) .switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)

View File

@ -1,30 +1,27 @@
package io.github.wulkanowy.data.repositories.timetable package io.github.wulkanowy.data.repositories.timetable
import io.github.wulkanowy.api.Api
import io.github.wulkanowy.data.db.entities.Semester import io.github.wulkanowy.data.db.entities.Semester
import io.github.wulkanowy.data.db.entities.Timetable import io.github.wulkanowy.data.db.entities.Timetable
import io.github.wulkanowy.utils.toLocalDate import io.github.wulkanowy.sdk.Sdk
import io.github.wulkanowy.utils.toLocalDateTime
import io.reactivex.Single import io.reactivex.Single
import org.threeten.bp.LocalDate import org.threeten.bp.LocalDate
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
@Singleton @Singleton
class TimetableRemote @Inject constructor(private val api: Api) { class TimetableRemote @Inject constructor(private val sdk: Sdk) {
fun getTimetable(semester: Semester, startDate: LocalDate, endDate: LocalDate): Single<List<Timetable>> { fun getTimetable(semester: Semester, startDate: LocalDate, endDate: LocalDate): Single<List<Timetable>> {
return Single.just(api.apply { diaryId = semester.diaryId }) return sdk.switchDiary(semester.diaryId, semester.schoolYear).getTimetable(startDate, endDate)
.flatMap { it.getTimetable(startDate, endDate) }
.map { lessons -> .map { lessons ->
lessons.map { lessons.map {
Timetable( Timetable(
studentId = semester.studentId, studentId = semester.studentId,
diaryId = semester.diaryId, diaryId = semester.diaryId,
number = it.number, number = it.number,
start = it.start.toLocalDateTime(), start = it.start,
end = it.end.toLocalDateTime(), end = it.end,
date = it.date.toLocalDate(), date = it.date,
subject = it.subject, subject = it.subject,
subjectOld = it.subjectOld, subjectOld = it.subjectOld,
group = it.group, group = it.group,

View File

@ -36,7 +36,7 @@ class TimetableRepository @Inject constructor(
old.singleOrNull { new.start == it.start }?.let { old -> old.singleOrNull { new.start == it.start }?.let { old ->
return@map new.copy( return@map new.copy(
room = if (new.room.isEmpty()) old.room else new.room, room = if (new.room.isEmpty()) old.room else new.room,
teacher = if (new.teacher.isEmpty() && !new.changes) old.teacher else new.teacher teacher = if (new.teacher.isEmpty() && !new.changes && !old.changes) old.teacher else new.teacher
) )
} }
} }

View File

@ -2,6 +2,7 @@ package io.github.wulkanowy.di
import android.appwidget.AppWidgetManager import android.appwidget.AppWidgetManager
import android.content.Context import android.content.Context
import com.yariksoffice.lingver.Lingver
import dagger.Module import dagger.Module
import dagger.Provides import dagger.Provides
import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.FlexibleAdapter
@ -32,4 +33,8 @@ internal class AppModule {
@Singleton @Singleton
@Provides @Provides
fun provideAppInfo() = AppInfo() fun provideAppInfo() = AppInfo()
@Singleton
@Provides
fun provideLingver() = Lingver.getInstance()
} }

View File

@ -29,17 +29,15 @@ import javax.inject.Singleton
@Suppress("unused") @Suppress("unused")
@AssistedModule @AssistedModule
@Module(includes = [AssistedInject_ServicesModule::class]) @Module(includes = [AssistedInject_ServicesModule::class, ServicesModule.Static::class])
abstract class ServicesModule { abstract class ServicesModule {
@Module @Module
companion object { object Static {
@JvmStatic
@Provides @Provides
fun provideWorkManager(context: Context) = WorkManager.getInstance(context) fun provideWorkManager(context: Context) = WorkManager.getInstance(context)
@JvmStatic
@Singleton @Singleton
@Provides @Provides
fun provideNotificationManager(context: Context) = NotificationManagerCompat.from(context) fun provideNotificationManager(context: Context) = NotificationManagerCompat.from(context)

View File

@ -11,6 +11,7 @@ import androidx.work.NetworkType.UNMETERED
import androidx.work.PeriodicWorkRequestBuilder import androidx.work.PeriodicWorkRequestBuilder
import androidx.work.WorkManager import androidx.work.WorkManager
import io.github.wulkanowy.data.db.SharedPrefProvider import io.github.wulkanowy.data.db.SharedPrefProvider
import io.github.wulkanowy.data.db.SharedPrefProvider.Companion.APP_VERSION_CODE_KEY
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
import io.github.wulkanowy.services.sync.channels.DebugChannel import io.github.wulkanowy.services.sync.channels.DebugChannel
import io.github.wulkanowy.services.sync.channels.NewEntriesChannel import io.github.wulkanowy.services.sync.channels.NewEntriesChannel
@ -32,10 +33,6 @@ class SyncManager @Inject constructor(
appInfo: AppInfo appInfo: AppInfo
) { ) {
companion object {
private const val APP_VERSION_CODE_KEY = "app_version_code"
}
init { init {
if (now().isHolidays) stopSyncWorker() if (now().isHolidays) stopSyncWorker()

View File

@ -11,10 +11,10 @@ import androidx.work.WorkerParameters
import com.squareup.inject.assisted.Assisted import com.squareup.inject.assisted.Assisted
import com.squareup.inject.assisted.AssistedInject import com.squareup.inject.assisted.AssistedInject
import io.github.wulkanowy.R import io.github.wulkanowy.R
import io.github.wulkanowy.api.interceptor.FeatureDisabledException
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
import io.github.wulkanowy.data.repositories.semester.SemesterRepository import io.github.wulkanowy.data.repositories.semester.SemesterRepository
import io.github.wulkanowy.data.repositories.student.StudentRepository import io.github.wulkanowy.data.repositories.student.StudentRepository
import io.github.wulkanowy.sdk.exception.FeatureDisabledException
import io.github.wulkanowy.services.sync.channels.DebugChannel import io.github.wulkanowy.services.sync.channels.DebugChannel
import io.github.wulkanowy.services.sync.works.Work import io.github.wulkanowy.services.sync.works.Work
import io.github.wulkanowy.utils.getCompatColor import io.github.wulkanowy.utils.getCompatColor
@ -78,4 +78,3 @@ class SyncWorker @AssistedInject constructor(
fun create(appContext: Context, workerParameters: WorkerParameters): ListenableWorker fun create(appContext: Context, workerParameters: WorkerParameters): ListenableWorker
} }
} }

View File

@ -30,7 +30,7 @@ class MessageWork @Inject constructor(
) : Work { ) : Work {
override fun create(student: Student, semester: Semester): Completable { override fun create(student: Student, semester: Semester): Completable {
return messageRepository.getMessages(student, RECEIVED, true, preferencesRepository.isNotificationsEnable) return messageRepository.getMessages(student, semester, RECEIVED, true, preferencesRepository.isNotificationsEnable)
.flatMap { messageRepository.getNotNotifiedMessages(student) } .flatMap { messageRepository.getNotNotifiedMessages(student) }
.flatMapCompletable { .flatMapCompletable {
if (it.isNotEmpty()) notify(it) if (it.isNotEmpty()) notify(it)

View File

@ -1,10 +1,10 @@
package io.github.wulkanowy.ui.base package io.github.wulkanowy.ui.base
import android.app.ActivityManager import android.app.ActivityManager
import android.os.Build.VERSION.SDK_INT
import android.os.Build.VERSION_CODES.LOLLIPOP
import android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK import android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
import android.os.Build.VERSION.SDK_INT
import android.os.Build.VERSION_CODES.LOLLIPOP
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import android.widget.Toast import android.widget.Toast
@ -22,7 +22,8 @@ import io.github.wulkanowy.utils.FragmentLifecycleLogger
import io.github.wulkanowy.utils.getThemeAttrColor import io.github.wulkanowy.utils.getThemeAttrColor
import javax.inject.Inject import javax.inject.Inject
abstract class BaseActivity<T : BasePresenter<out BaseView>> : AppCompatActivity(), BaseView, HasAndroidInjector { abstract class BaseActivity<T : BasePresenter<out BaseView>> : AppCompatActivity(), BaseView,
HasAndroidInjector {
@Inject @Inject
lateinit var androidInjector: DispatchingAndroidInjector<Any> lateinit var androidInjector: DispatchingAndroidInjector<Any>
@ -53,13 +54,15 @@ abstract class BaseActivity<T : BasePresenter<out BaseView>> : AppCompatActivity
override fun showError(text: String, error: Throwable) { override fun showError(text: String, error: Throwable) {
if (messageContainer != null) { if (messageContainer != null) {
Snackbar.make(messageContainer!!, text, LENGTH_LONG) Snackbar.make(messageContainer!!, text, LENGTH_LONG)
.setAction(R.string.all_details) { .setAction(R.string.all_details) { showErrorDetailsDialog(error) }
ErrorDialog.newInstance(error).show(supportFragmentManager, error.toString())
}
.show() .show()
} else showMessage(text) } else showMessage(text)
} }
override fun showErrorDetailsDialog(error: Throwable) {
ErrorDialog.newInstance(error).show(supportFragmentManager, error.toString())
}
override fun showMessage(text: String) { override fun showMessage(text: String) {
if (messageContainer != null) Snackbar.make(messageContainer!!, text, LENGTH_LONG).show() if (messageContainer != null) Snackbar.make(messageContainer!!, text, LENGTH_LONG).show()
else Toast.makeText(this, text, Toast.LENGTH_LONG).show() else Toast.makeText(this, text, Toast.LENGTH_LONG).show()

View File

@ -0,0 +1,27 @@
package io.github.wulkanowy.ui.base
import android.widget.Toast
import dagger.android.support.DaggerAppCompatDialogFragment
abstract class BaseDialogFragment : DaggerAppCompatDialogFragment(), BaseView {
override fun showError(text: String, error: Throwable) {
showMessage(text)
}
override fun showMessage(text: String) {
Toast.makeText(context, text, Toast.LENGTH_LONG).show()
}
override fun showExpiredDialog() {
(activity as? BaseActivity<*>)?.showExpiredDialog()
}
override fun openClearLoginView() {
(activity as? BaseActivity<*>)?.openClearLoginView()
}
override fun showErrorDetailsDialog(error: Throwable) {
ErrorDialog.newInstance(error).show(childFragmentManager, error.toString())
}
}

View File

@ -13,15 +13,17 @@ abstract class BaseFragment : DaggerFragment(), BaseView {
override fun showError(text: String, error: Throwable) { override fun showError(text: String, error: Throwable) {
if (messageContainer != null) { if (messageContainer != null) {
Snackbar.make(messageContainer!!, text, LENGTH_LONG) Snackbar.make(messageContainer!!, text, LENGTH_LONG)
.setAction(R.string.all_details) { .setAction(R.string.all_details) { if (isAdded) showErrorDetailsDialog(error) }
if (isAdded) ErrorDialog.newInstance(error).show(childFragmentManager, error.toString())
}
.show() .show()
} else { } else {
(activity as? BaseActivity<*>)?.showError(text, error) (activity as? BaseActivity<*>)?.showError(text, error)
} }
} }
override fun showErrorDetailsDialog(error: Throwable) {
ErrorDialog.newInstance(error).show(childFragmentManager, error.toString())
}
override fun showMessage(text: String) { override fun showMessage(text: String) {
if (messageContainer != null) { if (messageContainer != null) {
Snackbar.make(messageContainer!!, text, LENGTH_LONG).show() Snackbar.make(messageContainer!!, text, LENGTH_LONG).show()

View File

@ -9,4 +9,6 @@ interface BaseView {
fun showExpiredDialog() fun showExpiredDialog()
fun openClearLoginView() fun openClearLoginView()
fun showErrorDetailsDialog(error: Throwable)
} }

View File

@ -3,11 +3,12 @@ package io.github.wulkanowy.ui.base
import android.content.res.Resources import android.content.res.Resources
import com.readystatesoftware.chuck.api.ChuckCollector import com.readystatesoftware.chuck.api.ChuckCollector
import io.github.wulkanowy.R import io.github.wulkanowy.R
import io.github.wulkanowy.api.interceptor.FeatureDisabledException
import io.github.wulkanowy.api.interceptor.ServiceUnavailableException
import io.github.wulkanowy.api.login.BadCredentialsException
import io.github.wulkanowy.api.login.NotLoggedInException
import io.github.wulkanowy.data.exceptions.NoCurrentStudentException import io.github.wulkanowy.data.exceptions.NoCurrentStudentException
import io.github.wulkanowy.sdk.exception.BadCredentialsException
import io.github.wulkanowy.sdk.exception.FeatureDisabledException
import io.github.wulkanowy.sdk.exception.FeatureNotAvailableException
import io.github.wulkanowy.sdk.exception.NotLoggedInException
import io.github.wulkanowy.sdk.exception.ServiceUnavailableException
import io.github.wulkanowy.utils.security.ScramblerException import io.github.wulkanowy.utils.security.ScramblerException
import timber.log.Timber import timber.log.Timber
import java.net.SocketTimeoutException import java.net.SocketTimeoutException
@ -38,6 +39,7 @@ open class ErrorHandler @Inject constructor(protected val resources: Resources,
is FeatureDisabledException -> showErrorMessage(getString(R.string.error_feature_disabled), error) is FeatureDisabledException -> showErrorMessage(getString(R.string.error_feature_disabled), error)
is ScramblerException, is BadCredentialsException -> onSessionExpired() is ScramblerException, is BadCredentialsException -> onSessionExpired()
is NoCurrentStudentException -> onNoCurrentStudent() is NoCurrentStudentException -> onNoCurrentStudent()
is FeatureNotAvailableException -> showErrorMessage(getString(R.string.error_feature_not_available), error)
else -> showErrorMessage(getString(R.string.error_unknown), error) else -> showErrorMessage(getString(R.string.error_unknown), error)
} }
} }

View File

@ -3,6 +3,7 @@ package io.github.wulkanowy.ui.base
import android.content.pm.PackageManager.GET_ACTIVITIES import android.content.pm.PackageManager.GET_ACTIVITIES
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate import androidx.appcompat.app.AppCompatDelegate
import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM
import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_NO import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_NO
import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES
import io.github.wulkanowy.R import io.github.wulkanowy.R
@ -22,8 +23,12 @@ class ThemeManager @Inject constructor(private val preferencesRepository: Prefer
fun applyDefaultTheme() { fun applyDefaultTheme() {
AppCompatDelegate.setDefaultNightMode( AppCompatDelegate.setDefaultNightMode(
if (preferencesRepository.appTheme == "light") MODE_NIGHT_NO when (val theme = preferencesRepository.appTheme) {
else MODE_NIGHT_YES "light" -> MODE_NIGHT_NO
"dark", "black" -> MODE_NIGHT_YES
"system" -> MODE_NIGHT_FOLLOW_SYSTEM
else -> throw IllegalArgumentException("Wrong theme: $theme")
}
) )
} }

View File

@ -47,6 +47,11 @@ class AboutFragment : BaseFragment(), AboutView, MainView.TitledView {
Triple(getString(R.string.about_feedback), getString(R.string.about_feedback_summary), getCompatDrawable(R.drawable.ic_about_feedback)) Triple(getString(R.string.about_feedback), getString(R.string.about_feedback_summary), getCompatDrawable(R.drawable.ic_about_feedback))
} }
override val faqRes: Triple<String, String, Drawable?>?
get() = context?.run {
Triple(getString(R.string.about_faq), getString(R.string.about_faq_summary), getCompatDrawable(R.drawable.ic_about_faq))
}
override val discordRes: Triple<String, String, Drawable?>? override val discordRes: Triple<String, String, Drawable?>?
get() = context?.run { get() = context?.run {
Triple(getString(R.string.about_discord), getString(R.string.about_discord_summary), getCompatDrawable(R.drawable.ic_about_discord)) Triple(getString(R.string.about_discord), getString(R.string.about_discord_summary), getCompatDrawable(R.drawable.ic_about_discord))
@ -130,6 +135,10 @@ class AboutFragment : BaseFragment(), AboutView, MainView.TitledView {
} }
} }
override fun openFaqPage() {
context?.openInternetBrowser("https://wulkanowy.github.io/czesto-zadawane-pytania", ::showMessage)
}
override fun openLicenses() { override fun openLicenses() {
(activity as? MainActivity)?.pushView(LicenseFragment.newInstance()) (activity as? MainActivity)?.pushView(LicenseFragment.newInstance())
} }

View File

@ -28,10 +28,15 @@ class AboutPresenter @Inject constructor(
view?.run { view?.run {
when (item.title) { when (item.title) {
feedbackRes?.first -> { feedbackRes?.first -> {
Timber.i("Opening email client ") Timber.i("Opening email client")
openEmailClient() openEmailClient()
analytics.logEvent("about_open", "name" to "feedback") analytics.logEvent("about_open", "name" to "feedback")
} }
faqRes?.first -> {
Timber.i("Opening faq page")
openFaqPage()
analytics.logEvent("about_open", "name" to "faq")
}
discordRes?.first -> { discordRes?.first -> {
Timber.i("Opening discord") Timber.i("Opening discord")
openDiscordInvite() openDiscordInvite()
@ -61,6 +66,7 @@ class AboutPresenter @Inject constructor(
updateData(AboutScrollableHeader(), listOfNotNull( updateData(AboutScrollableHeader(), listOfNotNull(
versionRes?.let { (title, summary, image) -> AboutItem(title, summary, image) }, versionRes?.let { (title, summary, image) -> AboutItem(title, summary, image) },
feedbackRes?.let { (title, summary, image) -> AboutItem(title, summary, image) }, feedbackRes?.let { (title, summary, image) -> AboutItem(title, summary, image) },
faqRes?.let { (title, summary, image) -> AboutItem(title, summary, image) },
discordRes?.let { (title, summary, image) -> AboutItem(title, summary, image) }, discordRes?.let { (title, summary, image) -> AboutItem(title, summary, image) },
homepageRes?.let { (title, summary, image) -> AboutItem(title, summary, image) }, homepageRes?.let { (title, summary, image) -> AboutItem(title, summary, image) },
licensesRes?.let { (title, summary, image) -> AboutItem(title, summary, image) }, licensesRes?.let { (title, summary, image) -> AboutItem(title, summary, image) },

View File

@ -9,6 +9,8 @@ interface AboutView : BaseView {
val feedbackRes: Triple<String, String, Drawable?>? val feedbackRes: Triple<String, String, Drawable?>?
val faqRes: Triple<String, String, Drawable?>?
val discordRes: Triple<String, String, Drawable?>? val discordRes: Triple<String, String, Drawable?>?
val homepageRes: Triple<String, String, Drawable?>? val homepageRes: Triple<String, String, Drawable?>?
@ -25,6 +27,8 @@ interface AboutView : BaseView {
fun openEmailClient() fun openEmailClient()
fun openFaqPage()
fun openHomepage() fun openHomepage()
fun openLicenses() fun openLicenses()

View File

@ -7,18 +7,17 @@ import android.view.ViewGroup
import android.widget.Toast import android.widget.Toast
import android.widget.Toast.LENGTH_LONG import android.widget.Toast.LENGTH_LONG
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import dagger.android.support.DaggerAppCompatDialogFragment
import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
import io.github.wulkanowy.R import io.github.wulkanowy.R
import io.github.wulkanowy.ui.base.BaseActivity import io.github.wulkanowy.ui.base.BaseDialogFragment
import io.github.wulkanowy.ui.modules.login.LoginActivity import io.github.wulkanowy.ui.modules.login.LoginActivity
import io.github.wulkanowy.utils.setOnItemClickListener import io.github.wulkanowy.utils.setOnItemClickListener
import kotlinx.android.synthetic.main.dialog_account.* import kotlinx.android.synthetic.main.dialog_account.*
import javax.inject.Inject import javax.inject.Inject
class AccountDialog : DaggerAppCompatDialogFragment(), AccountView { class AccountDialog : BaseDialogFragment(), AccountView {
@Inject @Inject
lateinit var presenter: AccountPresenter lateinit var presenter: AccountPresenter
@ -77,14 +76,6 @@ class AccountDialog : DaggerAppCompatDialogFragment(), AccountView {
} }
} }
override fun showExpiredDialog() {
(activity as? BaseActivity<*>)?.showExpiredDialog()
}
override fun openClearLoginView() {
(activity as? BaseActivity<*>)?.openClearLoginView()
}
override fun showConfirmDialog() { override fun showConfirmDialog() {
context?.let { context?.let {
AlertDialog.Builder(it) AlertDialog.Builder(it)
@ -105,4 +96,3 @@ class AccountDialog : DaggerAppCompatDialogFragment(), AccountView {
super.onDestroy() super.onDestroy()
} }
} }

View File

@ -6,7 +6,11 @@ import android.view.Menu
import android.view.MenuInflater import android.view.MenuInflater
import android.view.MenuItem 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 android.view.ViewGroup import android.view.ViewGroup
import com.wdullaer.materialdatetimepicker.date.DatePickerDialog
import eu.davidea.flexibleadapter.FlexibleAdapter import eu.davidea.flexibleadapter.FlexibleAdapter
import eu.davidea.flexibleadapter.common.FlexibleItemDecoration import eu.davidea.flexibleadapter.common.FlexibleItemDecoration
import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager
@ -17,9 +21,11 @@ import io.github.wulkanowy.ui.base.BaseFragment
import io.github.wulkanowy.ui.modules.attendance.summary.AttendanceSummaryFragment import io.github.wulkanowy.ui.modules.attendance.summary.AttendanceSummaryFragment
import io.github.wulkanowy.ui.modules.main.MainActivity import io.github.wulkanowy.ui.modules.main.MainActivity
import io.github.wulkanowy.ui.modules.main.MainView import io.github.wulkanowy.ui.modules.main.MainView
import io.github.wulkanowy.utils.SchooldaysRangeLimiter
import io.github.wulkanowy.utils.dpToPx import io.github.wulkanowy.utils.dpToPx
import io.github.wulkanowy.utils.setOnItemClickListener import io.github.wulkanowy.utils.setOnItemClickListener
import kotlinx.android.synthetic.main.fragment_attendance.* import kotlinx.android.synthetic.main.fragment_attendance.*
import org.threeten.bp.LocalDate
import javax.inject.Inject import javax.inject.Inject
class AttendanceFragment : BaseFragment(), AttendanceView, MainView.MainChildView, class AttendanceFragment : BaseFragment(), AttendanceView, MainView.MainChildView,
@ -70,7 +76,11 @@ class AttendanceFragment : BaseFragment(), AttendanceView, MainView.MainChildVie
} }
attendanceSwipe.setOnRefreshListener(presenter::onSwipeRefresh) attendanceSwipe.setOnRefreshListener(presenter::onSwipeRefresh)
attendanceErrorRetry.setOnClickListener { presenter.onRetry() }
attendanceErrorDetails.setOnClickListener { presenter.onDetailsClick() }
attendancePreviousButton.setOnClickListener { presenter.onPreviousDay() } attendancePreviousButton.setOnClickListener { presenter.onPreviousDay() }
attendanceNavDate.setOnClickListener { presenter.onPickDate() }
attendanceNextButton.setOnClickListener { presenter.onNextDay() } attendanceNextButton.setOnClickListener { presenter.onNextDay() }
attendanceNavContainer.setElevationCompat(requireContext().dpToPx(8f)) attendanceNavContainer.setElevationCompat(requireContext().dpToPx(8f))
@ -110,11 +120,19 @@ class AttendanceFragment : BaseFragment(), AttendanceView, MainView.MainChildVie
} }
override fun showEmpty(show: Boolean) { override fun showEmpty(show: Boolean) {
attendanceEmpty.visibility = if (show) View.VISIBLE else View.GONE attendanceEmpty.visibility = if (show) VISIBLE else GONE
}
override fun showErrorView(show: Boolean) {
attendanceError.visibility = if (show) VISIBLE else GONE
}
override fun setErrorDetails(message: String) {
attendanceErrorMessage.text = message
} }
override fun showProgress(show: Boolean) { override fun showProgress(show: Boolean) {
attendanceProgress.visibility = if (show) View.VISIBLE else View.GONE attendanceProgress.visibility = if (show) VISIBLE else GONE
} }
override fun enableSwipe(enable: Boolean) { override fun enableSwipe(enable: Boolean) {
@ -122,7 +140,7 @@ class AttendanceFragment : BaseFragment(), AttendanceView, MainView.MainChildVie
} }
override fun showContent(show: Boolean) { override fun showContent(show: Boolean) {
attendanceRecycler.visibility = if (show) View.VISIBLE else View.GONE attendanceRecycler.visibility = if (show) VISIBLE else GONE
} }
override fun hideRefresh() { override fun hideRefresh() {
@ -130,17 +148,32 @@ class AttendanceFragment : BaseFragment(), AttendanceView, MainView.MainChildVie
} }
override fun showPreButton(show: Boolean) { override fun showPreButton(show: Boolean) {
attendancePreviousButton.visibility = if (show) View.VISIBLE else View.INVISIBLE attendancePreviousButton.visibility = if (show) VISIBLE else INVISIBLE
} }
override fun showNextButton(show: Boolean) { override fun showNextButton(show: Boolean) {
attendanceNextButton.visibility = if (show) View.VISIBLE else View.INVISIBLE attendanceNextButton.visibility = if (show) VISIBLE else INVISIBLE
} }
override fun showAttendanceDialog(lesson: Attendance) { override fun showAttendanceDialog(lesson: Attendance) {
(activity as? MainActivity)?.showDialogFragment(AttendanceDialog.newInstance(lesson)) (activity as? MainActivity)?.showDialogFragment(AttendanceDialog.newInstance(lesson))
} }
override fun showDatePickerDialog(currentDate: LocalDate) {
val dateSetListener = DatePickerDialog.OnDateSetListener { _, year, month, dayOfMonth ->
presenter.onDateSet(year, month + 1, dayOfMonth)
}
val datePickerDialog = DatePickerDialog.newInstance(dateSetListener,
currentDate.year, currentDate.monthValue - 1, currentDate.dayOfMonth)
with(datePickerDialog) {
setDateRangeLimiter(SchooldaysRangeLimiter())
version = DatePickerDialog.Version.VERSION_2
scrollOrientation = DatePickerDialog.ScrollOrientation.VERTICAL
show(this@AttendanceFragment.parentFragmentManager, null)
}
}
override fun openSummaryView() { override fun openSummaryView() {
(activity as? MainActivity)?.pushView(AttendanceSummaryFragment.newInstance()) (activity as? MainActivity)?.pushView(AttendanceSummaryFragment.newInstance())
} }

Some files were not shown because too many files have changed in this diff Show More