Compare commits
112 Commits
Author | SHA1 | Date | |
---|---|---|---|
d3a6ea5acf | |||
674a78b661 | |||
5c84c8d5b1 | |||
522a36d670 | |||
2d0cfc3e8e | |||
4b6b722f87 | |||
419675066f | |||
191b1ad022 | |||
792e44a9d0 | |||
ff5a47b0df | |||
7bf0acb703 | |||
ba5dbf90d8 | |||
54f41aaa63 | |||
1db42210e8 | |||
fb554a4a3b | |||
d8d13c73fb | |||
5c0160a24d | |||
ab7d30c995 | |||
1cfa1f15c0 | |||
2149a4db9f | |||
df57d16d21 | |||
2ff031005e | |||
b9ab85ee55 | |||
064998129e | |||
4044cdd9a5 | |||
1ee10a5902 | |||
27b1d076c7 | |||
c8b32fdb3b | |||
0b4434fdb6 | |||
699fbff082 | |||
4c295f2ab4 | |||
dcbaa170db | |||
c71b533645 | |||
63f2576ff1 | |||
b744a4182b | |||
0c4364609b | |||
3308d7fe6f | |||
2cdde78c54 | |||
428b599be0 | |||
3541ab81b8 | |||
7fa14e5077 | |||
cec1068f2e | |||
f737018548 | |||
9c01316178 | |||
c3a6f8253a | |||
d558c4db66 | |||
722886aaf2 | |||
31902a7667 | |||
4c1c4f8a43 | |||
7850412ba9 | |||
4f0ff5f49c | |||
131ba7dbb1 | |||
b95b529015 | |||
29226dd93e | |||
115da64167 | |||
6cd1877af7 | |||
78a90591fd | |||
45265d025d | |||
9bf5c2dc40 | |||
ee4bdd2a9a | |||
0b75635ad5 | |||
f7b5b9c413 | |||
52d66ac30b | |||
6ac5c6a0b4 | |||
45fc76a9a5 | |||
6d1fa0cf05 | |||
8eb0c0351b | |||
ec80f939f1 | |||
70fc51a0b5 | |||
bd700a88bf | |||
98f2f0e74f | |||
4a3b746d48 | |||
a1f864b35e | |||
17ac3cfd52 | |||
c6c2b1c6a3 | |||
5fba3d5775 | |||
6fe62edd63 | |||
87af3da1ad | |||
155f0cc347 | |||
2de1ad5334 | |||
763543a16e | |||
acabe90c9f | |||
f79da9003a | |||
fc9e558cd6 | |||
68140bd544 | |||
2c4c2d1f49 | |||
4894086d9d | |||
1d29ef5fe3 | |||
7fa333cff2 | |||
c1ffc2ae72 | |||
9c0e2dc533 | |||
9b18e3669d | |||
366ebc781d | |||
4bd0459155 | |||
b19084cb57 | |||
69be7ca412 | |||
07307b9709 | |||
ee4a5e56a9 | |||
c8f8ec77a9 | |||
be46a43427 | |||
183e379223 | |||
2350fc2ddf | |||
152f966a66 | |||
85ee7fad1d | |||
3ac085573f | |||
64a19d9627 | |||
76af623c94 | |||
11c285be01 | |||
a0528496eb | |||
299345b864 | |||
0a18fefb1f | |||
a26f0ec8c8 |
@ -1,3 +1,3 @@
|
|||||||
component_depth: 8
|
component_depth: 10
|
||||||
languages:
|
languages:
|
||||||
- kotlin
|
- kotlin
|
||||||
|
11
.travis.yml
11
.travis.yml
@ -14,7 +14,7 @@ cache:
|
|||||||
branches:
|
branches:
|
||||||
only:
|
only:
|
||||||
- develop
|
- develop
|
||||||
- 0.17.0
|
- 0.18.3
|
||||||
|
|
||||||
android:
|
android:
|
||||||
licenses:
|
licenses:
|
||||||
@ -48,20 +48,15 @@ before_script:
|
|||||||
script:
|
script:
|
||||||
- ./gradlew dependencies --stacktrace --daemon
|
- ./gradlew dependencies --stacktrace --daemon
|
||||||
- fossa --no-ansi || true
|
- fossa --no-ansi || true
|
||||||
#- ./gradlew lintPlayRelease -x fabricGenerateResourcesPlayRelease --stacktrace --daemon
|
- ./gradlew -Pcoverage testPlayDebugUnitTest --stacktrace --daemon
|
||||||
- ./gradlew -Pcoverage testPlayDebugUnitTest -x fabricGenerateResourcesPlay --stacktrace --daemon
|
|
||||||
- ./gradlew -Pcoverage createFdroidDebugCoverageReport --stacktrace --daemon
|
- ./gradlew -Pcoverage createFdroidDebugCoverageReport --stacktrace --daemon
|
||||||
- ./gradlew -Pcoverage jacocoTestReport --stacktrace --daemon
|
- ./gradlew -Pcoverage jacocoTestReport --stacktrace --daemon
|
||||||
- if [ -z ${SONAR_HOST+x} ]; then echo "sonar scan skipped"; else
|
|
||||||
git fetch --unshallow;
|
|
||||||
./gradlew sonarqube -x test -x lint -x fabricGenerateResourcesPlayRelease -x fabricGenerateResourcesFdroidRelease -Dsonar.host.url=$SONAR_HOST -Dsonar.organization=$SONAR_ORG -Dsonar.login=$SONAR_KEY -Dsonar.branch.name=${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH} --stacktrace --daemon;
|
|
||||||
fi
|
|
||||||
- |
|
- |
|
||||||
if [ $TRAVIS_TAG ]; then
|
if [ $TRAVIS_TAG ]; then
|
||||||
gpg --yes --batch --passphrase=$SERVICES_ENCRYPT_KEY ./app/src/release/google-services.json.gpg;
|
gpg --yes --batch --passphrase=$SERVICES_ENCRYPT_KEY ./app/src/release/google-services.json.gpg;
|
||||||
gpg --yes --batch --passphrase=$ENCRYPT_KEY ./app/key.p12.gpg;
|
gpg --yes --batch --passphrase=$ENCRYPT_KEY ./app/key.p12.gpg;
|
||||||
gpg --yes --batch --passphrase=$ENCRYPT_KEY ./app/upload-key.jks.gpg;
|
gpg --yes --batch --passphrase=$ENCRYPT_KEY ./app/upload-key.jks.gpg;
|
||||||
./gradlew publishPlayRelease -PenableCrashlytics --stacktrace;
|
./gradlew publishPlayRelease -PenableFirebase --stacktrace;
|
||||||
fi
|
fi
|
||||||
|
|
||||||
after_success:
|
after_success:
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
apply plugin: 'com.android.application'
|
apply plugin: 'com.android.application'
|
||||||
apply plugin: 'kotlin-android'
|
apply plugin: 'kotlin-android'
|
||||||
apply plugin: 'kotlin-kapt'
|
apply plugin: 'kotlin-kapt'
|
||||||
apply plugin: 'kotlin-android-extensions'
|
apply plugin: 'com.google.firebase.crashlytics'
|
||||||
apply plugin: 'io.fabric'
|
|
||||||
apply plugin: 'com.github.triplet.play'
|
apply plugin: 'com.github.triplet.play'
|
||||||
apply plugin: 'com.mikepenz.aboutlibraries.plugin'
|
apply plugin: 'com.mikepenz.aboutlibraries.plugin'
|
||||||
apply from: 'jacoco.gradle'
|
apply from: 'jacoco.gradle'
|
||||||
@ -18,14 +17,14 @@ android {
|
|||||||
testApplicationId "io.github.tests.wulkanowy"
|
testApplicationId "io.github.tests.wulkanowy"
|
||||||
minSdkVersion 17
|
minSdkVersion 17
|
||||||
targetSdkVersion 29
|
targetSdkVersion 29
|
||||||
versionCode 54
|
versionCode 62
|
||||||
versionName "0.17.0"
|
versionName "0.18.3"
|
||||||
multiDexEnabled true
|
multiDexEnabled true
|
||||||
|
resValue "string", "app_name", "Wulkanowy"
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
vectorDrawables.useSupportLibrary = true
|
vectorDrawables.useSupportLibrary = true
|
||||||
manifestPlaceholders = [
|
manifestPlaceholders = [
|
||||||
fabric_api_key : System.getenv("FABRIC_API_KEY") ?: "null",
|
firebase_enabled: project.hasProperty("enableFirebase")
|
||||||
crashlytics_enabled: project.hasProperty("enableCrashlytics")
|
|
||||||
]
|
]
|
||||||
javaCompileOptions {
|
javaCompileOptions {
|
||||||
annotationProcessorOptions {
|
annotationProcessorOptions {
|
||||||
@ -52,18 +51,17 @@ android {
|
|||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
release {
|
release {
|
||||||
buildConfigField "boolean", "CRASHLYTICS_ENABLED", "true"
|
|
||||||
minifyEnabled true
|
minifyEnabled true
|
||||||
shrinkResources true
|
shrinkResources true
|
||||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
signingConfig signingConfigs.release
|
signingConfig signingConfigs.release
|
||||||
}
|
}
|
||||||
debug {
|
debug {
|
||||||
buildConfigField "boolean", "CRASHLYTICS_ENABLED", project.hasProperty("enableCrashlytics") ? "true" : "false"
|
resValue "string", "app_name", "Wulkanowy DEV " + defaultConfig.versionCode
|
||||||
applicationIdSuffix ".dev"
|
applicationIdSuffix ".dev"
|
||||||
versionNameSuffix "-dev"
|
versionNameSuffix "-dev"
|
||||||
testCoverageEnabled = project.hasProperty('coverage')
|
testCoverageEnabled = project.hasProperty('coverage')
|
||||||
ext.enableCrashlytics = project.hasProperty("enableCrashlytics")
|
ext.enableCrashlytics = project.hasProperty("enableFirebase")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,11 +73,14 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fdroid {
|
fdroid {
|
||||||
buildConfigField "boolean", "CRASHLYTICS_ENABLED", "false"
|
|
||||||
dimension "platform"
|
dimension "platform"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
viewBinding {
|
||||||
|
enabled = true
|
||||||
|
}
|
||||||
|
|
||||||
lintOptions {
|
lintOptions {
|
||||||
disable 'HardwareIds'
|
disable 'HardwareIds'
|
||||||
}
|
}
|
||||||
@ -103,10 +104,6 @@ android {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
androidExtensions {
|
|
||||||
experimental = true
|
|
||||||
}
|
|
||||||
|
|
||||||
play {
|
play {
|
||||||
serviceAccountEmail = System.getenv("PLAY_SERVICE_ACCOUNT_EMAIL") ?: "jan@fakelog.cf"
|
serviceAccountEmail = System.getenv("PLAY_SERVICE_ACCOUNT_EMAIL") ?: "jan@fakelog.cf"
|
||||||
serviceAccountCredentials = file('key.p12')
|
serviceAccountCredentials = file('key.p12')
|
||||||
@ -117,8 +114,7 @@ play {
|
|||||||
ext {
|
ext {
|
||||||
work_manager = "2.3.4"
|
work_manager = "2.3.4"
|
||||||
room = "2.2.5"
|
room = "2.2.5"
|
||||||
dagger = "2.27"
|
dagger = "2.28"
|
||||||
// don't update https://github.com/ChuckerTeam/chucker/issues/242
|
|
||||||
chucker = "3.2.0"
|
chucker = "3.2.0"
|
||||||
mockk = "1.9.2"
|
mockk = "1.9.2"
|
||||||
}
|
}
|
||||||
@ -128,21 +124,21 @@ configurations.all {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation "io.github.wulkanowy:sdk:0.17.0"
|
implementation "io.github.wulkanowy:sdk:0.18.3"
|
||||||
|
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
||||||
implementation "androidx.core:core-ktx:1.2.0"
|
implementation "androidx.core:core-ktx:1.2.0"
|
||||||
implementation "androidx.activity:activity-ktx:1.1.0"
|
implementation "androidx.activity:activity-ktx:1.1.0"
|
||||||
implementation "androidx.appcompat:appcompat:1.2.0-beta01"
|
implementation "androidx.appcompat:appcompat:1.2.0-rc01"
|
||||||
implementation "androidx.appcompat:appcompat-resources:1.1.0"
|
implementation "androidx.appcompat:appcompat-resources:1.1.0"
|
||||||
implementation "androidx.fragment:fragment-ktx:1.2.4"
|
implementation "androidx.fragment:fragment-ktx:1.2.4"
|
||||||
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.1"
|
||||||
implementation "androidx.recyclerview:recyclerview:1.1.0"
|
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.1.0-beta01"
|
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0-rc01"
|
||||||
implementation "androidx.constraintlayout:constraintlayout:1.1.3"
|
implementation "androidx.constraintlayout:constraintlayout:1.1.3"
|
||||||
implementation "androidx.coordinatorlayout:coordinatorlayout:1.1.0"
|
implementation "androidx.coordinatorlayout:coordinatorlayout:1.1.0"
|
||||||
implementation "com.google.android.material:material:1.1.0"
|
implementation "com.google.android.material:material:1.1.0"
|
||||||
@ -167,30 +163,29 @@ dependencies {
|
|||||||
implementation "com.squareup.inject:assisted-inject-annotations-dagger2:0.5.2"
|
implementation "com.squareup.inject:assisted-inject-annotations-dagger2:0.5.2"
|
||||||
kapt "com.squareup.inject:assisted-inject-processor-dagger2:0.5.2"
|
kapt "com.squareup.inject:assisted-inject-processor-dagger2:0.5.2"
|
||||||
|
|
||||||
implementation "eu.davidea:flexible-adapter:5.1.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.2.1"
|
implementation "com.github.YarikSOffice:lingver:1.2.2"
|
||||||
|
|
||||||
implementation "com.github.pwittchen:reactivenetwork-rx2:3.0.6"
|
implementation "com.github.pwittchen:reactivenetwork-rx2:3.0.8"
|
||||||
implementation "io.reactivex.rxjava2:rxandroid:2.1.1"
|
implementation "io.reactivex.rxjava2:rxandroid:2.1.1"
|
||||||
implementation "io.reactivex.rxjava2:rxjava:2.2.19"
|
implementation "io.reactivex.rxjava2:rxjava:2.2.19"
|
||||||
|
|
||||||
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.3"
|
implementation "com.jakewharton.threetenabp:threetenabp:1.2.4"
|
||||||
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 "fr.bipi.treessence:treessence:0.3.2"
|
implementation "fr.bipi.treessence:treessence:0.3.2"
|
||||||
implementation "com.mikepenz:aboutlibraries-core:$about_libraries"
|
implementation "com.mikepenz:aboutlibraries-core:$about_libraries"
|
||||||
implementation 'com.wdullaer:materialdatetimepicker:4.2.3'
|
implementation 'com.wdullaer:materialdatetimepicker:4.2.3'
|
||||||
implementation "io.coil-kt:coil:0.9.5"
|
implementation "io.coil-kt:coil:0.11.0"
|
||||||
|
implementation "io.github.wulkanowy:AppKillerManager:3.0.0"
|
||||||
|
|
||||||
playImplementation 'com.google.firebase:firebase-analytics:17.3.0'
|
playImplementation 'com.google.firebase:firebase-analytics:17.4.2'
|
||||||
playImplementation 'com.google.firebase:firebase-inappmessaging-display-ktx:19.0.4'
|
playImplementation 'com.google.firebase:firebase-inappmessaging-display-ktx:19.0.7'
|
||||||
playImplementation "com.google.firebase:firebase-inappmessaging-ktx:19.0.4"
|
playImplementation "com.google.firebase:firebase-inappmessaging-ktx:19.0.7"
|
||||||
playImplementation "com.google.firebase:firebase-messaging:20.1.0"
|
playImplementation 'com.google.firebase:firebase-messaging:20.2.0'
|
||||||
playImplementation "com.crashlytics.sdk.android:crashlytics:2.10.1"
|
playImplementation 'com.google.firebase:firebase-crashlytics:17.0.0'
|
||||||
playImplementation 'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava'
|
playImplementation 'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava'
|
||||||
|
|
||||||
releaseImplementation "com.github.ChuckerTeam.Chucker:library-no-op:$chucker"
|
releaseImplementation "com.github.ChuckerTeam.Chucker:library-no-op:$chucker"
|
||||||
@ -200,7 +195,7 @@ dependencies {
|
|||||||
|
|
||||||
testImplementation "junit:junit:4.13"
|
testImplementation "junit:junit:4.13"
|
||||||
testImplementation "io.mockk:mockk:$mockk"
|
testImplementation "io.mockk:mockk:$mockk"
|
||||||
testImplementation "org.threeten:threetenbp:1.4.3"
|
testImplementation "org.threeten:threetenbp:1.4.4"
|
||||||
testImplementation "org.mockito:mockito-inline:3.3.3"
|
testImplementation "org.mockito:mockito-inline:3.3.3"
|
||||||
|
|
||||||
androidTestImplementation "androidx.test:core:1.2.0"
|
androidTestImplementation "androidx.test:core:1.2.0"
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
package io.github.wulkanowy.data.repositories
|
||||||
|
|
||||||
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
|
import org.threeten.bp.LocalDateTime
|
||||||
|
|
||||||
|
fun getStudent(): Student {
|
||||||
|
return Student(
|
||||||
|
email = "test",
|
||||||
|
password = "test123",
|
||||||
|
schoolSymbol = "23",
|
||||||
|
scrapperBaseUrl = "fakelog.cf",
|
||||||
|
loginType = "AUTO",
|
||||||
|
isCurrent = true,
|
||||||
|
studentName = "",
|
||||||
|
schoolShortName = "",
|
||||||
|
schoolName = "",
|
||||||
|
studentId = 0,
|
||||||
|
classId = 1,
|
||||||
|
symbol = "",
|
||||||
|
registrationDate = LocalDateTime.now(),
|
||||||
|
className = "",
|
||||||
|
loginMode = "API",
|
||||||
|
certificateKey = "",
|
||||||
|
privateKey = "",
|
||||||
|
mobileBaseUrl = "",
|
||||||
|
userLoginId = 0,
|
||||||
|
isParent = false
|
||||||
|
)
|
||||||
|
}
|
@ -24,7 +24,7 @@ class GradeLocalTest {
|
|||||||
fun createDb() {
|
fun createDb() {
|
||||||
testDb = Room.inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), AppDatabase::class.java)
|
testDb = Room.inMemoryDatabaseBuilder(ApplicationProvider.getApplicationContext(), AppDatabase::class.java)
|
||||||
.build()
|
.build()
|
||||||
gradeLocal = GradeLocal(testDb.gradeDao)
|
gradeLocal = GradeLocal(testDb.gradeDao, testDb.gradeSummaryDao)
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
@After
|
||||||
@ -43,7 +43,7 @@ class GradeLocalTest {
|
|||||||
val semester = Semester(1, 2, "", 2019, 2, 1, now(), now(), 1, 1)
|
val semester = Semester(1, 2, "", 2019, 2, 1, now(), now(), 1, 1)
|
||||||
|
|
||||||
val grades = gradeLocal
|
val grades = gradeLocal
|
||||||
.getGrades(semester)
|
.getGradesDetails(semester)
|
||||||
.blockingGet()
|
.blockingGet()
|
||||||
|
|
||||||
assertEquals(2, grades.size)
|
assertEquals(2, grades.size)
|
||||||
|
@ -11,6 +11,7 @@ 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.github.wulkanowy.sdk.Sdk
|
||||||
|
import io.github.wulkanowy.sdk.pojo.Grade
|
||||||
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
|
||||||
@ -52,7 +53,7 @@ class GradeRepositoryTest {
|
|||||||
fun initApi() {
|
fun initApi() {
|
||||||
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, testDb.gradeSummaryDao)
|
||||||
gradeRemote = GradeRemote(mockSdk)
|
gradeRemote = GradeRemote(mockSdk)
|
||||||
|
|
||||||
every { studentMock.registrationDate } returns LocalDateTime.of(2019, 2, 27, 12, 0)
|
every { studentMock.registrationDate } returns LocalDateTime.of(2019, 2, 27, 12, 0)
|
||||||
@ -75,10 +76,10 @@ class GradeRepositoryTest {
|
|||||||
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"),
|
||||||
createGradeApi(5, 4.0, of(2019, 2, 28), "Ocena jeszcze nowsza")
|
createGradeApi(5, 4.0, of(2019, 2, 28), "Ocena jeszcze nowsza")
|
||||||
))
|
) to emptyList())
|
||||||
|
|
||||||
val grades = GradeRepository(settings, gradeLocal, gradeRemote)
|
val grades = GradeRepository(settings, gradeLocal, gradeRemote)
|
||||||
.getGrades(studentMock, semesterMock, true).blockingGet().sortedByDescending { it.date }
|
.getGrades(studentMock, semesterMock, true).blockingGet().first.sortedByDescending { it.date }
|
||||||
|
|
||||||
assertFalse { grades[0].isRead }
|
assertFalse { grades[0].isRead }
|
||||||
assertFalse { grades[1].isRead }
|
assertFalse { grades[1].isRead }
|
||||||
@ -99,10 +100,10 @@ class GradeRepositoryTest {
|
|||||||
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"),
|
||||||
createGradeApi(2, 5.0, of(2019, 2, 28), "Ta jest już w ogóle nowa")
|
createGradeApi(2, 5.0, of(2019, 2, 28), "Ta jest już w ogóle nowa")
|
||||||
))
|
) to emptyList())
|
||||||
|
|
||||||
val grades = GradeRepository(settings, gradeLocal, gradeRemote)
|
val grades = GradeRepository(settings, gradeLocal, gradeRemote)
|
||||||
.getGrades(studentMock, semesterMock, true).blockingGet().sortedByDescending { it.date }
|
.getGrades(studentMock, semesterMock, true).blockingGet().first.sortedByDescending { it.date }
|
||||||
|
|
||||||
assertFalse { grades[0].isRead }
|
assertFalse { grades[0].isRead }
|
||||||
assertFalse { grades[1].isRead }
|
assertFalse { grades[1].isRead }
|
||||||
@ -121,12 +122,12 @@ class GradeRepositoryTest {
|
|||||||
every { mockSdk.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")
|
||||||
))
|
) to emptyList())
|
||||||
|
|
||||||
val grades = GradeRepository(settings, gradeLocal, gradeRemote)
|
val grades = GradeRepository(settings, gradeLocal, gradeRemote)
|
||||||
.getGrades(studentMock, semesterMock, true).blockingGet()
|
.getGrades(studentMock, semesterMock, true).blockingGet()
|
||||||
|
|
||||||
assertEquals(2, grades.size)
|
assertEquals(2, grades.first.size)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -140,12 +141,12 @@ class GradeRepositoryTest {
|
|||||||
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")
|
||||||
))
|
) to emptyList())
|
||||||
|
|
||||||
val grades = GradeRepository(settings, gradeLocal, gradeRemote)
|
val grades = GradeRepository(settings, gradeLocal, gradeRemote)
|
||||||
.getGrades(studentMock, semesterMock, true).blockingGet()
|
.getGrades(studentMock, semesterMock, true).blockingGet()
|
||||||
|
|
||||||
assertEquals(3, grades.size)
|
assertEquals(3, grades.first.size)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -156,12 +157,12 @@ class GradeRepositoryTest {
|
|||||||
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")
|
||||||
))
|
) to emptyList())
|
||||||
|
|
||||||
val grades = GradeRepository(settings, gradeLocal, gradeRemote)
|
val grades = GradeRepository(settings, gradeLocal, gradeRemote)
|
||||||
.getGrades(studentMock, semesterMock, true).blockingGet()
|
.getGrades(studentMock, semesterMock, true).blockingGet()
|
||||||
|
|
||||||
assertEquals(3, grades.size)
|
assertEquals(3, grades.first.size)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -171,11 +172,11 @@ 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 { mockSdk.getGrades(1) } returns Single.just(listOf())
|
every { mockSdk.getGrades(1) } returns Single.just(emptyList<Grade>() to emptyList())
|
||||||
|
|
||||||
val grades = GradeRepository(settings, gradeLocal, gradeRemote)
|
val grades = GradeRepository(settings, gradeLocal, gradeRemote)
|
||||||
.getGrades(studentMock, semesterMock, true).blockingGet()
|
.getGrades(studentMock, semesterMock, true).blockingGet()
|
||||||
|
|
||||||
assertEquals(0, grades.size)
|
assertEquals(0, grades.first.size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,13 +5,11 @@ import androidx.room.Room
|
|||||||
import androidx.test.core.app.ApplicationProvider
|
import androidx.test.core.app.ApplicationProvider
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
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.getStudent
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
|
||||||
import org.junit.After
|
import org.junit.After
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
import org.threeten.bp.LocalDateTime.now
|
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
@RunWith(AndroidJUnit4::class)
|
@RunWith(AndroidJUnit4::class)
|
||||||
@ -21,14 +19,13 @@ class StudentLocalTest {
|
|||||||
|
|
||||||
private lateinit var testDb: AppDatabase
|
private lateinit var testDb: AppDatabase
|
||||||
|
|
||||||
private lateinit var sharedProvider: SharedPrefProvider
|
private val student = getStudent()
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun createDb() {
|
fun createDb() {
|
||||||
val context = ApplicationProvider.getApplicationContext<Context>()
|
val context = ApplicationProvider.getApplicationContext<Context>()
|
||||||
testDb = Room.inMemoryDatabaseBuilder(context, AppDatabase::class.java)
|
testDb = Room.inMemoryDatabaseBuilder(context, AppDatabase::class.java)
|
||||||
.build()
|
.build()
|
||||||
sharedProvider = SharedPrefProvider(context.getSharedPreferences("TEST", Context.MODE_PRIVATE))
|
|
||||||
studentLocal = StudentLocal(testDb.studentDao, context)
|
studentLocal = StudentLocal(testDb.studentDao, context)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,8 +36,7 @@ class StudentLocalTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun saveAndReadTest() {
|
fun saveAndReadTest() {
|
||||||
studentLocal.saveStudents(listOf(Student(email = "test", password = "test123", schoolSymbol = "23", scrapperBaseUrl = "fakelog.cf", loginType = "AUTO", isCurrent = true, studentName = "", schoolShortName = "", schoolName = "", studentId = 0, classId = 1, symbol = "", registrationDate = now(), className = "", loginMode = "API", certificateKey = "", privateKey = "", mobileBaseUrl = "", userLoginId = 0, isParent = false)))
|
studentLocal.saveStudents(listOf(student)).blockingGet()
|
||||||
.blockingGet()
|
|
||||||
|
|
||||||
val student = studentLocal.getCurrentStudent(true).blockingGet()
|
val student = studentLocal.getCurrentStudent(true).blockingGet()
|
||||||
assertEquals("23", student.schoolSymbol)
|
assertEquals("23", student.schoolSymbol)
|
||||||
|
@ -8,11 +8,15 @@ 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.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.repositories.TestInternetObservingStrategy
|
import io.github.wulkanowy.data.repositories.TestInternetObservingStrategy
|
||||||
|
import io.github.wulkanowy.data.repositories.getStudent
|
||||||
|
import io.github.wulkanowy.services.alarm.TimetableNotificationSchedulerHelper
|
||||||
import io.github.wulkanowy.sdk.Sdk
|
import io.github.wulkanowy.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.mockk
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
import org.junit.After
|
import org.junit.After
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
@ -33,9 +37,17 @@ class TimetableRepositoryTest {
|
|||||||
.strategy(TestInternetObservingStrategy())
|
.strategy(TestInternetObservingStrategy())
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
|
@MockK
|
||||||
|
private lateinit var studentMock: Student
|
||||||
|
|
||||||
|
private val student = getStudent()
|
||||||
|
|
||||||
@MockK
|
@MockK
|
||||||
private lateinit var semesterMock: Semester
|
private lateinit var semesterMock: Semester
|
||||||
|
|
||||||
|
@MockK
|
||||||
|
private lateinit var timetableNotificationSchedulerHelper: TimetableNotificationSchedulerHelper
|
||||||
|
|
||||||
private lateinit var timetableRemote: TimetableRemote
|
private lateinit var timetableRemote: TimetableRemote
|
||||||
|
|
||||||
private lateinit var timetableLocal: TimetableLocal
|
private lateinit var timetableLocal: TimetableLocal
|
||||||
@ -49,10 +61,17 @@ class TimetableRepositoryTest {
|
|||||||
timetableLocal = TimetableLocal(testDb.timetableDao)
|
timetableLocal = TimetableLocal(testDb.timetableDao)
|
||||||
timetableRemote = TimetableRemote(mockSdk)
|
timetableRemote = TimetableRemote(mockSdk)
|
||||||
|
|
||||||
|
every { timetableNotificationSchedulerHelper.scheduleNotifications(any(), any()) } returns mockk()
|
||||||
|
every { timetableNotificationSchedulerHelper.cancelScheduled(any(), any()) } returns mockk()
|
||||||
|
|
||||||
|
every { studentMock.studentId } returns 1
|
||||||
|
every { studentMock.studentName } returns "Jan Kowalski"
|
||||||
|
|
||||||
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.schoolYear } returns 2019
|
||||||
every { semesterMock.semesterId } returns 1
|
every { semesterMock.semesterId } returns 1
|
||||||
|
|
||||||
every { mockSdk.switchDiary(any(), any()) } returns mockSdk
|
every { mockSdk.switchDiary(any(), any()) } returns mockSdk
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,8 +96,8 @@ class TimetableRepositoryTest {
|
|||||||
createTimetableRemote(of(2019, 3, 5, 10, 30), 4, "", "W-F")
|
createTimetableRemote(of(2019, 3, 5, 10, 30), 4, "", "W-F")
|
||||||
))
|
))
|
||||||
|
|
||||||
val lessons = TimetableRepository(settings, timetableLocal, timetableRemote)
|
val lessons = TimetableRepository(settings, timetableLocal, timetableRemote, timetableNotificationSchedulerHelper)
|
||||||
.getTimetable(semesterMock, LocalDate.of(2019, 3, 5), LocalDate.of(2019, 3, 5), true)
|
.getTimetable(student, semesterMock, LocalDate.of(2019, 3, 5), LocalDate.of(2019, 3, 5), true)
|
||||||
.blockingGet()
|
.blockingGet()
|
||||||
|
|
||||||
assertEquals(4, lessons.size)
|
assertEquals(4, lessons.size)
|
||||||
@ -123,8 +142,8 @@ class TimetableRepositoryTest {
|
|||||||
createTimetableRemote(of(2019, 12, 25, 10, 40), 4, "126", "Matematyka", "Paweł Czwartkowski", true)
|
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, timetableNotificationSchedulerHelper)
|
||||||
.getTimetable(semesterMock, LocalDate.of(2019, 12, 23), LocalDate.of(2019, 12, 25), true)
|
.getTimetable(student, semesterMock, LocalDate.of(2019, 12, 23), LocalDate.of(2019, 12, 25), true)
|
||||||
.blockingGet()
|
.blockingGet()
|
||||||
|
|
||||||
assertEquals(12, lessons.size)
|
assertEquals(12, lessons.size)
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
<resources>
|
|
||||||
<string name="app_name">Wulkanowy DEV</string>
|
|
||||||
</resources>
|
|
@ -5,8 +5,6 @@ package io.github.wulkanowy.utils
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
fun initCrashlytics(context: Context, appInfo: AppInfo) {}
|
|
||||||
|
|
||||||
open class TimberTreeNoOp : Timber.Tree() {
|
open class TimberTreeNoOp : Timber.Tree() {
|
||||||
override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {}
|
override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {}
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,18 @@
|
|||||||
package io.github.wulkanowy.utils
|
package io.github.wulkanowy.utils
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
|
@Suppress("UNUSED_PARAMETER")
|
||||||
class FirebaseAnalyticsHelper @Inject constructor() {
|
class FirebaseAnalyticsHelper @Inject constructor() {
|
||||||
|
|
||||||
@Suppress("UNUSED_PARAMETER")
|
|
||||||
fun logEvent(name: String, vararg params: Pair<String, Any?>) {
|
fun logEvent(name: String, vararg params: Pair<String, Any?>) {
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setCurrentScreen(activity: Activity, name: String?) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,8 @@
|
|||||||
android:supportsRtl="false"
|
android:supportsRtl="false"
|
||||||
android:theme="@style/WulkanowyTheme"
|
android:theme="@style/WulkanowyTheme"
|
||||||
android:usesCleartextTraffic="true"
|
android:usesCleartextTraffic="true"
|
||||||
tools:ignore="GoogleAppIndexingWarning,UnusedAttribute">
|
tools:ignore="GoogleAppIndexingWarning,UnusedAttribute"
|
||||||
|
tools:replace="android:supportsRtl,android:allowBackup">
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.modules.splash.SplashActivity"
|
android:name=".ui.modules.splash.SplashActivity"
|
||||||
android:screenOrientation="portrait"
|
android:screenOrientation="portrait"
|
||||||
@ -39,7 +40,8 @@
|
|||||||
android:name=".ui.modules.main.MainActivity"
|
android:name=".ui.modules.main.MainActivity"
|
||||||
android:configChanges="orientation|screenSize"
|
android:configChanges="orientation|screenSize"
|
||||||
android:label="@string/main_title"
|
android:label="@string/main_title"
|
||||||
android:theme="@style/WulkanowyTheme.NoActionBar" />
|
android:theme="@style/WulkanowyTheme.NoActionBar"
|
||||||
|
android:windowSoftInputMode="adjustPan" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.modules.message.send.SendMessageActivity"
|
android:name=".ui.modules.message.send.SendMessageActivity"
|
||||||
android:configChanges="orientation|screenSize"
|
android:configChanges="orientation|screenSize"
|
||||||
@ -91,6 +93,8 @@
|
|||||||
android:resource="@xml/provider_widget_lucky_number" />
|
android:resource="@xml/provider_widget_lucky_number" />
|
||||||
</receiver>
|
</receiver>
|
||||||
|
|
||||||
|
<receiver android:name=".services.alarm.TimetableNotificationReceiver" />
|
||||||
|
|
||||||
<provider
|
<provider
|
||||||
android:name="androidx.work.impl.WorkManagerInitializer"
|
android:name="androidx.work.impl.WorkManagerInitializer"
|
||||||
android:authorities="${applicationId}.workmanager-init"
|
android:authorities="${applicationId}.workmanager-init"
|
||||||
@ -107,12 +111,33 @@
|
|||||||
android:resource="@xml/provider_paths" />
|
android:resource="@xml/provider_paths" />
|
||||||
</provider>
|
</provider>
|
||||||
|
|
||||||
|
<!-- workaround for https://github.com/firebase/firebase-android-sdk/issues/473 enabled:false -->
|
||||||
|
<!-- https://firebase.googleblog.com/2017/03/take-control-of-your-firebase-init-on.html -->
|
||||||
|
<provider
|
||||||
|
android:name="com.google.firebase.provider.FirebaseInitProvider"
|
||||||
|
android:authorities="${applicationId}.firebaseinitprovider"
|
||||||
|
android:enabled="${firebase_enabled}"
|
||||||
|
android:exported="false" />
|
||||||
|
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="io.fabric.ApiKey"
|
android:name="firebase_analytics_collection_enabled"
|
||||||
android:value="${fabric_api_key}" />
|
android:value="${firebase_enabled}" />
|
||||||
|
|
||||||
|
<meta-data
|
||||||
|
android:name="google_analytics_adid_collection_enabled"
|
||||||
|
android:value="${firebase_enabled}" />
|
||||||
|
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="firebase_crashlytics_collection_enabled"
|
android:name="firebase_crashlytics_collection_enabled"
|
||||||
android:value="${crashlytics_enabled}" />
|
android:value="${firebase_enabled}" />
|
||||||
|
|
||||||
|
<meta-data
|
||||||
|
android:name="firebase_messaging_auto_init_enabled"
|
||||||
|
android:value="${firebase_enabled}" />
|
||||||
|
|
||||||
|
<meta-data
|
||||||
|
android:name="firebase_inapp_messaging_auto_data_collection_enabled"
|
||||||
|
android:value="${firebase_enabled}" />
|
||||||
|
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="com.google.firebase.messaging.default_notification_icon"
|
android:name="com.google.firebase.messaging.default_notification_icon"
|
||||||
|
@ -10,8 +10,6 @@ import com.jakewharton.threetenabp.AndroidThreeTen
|
|||||||
import com.yariksoffice.lingver.Lingver
|
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.utils.Log
|
|
||||||
import fr.bipi.tressence.file.FileLoggerTree
|
import fr.bipi.tressence.file.FileLoggerTree
|
||||||
import io.github.wulkanowy.di.DaggerAppComponent
|
import io.github.wulkanowy.di.DaggerAppComponent
|
||||||
import io.github.wulkanowy.services.sync.SyncWorkerFactory
|
import io.github.wulkanowy.services.sync.SyncWorkerFactory
|
||||||
@ -21,7 +19,6 @@ import io.github.wulkanowy.utils.AppInfo
|
|||||||
import io.github.wulkanowy.utils.CrashlyticsExceptionTree
|
import io.github.wulkanowy.utils.CrashlyticsExceptionTree
|
||||||
import io.github.wulkanowy.utils.CrashlyticsTree
|
import io.github.wulkanowy.utils.CrashlyticsTree
|
||||||
import io.github.wulkanowy.utils.DebugLogTree
|
import io.github.wulkanowy.utils.DebugLogTree
|
||||||
import io.github.wulkanowy.utils.initCrashlytics
|
|
||||||
import io.reactivex.exceptions.UndeliverableException
|
import io.reactivex.exceptions.UndeliverableException
|
||||||
import io.reactivex.plugins.RxJavaPlugins
|
import io.reactivex.plugins.RxJavaPlugins
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
@ -52,12 +49,10 @@ class WulkanowyApp : DaggerApplication(), Configuration.Provider {
|
|||||||
themeManager.applyDefaultTheme()
|
themeManager.applyDefaultTheme()
|
||||||
|
|
||||||
initLogging()
|
initLogging()
|
||||||
initCrashlytics(this, appInfo)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initLogging() {
|
private fun initLogging() {
|
||||||
if (appInfo.isDebug) {
|
if (appInfo.isDebug) {
|
||||||
FlexibleAdapter.enableLogs(Log.Level.DEBUG)
|
|
||||||
Timber.plant(DebugLogTree())
|
Timber.plant(DebugLogTree())
|
||||||
Timber.plant(FileLoggerTree.Builder()
|
Timber.plant(FileLoggerTree.Builder()
|
||||||
.withFileName("wulkanowy.%g.log")
|
.withFileName("wulkanowy.%g.log")
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
package io.github.wulkanowy.data
|
package io.github.wulkanowy.data
|
||||||
|
|
||||||
|
import android.app.AlarmManager
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import android.content.res.AssetManager
|
import android.content.res.AssetManager
|
||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
|
import androidx.core.content.getSystemService
|
||||||
import androidx.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
|
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.InternetObservingSettings
|
||||||
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.strategy.WalledGardenInternetObservingStrategy
|
import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.strategy.WalledGardenInternetObservingStrategy
|
||||||
|
@ -1,30 +0,0 @@
|
|||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -22,6 +22,9 @@ interface StudentDao {
|
|||||||
@Query("SELECT * FROM Students WHERE is_current = 1")
|
@Query("SELECT * FROM Students WHERE is_current = 1")
|
||||||
fun loadCurrent(): Maybe<Student>
|
fun loadCurrent(): Maybe<Student>
|
||||||
|
|
||||||
|
@Query("SELECT * FROM Students WHERE id = :id")
|
||||||
|
fun loadById(id: Int): Maybe<Student>
|
||||||
|
|
||||||
@Query("SELECT * FROM Students")
|
@Query("SELECT * FROM Students")
|
||||||
fun loadAll(): Maybe<List<Student>>
|
fun loadAll(): Maybe<List<Student>>
|
||||||
|
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
package io.github.wulkanowy.data.pojos
|
|
||||||
|
|
||||||
class AppCreator(val displayName: String, val githubUsername: String)
|
|
@ -0,0 +1,3 @@
|
|||||||
|
package io.github.wulkanowy.data.pojos
|
||||||
|
|
||||||
|
class Contributor(val displayName: String, val githubUsername: String)
|
@ -2,18 +2,18 @@ package io.github.wulkanowy.data.repositories.appcreator
|
|||||||
|
|
||||||
import android.content.res.AssetManager
|
import android.content.res.AssetManager
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import io.github.wulkanowy.data.pojos.AppCreator
|
import io.github.wulkanowy.data.pojos.Contributor
|
||||||
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 AppCreatorRepository @Inject constructor(private val assets: AssetManager) {
|
class AppCreatorRepository @Inject constructor(private val assets: AssetManager) {
|
||||||
fun getAppCreators(): Single<List<AppCreator>> {
|
fun getAppCreators(): Single<List<Contributor>> {
|
||||||
return Single.fromCallable<List<AppCreator>> {
|
return Single.fromCallable<List<Contributor>> {
|
||||||
Gson().fromJson(
|
Gson().fromJson(
|
||||||
assets.open("contributors.json").bufferedReader().use { it.readText() },
|
assets.open("contributors.json").bufferedReader().use { it.readText() },
|
||||||
Array<AppCreator>::class.java
|
Array<Contributor>::class.java
|
||||||
).toList()
|
).toList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,10 @@ package io.github.wulkanowy.data.repositories.attendance
|
|||||||
|
|
||||||
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.data.db.entities.Student
|
||||||
import io.github.wulkanowy.sdk.Sdk
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
import io.github.wulkanowy.sdk.pojo.Absent
|
import io.github.wulkanowy.sdk.pojo.Absent
|
||||||
|
import io.github.wulkanowy.utils.init
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
import org.threeten.bp.LocalDate
|
import org.threeten.bp.LocalDate
|
||||||
import org.threeten.bp.LocalDateTime
|
import org.threeten.bp.LocalDateTime
|
||||||
@ -14,8 +16,9 @@ import javax.inject.Singleton
|
|||||||
@Singleton
|
@Singleton
|
||||||
class AttendanceRemote @Inject constructor(private val sdk: Sdk) {
|
class AttendanceRemote @Inject constructor(private val sdk: Sdk) {
|
||||||
|
|
||||||
fun getAttendance(semester: Semester, startDate: LocalDate, endDate: LocalDate): Single<List<Attendance>> {
|
fun getAttendance(student: Student, semester: Semester, startDate: LocalDate, endDate: LocalDate): Single<List<Attendance>> {
|
||||||
return sdk.switchDiary(semester.diaryId, semester.schoolYear).getAttendance(startDate, endDate, semester.semesterId)
|
return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear)
|
||||||
|
.getAttendance(startDate, endDate, semester.semesterId)
|
||||||
.map { attendance ->
|
.map { attendance ->
|
||||||
attendance.map {
|
attendance.map {
|
||||||
Attendance(
|
Attendance(
|
||||||
@ -39,8 +42,8 @@ class AttendanceRemote @Inject constructor(private val sdk: Sdk) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun excuseAbsence(semester: Semester, absenceList: List<Attendance>, reason: String?): Single<Boolean> {
|
fun excuseAbsence(student: Student, semester: Semester, absenceList: List<Attendance>, reason: String?): Single<Boolean> {
|
||||||
return sdk.switchDiary(semester.diaryId, semester.schoolYear).excuseForAbsence(absenceList.map { attendance ->
|
return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear).excuseForAbsence(absenceList.map { attendance ->
|
||||||
Absent(
|
Absent(
|
||||||
date = LocalDateTime.of(attendance.date, LocalTime.of(0, 0)),
|
date = LocalDateTime.of(attendance.date, LocalTime.of(0, 0)),
|
||||||
timeId = attendance.timeId
|
timeId = attendance.timeId
|
||||||
|
@ -4,7 +4,8 @@ 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.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.friday
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
|
import io.github.wulkanowy.utils.sunday
|
||||||
import io.github.wulkanowy.utils.monday
|
import io.github.wulkanowy.utils.monday
|
||||||
import io.github.wulkanowy.utils.uniqueSubtract
|
import io.github.wulkanowy.utils.uniqueSubtract
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
@ -20,29 +21,25 @@ class AttendanceRepository @Inject constructor(
|
|||||||
private val remote: AttendanceRemote
|
private val remote: AttendanceRemote
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun getAttendance(semester: Semester, startDate: LocalDate, endDate: LocalDate, forceRefresh: Boolean)
|
fun getAttendance(student: Student, semester: Semester, start: LocalDate, end: LocalDate, forceRefresh: Boolean): Single<List<Attendance>> {
|
||||||
: Single<List<Attendance>> {
|
return local.getAttendance(semester, start.monday, end.sunday).filter { !forceRefresh }
|
||||||
return Single.fromCallable { startDate.monday to endDate.friday }
|
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings).flatMap {
|
||||||
.flatMap { dates ->
|
if (it) remote.getAttendance(student, semester, start.monday, end.sunday)
|
||||||
local.getAttendance(semester, dates.first, dates.second).filter { !forceRefresh }
|
else Single.error(UnknownHostException())
|
||||||
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings).flatMap {
|
}.flatMap { newAttendance ->
|
||||||
if (it) remote.getAttendance(semester, dates.first, dates.second)
|
local.getAttendance(semester, start.monday, end.sunday)
|
||||||
else Single.error(UnknownHostException())
|
.toSingle(emptyList())
|
||||||
}.flatMap { newAttendance ->
|
.doOnSuccess { oldAttendance ->
|
||||||
local.getAttendance(semester, dates.first, dates.second)
|
local.deleteAttendance(oldAttendance.uniqueSubtract(newAttendance))
|
||||||
.toSingle(emptyList())
|
local.saveAttendance(newAttendance.uniqueSubtract(oldAttendance))
|
||||||
.doOnSuccess { oldAttendance ->
|
}
|
||||||
local.deleteAttendance(oldAttendance.uniqueSubtract(newAttendance))
|
}.flatMap {
|
||||||
local.saveAttendance(newAttendance.uniqueSubtract(oldAttendance))
|
local.getAttendance(semester, start.monday, end.sunday)
|
||||||
}
|
.toSingle(emptyList())
|
||||||
}.flatMap {
|
}).map { list -> list.filter { it.date in start..end } }
|
||||||
local.getAttendance(semester, dates.first, dates.second)
|
|
||||||
.toSingle(emptyList())
|
|
||||||
}).map { list -> list.filter { it.date in startDate..endDate } }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun excuseForAbsence(semester: Semester, attendanceList: List<Attendance>, reason: String? = null): Single<Boolean> {
|
fun excuseForAbsence(student: Student, semester: Semester, attendanceList: List<Attendance>, reason: String? = null): Single<Boolean> {
|
||||||
return remote.excuseAbsence(semester, attendanceList, reason)
|
return remote.excuseAbsence(student, semester, attendanceList, reason)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,9 @@ package io.github.wulkanowy.data.repositories.attendancesummary
|
|||||||
|
|
||||||
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.data.db.entities.Student
|
||||||
import io.github.wulkanowy.sdk.Sdk
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
|
import io.github.wulkanowy.utils.init
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
@ -10,8 +12,9 @@ import javax.inject.Singleton
|
|||||||
@Singleton
|
@Singleton
|
||||||
class AttendanceSummaryRemote @Inject constructor(private val sdk: Sdk) {
|
class AttendanceSummaryRemote @Inject constructor(private val sdk: Sdk) {
|
||||||
|
|
||||||
fun getAttendanceSummary(semester: Semester, subjectId: Int): Single<List<AttendanceSummary>> {
|
fun getAttendanceSummary(student: Student, semester: Semester, subjectId: Int): Single<List<AttendanceSummary>> {
|
||||||
return sdk.switchDiary(semester.diaryId, semester.schoolYear).getAttendanceSummary(subjectId)
|
return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear)
|
||||||
|
.getAttendanceSummary(subjectId)
|
||||||
.map { attendance ->
|
.map { attendance ->
|
||||||
attendance.map {
|
attendance.map {
|
||||||
AttendanceSummary(
|
AttendanceSummary(
|
||||||
|
@ -4,6 +4,7 @@ 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.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.data.db.entities.Student
|
||||||
import io.github.wulkanowy.utils.uniqueSubtract
|
import io.github.wulkanowy.utils.uniqueSubtract
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
import java.net.UnknownHostException
|
import java.net.UnknownHostException
|
||||||
@ -17,11 +18,11 @@ class AttendanceSummaryRepository @Inject constructor(
|
|||||||
private val remote: AttendanceSummaryRemote
|
private val remote: AttendanceSummaryRemote
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun getAttendanceSummary(semester: Semester, subjectId: Int, forceRefresh: Boolean = false): Single<List<AttendanceSummary>> {
|
fun getAttendanceSummary(student: Student, semester: Semester, subjectId: Int, forceRefresh: Boolean = false): Single<List<AttendanceSummary>> {
|
||||||
return local.getAttendanceSummary(semester, subjectId).filter { !forceRefresh }
|
return local.getAttendanceSummary(semester, subjectId).filter { !forceRefresh }
|
||||||
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
||||||
.flatMap {
|
.flatMap {
|
||||||
if (it) remote.getAttendanceSummary(semester, subjectId)
|
if (it) remote.getAttendanceSummary(student, semester, subjectId)
|
||||||
else Single.error(UnknownHostException())
|
else Single.error(UnknownHostException())
|
||||||
}.flatMap { new ->
|
}.flatMap { new ->
|
||||||
local.getAttendanceSummary(semester, subjectId).toSingle(emptyList())
|
local.getAttendanceSummary(semester, subjectId).toSingle(emptyList())
|
||||||
|
@ -2,7 +2,9 @@ package io.github.wulkanowy.data.repositories.completedlessons
|
|||||||
|
|
||||||
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.data.db.entities.Student
|
||||||
import io.github.wulkanowy.sdk.Sdk
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
|
import io.github.wulkanowy.utils.init
|
||||||
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
|
||||||
@ -11,8 +13,9 @@ import javax.inject.Singleton
|
|||||||
@Singleton
|
@Singleton
|
||||||
class CompletedLessonsRemote @Inject constructor(private val sdk: Sdk) {
|
class CompletedLessonsRemote @Inject constructor(private val sdk: Sdk) {
|
||||||
|
|
||||||
fun getCompletedLessons(semester: Semester, startDate: LocalDate, endDate: LocalDate): Single<List<CompletedLesson>> {
|
fun getCompletedLessons(student: Student, semester: Semester, startDate: LocalDate, endDate: LocalDate): Single<List<CompletedLesson>> {
|
||||||
return sdk.switchDiary(semester.diaryId, semester.schoolYear).getCompletedLessons(startDate, endDate)
|
return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear)
|
||||||
|
.getCompletedLessons(startDate, endDate)
|
||||||
.map { lessons ->
|
.map { lessons ->
|
||||||
lessons.map {
|
lessons.map {
|
||||||
it.absence
|
it.absence
|
||||||
|
@ -4,7 +4,8 @@ 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.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.utils.friday
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
|
import io.github.wulkanowy.utils.sunday
|
||||||
import io.github.wulkanowy.utils.monday
|
import io.github.wulkanowy.utils.monday
|
||||||
import io.github.wulkanowy.utils.uniqueSubtract
|
import io.github.wulkanowy.utils.uniqueSubtract
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
@ -20,25 +21,22 @@ class CompletedLessonsRepository @Inject constructor(
|
|||||||
private val remote: CompletedLessonsRemote
|
private val remote: CompletedLessonsRemote
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun getCompletedLessons(semester: Semester, startDate: LocalDate, endDate: LocalDate, forceRefresh: Boolean = false): Single<List<CompletedLesson>> {
|
fun getCompletedLessons(student: Student, semester: Semester, start: LocalDate, end: LocalDate, forceRefresh: Boolean = false): Single<List<CompletedLesson>> {
|
||||||
return Single.fromCallable { startDate.monday to endDate.friday }
|
return local.getCompletedLessons(semester, start.monday, end.sunday).filter { !forceRefresh }
|
||||||
.flatMap { dates ->
|
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
||||||
local.getCompletedLessons(semester, dates.first, dates.second).filter { !forceRefresh }
|
.flatMap {
|
||||||
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
if (it) remote.getCompletedLessons(student, semester, start.monday, end.sunday)
|
||||||
.flatMap {
|
else Single.error(UnknownHostException())
|
||||||
if (it) remote.getCompletedLessons(semester, dates.first, dates.second)
|
}.flatMap { new ->
|
||||||
else Single.error(UnknownHostException())
|
local.getCompletedLessons(semester, start.monday, end.sunday)
|
||||||
}.flatMap { new ->
|
.toSingle(emptyList())
|
||||||
local.getCompletedLessons(semester, dates.first, dates.second)
|
.doOnSuccess { old ->
|
||||||
.toSingle(emptyList())
|
local.deleteCompleteLessons(old.uniqueSubtract(new))
|
||||||
.doOnSuccess { old ->
|
local.saveCompletedLessons(new.uniqueSubtract(old))
|
||||||
local.deleteCompleteLessons(old.uniqueSubtract(new))
|
}
|
||||||
local.saveCompletedLessons(new.uniqueSubtract(old))
|
}.flatMap {
|
||||||
}
|
local.getCompletedLessons(semester, start.monday, end.sunday)
|
||||||
}.flatMap {
|
.toSingle(emptyList())
|
||||||
local.getCompletedLessons(semester, dates.first, dates.second)
|
}).map { list -> list.filter { it.date in start..end } }
|
||||||
.toSingle(emptyList())
|
|
||||||
}).map { list -> list.filter { it.date in startDate..endDate } }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,9 @@ package io.github.wulkanowy.data.repositories.exam
|
|||||||
|
|
||||||
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.data.db.entities.Student
|
||||||
import io.github.wulkanowy.sdk.Sdk
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
|
import io.github.wulkanowy.utils.init
|
||||||
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
|
||||||
@ -11,8 +13,9 @@ import javax.inject.Singleton
|
|||||||
@Singleton
|
@Singleton
|
||||||
class ExamRemote @Inject constructor(private val sdk: Sdk) {
|
class ExamRemote @Inject constructor(private val sdk: Sdk) {
|
||||||
|
|
||||||
fun getExams(semester: Semester, startDate: LocalDate, endDate: LocalDate): Single<List<Exam>> {
|
fun getExams(student: Student, semester: Semester, startDate: LocalDate, endDate: LocalDate): Single<List<Exam>> {
|
||||||
return sdk.switchDiary(semester.diaryId, semester.schoolYear).getExams(startDate, endDate, semester.semesterId)
|
return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear)
|
||||||
|
.getExams(startDate, endDate, semester.semesterId)
|
||||||
.map { exams ->
|
.map { exams ->
|
||||||
exams.map {
|
exams.map {
|
||||||
Exam(
|
Exam(
|
||||||
|
@ -4,7 +4,8 @@ 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.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.friday
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
|
import io.github.wulkanowy.utils.sunday
|
||||||
import io.github.wulkanowy.utils.monday
|
import io.github.wulkanowy.utils.monday
|
||||||
import io.github.wulkanowy.utils.uniqueSubtract
|
import io.github.wulkanowy.utils.uniqueSubtract
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
@ -20,25 +21,22 @@ class ExamRepository @Inject constructor(
|
|||||||
private val remote: ExamRemote
|
private val remote: ExamRemote
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun getExams(semester: Semester, startDate: LocalDate, endDate: LocalDate, forceRefresh: Boolean = false): Single<List<Exam>> {
|
fun getExams(student: Student, semester: Semester, start: LocalDate, end: LocalDate, forceRefresh: Boolean = false): Single<List<Exam>> {
|
||||||
return Single.fromCallable { startDate.monday to endDate.friday }
|
return local.getExams(semester, start.monday, end.sunday).filter { !forceRefresh }
|
||||||
.flatMap { dates ->
|
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
||||||
local.getExams(semester, dates.first, dates.second).filter { !forceRefresh }
|
.flatMap {
|
||||||
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
if (it) remote.getExams(student, semester, start.monday, end.sunday)
|
||||||
.flatMap {
|
else Single.error(UnknownHostException())
|
||||||
if (it) remote.getExams(semester, dates.first, dates.second)
|
}.flatMap { new ->
|
||||||
else Single.error(UnknownHostException())
|
local.getExams(semester, start.monday, end.sunday)
|
||||||
}.flatMap { new ->
|
.toSingle(emptyList())
|
||||||
local.getExams(semester, dates.first, dates.second)
|
.doOnSuccess { old ->
|
||||||
.toSingle(emptyList())
|
local.deleteExams(old.uniqueSubtract(new))
|
||||||
.doOnSuccess { old ->
|
local.saveExams(new.uniqueSubtract(old))
|
||||||
local.deleteExams(old.uniqueSubtract(new))
|
}
|
||||||
local.saveExams(new.uniqueSubtract(old))
|
}.flatMap {
|
||||||
}
|
local.getExams(semester, start.monday, end.sunday)
|
||||||
}.flatMap {
|
.toSingle(emptyList())
|
||||||
local.getExams(semester, dates.first, dates.second)
|
}).map { list -> list.filter { it.date in start..end } }
|
||||||
.toSingle(emptyList())
|
|
||||||
}).map { list -> list.filter { it.date in startDate..endDate } }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,19 @@
|
|||||||
package io.github.wulkanowy.data.repositories.grade
|
package io.github.wulkanowy.data.repositories.grade
|
||||||
|
|
||||||
import io.github.wulkanowy.data.db.dao.GradeDao
|
import io.github.wulkanowy.data.db.dao.GradeDao
|
||||||
|
import io.github.wulkanowy.data.db.dao.GradeSummaryDao
|
||||||
import io.github.wulkanowy.data.db.entities.Grade
|
import io.github.wulkanowy.data.db.entities.Grade
|
||||||
|
import io.github.wulkanowy.data.db.entities.GradeSummary
|
||||||
import io.github.wulkanowy.data.db.entities.Semester
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
import io.reactivex.Maybe
|
import io.reactivex.Maybe
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class GradeLocal @Inject constructor(private val gradeDb: GradeDao) {
|
class GradeLocal @Inject constructor(
|
||||||
|
private val gradeDb: GradeDao,
|
||||||
|
private val gradeSummaryDb: GradeSummaryDao
|
||||||
|
) {
|
||||||
|
|
||||||
fun saveGrades(grades: List<Grade>) {
|
fun saveGrades(grades: List<Grade>) {
|
||||||
gradeDb.insertAll(grades)
|
gradeDb.insertAll(grades)
|
||||||
@ -22,7 +27,19 @@ class GradeLocal @Inject constructor(private val gradeDb: GradeDao) {
|
|||||||
gradeDb.updateAll(grades)
|
gradeDb.updateAll(grades)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getGrades(semester: Semester): Maybe<List<Grade>> {
|
fun getGradesDetails(semester: Semester): Maybe<List<Grade>> {
|
||||||
return gradeDb.loadAll(semester.semesterId, semester.studentId).filter { it.isNotEmpty() }
|
return gradeDb.loadAll(semester.semesterId, semester.studentId).filter { it.isNotEmpty() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun saveGradesSummary(gradesSummary: List<GradeSummary>) {
|
||||||
|
gradeSummaryDb.insertAll(gradesSummary)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun deleteGradesSummary(gradesSummary: List<GradeSummary>) {
|
||||||
|
gradeSummaryDb.deleteAll(gradesSummary)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getGradesSummary(semester: Semester): Maybe<List<GradeSummary>> {
|
||||||
|
return gradeSummaryDb.loadAll(semester.semesterId, semester.studentId).filter { it.isNotEmpty() }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
package io.github.wulkanowy.data.repositories.grade
|
package io.github.wulkanowy.data.repositories.grade
|
||||||
|
|
||||||
import io.github.wulkanowy.data.db.entities.Grade
|
import io.github.wulkanowy.data.db.entities.Grade
|
||||||
|
import io.github.wulkanowy.data.db.entities.GradeSummary
|
||||||
import io.github.wulkanowy.data.db.entities.Semester
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import io.github.wulkanowy.sdk.Sdk
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
|
import io.github.wulkanowy.utils.init
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
@ -10,10 +13,11 @@ import javax.inject.Singleton
|
|||||||
@Singleton
|
@Singleton
|
||||||
class GradeRemote @Inject constructor(private val sdk: Sdk) {
|
class GradeRemote @Inject constructor(private val sdk: Sdk) {
|
||||||
|
|
||||||
fun getGrades(semester: Semester): Single<List<Grade>> {
|
fun getGrades(student: Student, semester: Semester): Single<Pair<List<Grade>, List<GradeSummary>>> {
|
||||||
return sdk.switchDiary(semester.diaryId, semester.schoolYear).getGrades(semester.semesterId)
|
return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear)
|
||||||
.map { grades ->
|
.getGrades(semester.semesterId)
|
||||||
grades.map {
|
.map { (details, summary) ->
|
||||||
|
details.map {
|
||||||
Grade(
|
Grade(
|
||||||
studentId = semester.studentId,
|
studentId = semester.studentId,
|
||||||
semesterId = semester.semesterId,
|
semesterId = semester.semesterId,
|
||||||
@ -30,6 +34,19 @@ class GradeRemote @Inject constructor(private val sdk: Sdk) {
|
|||||||
date = it.date,
|
date = it.date,
|
||||||
teacher = it.teacher
|
teacher = it.teacher
|
||||||
)
|
)
|
||||||
|
} to summary.map {
|
||||||
|
GradeSummary(
|
||||||
|
semesterId = semester.semesterId,
|
||||||
|
studentId = semester.studentId,
|
||||||
|
position = 0,
|
||||||
|
subject = it.name,
|
||||||
|
predictedGrade = it.predicted,
|
||||||
|
finalGrade = it.final,
|
||||||
|
pointsSum = it.pointsSum,
|
||||||
|
proposedPoints = it.proposedPoints,
|
||||||
|
finalPoints = it.finalPoints,
|
||||||
|
average = it.average
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package io.github.wulkanowy.data.repositories.grade
|
|||||||
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.db.entities.Grade
|
import io.github.wulkanowy.data.db.entities.Grade
|
||||||
|
import io.github.wulkanowy.data.db.entities.GradeSummary
|
||||||
import io.github.wulkanowy.data.db.entities.Semester
|
import io.github.wulkanowy.data.db.entities.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
|
||||||
@ -19,34 +20,47 @@ class GradeRepository @Inject constructor(
|
|||||||
private val remote: GradeRemote
|
private val remote: GradeRemote
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun getGrades(student: Student, semester: Semester, forceRefresh: Boolean = false, notify: Boolean = false): Single<List<Grade>> {
|
fun getGrades(student: Student, semester: Semester, forceRefresh: Boolean = false, notify: Boolean = false): Single<Pair<List<Grade>, List<GradeSummary>>> {
|
||||||
return local.getGrades(semester).filter { !forceRefresh }
|
return local.getGradesDetails(semester).flatMap { details ->
|
||||||
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
local.getGradesSummary(semester).map { summary -> details to summary }
|
||||||
.flatMap {
|
}.filter { !forceRefresh }
|
||||||
if (it) remote.getGrades(semester)
|
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings).flatMap {
|
||||||
else Single.error(UnknownHostException())
|
if (it) remote.getGrades(student, semester)
|
||||||
}.flatMap { new ->
|
else Single.error(UnknownHostException())
|
||||||
local.getGrades(semester).toSingle(emptyList())
|
}.flatMap { (newDetails, newSummary) ->
|
||||||
.doOnSuccess { old ->
|
local.getGradesDetails(semester).toSingle(emptyList())
|
||||||
val notifyBreakDate = old.maxBy { it.date }?.date ?: student.registrationDate.toLocalDate()
|
.doOnSuccess { old ->
|
||||||
local.deleteGrades(old.uniqueSubtract(new))
|
val notifyBreakDate = old.maxBy { it.date }?.date ?: student.registrationDate.toLocalDate()
|
||||||
local.saveGrades(new.uniqueSubtract(old)
|
local.deleteGrades(old.uniqueSubtract(newDetails))
|
||||||
.onEach {
|
local.saveGrades(newDetails.uniqueSubtract(old)
|
||||||
if (it.date >= notifyBreakDate) it.apply {
|
.onEach {
|
||||||
isRead = false
|
if (it.date >= notifyBreakDate) it.apply {
|
||||||
if (notify) isNotified = false
|
isRead = false
|
||||||
}
|
if (notify) isNotified = false
|
||||||
})
|
}
|
||||||
}
|
})
|
||||||
}.flatMap { local.getGrades(semester).toSingle(emptyList()) })
|
}.flatMap {
|
||||||
|
local.getGradesSummary(semester).toSingle(emptyList())
|
||||||
|
.doOnSuccess { old ->
|
||||||
|
local.deleteGradesSummary(old.uniqueSubtract(newSummary))
|
||||||
|
local.saveGradesSummary(newSummary.uniqueSubtract(old))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.flatMap {
|
||||||
|
local.getGradesDetails(semester).toSingle(emptyList()).flatMap { details ->
|
||||||
|
local.getGradesSummary(semester).toSingle(emptyList()).map { summary ->
|
||||||
|
details to summary
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getUnreadGrades(semester: Semester): Single<List<Grade>> {
|
fun getUnreadGrades(semester: Semester): Single<List<Grade>> {
|
||||||
return local.getGrades(semester).map { it.filter { grade -> !grade.isRead } }.toSingle(emptyList())
|
return local.getGradesDetails(semester).map { it.filter { grade -> !grade.isRead } }.toSingle(emptyList())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getNotNotifiedGrades(semester: Semester): Single<List<Grade>> {
|
fun getNotNotifiedGrades(semester: Semester): Single<List<Grade>> {
|
||||||
return local.getGrades(semester).map { it.filter { grade -> !grade.isNotified } }.toSingle(emptyList())
|
return local.getGradesDetails(semester).map { it.filter { grade -> !grade.isNotified } }.toSingle(emptyList())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateGrade(grade: Grade): Completable {
|
fun updateGrade(grade: Grade): Completable {
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
package io.github.wulkanowy.data.repositories.gradessummary
|
|
||||||
|
|
||||||
import io.github.wulkanowy.data.db.dao.GradeSummaryDao
|
|
||||||
import io.github.wulkanowy.data.db.entities.GradeSummary
|
|
||||||
import io.github.wulkanowy.data.db.entities.Semester
|
|
||||||
import io.reactivex.Maybe
|
|
||||||
import javax.inject.Inject
|
|
||||||
import javax.inject.Singleton
|
|
||||||
|
|
||||||
@Singleton
|
|
||||||
class GradeSummaryLocal @Inject constructor(private val gradeSummaryDb: GradeSummaryDao) {
|
|
||||||
|
|
||||||
fun saveGradesSummary(gradesSummary: List<GradeSummary>) {
|
|
||||||
gradeSummaryDb.insertAll(gradesSummary)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun deleteGradesSummary(gradesSummary: List<GradeSummary>) {
|
|
||||||
gradeSummaryDb.deleteAll(gradesSummary)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getGradesSummary(semester: Semester): Maybe<List<GradeSummary>> {
|
|
||||||
return gradeSummaryDb.loadAll(semester.semesterId, semester.studentId).filter { it.isNotEmpty() }
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
package io.github.wulkanowy.data.repositories.gradessummary
|
|
||||||
|
|
||||||
import io.github.wulkanowy.data.db.entities.GradeSummary
|
|
||||||
import io.github.wulkanowy.data.db.entities.Semester
|
|
||||||
import io.github.wulkanowy.sdk.Sdk
|
|
||||||
import io.reactivex.Single
|
|
||||||
import javax.inject.Inject
|
|
||||||
import javax.inject.Singleton
|
|
||||||
|
|
||||||
@Singleton
|
|
||||||
class GradeSummaryRemote @Inject constructor(private val sdk: Sdk) {
|
|
||||||
|
|
||||||
fun getGradeSummary(semester: Semester): Single<List<GradeSummary>> {
|
|
||||||
return sdk.switchDiary(semester.diaryId, semester.schoolYear).getGradesSummary(semester.semesterId)
|
|
||||||
.map { gradesSummary ->
|
|
||||||
gradesSummary.map {
|
|
||||||
GradeSummary(
|
|
||||||
semesterId = semester.semesterId,
|
|
||||||
studentId = semester.studentId,
|
|
||||||
position = 0,
|
|
||||||
subject = it.name,
|
|
||||||
predictedGrade = it.predicted,
|
|
||||||
finalGrade = it.final,
|
|
||||||
pointsSum = it.pointsSum,
|
|
||||||
proposedPoints = it.proposedPoints,
|
|
||||||
finalPoints = it.finalPoints,
|
|
||||||
average = it.average
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
package io.github.wulkanowy.data.repositories.gradessummary
|
|
||||||
|
|
||||||
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.GradeSummary
|
|
||||||
import io.github.wulkanowy.data.db.entities.Semester
|
|
||||||
import io.github.wulkanowy.utils.uniqueSubtract
|
|
||||||
import io.reactivex.Single
|
|
||||||
import java.net.UnknownHostException
|
|
||||||
import javax.inject.Inject
|
|
||||||
import javax.inject.Singleton
|
|
||||||
|
|
||||||
@Singleton
|
|
||||||
class GradeSummaryRepository @Inject constructor(
|
|
||||||
private val settings: InternetObservingSettings,
|
|
||||||
private val local: GradeSummaryLocal,
|
|
||||||
private val remote: GradeSummaryRemote
|
|
||||||
) {
|
|
||||||
|
|
||||||
fun getGradesSummary(semester: Semester, forceRefresh: Boolean = false): Single<List<GradeSummary>> {
|
|
||||||
return local.getGradesSummary(semester).filter { !forceRefresh }
|
|
||||||
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
|
||||||
.flatMap {
|
|
||||||
if (it) remote.getGradeSummary(semester)
|
|
||||||
else Single.error(UnknownHostException())
|
|
||||||
}.flatMap { new ->
|
|
||||||
local.getGradesSummary(semester).toSingle(emptyList())
|
|
||||||
.doOnSuccess { old ->
|
|
||||||
local.deleteGradesSummary(old.uniqueSubtract(new))
|
|
||||||
local.saveGradesSummary(new.uniqueSubtract(old))
|
|
||||||
}
|
|
||||||
}.flatMap { local.getGradesSummary(semester).toSingle(emptyList()) })
|
|
||||||
}
|
|
||||||
}
|
|
@ -3,7 +3,9 @@ package io.github.wulkanowy.data.repositories.gradestatistics
|
|||||||
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.data.db.entities.Student
|
||||||
import io.github.wulkanowy.sdk.Sdk
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
|
import io.github.wulkanowy.utils.init
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
@ -11,8 +13,8 @@ import javax.inject.Singleton
|
|||||||
@Singleton
|
@Singleton
|
||||||
class GradeStatisticsRemote @Inject constructor(private val sdk: Sdk) {
|
class GradeStatisticsRemote @Inject constructor(private val sdk: Sdk) {
|
||||||
|
|
||||||
fun getGradeStatistics(semester: Semester, isSemester: Boolean): Single<List<GradeStatistics>> {
|
fun getGradeStatistics(student: Student, semester: Semester, isSemester: Boolean): Single<List<GradeStatistics>> {
|
||||||
return sdk.switchDiary(semester.diaryId, semester.schoolYear).let {
|
return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear).let {
|
||||||
if (isSemester) it.getGradesAnnualStatistics(semester.semesterId)
|
if (isSemester) it.getGradesAnnualStatistics(semester.semesterId)
|
||||||
else it.getGradesPartialStatistics(semester.semesterId)
|
else it.getGradesPartialStatistics(semester.semesterId)
|
||||||
}.map { gradeStatistics ->
|
}.map { gradeStatistics ->
|
||||||
@ -29,8 +31,9 @@ class GradeStatisticsRemote @Inject constructor(private val sdk: Sdk) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getGradePointsStatistics(semester: Semester): Single<List<GradePointsStatistics>> {
|
fun getGradePointsStatistics(student: Student, semester: Semester): Single<List<GradePointsStatistics>> {
|
||||||
return sdk.switchDiary(semester.diaryId, semester.schoolYear).getGradesPointsStatistics(semester.semesterId)
|
return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear)
|
||||||
|
.getGradesPointsStatistics(semester.semesterId)
|
||||||
.map { gradePointsStatistics ->
|
.map { gradePointsStatistics ->
|
||||||
gradePointsStatistics.map {
|
gradePointsStatistics.map {
|
||||||
GradePointsStatistics(
|
GradePointsStatistics(
|
||||||
|
@ -5,6 +5,7 @@ import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.Inter
|
|||||||
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.data.db.entities.Student
|
||||||
import io.github.wulkanowy.data.pojos.GradeStatisticsItem
|
import io.github.wulkanowy.data.pojos.GradeStatisticsItem
|
||||||
import io.github.wulkanowy.ui.modules.grade.statistics.ViewType
|
import io.github.wulkanowy.ui.modules.grade.statistics.ViewType
|
||||||
import io.github.wulkanowy.utils.uniqueSubtract
|
import io.github.wulkanowy.utils.uniqueSubtract
|
||||||
@ -20,11 +21,11 @@ class GradeStatisticsRepository @Inject constructor(
|
|||||||
private val remote: GradeStatisticsRemote
|
private val remote: GradeStatisticsRemote
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun getGradesStatistics(semester: Semester, subjectName: String, isSemester: Boolean, forceRefresh: Boolean = false): Single<List<GradeStatisticsItem>> {
|
fun getGradesStatistics(student: Student, semester: Semester, subjectName: String, isSemester: Boolean, forceRefresh: Boolean = false): Single<List<GradeStatisticsItem>> {
|
||||||
return local.getGradesStatistics(semester, isSemester, subjectName).map { it.mapToStatisticItems() }.filter { !forceRefresh }
|
return local.getGradesStatistics(semester, isSemester, subjectName).map { it.mapToStatisticItems() }.filter { !forceRefresh }
|
||||||
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
||||||
.flatMap {
|
.flatMap {
|
||||||
if (it) remote.getGradeStatistics(semester, isSemester)
|
if (it) remote.getGradeStatistics(student, semester, isSemester)
|
||||||
else Single.error(UnknownHostException())
|
else Single.error(UnknownHostException())
|
||||||
}.flatMap { new ->
|
}.flatMap { new ->
|
||||||
local.getGradesStatistics(semester, isSemester).toSingle(emptyList())
|
local.getGradesStatistics(semester, isSemester).toSingle(emptyList())
|
||||||
@ -35,11 +36,11 @@ class GradeStatisticsRepository @Inject constructor(
|
|||||||
}.flatMap { local.getGradesStatistics(semester, isSemester, subjectName).map { it.mapToStatisticItems() }.toSingle(emptyList()) })
|
}.flatMap { local.getGradesStatistics(semester, isSemester, subjectName).map { it.mapToStatisticItems() }.toSingle(emptyList()) })
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getGradesPointsStatistics(semester: Semester, subjectName: String, forceRefresh: Boolean): Single<List<GradeStatisticsItem>> {
|
fun getGradesPointsStatistics(student: Student, semester: Semester, subjectName: String, forceRefresh: Boolean): Single<List<GradeStatisticsItem>> {
|
||||||
return local.getGradesPointsStatistics(semester, subjectName).map { it.mapToStatisticsItem() }.filter { !forceRefresh }
|
return local.getGradesPointsStatistics(semester, subjectName).map { it.mapToStatisticsItem() }.filter { !forceRefresh }
|
||||||
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
||||||
.flatMap {
|
.flatMap {
|
||||||
if (it) remote.getGradePointsStatistics(semester)
|
if (it) remote.getGradePointsStatistics(student, semester)
|
||||||
else Single.error(UnknownHostException())
|
else Single.error(UnknownHostException())
|
||||||
}.flatMap { new ->
|
}.flatMap { new ->
|
||||||
local.getGradesPointsStatistics(semester).toSingle(emptyList())
|
local.getGradesPointsStatistics(semester).toSingle(emptyList())
|
||||||
|
@ -2,7 +2,9 @@ package io.github.wulkanowy.data.repositories.homework
|
|||||||
|
|
||||||
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.data.db.entities.Student
|
||||||
import io.github.wulkanowy.sdk.Sdk
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
|
import io.github.wulkanowy.utils.init
|
||||||
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
|
||||||
@ -11,8 +13,9 @@ import javax.inject.Singleton
|
|||||||
@Singleton
|
@Singleton
|
||||||
class HomeworkRemote @Inject constructor(private val sdk: Sdk) {
|
class HomeworkRemote @Inject constructor(private val sdk: Sdk) {
|
||||||
|
|
||||||
fun getHomework(semester: Semester, startDate: LocalDate, endDate: LocalDate): Single<List<Homework>> {
|
fun getHomework(student: Student, semester: Semester, startDate: LocalDate, endDate: LocalDate): Single<List<Homework>> {
|
||||||
return sdk.switchDiary(semester.diaryId, semester.schoolYear).getHomework(startDate, endDate)
|
return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear)
|
||||||
|
.getHomework(startDate, endDate)
|
||||||
.map { homework ->
|
.map { homework ->
|
||||||
homework.map {
|
homework.map {
|
||||||
Homework(
|
Homework(
|
||||||
|
@ -4,7 +4,8 @@ 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.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.friday
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
|
import io.github.wulkanowy.utils.sunday
|
||||||
import io.github.wulkanowy.utils.monday
|
import io.github.wulkanowy.utils.monday
|
||||||
import io.github.wulkanowy.utils.uniqueSubtract
|
import io.github.wulkanowy.utils.uniqueSubtract
|
||||||
import io.reactivex.Completable
|
import io.reactivex.Completable
|
||||||
@ -21,12 +22,12 @@ class HomeworkRepository @Inject constructor(
|
|||||||
private val remote: HomeworkRemote
|
private val remote: HomeworkRemote
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun getHomework(semester: Semester, start: LocalDate, end: LocalDate, forceRefresh: Boolean = false): Single<List<Homework>> {
|
fun getHomework(student: Student, semester: Semester, start: LocalDate, end: LocalDate, forceRefresh: Boolean = false): Single<List<Homework>> {
|
||||||
return Single.fromCallable { start.monday to end.friday }.flatMap { (monday, friday) ->
|
return Single.fromCallable { start.monday to end.sunday }.flatMap { (monday, friday) ->
|
||||||
local.getHomework(semester, monday, friday).filter { !forceRefresh }
|
local.getHomework(semester, monday, friday).filter { !forceRefresh }
|
||||||
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
||||||
.flatMap {
|
.flatMap {
|
||||||
if (it) remote.getHomework(semester, monday, friday)
|
if (it) remote.getHomework(student, semester, monday, friday)
|
||||||
else Single.error(UnknownHostException())
|
else Single.error(UnknownHostException())
|
||||||
}.flatMap { new ->
|
}.flatMap { new ->
|
||||||
local.getHomework(semester, monday, friday).toSingle(emptyList())
|
local.getHomework(semester, monday, friday).toSingle(emptyList())
|
||||||
|
@ -3,6 +3,7 @@ package io.github.wulkanowy.data.repositories.luckynumber
|
|||||||
import io.github.wulkanowy.data.db.entities.LuckyNumber
|
import io.github.wulkanowy.data.db.entities.LuckyNumber
|
||||||
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.sdk.Sdk
|
||||||
|
import io.github.wulkanowy.utils.init
|
||||||
import io.reactivex.Maybe
|
import io.reactivex.Maybe
|
||||||
import org.threeten.bp.LocalDate
|
import org.threeten.bp.LocalDate
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@ -12,7 +13,7 @@ import javax.inject.Singleton
|
|||||||
class LuckyNumberRemote @Inject constructor(private val sdk: Sdk) {
|
class LuckyNumberRemote @Inject constructor(private val sdk: Sdk) {
|
||||||
|
|
||||||
fun getLuckyNumber(student: Student): Maybe<LuckyNumber> {
|
fun getLuckyNumber(student: Student): Maybe<LuckyNumber> {
|
||||||
return sdk.getLuckyNumber(student.schoolShortName).map {
|
return sdk.init(student).getLuckyNumber(student.schoolShortName).map {
|
||||||
LuckyNumber(
|
LuckyNumber(
|
||||||
studentId = student.studentId,
|
studentId = student.studentId,
|
||||||
date = LocalDate.now(),
|
date = LocalDate.now(),
|
||||||
|
@ -2,7 +2,6 @@ package io.github.wulkanowy.data.repositories.luckynumber
|
|||||||
|
|
||||||
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.SdkHelper
|
|
||||||
import io.github.wulkanowy.data.db.entities.LuckyNumber
|
import io.github.wulkanowy.data.db.entities.LuckyNumber
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import io.reactivex.Completable
|
import io.reactivex.Completable
|
||||||
@ -16,36 +15,33 @@ import javax.inject.Singleton
|
|||||||
class LuckyNumberRepository @Inject constructor(
|
class LuckyNumberRepository @Inject constructor(
|
||||||
private val settings: InternetObservingSettings,
|
private val settings: InternetObservingSettings,
|
||||||
private val local: LuckyNumberLocal,
|
private val local: LuckyNumberLocal,
|
||||||
private val remote: LuckyNumberRemote,
|
private val remote: LuckyNumberRemote
|
||||||
private val sdkHelper: SdkHelper
|
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun getLuckyNumber(student: Student, forceRefresh: Boolean = false, notify: Boolean = false): Maybe<LuckyNumber> {
|
fun getLuckyNumber(student: Student, forceRefresh: Boolean = false, notify: Boolean = false): Maybe<LuckyNumber> {
|
||||||
return Maybe.just(sdkHelper.init(student)).flatMap {
|
return local.getLuckyNumber(student, LocalDate.now()).filter { !forceRefresh }
|
||||||
local.getLuckyNumber(student, LocalDate.now()).filter { !forceRefresh }
|
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
||||||
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
.flatMapMaybe {
|
||||||
.flatMapMaybe {
|
if (it) remote.getLuckyNumber(student)
|
||||||
if (it) remote.getLuckyNumber(student)
|
else Maybe.error(UnknownHostException())
|
||||||
else Maybe.error(UnknownHostException())
|
}.flatMap { new ->
|
||||||
}.flatMap { new ->
|
local.getLuckyNumber(student, LocalDate.now())
|
||||||
local.getLuckyNumber(student, LocalDate.now())
|
.doOnSuccess { old ->
|
||||||
.doOnSuccess { old ->
|
if (new != old) {
|
||||||
if (new != old) {
|
local.deleteLuckyNumber(old)
|
||||||
local.deleteLuckyNumber(old)
|
|
||||||
local.saveLuckyNumber(new.apply {
|
|
||||||
if (notify) isNotified = false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.doOnComplete {
|
|
||||||
local.saveLuckyNumber(new.apply {
|
local.saveLuckyNumber(new.apply {
|
||||||
if (notify) isNotified = false
|
if (notify) isNotified = false
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}.flatMap({ local.getLuckyNumber(student, LocalDate.now()) }, { Maybe.error(it) },
|
}
|
||||||
{ local.getLuckyNumber(student, LocalDate.now()) })
|
.doOnComplete {
|
||||||
)
|
local.saveLuckyNumber(new.apply {
|
||||||
}
|
if (notify) isNotified = false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}.flatMap({ local.getLuckyNumber(student, LocalDate.now()) }, { Maybe.error(it) },
|
||||||
|
{ local.getLuckyNumber(student, LocalDate.now()) })
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getNotNotifiedLuckyNumber(student: Student): Maybe<LuckyNumber> {
|
fun getNotNotifiedLuckyNumber(student: Student): Maybe<LuckyNumber> {
|
||||||
|
@ -8,6 +8,7 @@ import io.github.wulkanowy.data.db.entities.Student
|
|||||||
import io.github.wulkanowy.sdk.Sdk
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
import io.github.wulkanowy.sdk.pojo.Folder
|
import io.github.wulkanowy.sdk.pojo.Folder
|
||||||
import io.github.wulkanowy.sdk.pojo.SentMessage
|
import io.github.wulkanowy.sdk.pojo.SentMessage
|
||||||
|
import io.github.wulkanowy.utils.init
|
||||||
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
|
||||||
@ -18,7 +19,7 @@ import io.github.wulkanowy.sdk.pojo.Recipient as SdkRecipient
|
|||||||
class MessageRemote @Inject constructor(private val sdk: Sdk) {
|
class MessageRemote @Inject constructor(private val sdk: Sdk) {
|
||||||
|
|
||||||
fun getMessages(student: Student, semester: Semester, folder: MessageFolder): Single<List<Message>> {
|
fun getMessages(student: Student, semester: Semester, folder: MessageFolder): Single<List<Message>> {
|
||||||
return sdk.getMessages(Folder.valueOf(folder.name), semester.start.atStartOfDay(), semester.end.atStartOfDay()).map { messages ->
|
return sdk.init(student).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(),
|
||||||
@ -41,8 +42,8 @@ class MessageRemote @Inject constructor(private val sdk: Sdk) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getMessagesContentDetails(message: Message, markAsRead: Boolean = false): Single<Pair<String, List<MessageAttachment>>> {
|
fun getMessagesContentDetails(student: Student, message: Message, markAsRead: Boolean = false): Single<Pair<String, List<MessageAttachment>>> {
|
||||||
return sdk.getMessageDetails(message.messageId, message.folderId, markAsRead, message.realId).map { details ->
|
return sdk.init(student).getMessageDetails(message.messageId, message.folderId, markAsRead, message.realId).map { details ->
|
||||||
details.content to details.attachments.map {
|
details.content to details.attachments.map {
|
||||||
MessageAttachment(
|
MessageAttachment(
|
||||||
realId = it.id,
|
realId = it.id,
|
||||||
@ -55,8 +56,8 @@ class MessageRemote @Inject constructor(private val sdk: Sdk) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun sendMessage(subject: String, content: String, recipients: List<Recipient>): Single<SentMessage> {
|
fun sendMessage(student: Student, subject: String, content: String, recipients: List<Recipient>): Single<SentMessage> {
|
||||||
return sdk.sendMessage(
|
return sdk.init(student).sendMessage(
|
||||||
subject = subject,
|
subject = subject,
|
||||||
content = content,
|
content = content,
|
||||||
recipients = recipients.map {
|
recipients = recipients.map {
|
||||||
@ -73,7 +74,7 @@ class MessageRemote @Inject constructor(private val sdk: Sdk) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun deleteMessage(message: Message): Single<Boolean> {
|
fun deleteMessage(student: Student, message: Message): Single<Boolean> {
|
||||||
return sdk.deleteMessages(listOf(Pair(message.realId, message.folderId)))
|
return sdk.init(student).deleteMessages(listOf(message.messageId to message.folderId))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@ 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.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.MessageWithAttachment
|
import io.github.wulkanowy.data.db.entities.MessageWithAttachment
|
||||||
import io.github.wulkanowy.data.db.entities.Recipient
|
import io.github.wulkanowy.data.db.entities.Recipient
|
||||||
@ -22,60 +21,53 @@ import javax.inject.Singleton
|
|||||||
class MessageRepository @Inject constructor(
|
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 sdkHelper: SdkHelper
|
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun getMessages(student: Student, semester: Semester, 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(sdkHelper.init(student))
|
return local.getMessages(student, folder).filter { !forceRefresh }
|
||||||
.flatMap { _ ->
|
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
||||||
local.getMessages(student, folder).filter { !forceRefresh }
|
.flatMap {
|
||||||
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
if (it) remote.getMessages(student, semester, folder)
|
||||||
.flatMap {
|
else Single.error(UnknownHostException())
|
||||||
if (it) remote.getMessages(student, semester, folder)
|
}.flatMap { new ->
|
||||||
else Single.error(UnknownHostException())
|
local.getMessages(student, folder).toSingle(emptyList())
|
||||||
}.flatMap { new ->
|
.doOnSuccess { old ->
|
||||||
local.getMessages(student, folder).toSingle(emptyList())
|
local.deleteMessages(old.uniqueSubtract(new))
|
||||||
.doOnSuccess { old ->
|
local.saveMessages(new.uniqueSubtract(old)
|
||||||
local.deleteMessages(old.uniqueSubtract(new))
|
.onEach {
|
||||||
local.saveMessages(new.uniqueSubtract(old)
|
it.isNotified = !notify
|
||||||
.onEach {
|
})
|
||||||
it.isNotified = !notify
|
}
|
||||||
})
|
}.flatMap { local.getMessages(student, folder).toSingle(emptyList()) }
|
||||||
}
|
)
|
||||||
}.flatMap { local.getMessages(student, folder).toSingle(emptyList()) }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getMessage(student: Student, message: Message, markAsRead: Boolean = false): Single<MessageWithAttachment> {
|
fun getMessage(student: Student, message: Message, markAsRead: Boolean = false): Single<MessageWithAttachment> {
|
||||||
return Single.just(sdkHelper.init(student))
|
return local.getMessageWithAttachment(student, message)
|
||||||
.flatMap { _ ->
|
.filter {
|
||||||
local.getMessageWithAttachment(student, message)
|
it.message.content.isNotEmpty().also { status ->
|
||||||
.filter {
|
Timber.d("Message content in db empty: ${!status}")
|
||||||
it.message.content.isNotEmpty().also { status ->
|
} && !it.message.unread
|
||||||
Timber.d("Message content in db empty: ${!status}")
|
|
||||||
} && !it.message.unread
|
|
||||||
}
|
|
||||||
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
|
||||||
.flatMap {
|
|
||||||
if (it) local.getMessageWithAttachment(student, message)
|
|
||||||
else Single.error(UnknownHostException())
|
|
||||||
}
|
|
||||||
.flatMap { dbMessage ->
|
|
||||||
remote.getMessagesContentDetails(dbMessage.message, markAsRead).doOnSuccess { (downloadedMessage, attachments) ->
|
|
||||||
local.updateMessages(listOf(dbMessage.message.copy(unread = !markAsRead).apply {
|
|
||||||
id = dbMessage.message.id
|
|
||||||
content = content.ifBlank { downloadedMessage }
|
|
||||||
}))
|
|
||||||
local.saveMessageAttachments(attachments)
|
|
||||||
Timber.d("Message ${message.messageId} with blank content: ${dbMessage.message.content.isBlank()}, marked as read")
|
|
||||||
}
|
|
||||||
}.flatMap {
|
|
||||||
local.getMessageWithAttachment(student, message)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
||||||
|
.flatMap {
|
||||||
|
if (it) local.getMessageWithAttachment(student, message)
|
||||||
|
else Single.error(UnknownHostException())
|
||||||
|
}
|
||||||
|
.flatMap { dbMessage ->
|
||||||
|
remote.getMessagesContentDetails(student, dbMessage.message, markAsRead).doOnSuccess { (downloadedMessage, attachments) ->
|
||||||
|
local.updateMessages(listOf(dbMessage.message.copy(unread = !markAsRead).apply {
|
||||||
|
id = dbMessage.message.id
|
||||||
|
content = content.ifBlank { downloadedMessage }
|
||||||
|
}))
|
||||||
|
local.saveMessageAttachments(attachments)
|
||||||
|
Timber.d("Message ${message.messageId} with blank content: ${dbMessage.message.content.isBlank()}, marked as read")
|
||||||
|
}
|
||||||
|
}.flatMap {
|
||||||
|
local.getMessageWithAttachment(student, message)
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getNotNotifiedMessages(student: Student): Single<List<Message>> {
|
fun getNotNotifiedMessages(student: Student): Single<List<Message>> {
|
||||||
@ -88,18 +80,18 @@ class MessageRepository @Inject constructor(
|
|||||||
return Completable.fromCallable { local.updateMessages(messages) }
|
return Completable.fromCallable { local.updateMessages(messages) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun sendMessage(subject: String, content: String, recipients: List<Recipient>): Single<SentMessage> {
|
fun sendMessage(student: Student, subject: String, content: String, recipients: List<Recipient>): Single<SentMessage> {
|
||||||
return ReactiveNetwork.checkInternetConnectivity(settings)
|
return ReactiveNetwork.checkInternetConnectivity(settings)
|
||||||
.flatMap {
|
.flatMap {
|
||||||
if (it) remote.sendMessage(subject, content, recipients)
|
if (it) remote.sendMessage(student, subject, content, recipients)
|
||||||
else Single.error(UnknownHostException())
|
else Single.error(UnknownHostException())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun deleteMessage(message: Message): Single<Boolean> {
|
fun deleteMessage(student: Student, message: Message): Single<Boolean> {
|
||||||
return ReactiveNetwork.checkInternetConnectivity(settings)
|
return ReactiveNetwork.checkInternetConnectivity(settings)
|
||||||
.flatMap {
|
.flatMap {
|
||||||
if (it) remote.deleteMessage(message)
|
if (it) remote.deleteMessage(student, message)
|
||||||
else Single.error(UnknownHostException())
|
else Single.error(UnknownHostException())
|
||||||
}
|
}
|
||||||
.doOnSuccess {
|
.doOnSuccess {
|
||||||
|
@ -2,8 +2,10 @@ package io.github.wulkanowy.data.repositories.mobiledevice
|
|||||||
|
|
||||||
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.github.wulkanowy.data.pojos.MobileDeviceToken
|
import io.github.wulkanowy.data.pojos.MobileDeviceToken
|
||||||
import io.github.wulkanowy.sdk.Sdk
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
|
import io.github.wulkanowy.utils.init
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
@ -11,13 +13,14 @@ import javax.inject.Singleton
|
|||||||
@Singleton
|
@Singleton
|
||||||
class MobileDeviceRemote @Inject constructor(private val sdk: Sdk) {
|
class MobileDeviceRemote @Inject constructor(private val sdk: Sdk) {
|
||||||
|
|
||||||
fun getDevices(semester: Semester): Single<List<MobileDevice>> {
|
fun getDevices(student: Student, semester: Semester): Single<List<MobileDevice>> {
|
||||||
return sdk.switchDiary(semester.diaryId, semester.schoolYear).getRegisteredDevices()
|
return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear)
|
||||||
|
.getRegisteredDevices()
|
||||||
.map { devices ->
|
.map { devices ->
|
||||||
devices.map {
|
devices.map {
|
||||||
MobileDevice(
|
MobileDevice(
|
||||||
studentId = semester.studentId,
|
studentId = semester.studentId,
|
||||||
date = it.date,
|
date = it.createDate,
|
||||||
deviceId = it.id,
|
deviceId = it.id,
|
||||||
name = it.name
|
name = it.name
|
||||||
)
|
)
|
||||||
@ -25,12 +28,14 @@ class MobileDeviceRemote @Inject constructor(private val sdk: Sdk) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun unregisterDevice(semester: Semester, device: MobileDevice): Single<Boolean> {
|
fun unregisterDevice(student: Student, semester: Semester, device: MobileDevice): Single<Boolean> {
|
||||||
return sdk.switchDiary(semester.diaryId, semester.schoolYear).unregisterDevice(device.deviceId)
|
return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear)
|
||||||
|
.unregisterDevice(device.deviceId)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getToken(semester: Semester): Single<MobileDeviceToken> {
|
fun getToken(student: Student, semester: Semester): Single<MobileDeviceToken> {
|
||||||
return sdk.switchDiary(semester.diaryId, semester.schoolYear).getToken()
|
return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear)
|
||||||
|
.getToken()
|
||||||
.map {
|
.map {
|
||||||
MobileDeviceToken(
|
MobileDeviceToken(
|
||||||
token = it.token,
|
token = it.token,
|
||||||
|
@ -4,6 +4,7 @@ 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.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.github.wulkanowy.data.pojos.MobileDeviceToken
|
import io.github.wulkanowy.data.pojos.MobileDeviceToken
|
||||||
import io.github.wulkanowy.utils.uniqueSubtract
|
import io.github.wulkanowy.utils.uniqueSubtract
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
@ -18,11 +19,11 @@ class MobileDeviceRepository @Inject constructor(
|
|||||||
private val remote: MobileDeviceRemote
|
private val remote: MobileDeviceRemote
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun getDevices(semester: Semester, forceRefresh: Boolean = false): Single<List<MobileDevice>> {
|
fun getDevices(student: Student, semester: Semester, forceRefresh: Boolean = false): Single<List<MobileDevice>> {
|
||||||
return local.getDevices(semester).filter { !forceRefresh }
|
return local.getDevices(semester).filter { !forceRefresh }
|
||||||
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
||||||
.flatMap {
|
.flatMap {
|
||||||
if (it) remote.getDevices(semester)
|
if (it) remote.getDevices(student, semester)
|
||||||
else Single.error(UnknownHostException())
|
else Single.error(UnknownHostException())
|
||||||
}.flatMap { new ->
|
}.flatMap { new ->
|
||||||
local.getDevices(semester).toSingle(emptyList())
|
local.getDevices(semester).toSingle(emptyList())
|
||||||
@ -34,18 +35,18 @@ class MobileDeviceRepository @Inject constructor(
|
|||||||
).flatMap { local.getDevices(semester).toSingle(emptyList()) }
|
).flatMap { local.getDevices(semester).toSingle(emptyList()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun unregisterDevice(semester: Semester, device: MobileDevice): Single<Boolean> {
|
fun unregisterDevice(student: Student, semester: Semester, device: MobileDevice): Single<Boolean> {
|
||||||
return ReactiveNetwork.checkInternetConnectivity(settings)
|
return ReactiveNetwork.checkInternetConnectivity(settings)
|
||||||
.flatMap {
|
.flatMap {
|
||||||
if (it) remote.unregisterDevice(semester, device)
|
if (it) remote.unregisterDevice(student, semester, device)
|
||||||
else Single.error(UnknownHostException())
|
else Single.error(UnknownHostException())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getToken(semester: Semester): Single<MobileDeviceToken> {
|
fun getToken(student: Student, semester: Semester): Single<MobileDeviceToken> {
|
||||||
return ReactiveNetwork.checkInternetConnectivity(settings)
|
return ReactiveNetwork.checkInternetConnectivity(settings)
|
||||||
.flatMap {
|
.flatMap {
|
||||||
if (it) remote.getToken(semester)
|
if (it) remote.getToken(student, semester)
|
||||||
else Single.error(UnknownHostException())
|
else Single.error(UnknownHostException())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,9 @@ package io.github.wulkanowy.data.repositories.note
|
|||||||
|
|
||||||
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.data.db.entities.Student
|
||||||
import io.github.wulkanowy.sdk.Sdk
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
|
import io.github.wulkanowy.utils.init
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
@ -10,8 +12,9 @@ import javax.inject.Singleton
|
|||||||
@Singleton
|
@Singleton
|
||||||
class NoteRemote @Inject constructor(private val sdk: Sdk) {
|
class NoteRemote @Inject constructor(private val sdk: Sdk) {
|
||||||
|
|
||||||
fun getNotes(semester: Semester): Single<List<Note>> {
|
fun getNotes(student: Student, semester: Semester): Single<List<Note>> {
|
||||||
return sdk.switchDiary(semester.diaryId, semester.schoolYear).getNotes(semester.semesterId)
|
return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear)
|
||||||
|
.getNotes(semester.semesterId)
|
||||||
.map { notes ->
|
.map { notes ->
|
||||||
notes.map {
|
notes.map {
|
||||||
Note(
|
Note(
|
||||||
|
@ -23,7 +23,7 @@ class NoteRepository @Inject constructor(
|
|||||||
return local.getNotes(student).filter { !forceRefresh }
|
return local.getNotes(student).filter { !forceRefresh }
|
||||||
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
||||||
.flatMap {
|
.flatMap {
|
||||||
if (it) remote.getNotes(semester)
|
if (it) remote.getNotes(student, semester)
|
||||||
else Single.error(UnknownHostException())
|
else Single.error(UnknownHostException())
|
||||||
}.flatMap { new ->
|
}.flatMap { new ->
|
||||||
local.getNotes(student).toSingle(emptyList())
|
local.getNotes(student).toSingle(emptyList())
|
||||||
|
@ -3,6 +3,7 @@ package io.github.wulkanowy.data.repositories.preferences
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
|
import io.github.wulkanowy.ui.modules.grade.GradeAverageMode
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@ -17,8 +18,8 @@ class PreferencesRepository @Inject constructor(
|
|||||||
val isShowPresent: Boolean
|
val isShowPresent: Boolean
|
||||||
get() = getBoolean(R.string.pref_key_attendance_present, R.bool.pref_default_attendance_present)
|
get() = getBoolean(R.string.pref_key_attendance_present, R.bool.pref_default_attendance_present)
|
||||||
|
|
||||||
val gradeAverageMode: String
|
val gradeAverageMode: GradeAverageMode
|
||||||
get() = getString(R.string.pref_key_grade_average_mode, R.string.pref_default_grade_average_mode)
|
get() = GradeAverageMode.getByValue(getString(R.string.pref_key_grade_average_mode, R.string.pref_default_grade_average_mode))
|
||||||
|
|
||||||
val gradeAverageForceCalc: Boolean
|
val gradeAverageForceCalc: Boolean
|
||||||
get() = getBoolean(R.string.pref_key_grade_average_force_calc, R.bool.pref_default_grade_average_force_calc)
|
get() = getBoolean(R.string.pref_key_grade_average_force_calc, R.bool.pref_default_grade_average_force_calc)
|
||||||
@ -26,6 +27,9 @@ class PreferencesRepository @Inject constructor(
|
|||||||
val isGradeExpandable: Boolean
|
val isGradeExpandable: Boolean
|
||||||
get() = !getBoolean(R.string.pref_key_expand_grade, R.bool.pref_default_expand_grade)
|
get() = !getBoolean(R.string.pref_key_expand_grade, R.bool.pref_default_expand_grade)
|
||||||
|
|
||||||
|
val showAllSubjectsOnStatisticsList: Boolean
|
||||||
|
get() = getBoolean(R.string.pref_key_grade_statistics_list, R.bool.pref_default_grade_statistics_list)
|
||||||
|
|
||||||
val appThemeKey = 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() = getString(appThemeKey, R.string.pref_default_app_theme)
|
get() = getString(appThemeKey, R.string.pref_default_app_theme)
|
||||||
@ -52,6 +56,10 @@ class PreferencesRepository @Inject constructor(
|
|||||||
val isNotificationsEnable: Boolean
|
val isNotificationsEnable: Boolean
|
||||||
get() = getBoolean(R.string.pref_key_notifications_enable, R.bool.pref_default_notifications_enable)
|
get() = getBoolean(R.string.pref_key_notifications_enable, R.bool.pref_default_notifications_enable)
|
||||||
|
|
||||||
|
val isUpcomingLessonsNotificationsEnableKey = context.getString(R.string.pref_key_notifications_upcoming_lessons_enable)
|
||||||
|
val isUpcomingLessonsNotificationsEnable: Boolean
|
||||||
|
get() = getBoolean(isUpcomingLessonsNotificationsEnableKey, R.bool.pref_default_notification_upcoming_lessons_enable)
|
||||||
|
|
||||||
val isDebugNotificationEnableKey = 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() = getBoolean(isDebugNotificationEnableKey, R.bool.pref_default_notification_debug)
|
get() = getBoolean(isDebugNotificationEnableKey, R.bool.pref_default_notification_debug)
|
||||||
@ -68,6 +76,9 @@ class PreferencesRepository @Inject constructor(
|
|||||||
val showWholeClassPlan: String
|
val showWholeClassPlan: String
|
||||||
get() = getString(R.string.pref_key_timetable_show_whole_class, R.string.pref_default_timetable_show_whole_class)
|
get() = getString(R.string.pref_key_timetable_show_whole_class, R.string.pref_default_timetable_show_whole_class)
|
||||||
|
|
||||||
|
val showTimetableTimers: Boolean
|
||||||
|
get() = getBoolean(R.string.pref_key_timetable_show_timers, R.bool.pref_default_timetable_show_timers)
|
||||||
|
|
||||||
private fun getString(id: Int, default: Int) = getString(context.getString(id), default)
|
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 getString(id: String, default: Int) = sharedPref.getString(id, context.getString(default)) ?: context.getString(default)
|
||||||
|
@ -3,7 +3,9 @@ package io.github.wulkanowy.data.repositories.recipient
|
|||||||
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.data.db.entities.Student
|
||||||
import io.github.wulkanowy.sdk.Sdk
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
|
import io.github.wulkanowy.utils.init
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
@ -12,15 +14,15 @@ import io.github.wulkanowy.sdk.pojo.Recipient as SdkRecipient
|
|||||||
@Singleton
|
@Singleton
|
||||||
class RecipientRemote @Inject constructor(private val sdk: Sdk) {
|
class RecipientRemote @Inject constructor(private val sdk: Sdk) {
|
||||||
|
|
||||||
fun getRecipients(role: Int, unit: ReportingUnit): Single<List<Recipient>> {
|
fun getRecipients(student: Student, role: Int, unit: ReportingUnit): Single<List<Recipient>> {
|
||||||
return sdk.getRecipients(unit.realId, role)
|
return sdk.init(student).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(student: Student, message: Message): Single<List<Recipient>> {
|
||||||
return sdk.getMessageRecipients(message.messageId, message.senderId)
|
return sdk.init(student).getMessageRecipients(message.messageId, message.senderId)
|
||||||
.map { recipients ->
|
.map { recipients ->
|
||||||
recipients.map { it.toRecipient() }
|
recipients.map { it.toRecipient() }
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@ 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.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
|
||||||
@ -17,36 +16,31 @@ import javax.inject.Singleton
|
|||||||
class RecipientRepository @Inject constructor(
|
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 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(sdkHelper.init(student))
|
return local.getRecipients(student, role, unit).filter { !forceRefresh }
|
||||||
.flatMap { _ ->
|
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
||||||
local.getRecipients(student, role, unit).filter { !forceRefresh }
|
.flatMap {
|
||||||
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
if (it) remote.getRecipients(student, role, unit)
|
||||||
.flatMap {
|
else Single.error(UnknownHostException())
|
||||||
if (it) remote.getRecipients(role, unit)
|
}.flatMap { new ->
|
||||||
else Single.error(UnknownHostException())
|
local.getRecipients(student, role, unit).toSingle(emptyList())
|
||||||
}.flatMap { new ->
|
.doOnSuccess { old ->
|
||||||
local.getRecipients(student, role, unit).toSingle(emptyList())
|
local.deleteRecipients(old.uniqueSubtract(new))
|
||||||
.doOnSuccess { old ->
|
local.saveRecipients(new.uniqueSubtract(old))
|
||||||
local.deleteRecipients(old.uniqueSubtract(new))
|
|
||||||
local.saveRecipients(new.uniqueSubtract(old))
|
|
||||||
}
|
|
||||||
}.flatMap {
|
|
||||||
local.getRecipients(student, role, unit).toSingle(emptyList())
|
|
||||||
}
|
}
|
||||||
)
|
}.flatMap {
|
||||||
}
|
local.getRecipients(student, role, unit).toSingle(emptyList())
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getMessageRecipients(student: Student, message: Message): Single<List<Recipient>> {
|
fun getMessageRecipients(student: Student, message: Message): Single<List<Recipient>> {
|
||||||
return Single.just(sdkHelper.init(student))
|
return ReactiveNetwork.checkInternetConnectivity(settings)
|
||||||
.flatMap { ReactiveNetwork.checkInternetConnectivity(settings) }
|
|
||||||
.flatMap {
|
.flatMap {
|
||||||
if (it) remote.getMessageRecipients(message)
|
if (it) remote.getMessageRecipients(student, message)
|
||||||
else Single.error(UnknownHostException())
|
else Single.error(UnknownHostException())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
package io.github.wulkanowy.data.repositories.reportingunit
|
package io.github.wulkanowy.data.repositories.reportingunit
|
||||||
|
|
||||||
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.sdk.Sdk
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
|
import io.github.wulkanowy.utils.init
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
@ -9,8 +11,8 @@ import javax.inject.Singleton
|
|||||||
@Singleton
|
@Singleton
|
||||||
class ReportingUnitRemote @Inject constructor(private val sdk: Sdk) {
|
class ReportingUnitRemote @Inject constructor(private val sdk: Sdk) {
|
||||||
|
|
||||||
fun getReportingUnits(): Single<List<ReportingUnit>> {
|
fun getReportingUnits(student: Student): Single<List<ReportingUnit>> {
|
||||||
return sdk.getReportingUnits().map {
|
return sdk.init(student).getReportingUnits().map {
|
||||||
it.map { unit ->
|
it.map { unit ->
|
||||||
ReportingUnit(
|
ReportingUnit(
|
||||||
studentId = sdk.studentId,
|
studentId = sdk.studentId,
|
||||||
|
@ -2,7 +2,6 @@ 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.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
|
||||||
@ -16,41 +15,34 @@ import javax.inject.Singleton
|
|||||||
class ReportingUnitRepository @Inject constructor(
|
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 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(sdkHelper.init(student))
|
return local.getReportingUnits(student).filter { !forceRefresh }
|
||||||
.flatMap { _ ->
|
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
||||||
local.getReportingUnits(student).filter { !forceRefresh }
|
.flatMap {
|
||||||
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
if (it) remote.getReportingUnits(student)
|
||||||
.flatMap {
|
else Single.error(UnknownHostException())
|
||||||
if (it) remote.getReportingUnits()
|
}.flatMap { new ->
|
||||||
else Single.error(UnknownHostException())
|
local.getReportingUnits(student).toSingle(emptyList())
|
||||||
}.flatMap { new ->
|
.doOnSuccess { old ->
|
||||||
local.getReportingUnits(student).toSingle(emptyList())
|
local.deleteReportingUnits(old.uniqueSubtract(new))
|
||||||
.doOnSuccess { old ->
|
local.saveReportingUnits(new.uniqueSubtract(old))
|
||||||
local.deleteReportingUnits(old.uniqueSubtract(new))
|
}
|
||||||
local.saveReportingUnits(new.uniqueSubtract(old))
|
}.flatMap { local.getReportingUnits(student).toSingle(emptyList()) }
|
||||||
}
|
)
|
||||||
}.flatMap { local.getReportingUnits(student).toSingle(emptyList()) }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getReportingUnit(student: Student, unitId: Int): Maybe<ReportingUnit> {
|
fun getReportingUnit(student: Student, unitId: Int): Maybe<ReportingUnit> {
|
||||||
return Maybe.just(sdkHelper.init(student))
|
return local.getReportingUnit(student, unitId)
|
||||||
.flatMap { _ ->
|
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
||||||
local.getReportingUnit(student, unitId)
|
.flatMap {
|
||||||
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
if (it) getReportingUnits(student, true)
|
||||||
.flatMap {
|
else Single.error(UnknownHostException())
|
||||||
if (it) getReportingUnits(student, true)
|
}.flatMapMaybe {
|
||||||
else Single.error(UnknownHostException())
|
local.getReportingUnit(student, unitId)
|
||||||
}.flatMapMaybe {
|
}
|
||||||
local.getReportingUnit(student, unitId)
|
)
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,14 +2,17 @@ package io.github.wulkanowy.data.repositories.school
|
|||||||
|
|
||||||
import io.github.wulkanowy.data.db.entities.School
|
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.sdk.Sdk
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
|
import io.github.wulkanowy.utils.init
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class SchoolRemote @Inject constructor(private val sdk: Sdk) {
|
class SchoolRemote @Inject constructor(private val sdk: Sdk) {
|
||||||
|
|
||||||
fun getSchoolInfo(semester: Semester): Single<School> {
|
fun getSchoolInfo(student: Student, semester: Semester): Single<School> {
|
||||||
return sdk.switchDiary(semester.diaryId, semester.schoolYear).getSchool()
|
return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear)
|
||||||
|
.getSchool()
|
||||||
.map {
|
.map {
|
||||||
School(
|
School(
|
||||||
studentId = semester.studentId,
|
studentId = semester.studentId,
|
||||||
|
@ -4,6 +4,7 @@ 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.db.entities.School
|
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.reactivex.Maybe
|
import io.reactivex.Maybe
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
import java.net.UnknownHostException
|
import java.net.UnknownHostException
|
||||||
@ -17,11 +18,11 @@ class SchoolRepository @Inject constructor(
|
|||||||
private val remote: SchoolRemote
|
private val remote: SchoolRemote
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun getSchoolInfo(semester: Semester, forceRefresh: Boolean = false): Maybe<School> {
|
fun getSchoolInfo(student: Student, semester: Semester, forceRefresh: Boolean = false): Maybe<School> {
|
||||||
return local.getSchool(semester).filter { !forceRefresh }
|
return local.getSchool(semester).filter { !forceRefresh }
|
||||||
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
||||||
.flatMap {
|
.flatMap {
|
||||||
if (it) remote.getSchoolInfo(semester)
|
if (it) remote.getSchoolInfo(student, semester)
|
||||||
else Single.error(UnknownHostException())
|
else Single.error(UnknownHostException())
|
||||||
}.flatMapMaybe { new ->
|
}.flatMapMaybe { new ->
|
||||||
local.getSchool(semester)
|
local.getSchool(semester)
|
||||||
|
@ -3,6 +3,7 @@ package io.github.wulkanowy.data.repositories.semester
|
|||||||
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.github.wulkanowy.sdk.Sdk
|
||||||
|
import io.github.wulkanowy.utils.init
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
@ -11,7 +12,7 @@ import javax.inject.Singleton
|
|||||||
class SemesterRemote @Inject constructor(private val sdk: Sdk) {
|
class SemesterRemote @Inject constructor(private val sdk: Sdk) {
|
||||||
|
|
||||||
fun getSemesters(student: Student): Single<List<Semester>> {
|
fun getSemesters(student: Student): Single<List<Semester>> {
|
||||||
return sdk.getSemesters().map { semesters ->
|
return sdk.init(student).getSemesters().map { semesters ->
|
||||||
semesters.map {
|
semesters.map {
|
||||||
Semester(
|
Semester(
|
||||||
studentId = student.studentId,
|
studentId = student.studentId,
|
||||||
|
@ -2,13 +2,12 @@ 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.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.sdk.Sdk
|
||||||
import io.github.wulkanowy.utils.getCurrentOrLast
|
import io.github.wulkanowy.utils.getCurrentOrLast
|
||||||
import io.github.wulkanowy.utils.isCurrent
|
import io.github.wulkanowy.utils.isCurrent
|
||||||
import io.github.wulkanowy.utils.uniqueSubtract
|
import io.github.wulkanowy.utils.uniqueSubtract
|
||||||
import io.reactivex.Maybe
|
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
import java.net.UnknownHostException
|
import java.net.UnknownHostException
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@ -18,31 +17,28 @@ import javax.inject.Singleton
|
|||||||
class SemesterRepository @Inject constructor(
|
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 sdkHelper: SdkHelper
|
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun getSemesters(student: Student, forceRefresh: Boolean = false, refreshOnNoCurrent: Boolean = false): Single<List<Semester>> {
|
fun getSemesters(student: Student, forceRefresh: Boolean = false, refreshOnNoCurrent: Boolean = false): Single<List<Semester>> {
|
||||||
return Maybe.just(sdkHelper.init(student))
|
return local.getSemesters(student).filter { !forceRefresh }.filter { semesters ->
|
||||||
.flatMap {
|
when {
|
||||||
local.getSemesters(student).filter { !forceRefresh }.filter {
|
Sdk.Mode.valueOf(student.loginMode) != Sdk.Mode.API -> semesters.firstOrNull { it.isCurrent }?.diaryId != 0
|
||||||
if (refreshOnNoCurrent) {
|
refreshOnNoCurrent -> semesters.any { semester -> semester.isCurrent }
|
||||||
it.any { semester -> semester.isCurrent }
|
else -> true
|
||||||
} else true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
}.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
||||||
.flatMap {
|
.flatMap {
|
||||||
if (it) remote.getSemesters(student)
|
if (it) remote.getSemesters(student)
|
||||||
else Single.error(UnknownHostException())
|
else Single.error(UnknownHostException())
|
||||||
}.flatMap { new ->
|
}.flatMap { new ->
|
||||||
if (new.isEmpty()) throw IllegalArgumentException("Empty semester list!")
|
if (new.isEmpty()) throw IllegalArgumentException("Empty semester list!")
|
||||||
|
|
||||||
local.getSemesters(student).toSingle(emptyList()).doOnSuccess { old ->
|
local.getSemesters(student).toSingle(emptyList()).doOnSuccess { old ->
|
||||||
local.deleteSemesters(old.uniqueSubtract(new))
|
local.deleteSemesters(old.uniqueSubtract(new))
|
||||||
local.saveSemesters(new.uniqueSubtract(old))
|
local.saveSemesters(new.uniqueSubtract(old))
|
||||||
}
|
}
|
||||||
}.flatMap { local.getSemesters(student).toSingle(emptyList()) })
|
}.flatMap { local.getSemesters(student).toSingle(emptyList()) })
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getCurrentSemester(student: Student, forceRefresh: Boolean = false): Single<Semester> {
|
fun getCurrentSemester(student: Student, forceRefresh: Boolean = false): Single<Semester> {
|
||||||
|
@ -29,10 +29,18 @@ class StudentLocal @Inject constructor(
|
|||||||
|
|
||||||
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 && Sdk.Mode.valueOf(loginMode) != Sdk.Mode.API) password = decrypt(password) } } }
|
||||||
.filter { it.isNotEmpty() }
|
.filter { it.isNotEmpty() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getStudentById(id: Int): Maybe<Student> {
|
||||||
|
return studentDb.loadById(id).map {
|
||||||
|
it.apply {
|
||||||
|
if (Sdk.Mode.valueOf(loginMode) != Sdk.Mode.API) password = decrypt(password)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun getCurrentStudent(decryptPass: Boolean): Maybe<Student> {
|
fun getCurrentStudent(decryptPass: Boolean): Maybe<Student> {
|
||||||
return studentDb.loadCurrent().map {
|
return studentDb.loadCurrent().map {
|
||||||
it.apply {
|
it.apply {
|
||||||
|
@ -39,7 +39,7 @@ class StudentRemote @Inject constructor(private val sdk: Sdk) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getStudentsMobileApi(token: String, pin: String, symbol: String): Single<List<Student>> {
|
fun getStudentsMobileApi(token: String, pin: String, symbol: String): Single<List<Student>> {
|
||||||
return sdk.getStudentsFromMobileApi(token, pin, symbol).map { mapStudents(it, "", "") }
|
return sdk.getStudentsFromMobileApi(token, pin, symbol, "").map { mapStudents(it, "", "") }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getStudentsScrapper(email: String, password: String, scrapperBaseUrl: String, symbol: String): Single<List<Student>> {
|
fun getStudentsScrapper(email: String, password: String, scrapperBaseUrl: String, symbol: String): Single<List<Student>> {
|
||||||
@ -47,6 +47,6 @@ class StudentRemote @Inject constructor(private val sdk: Sdk) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getStudentsHybrid(email: String, password: String, scrapperBaseUrl: String, symbol: String): Single<List<Student>> {
|
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) }
|
return sdk.getStudentsHybrid(email, password, scrapperBaseUrl, "", symbol).map { mapStudents(it, email, password) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,12 @@ class StudentRepository @Inject constructor(
|
|||||||
return local.getStudents(decryptPass).toSingle(emptyList())
|
return local.getStudents(decryptPass).toSingle(emptyList())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getStudentById(id: Int): Single<Student> {
|
||||||
|
return local.getStudentById(id)
|
||||||
|
.switchIfEmpty(Maybe.error(NoCurrentStudentException()))
|
||||||
|
.toSingle()
|
||||||
|
}
|
||||||
|
|
||||||
fun getCurrentStudent(decryptPass: Boolean = true): Single<Student> {
|
fun getCurrentStudent(decryptPass: Boolean = true): Single<Student> {
|
||||||
return local.getCurrentStudent(decryptPass)
|
return local.getCurrentStudent(decryptPass)
|
||||||
.switchIfEmpty(Maybe.error(NoCurrentStudentException()))
|
.switchIfEmpty(Maybe.error(NoCurrentStudentException()))
|
||||||
|
@ -12,7 +12,7 @@ class SubjectLocal @Inject constructor(private val subjectDao: SubjectDao) {
|
|||||||
|
|
||||||
fun getSubjects(semester: Semester): Maybe<List<Subject>> {
|
fun getSubjects(semester: Semester): Maybe<List<Subject>> {
|
||||||
return subjectDao.loadAll(semester.diaryId, semester.studentId)
|
return subjectDao.loadAll(semester.diaryId, semester.studentId)
|
||||||
.filter { !it.isEmpty() }
|
.filter { it.isNotEmpty() }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun saveSubjects(subjects: List<Subject>) {
|
fun saveSubjects(subjects: List<Subject>) {
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
package io.github.wulkanowy.data.repositories.subject
|
package io.github.wulkanowy.data.repositories.subject
|
||||||
|
|
||||||
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.Subject
|
import io.github.wulkanowy.data.db.entities.Subject
|
||||||
import io.github.wulkanowy.sdk.Sdk
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
|
import io.github.wulkanowy.utils.init
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
@ -10,8 +12,9 @@ import javax.inject.Singleton
|
|||||||
@Singleton
|
@Singleton
|
||||||
class SubjectRemote @Inject constructor(private val sdk: Sdk) {
|
class SubjectRemote @Inject constructor(private val sdk: Sdk) {
|
||||||
|
|
||||||
fun getSubjects(semester: Semester): Single<List<Subject>> {
|
fun getSubjects(student: Student, semester: Semester): Single<List<Subject>> {
|
||||||
return sdk.switchDiary(semester.diaryId, semester.schoolYear).getSubjects()
|
return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear)
|
||||||
|
.getSubjects()
|
||||||
.map { subjects ->
|
.map { subjects ->
|
||||||
subjects.map {
|
subjects.map {
|
||||||
Subject(
|
Subject(
|
||||||
|
@ -3,6 +3,7 @@ package io.github.wulkanowy.data.repositories.subject
|
|||||||
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.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.Subject
|
import io.github.wulkanowy.data.db.entities.Subject
|
||||||
import io.github.wulkanowy.utils.uniqueSubtract
|
import io.github.wulkanowy.utils.uniqueSubtract
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
@ -17,11 +18,11 @@ class SubjectRepository @Inject constructor(
|
|||||||
private val remote: SubjectRemote
|
private val remote: SubjectRemote
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun getSubjects(semester: Semester, forceRefresh: Boolean = false): Single<List<Subject>> {
|
fun getSubjects(student: Student, semester: Semester, forceRefresh: Boolean = false): Single<List<Subject>> {
|
||||||
return local.getSubjects(semester).filter { !forceRefresh }
|
return local.getSubjects(semester).filter { !forceRefresh }
|
||||||
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
||||||
.flatMap {
|
.flatMap {
|
||||||
if (it) remote.getSubjects(semester)
|
if (it) remote.getSubjects(student, semester)
|
||||||
else Single.error(UnknownHostException())
|
else Single.error(UnknownHostException())
|
||||||
}.flatMap { new ->
|
}.flatMap { new ->
|
||||||
local.getSubjects(semester)
|
local.getSubjects(semester)
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
package io.github.wulkanowy.data.repositories.teacher
|
package io.github.wulkanowy.data.repositories.teacher
|
||||||
|
|
||||||
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.Teacher
|
import io.github.wulkanowy.data.db.entities.Teacher
|
||||||
import io.github.wulkanowy.sdk.Sdk
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
|
import io.github.wulkanowy.utils.init
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
@ -10,8 +12,9 @@ import javax.inject.Singleton
|
|||||||
@Singleton
|
@Singleton
|
||||||
class TeacherRemote @Inject constructor(private val sdk: Sdk) {
|
class TeacherRemote @Inject constructor(private val sdk: Sdk) {
|
||||||
|
|
||||||
fun getTeachers(semester: Semester): Single<List<Teacher>> {
|
fun getTeachers(student: Student, semester: Semester): Single<List<Teacher>> {
|
||||||
return sdk.switchDiary(semester.diaryId, semester.schoolYear).getTeachers(semester.semesterId)
|
return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear)
|
||||||
|
.getTeachers(semester.semesterId)
|
||||||
.map { teachers ->
|
.map { teachers ->
|
||||||
teachers.map {
|
teachers.map {
|
||||||
Teacher(
|
Teacher(
|
||||||
|
@ -3,6 +3,7 @@ package io.github.wulkanowy.data.repositories.teacher
|
|||||||
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.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.Teacher
|
import io.github.wulkanowy.data.db.entities.Teacher
|
||||||
import io.github.wulkanowy.utils.uniqueSubtract
|
import io.github.wulkanowy.utils.uniqueSubtract
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
@ -17,11 +18,11 @@ class TeacherRepository @Inject constructor(
|
|||||||
private val remote: TeacherRemote
|
private val remote: TeacherRemote
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun getTeachers(semester: Semester, forceRefresh: Boolean = false): Single<List<Teacher>> {
|
fun getTeachers(student: Student, 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)
|
||||||
.flatMap {
|
.flatMap {
|
||||||
if (it) remote.getTeachers(semester)
|
if (it) remote.getTeachers(student, semester)
|
||||||
else Single.error(UnknownHostException())
|
else Single.error(UnknownHostException())
|
||||||
}.flatMap { new ->
|
}.flatMap { new ->
|
||||||
local.getTeachers(semester).toSingle(emptyList())
|
local.getTeachers(semester).toSingle(emptyList())
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
package io.github.wulkanowy.data.repositories.timetable
|
package io.github.wulkanowy.data.repositories.timetable
|
||||||
|
|
||||||
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.Timetable
|
import io.github.wulkanowy.data.db.entities.Timetable
|
||||||
import io.github.wulkanowy.sdk.Sdk
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
|
import io.github.wulkanowy.utils.init
|
||||||
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
|
||||||
@ -11,8 +13,9 @@ import javax.inject.Singleton
|
|||||||
@Singleton
|
@Singleton
|
||||||
class TimetableRemote @Inject constructor(private val sdk: Sdk) {
|
class TimetableRemote @Inject constructor(private val sdk: Sdk) {
|
||||||
|
|
||||||
fun getTimetable(semester: Semester, startDate: LocalDate, endDate: LocalDate): Single<List<Timetable>> {
|
fun getTimetable(student: Student, semester: Semester, startDate: LocalDate, endDate: LocalDate): Single<List<Timetable>> {
|
||||||
return sdk.switchDiary(semester.diaryId, semester.schoolYear).getTimetable(startDate, endDate)
|
return sdk.init(student).switchDiary(semester.diaryId, semester.schoolYear)
|
||||||
|
.getTimetable(startDate, endDate)
|
||||||
.map { lessons ->
|
.map { lessons ->
|
||||||
lessons.map {
|
lessons.map {
|
||||||
Timetable(
|
Timetable(
|
||||||
|
@ -3,8 +3,10 @@ package io.github.wulkanowy.data.repositories.timetable
|
|||||||
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.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.Timetable
|
import io.github.wulkanowy.data.db.entities.Timetable
|
||||||
import io.github.wulkanowy.utils.friday
|
import io.github.wulkanowy.services.alarm.TimetableNotificationSchedulerHelper
|
||||||
|
import io.github.wulkanowy.utils.sunday
|
||||||
import io.github.wulkanowy.utils.monday
|
import io.github.wulkanowy.utils.monday
|
||||||
import io.github.wulkanowy.utils.uniqueSubtract
|
import io.github.wulkanowy.utils.uniqueSubtract
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
@ -17,21 +19,22 @@ import javax.inject.Singleton
|
|||||||
class TimetableRepository @Inject constructor(
|
class TimetableRepository @Inject constructor(
|
||||||
private val settings: InternetObservingSettings,
|
private val settings: InternetObservingSettings,
|
||||||
private val local: TimetableLocal,
|
private val local: TimetableLocal,
|
||||||
private val remote: TimetableRemote
|
private val remote: TimetableRemote,
|
||||||
|
private val schedulerHelper: TimetableNotificationSchedulerHelper
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun getTimetable(semester: Semester, start: LocalDate, end: LocalDate, forceRefresh: Boolean = false): Single<List<Timetable>> {
|
fun getTimetable(student: Student, semester: Semester, start: LocalDate, end: LocalDate, forceRefresh: Boolean = false): Single<List<Timetable>> {
|
||||||
return Single.fromCallable { start.monday to end.friday }.flatMap { (monday, friday) ->
|
return Single.fromCallable { start.monday to end.sunday }.flatMap { (monday, sunday) ->
|
||||||
local.getTimetable(semester, monday, friday).filter { !forceRefresh }
|
local.getTimetable(semester, monday, sunday).filter { !forceRefresh }
|
||||||
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings).flatMap {
|
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings).flatMap {
|
||||||
if (it) remote.getTimetable(semester, monday, friday)
|
if (it) remote.getTimetable(student, semester, monday, sunday)
|
||||||
else Single.error(UnknownHostException())
|
else Single.error(UnknownHostException())
|
||||||
}.flatMap { new ->
|
}.flatMap { new ->
|
||||||
local.getTimetable(semester, monday, friday)
|
local.getTimetable(semester, monday, sunday)
|
||||||
.toSingle(emptyList())
|
.toSingle(emptyList())
|
||||||
.doOnSuccess { old ->
|
.doOnSuccess { old ->
|
||||||
local.deleteTimetable(old.uniqueSubtract(new))
|
local.deleteTimetable(old.uniqueSubtract(new).also { schedulerHelper.cancelScheduled(it) })
|
||||||
local.saveTimetable(new.uniqueSubtract(old).map { item ->
|
local.saveTimetable(new.uniqueSubtract(old).also { schedulerHelper.scheduleNotifications(it, student) }.map { item ->
|
||||||
item.also { new ->
|
item.also { new ->
|
||||||
old.singleOrNull { new.start == it.start }?.let { old ->
|
old.singleOrNull { new.start == it.start }?.let { old ->
|
||||||
return@map new.copy(
|
return@map new.copy(
|
||||||
@ -43,8 +46,8 @@ class TimetableRepository @Inject constructor(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}.flatMap {
|
}.flatMap {
|
||||||
local.getTimetable(semester, monday, friday).toSingle(emptyList())
|
local.getTimetable(semester, monday, sunday).toSingle(emptyList())
|
||||||
}).map { list -> list.filter { it.date in start..end } }
|
}).map { list -> list.filter { it.date in start..end }.also { schedulerHelper.scheduleNotifications(it, student) } }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,6 @@ import android.content.Context
|
|||||||
import com.yariksoffice.lingver.Lingver
|
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.items.AbstractFlexibleItem
|
|
||||||
import io.github.wulkanowy.WulkanowyApp
|
import io.github.wulkanowy.WulkanowyApp
|
||||||
import io.github.wulkanowy.utils.AppInfo
|
import io.github.wulkanowy.utils.AppInfo
|
||||||
import io.github.wulkanowy.utils.SchedulersProvider
|
import io.github.wulkanowy.utils.SchedulersProvider
|
||||||
@ -23,9 +21,6 @@ internal class AppModule {
|
|||||||
@Provides
|
@Provides
|
||||||
fun provideSchedulersProvider() = SchedulersProvider()
|
fun provideSchedulersProvider() = SchedulersProvider()
|
||||||
|
|
||||||
@Provides
|
|
||||||
fun provideFlexibleAdapter() = FlexibleAdapter<AbstractFlexibleItem<*>>(null, null, true)
|
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
@Provides
|
@Provides
|
||||||
fun provideAppWidgetManager(context: Context): AppWidgetManager = AppWidgetManager.getInstance(context)
|
fun provideAppWidgetManager(context: Context): AppWidgetManager = AppWidgetManager.getInstance(context)
|
||||||
|
@ -3,6 +3,8 @@ package io.github.wulkanowy.di
|
|||||||
import dagger.Module
|
import dagger.Module
|
||||||
import dagger.android.ContributesAndroidInjector
|
import dagger.android.ContributesAndroidInjector
|
||||||
import io.github.wulkanowy.di.scopes.PerActivity
|
import io.github.wulkanowy.di.scopes.PerActivity
|
||||||
|
import io.github.wulkanowy.ui.base.ErrorDialog
|
||||||
|
import io.github.wulkanowy.services.alarm.TimetableNotificationReceiver
|
||||||
import io.github.wulkanowy.ui.modules.login.LoginActivity
|
import io.github.wulkanowy.ui.modules.login.LoginActivity
|
||||||
import io.github.wulkanowy.ui.modules.login.LoginModule
|
import io.github.wulkanowy.ui.modules.login.LoginModule
|
||||||
import io.github.wulkanowy.ui.modules.luckynumberwidget.LuckyNumberWidgetConfigureActivity
|
import io.github.wulkanowy.ui.modules.luckynumberwidget.LuckyNumberWidgetConfigureActivity
|
||||||
@ -18,6 +20,9 @@ import io.github.wulkanowy.ui.modules.timetablewidget.TimetableWidgetProvider
|
|||||||
@Module
|
@Module
|
||||||
internal abstract class BindingModule {
|
internal abstract class BindingModule {
|
||||||
|
|
||||||
|
@ContributesAndroidInjector
|
||||||
|
abstract fun bindErrorDialog(): ErrorDialog
|
||||||
|
|
||||||
@PerActivity
|
@PerActivity
|
||||||
@ContributesAndroidInjector
|
@ContributesAndroidInjector
|
||||||
abstract fun bindSplashActivity(): SplashActivity
|
abstract fun bindSplashActivity(): SplashActivity
|
||||||
@ -44,4 +49,7 @@ internal abstract class BindingModule {
|
|||||||
|
|
||||||
@ContributesAndroidInjector
|
@ContributesAndroidInjector
|
||||||
abstract fun bindLuckyNumberWidgetProvider(): LuckyNumberWidgetProvider
|
abstract fun bindLuckyNumberWidgetProvider(): LuckyNumberWidgetProvider
|
||||||
|
|
||||||
|
@ContributesAndroidInjector
|
||||||
|
abstract fun bindTimetableNotificationReceiver(): TimetableNotificationReceiver
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
package io.github.wulkanowy.services
|
package io.github.wulkanowy.services
|
||||||
|
|
||||||
|
import android.app.AlarmManager
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.core.app.NotificationManagerCompat
|
import androidx.core.app.NotificationManagerCompat
|
||||||
|
import androidx.core.content.getSystemService
|
||||||
import androidx.work.WorkManager
|
import androidx.work.WorkManager
|
||||||
import com.squareup.inject.assisted.dagger2.AssistedModule
|
import com.squareup.inject.assisted.dagger2.AssistedModule
|
||||||
import dagger.Binds
|
import dagger.Binds
|
||||||
@ -15,13 +17,13 @@ import io.github.wulkanowy.services.sync.channels.LuckyNumberChannel
|
|||||||
import io.github.wulkanowy.services.sync.channels.NewGradesChannel
|
import io.github.wulkanowy.services.sync.channels.NewGradesChannel
|
||||||
import io.github.wulkanowy.services.sync.channels.NewMessagesChannel
|
import io.github.wulkanowy.services.sync.channels.NewMessagesChannel
|
||||||
import io.github.wulkanowy.services.sync.channels.NewNotesChannel
|
import io.github.wulkanowy.services.sync.channels.NewNotesChannel
|
||||||
|
import io.github.wulkanowy.services.sync.channels.UpcomingLessonsChannel
|
||||||
import io.github.wulkanowy.services.sync.channels.PushChannel
|
import io.github.wulkanowy.services.sync.channels.PushChannel
|
||||||
import io.github.wulkanowy.services.sync.works.AttendanceSummaryWork
|
import io.github.wulkanowy.services.sync.works.AttendanceSummaryWork
|
||||||
import io.github.wulkanowy.services.sync.works.AttendanceWork
|
import io.github.wulkanowy.services.sync.works.AttendanceWork
|
||||||
import io.github.wulkanowy.services.sync.works.CompletedLessonWork
|
import io.github.wulkanowy.services.sync.works.CompletedLessonWork
|
||||||
import io.github.wulkanowy.services.sync.works.ExamWork
|
import io.github.wulkanowy.services.sync.works.ExamWork
|
||||||
import io.github.wulkanowy.services.sync.works.GradeStatisticsWork
|
import io.github.wulkanowy.services.sync.works.GradeStatisticsWork
|
||||||
import io.github.wulkanowy.services.sync.works.GradeSummaryWork
|
|
||||||
import io.github.wulkanowy.services.sync.works.GradeWork
|
import io.github.wulkanowy.services.sync.works.GradeWork
|
||||||
import io.github.wulkanowy.services.sync.works.HomeworkWork
|
import io.github.wulkanowy.services.sync.works.HomeworkWork
|
||||||
import io.github.wulkanowy.services.sync.works.LuckyNumberWork
|
import io.github.wulkanowy.services.sync.works.LuckyNumberWork
|
||||||
@ -47,6 +49,10 @@ abstract class ServicesModule {
|
|||||||
@Singleton
|
@Singleton
|
||||||
@Provides
|
@Provides
|
||||||
fun provideNotificationManager(context: Context) = NotificationManagerCompat.from(context)
|
fun provideNotificationManager(context: Context) = NotificationManagerCompat.from(context)
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
@Provides
|
||||||
|
fun provideAlarmManager(context: Context): AlarmManager = context.getSystemService()!!
|
||||||
}
|
}
|
||||||
|
|
||||||
@ContributesAndroidInjector
|
@ContributesAndroidInjector
|
||||||
@ -64,10 +70,6 @@ abstract class ServicesModule {
|
|||||||
@IntoSet
|
@IntoSet
|
||||||
abstract fun provideAttendanceWork(work: AttendanceWork): Work
|
abstract fun provideAttendanceWork(work: AttendanceWork): Work
|
||||||
|
|
||||||
@Binds
|
|
||||||
@IntoSet
|
|
||||||
abstract fun provideGradeSummaryWork(work: GradeSummaryWork): Work
|
|
||||||
|
|
||||||
@Binds
|
@Binds
|
||||||
@IntoSet
|
@IntoSet
|
||||||
abstract fun provideExamWork(work: ExamWork): Work
|
abstract fun provideExamWork(work: ExamWork): Work
|
||||||
@ -131,4 +133,8 @@ abstract class ServicesModule {
|
|||||||
@Binds
|
@Binds
|
||||||
@IntoSet
|
@IntoSet
|
||||||
abstract fun providePushChannel(channel: PushChannel): Channel
|
abstract fun providePushChannel(channel: PushChannel): Channel
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@IntoSet
|
||||||
|
abstract fun provideUpcomingLessonsChannel(channel: UpcomingLessonsChannel): Channel
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,117 @@
|
|||||||
|
package io.github.wulkanowy.services.alarm
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.app.PendingIntent
|
||||||
|
import android.app.PendingIntent.FLAG_UPDATE_CURRENT
|
||||||
|
import android.content.BroadcastReceiver
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Build
|
||||||
|
import android.os.Build.VERSION_CODES.N
|
||||||
|
import androidx.core.app.NotificationCompat
|
||||||
|
import androidx.core.app.NotificationManagerCompat
|
||||||
|
import dagger.android.AndroidInjection
|
||||||
|
import io.github.wulkanowy.R
|
||||||
|
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
||||||
|
import io.github.wulkanowy.services.sync.channels.UpcomingLessonsChannel.Companion.CHANNEL_ID
|
||||||
|
import io.github.wulkanowy.ui.modules.main.MainActivity
|
||||||
|
import io.github.wulkanowy.ui.modules.main.MainView
|
||||||
|
import io.github.wulkanowy.utils.SchedulersProvider
|
||||||
|
import io.github.wulkanowy.utils.getCompatColor
|
||||||
|
import io.github.wulkanowy.utils.toLocalDateTime
|
||||||
|
import timber.log.Timber
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class TimetableNotificationReceiver : BroadcastReceiver() {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var studentRepository: StudentRepository
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var schedulers: SchedulersProvider
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val NOTIFICATION_TYPE_CURRENT = 1
|
||||||
|
const val NOTIFICATION_TYPE_UPCOMING = 2
|
||||||
|
const val NOTIFICATION_TYPE_LAST_LESSON_CANCELLATION = 3
|
||||||
|
|
||||||
|
const val NOTIFICATION_ID = "id"
|
||||||
|
|
||||||
|
const val STUDENT_NAME = "student_name"
|
||||||
|
const val STUDENT_ID = "student_id"
|
||||||
|
const val LESSON_TYPE = "type"
|
||||||
|
const val LESSON_TITLE = "title"
|
||||||
|
const val LESSON_ROOM = "room"
|
||||||
|
const val LESSON_NEXT_TITLE = "next_title"
|
||||||
|
const val LESSON_NEXT_ROOM = "next_room"
|
||||||
|
const val LESSON_START = "start_timestamp"
|
||||||
|
const val LESSON_END = "end_timestamp"
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("CheckResult")
|
||||||
|
override fun onReceive(context: Context, intent: Intent) {
|
||||||
|
Timber.d("Receiving intent... ${intent.toUri(0)}")
|
||||||
|
AndroidInjection.inject(this, context)
|
||||||
|
|
||||||
|
studentRepository.getCurrentStudent(false)
|
||||||
|
.subscribeOn(schedulers.backgroundThread)
|
||||||
|
.observeOn(schedulers.mainThread)
|
||||||
|
.subscribe({
|
||||||
|
val studentId = intent.getIntExtra(STUDENT_ID, 0)
|
||||||
|
if (it.studentId == studentId) prepareNotification(context, intent)
|
||||||
|
else Timber.d("Notification studentId($studentId) differs from current(${it.studentId})")
|
||||||
|
}, { Timber.e(it) })
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun prepareNotification(context: Context, intent: Intent) {
|
||||||
|
val type = intent.getIntExtra(LESSON_TYPE, 0)
|
||||||
|
val notificationId = intent.getIntExtra(NOTIFICATION_ID, MainView.Section.TIMETABLE.id)
|
||||||
|
|
||||||
|
if (type == NOTIFICATION_TYPE_LAST_LESSON_CANCELLATION) {
|
||||||
|
return NotificationManagerCompat.from(context).cancel(notificationId)
|
||||||
|
}
|
||||||
|
|
||||||
|
val studentId = intent.getIntExtra(STUDENT_ID, 0)
|
||||||
|
val studentName = intent.getStringExtra(STUDENT_NAME)
|
||||||
|
|
||||||
|
val subject = intent.getStringExtra(LESSON_TITLE)
|
||||||
|
val room = intent.getStringExtra(LESSON_ROOM)
|
||||||
|
|
||||||
|
val start = intent.getLongExtra(LESSON_START, 0)
|
||||||
|
val end = intent.getLongExtra(LESSON_END, 0)
|
||||||
|
|
||||||
|
val nextSubject = intent.getStringExtra(LESSON_NEXT_TITLE)
|
||||||
|
val nextRoom = intent.getStringExtra(LESSON_NEXT_ROOM)
|
||||||
|
|
||||||
|
Timber.d("TimetableNotification receive: type: $type, subject: $subject, start: ${start.toLocalDateTime()}, student: $studentId")
|
||||||
|
|
||||||
|
showNotification(context, notificationId, studentName,
|
||||||
|
if (type == NOTIFICATION_TYPE_CURRENT) end else start, end - start,
|
||||||
|
context.getString(if (type == NOTIFICATION_TYPE_CURRENT) R.string.timetable_now else R.string.timetable_next, "($room) $subject".removePrefix("()")),
|
||||||
|
nextSubject?.let { context.getString(R.string.timetable_later, "($nextRoom) $nextSubject".removePrefix("()")) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showNotification(context: Context, notificationId: Int, studentName: String?, countDown: Long, timeout: Long, title: String, next: String?) {
|
||||||
|
NotificationManagerCompat.from(context).notify(notificationId, NotificationCompat.Builder(context, CHANNEL_ID)
|
||||||
|
.setContentTitle(title)
|
||||||
|
.setContentText(next)
|
||||||
|
.setAutoCancel(false)
|
||||||
|
.setOngoing(true)
|
||||||
|
.setWhen(countDown)
|
||||||
|
.apply {
|
||||||
|
if (Build.VERSION.SDK_INT >= N) setUsesChronometer(true)
|
||||||
|
}
|
||||||
|
.setTimeoutAfter(timeout)
|
||||||
|
.setSmallIcon(R.drawable.ic_stat_timetable)
|
||||||
|
.setColor(context.getCompatColor(R.color.colorPrimary))
|
||||||
|
.setStyle(NotificationCompat.InboxStyle().also {
|
||||||
|
it.setSummaryText(studentName)
|
||||||
|
it.addLine(next)
|
||||||
|
})
|
||||||
|
.setContentIntent(PendingIntent.getActivity(context, MainView.Section.TIMETABLE.id,
|
||||||
|
MainActivity.getStartIntent(context, MainView.Section.TIMETABLE, true), FLAG_UPDATE_CURRENT))
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,109 @@
|
|||||||
|
package io.github.wulkanowy.services.alarm
|
||||||
|
|
||||||
|
import android.app.AlarmManager
|
||||||
|
import android.app.AlarmManager.RTC_WAKEUP
|
||||||
|
import android.app.PendingIntent
|
||||||
|
import android.app.PendingIntent.FLAG_UPDATE_CURRENT
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import androidx.core.app.AlarmManagerCompat
|
||||||
|
import androidx.core.app.NotificationManagerCompat
|
||||||
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
|
import io.github.wulkanowy.data.db.entities.Timetable
|
||||||
|
import io.github.wulkanowy.data.repositories.preferences.PreferencesRepository
|
||||||
|
import io.github.wulkanowy.services.alarm.TimetableNotificationReceiver.Companion.LESSON_END
|
||||||
|
import io.github.wulkanowy.services.alarm.TimetableNotificationReceiver.Companion.LESSON_NEXT_ROOM
|
||||||
|
import io.github.wulkanowy.services.alarm.TimetableNotificationReceiver.Companion.LESSON_NEXT_TITLE
|
||||||
|
import io.github.wulkanowy.services.alarm.TimetableNotificationReceiver.Companion.LESSON_ROOM
|
||||||
|
import io.github.wulkanowy.services.alarm.TimetableNotificationReceiver.Companion.LESSON_START
|
||||||
|
import io.github.wulkanowy.services.alarm.TimetableNotificationReceiver.Companion.LESSON_TITLE
|
||||||
|
import io.github.wulkanowy.services.alarm.TimetableNotificationReceiver.Companion.LESSON_TYPE
|
||||||
|
import io.github.wulkanowy.services.alarm.TimetableNotificationReceiver.Companion.NOTIFICATION_ID
|
||||||
|
import io.github.wulkanowy.services.alarm.TimetableNotificationReceiver.Companion.NOTIFICATION_TYPE_CURRENT
|
||||||
|
import io.github.wulkanowy.services.alarm.TimetableNotificationReceiver.Companion.NOTIFICATION_TYPE_LAST_LESSON_CANCELLATION
|
||||||
|
import io.github.wulkanowy.services.alarm.TimetableNotificationReceiver.Companion.NOTIFICATION_TYPE_UPCOMING
|
||||||
|
import io.github.wulkanowy.services.alarm.TimetableNotificationReceiver.Companion.STUDENT_ID
|
||||||
|
import io.github.wulkanowy.services.alarm.TimetableNotificationReceiver.Companion.STUDENT_NAME
|
||||||
|
import io.github.wulkanowy.ui.modules.main.MainView
|
||||||
|
import io.github.wulkanowy.utils.toTimestamp
|
||||||
|
import org.threeten.bp.LocalDateTime
|
||||||
|
import org.threeten.bp.LocalDateTime.now
|
||||||
|
import timber.log.Timber
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class TimetableNotificationSchedulerHelper @Inject constructor(
|
||||||
|
private val context: Context,
|
||||||
|
private val alarmManager: AlarmManager,
|
||||||
|
private val preferencesRepository: PreferencesRepository
|
||||||
|
) {
|
||||||
|
|
||||||
|
private fun getRequestCode(time: LocalDateTime, studentId: Int) = (time.toTimestamp() * studentId).toInt()
|
||||||
|
|
||||||
|
private fun getUpcomingLessonTime(index: Int, day: List<Timetable>, lesson: Timetable): LocalDateTime {
|
||||||
|
return day.getOrNull(index - 1)?.end ?: lesson.start.minusMinutes(30)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun cancelScheduled(lessons: List<Timetable>, studentId: Int = 1) {
|
||||||
|
lessons.sortedBy { it.start }.forEachIndexed { index, lesson ->
|
||||||
|
val upcomingTime = getUpcomingLessonTime(index, lessons, lesson)
|
||||||
|
cancelScheduledTo(upcomingTime..lesson.start, getRequestCode(upcomingTime, studentId))
|
||||||
|
cancelScheduledTo(lesson.start..lesson.end, getRequestCode(lesson.start, studentId))
|
||||||
|
|
||||||
|
Timber.d("TimetableNotification canceled: type 1 & 2, subject: ${lesson.subject}, start: ${lesson.start}, student: $studentId")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun cancelScheduledTo(range: ClosedRange<LocalDateTime>, requestCode: Int) {
|
||||||
|
if (now() in range) cancelNotification()
|
||||||
|
alarmManager.cancel(PendingIntent.getBroadcast(context, requestCode, Intent(), FLAG_UPDATE_CURRENT))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun cancelNotification() = NotificationManagerCompat.from(context).cancel(MainView.Section.TIMETABLE.id)
|
||||||
|
|
||||||
|
fun scheduleNotifications(lessons: List<Timetable>, student: Student) {
|
||||||
|
if (!preferencesRepository.isUpcomingLessonsNotificationsEnable) return cancelScheduled(lessons, student.studentId)
|
||||||
|
|
||||||
|
lessons.groupBy { it.date }
|
||||||
|
.map { it.value.sortedBy { lesson -> lesson.start } }
|
||||||
|
.map { it.filter { lesson -> !lesson.canceled && lesson.isStudentPlan } }
|
||||||
|
.map { day ->
|
||||||
|
day.forEachIndexed { index, lesson ->
|
||||||
|
val intent = createIntent(student, lesson, day.getOrNull(index + 1))
|
||||||
|
|
||||||
|
if (lesson.start > now()) {
|
||||||
|
scheduleBroadcast(intent, student.studentId, NOTIFICATION_TYPE_UPCOMING, getUpcomingLessonTime(index, day, lesson))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lesson.end > now()) {
|
||||||
|
scheduleBroadcast(intent, student.studentId, NOTIFICATION_TYPE_CURRENT, lesson.start)
|
||||||
|
if (day.lastIndex == index) {
|
||||||
|
scheduleBroadcast(intent, student.studentId, NOTIFICATION_TYPE_LAST_LESSON_CANCELLATION, lesson.end)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createIntent(student: Student, lesson: Timetable, nextLesson: Timetable?): Intent {
|
||||||
|
return Intent(context, TimetableNotificationReceiver::class.java).apply {
|
||||||
|
putExtra(STUDENT_ID, student.studentId)
|
||||||
|
putExtra(STUDENT_NAME, student.studentName)
|
||||||
|
putExtra(LESSON_ROOM, lesson.room)
|
||||||
|
putExtra(LESSON_START, lesson.start.toTimestamp())
|
||||||
|
putExtra(LESSON_END, lesson.end.toTimestamp())
|
||||||
|
putExtra(LESSON_TITLE, lesson.subject)
|
||||||
|
putExtra(LESSON_NEXT_TITLE, nextLesson?.subject)
|
||||||
|
putExtra(LESSON_NEXT_ROOM, nextLesson?.room)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun scheduleBroadcast(intent: Intent, studentId: Int, notificationType: Int, time: LocalDateTime) {
|
||||||
|
AlarmManagerCompat.setExactAndAllowWhileIdle(alarmManager, RTC_WAKEUP, time.toTimestamp(),
|
||||||
|
PendingIntent.getBroadcast(context, getRequestCode(time, studentId), intent.also {
|
||||||
|
it.putExtra(NOTIFICATION_ID, MainView.Section.TIMETABLE.id)
|
||||||
|
it.putExtra(LESSON_TYPE, notificationType)
|
||||||
|
}, FLAG_UPDATE_CURRENT)
|
||||||
|
)
|
||||||
|
Timber.d("TimetableNotification scheduled: type: $notificationType, subject: ${intent.getStringExtra(LESSON_TITLE)}, start: $time, student: $studentId")
|
||||||
|
}
|
||||||
|
}
|
@ -42,7 +42,7 @@ class SyncManager @Inject constructor(
|
|||||||
init {
|
init {
|
||||||
if (now().isHolidays) stopSyncWorker()
|
if (now().isHolidays) stopSyncWorker()
|
||||||
|
|
||||||
if (SDK_INT > O) {
|
if (SDK_INT >= O) {
|
||||||
channels.forEach { it.create() }
|
channels.forEach { it.create() }
|
||||||
notificationManager.deleteNotificationChannel("new_entries_channel")
|
notificationManager.deleteNotificationChannel("new_entries_channel")
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package io.github.wulkanowy.services.sync
|
package io.github.wulkanowy.services.sync
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Build.VERSION_CODES.LOLLIPOP
|
|
||||||
import androidx.core.app.NotificationCompat
|
import androidx.core.app.NotificationCompat
|
||||||
import androidx.core.app.NotificationCompat.BigTextStyle
|
import androidx.core.app.NotificationCompat.BigTextStyle
|
||||||
import androidx.core.app.NotificationCompat.PRIORITY_DEFAULT
|
import androidx.core.app.NotificationCompat.PRIORITY_DEFAULT
|
||||||
@ -17,9 +16,9 @@ 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.sdk.exception.FeatureDisabledException
|
||||||
|
import io.github.wulkanowy.sdk.exception.FeatureNotAvailableException
|
||||||
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.AppInfo
|
|
||||||
import io.github.wulkanowy.utils.getCompatColor
|
import io.github.wulkanowy.utils.getCompatColor
|
||||||
import io.reactivex.Completable
|
import io.reactivex.Completable
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
@ -33,8 +32,7 @@ class SyncWorker @AssistedInject constructor(
|
|||||||
private val semesterRepository: SemesterRepository,
|
private val semesterRepository: SemesterRepository,
|
||||||
private val works: Set<@JvmSuppressWildcards Work>,
|
private val works: Set<@JvmSuppressWildcards Work>,
|
||||||
private val preferencesRepository: PreferencesRepository,
|
private val preferencesRepository: PreferencesRepository,
|
||||||
private val notificationManager: NotificationManagerCompat,
|
private val notificationManager: NotificationManagerCompat
|
||||||
private val appInfo: AppInfo
|
|
||||||
) : RxWorker(appContext, workerParameters) {
|
) : RxWorker(appContext, workerParameters) {
|
||||||
|
|
||||||
override fun createWork(): Single<Result> {
|
override fun createWork(): Single<Result> {
|
||||||
@ -47,6 +45,10 @@ class SyncWorker @AssistedInject constructor(
|
|||||||
.flatMapCompletable { semester ->
|
.flatMapCompletable { semester ->
|
||||||
Completable.mergeDelayError(works.map { work ->
|
Completable.mergeDelayError(works.map { work ->
|
||||||
work.create(student, semester)
|
work.create(student, semester)
|
||||||
|
.onErrorResumeNext {
|
||||||
|
if (it is FeatureDisabledException || it is FeatureNotAvailableException) Completable.complete()
|
||||||
|
else Completable.error(it)
|
||||||
|
}
|
||||||
.doOnSubscribe { Timber.i("${work::class.java.simpleName} is starting") }
|
.doOnSubscribe { Timber.i("${work::class.java.simpleName} is starting") }
|
||||||
.doOnError { Timber.i("${work::class.java.simpleName} result: An exception occurred") }
|
.doOnError { Timber.i("${work::class.java.simpleName} result: An exception occurred") }
|
||||||
.doOnComplete { Timber.i("${work::class.java.simpleName} result: Success") }
|
.doOnComplete { Timber.i("${work::class.java.simpleName} result: Success") }
|
||||||
@ -57,11 +59,11 @@ class SyncWorker @AssistedInject constructor(
|
|||||||
.onErrorReturn {
|
.onErrorReturn {
|
||||||
Timber.e(it, "There was an error during synchronization")
|
Timber.e(it, "There was an error during synchronization")
|
||||||
when {
|
when {
|
||||||
it is FeatureDisabledException -> Result.success()
|
|
||||||
inputData.getBoolean("one_time", false) -> {
|
inputData.getBoolean("one_time", false) -> {
|
||||||
Result.failure(Data.Builder()
|
Result.failure(Data.Builder()
|
||||||
.putString("error", it.toString())
|
.putString("error", it.toString())
|
||||||
.build())
|
.build()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
else -> Result.retry()
|
else -> Result.retry()
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ class DebugChannel @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun create() {
|
override fun create() {
|
||||||
if (appInfo.isDebug) return
|
if (!appInfo.isDebug) return
|
||||||
notificationManager.createNotificationChannel(
|
notificationManager.createNotificationChannel(
|
||||||
NotificationChannel(CHANNEL_ID, context.getString(R.string.channel_debug), IMPORTANCE_DEFAULT)
|
NotificationChannel(CHANNEL_ID, context.getString(R.string.channel_debug), IMPORTANCE_DEFAULT)
|
||||||
.apply {
|
.apply {
|
||||||
|
@ -0,0 +1,31 @@
|
|||||||
|
package io.github.wulkanowy.services.sync.channels
|
||||||
|
|
||||||
|
import android.annotation.TargetApi
|
||||||
|
import android.app.Notification.VISIBILITY_PUBLIC
|
||||||
|
import android.app.NotificationChannel
|
||||||
|
import android.app.NotificationManager.IMPORTANCE_DEFAULT
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.core.app.NotificationManagerCompat
|
||||||
|
import io.github.wulkanowy.R
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@TargetApi(26)
|
||||||
|
class UpcomingLessonsChannel @Inject constructor(
|
||||||
|
private val notificationManager: NotificationManagerCompat,
|
||||||
|
private val context: Context
|
||||||
|
) : Channel {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val CHANNEL_ID = "lesson_channel"
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun create() {
|
||||||
|
notificationManager.createNotificationChannel(
|
||||||
|
NotificationChannel(CHANNEL_ID, context.getString(R.string.channel_upcoming_lessons), IMPORTANCE_DEFAULT).apply {
|
||||||
|
lockscreenVisibility = VISIBILITY_PUBLIC
|
||||||
|
setShowBadge(false)
|
||||||
|
enableVibration(false)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -11,7 +11,7 @@ class AttendanceSummaryWork @Inject constructor(
|
|||||||
) : Work {
|
) : Work {
|
||||||
|
|
||||||
override fun create(student: Student, semester: Semester): Completable {
|
override fun create(student: Student, semester: Semester): Completable {
|
||||||
return attendanceSummaryRepository.getAttendanceSummary(semester, -1, true).ignoreElement()
|
return attendanceSummaryRepository.getAttendanceSummary(student, semester, -1, true).ignoreElement()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ package io.github.wulkanowy.services.sync.works
|
|||||||
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.attendance.AttendanceRepository
|
import io.github.wulkanowy.data.repositories.attendance.AttendanceRepository
|
||||||
import io.github.wulkanowy.utils.friday
|
import io.github.wulkanowy.utils.sunday
|
||||||
import io.github.wulkanowy.utils.monday
|
import io.github.wulkanowy.utils.monday
|
||||||
import io.reactivex.Completable
|
import io.reactivex.Completable
|
||||||
import org.threeten.bp.LocalDate.now
|
import org.threeten.bp.LocalDate.now
|
||||||
@ -12,7 +12,7 @@ import javax.inject.Inject
|
|||||||
class AttendanceWork @Inject constructor(private val attendanceRepository: AttendanceRepository) : Work {
|
class AttendanceWork @Inject constructor(private val attendanceRepository: AttendanceRepository) : Work {
|
||||||
|
|
||||||
override fun create(student: Student, semester: Semester): Completable {
|
override fun create(student: Student, semester: Semester): Completable {
|
||||||
return attendanceRepository.getAttendance(semester, now().monday, now().friday, true)
|
return attendanceRepository.getAttendance(student, semester, now().monday, now().sunday, true)
|
||||||
.ignoreElement()
|
.ignoreElement()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ package io.github.wulkanowy.services.sync.works
|
|||||||
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.completedlessons.CompletedLessonsRepository
|
import io.github.wulkanowy.data.repositories.completedlessons.CompletedLessonsRepository
|
||||||
import io.github.wulkanowy.utils.friday
|
import io.github.wulkanowy.utils.sunday
|
||||||
import io.github.wulkanowy.utils.monday
|
import io.github.wulkanowy.utils.monday
|
||||||
import io.reactivex.Completable
|
import io.reactivex.Completable
|
||||||
import org.threeten.bp.LocalDate.now
|
import org.threeten.bp.LocalDate.now
|
||||||
@ -14,7 +14,7 @@ class CompletedLessonWork @Inject constructor(
|
|||||||
) : Work {
|
) : Work {
|
||||||
|
|
||||||
override fun create(student: Student, semester: Semester): Completable {
|
override fun create(student: Student, semester: Semester): Completable {
|
||||||
return completedLessonsRepository.getCompletedLessons(semester, now().monday, now().friday, true)
|
return completedLessonsRepository.getCompletedLessons(student, semester, now().monday, now().sunday, true)
|
||||||
.ignoreElement()
|
.ignoreElement()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ package io.github.wulkanowy.services.sync.works
|
|||||||
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.exam.ExamRepository
|
import io.github.wulkanowy.data.repositories.exam.ExamRepository
|
||||||
import io.github.wulkanowy.utils.friday
|
import io.github.wulkanowy.utils.sunday
|
||||||
import io.github.wulkanowy.utils.monday
|
import io.github.wulkanowy.utils.monday
|
||||||
import io.reactivex.Completable
|
import io.reactivex.Completable
|
||||||
import org.threeten.bp.LocalDate.now
|
import org.threeten.bp.LocalDate.now
|
||||||
@ -12,6 +12,6 @@ import javax.inject.Inject
|
|||||||
class ExamWork @Inject constructor(private val examRepository: ExamRepository) : Work {
|
class ExamWork @Inject constructor(private val examRepository: ExamRepository) : Work {
|
||||||
|
|
||||||
override fun create(student: Student, semester: Semester): Completable {
|
override fun create(student: Student, semester: Semester): Completable {
|
||||||
return examRepository.getExams(semester, now().monday, now().friday, true).ignoreElement()
|
return examRepository.getExams(student, semester, now().monday, now().sunday, true).ignoreElement()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ import javax.inject.Inject
|
|||||||
class GradeStatisticsWork @Inject constructor(private val gradeStatisticsRepository: GradeStatisticsRepository) : Work {
|
class GradeStatisticsWork @Inject constructor(private val gradeStatisticsRepository: GradeStatisticsRepository) : Work {
|
||||||
|
|
||||||
override fun create(student: Student, semester: Semester): Completable {
|
override fun create(student: Student, semester: Semester): Completable {
|
||||||
return gradeStatisticsRepository.getGradesStatistics(semester, "Wszystkie", false, true)
|
return gradeStatisticsRepository.getGradesStatistics(student, semester, "Wszystkie", false, true)
|
||||||
.ignoreElement()
|
.ignoreElement()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,14 +0,0 @@
|
|||||||
package io.github.wulkanowy.services.sync.works
|
|
||||||
|
|
||||||
import io.github.wulkanowy.data.db.entities.Semester
|
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
|
||||||
import io.github.wulkanowy.data.repositories.gradessummary.GradeSummaryRepository
|
|
||||||
import io.reactivex.Completable
|
|
||||||
import javax.inject.Inject
|
|
||||||
|
|
||||||
class GradeSummaryWork @Inject constructor(private val gradeSummaryRepository: GradeSummaryRepository) : Work {
|
|
||||||
|
|
||||||
override fun create(student: Student, semester: Semester): Completable {
|
|
||||||
return gradeSummaryRepository.getGradesSummary(semester, true).ignoreElement()
|
|
||||||
}
|
|
||||||
}
|
|
@ -58,4 +58,3 @@ class GradeWork @Inject constructor(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ package io.github.wulkanowy.services.sync.works
|
|||||||
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.homework.HomeworkRepository
|
import io.github.wulkanowy.data.repositories.homework.HomeworkRepository
|
||||||
import io.github.wulkanowy.utils.friday
|
import io.github.wulkanowy.utils.sunday
|
||||||
import io.github.wulkanowy.utils.monday
|
import io.github.wulkanowy.utils.monday
|
||||||
import io.reactivex.Completable
|
import io.reactivex.Completable
|
||||||
import org.threeten.bp.LocalDate.now
|
import org.threeten.bp.LocalDate.now
|
||||||
@ -12,6 +12,6 @@ import javax.inject.Inject
|
|||||||
class HomeworkWork @Inject constructor(private val homeworkRepository: HomeworkRepository) : Work {
|
class HomeworkWork @Inject constructor(private val homeworkRepository: HomeworkRepository) : Work {
|
||||||
|
|
||||||
override fun create(student: Student, semester: Semester): Completable {
|
override fun create(student: Student, semester: Semester): Completable {
|
||||||
return homeworkRepository.getHomework(semester, now().monday, now().friday, true).ignoreElement()
|
return homeworkRepository.getHomework(student, semester, now().monday, now().sunday, true).ignoreElement()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,6 @@ import javax.inject.Inject
|
|||||||
class TeacherWork @Inject constructor(private val teacherRepository: TeacherRepository) : Work {
|
class TeacherWork @Inject constructor(private val teacherRepository: TeacherRepository) : Work {
|
||||||
|
|
||||||
override fun create(student: Student, semester: Semester): Completable {
|
override fun create(student: Student, semester: Semester): Completable {
|
||||||
return teacherRepository.getTeachers(semester, true).ignoreElement()
|
return teacherRepository.getTeachers(student, semester, true).ignoreElement()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ package io.github.wulkanowy.services.sync.works
|
|||||||
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.timetable.TimetableRepository
|
import io.github.wulkanowy.data.repositories.timetable.TimetableRepository
|
||||||
import io.github.wulkanowy.utils.friday
|
import io.github.wulkanowy.utils.sunday
|
||||||
import io.github.wulkanowy.utils.monday
|
import io.github.wulkanowy.utils.monday
|
||||||
import io.reactivex.Completable
|
import io.reactivex.Completable
|
||||||
import org.threeten.bp.LocalDate.now
|
import org.threeten.bp.LocalDate.now
|
||||||
@ -12,7 +12,7 @@ import javax.inject.Inject
|
|||||||
class TimetableWork @Inject constructor(private val timetableRepository: TimetableRepository) : Work {
|
class TimetableWork @Inject constructor(private val timetableRepository: TimetableRepository) : Work {
|
||||||
|
|
||||||
override fun create(student: Student, semester: Semester): Completable {
|
override fun create(student: Student, semester: Semester): Completable {
|
||||||
return timetableRepository.getTimetable(semester, now().monday, now().friday, true)
|
return timetableRepository.getTimetable(student, semester, now().monday, now().sunday, true)
|
||||||
.ignoreElement()
|
.ignoreElement()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ import android.widget.Toast
|
|||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.appcompat.app.AppCompatDelegate
|
import androidx.appcompat.app.AppCompatDelegate
|
||||||
|
import androidx.viewbinding.ViewBinding
|
||||||
import com.google.android.material.snackbar.Snackbar
|
import com.google.android.material.snackbar.Snackbar
|
||||||
import com.google.android.material.snackbar.Snackbar.LENGTH_LONG
|
import com.google.android.material.snackbar.Snackbar.LENGTH_LONG
|
||||||
import dagger.android.AndroidInjection
|
import dagger.android.AndroidInjection
|
||||||
@ -20,10 +21,13 @@ import io.github.wulkanowy.R
|
|||||||
import io.github.wulkanowy.ui.modules.login.LoginActivity
|
import io.github.wulkanowy.ui.modules.login.LoginActivity
|
||||||
import io.github.wulkanowy.utils.FragmentLifecycleLogger
|
import io.github.wulkanowy.utils.FragmentLifecycleLogger
|
||||||
import io.github.wulkanowy.utils.getThemeAttrColor
|
import io.github.wulkanowy.utils.getThemeAttrColor
|
||||||
|
import io.github.wulkanowy.utils.lifecycleAwareVariable
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
abstract class BaseActivity<T : BasePresenter<out BaseView>> : AppCompatActivity(), BaseView,
|
abstract class BaseActivity<T : BasePresenter<out BaseView>, VB : ViewBinding> :
|
||||||
HasAndroidInjector {
|
AppCompatActivity(), BaseView, HasAndroidInjector {
|
||||||
|
|
||||||
|
protected var binding: VB by lifecycleAwareVariable()
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var androidInjector: DispatchingAndroidInjector<Any>
|
lateinit var androidInjector: DispatchingAndroidInjector<Any>
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
package io.github.wulkanowy.ui.base
|
package io.github.wulkanowy.ui.base
|
||||||
|
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
|
import androidx.viewbinding.ViewBinding
|
||||||
import dagger.android.support.DaggerAppCompatDialogFragment
|
import dagger.android.support.DaggerAppCompatDialogFragment
|
||||||
|
import io.github.wulkanowy.utils.lifecycleAwareVariable
|
||||||
|
|
||||||
abstract class BaseDialogFragment : DaggerAppCompatDialogFragment(), BaseView {
|
abstract class BaseDialogFragment<VB : ViewBinding> : DaggerAppCompatDialogFragment(), BaseView {
|
||||||
|
|
||||||
|
protected var binding: VB by lifecycleAwareVariable()
|
||||||
|
|
||||||
override fun showError(text: String, error: Throwable) {
|
override fun showError(text: String, error: Throwable) {
|
||||||
showMessage(text)
|
showMessage(text)
|
||||||
@ -14,11 +18,11 @@ abstract class BaseDialogFragment : DaggerAppCompatDialogFragment(), BaseView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun showExpiredDialog() {
|
override fun showExpiredDialog() {
|
||||||
(activity as? BaseActivity<*>)?.showExpiredDialog()
|
(activity as? BaseActivity<*, *>)?.showExpiredDialog()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun openClearLoginView() {
|
override fun openClearLoginView() {
|
||||||
(activity as? BaseActivity<*>)?.openClearLoginView()
|
(activity as? BaseActivity<*, *>)?.openClearLoginView()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun showErrorDetailsDialog(error: Throwable) {
|
override fun showErrorDetailsDialog(error: Throwable) {
|
||||||
|
@ -0,0 +1,58 @@
|
|||||||
|
package io.github.wulkanowy.ui.base
|
||||||
|
|
||||||
|
import android.util.DisplayMetrics
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import androidx.recyclerview.widget.LinearSmoothScroller
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import kotlin.math.max
|
||||||
|
import kotlin.math.min
|
||||||
|
|
||||||
|
abstract class BaseExpandableAdapter<T : RecyclerView.ViewHolder> : RecyclerView.Adapter<T>() {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val MILLISECONDS_PER_INCH = 100f
|
||||||
|
private const val AUTO_SCROLL_DELAY = 150L
|
||||||
|
}
|
||||||
|
|
||||||
|
private var recyclerView: RecyclerView? = null
|
||||||
|
|
||||||
|
override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
|
||||||
|
super.onAttachedToRecyclerView(recyclerView)
|
||||||
|
this.recyclerView = recyclerView
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDetachedFromRecyclerView(recyclerView: RecyclerView) {
|
||||||
|
super.onDetachedFromRecyclerView(recyclerView)
|
||||||
|
this.recyclerView = null
|
||||||
|
}
|
||||||
|
|
||||||
|
// original: https://github.com/davideas/FlexibleAdapter/blob/5.1.0/flexible-adapter/src/main/java/eu/davidea/flexibleadapter/FlexibleAdapter.java#L4984-L5011
|
||||||
|
protected fun scrollToHeaderWithSubItems(position: Int, subItemsCount: Int) {
|
||||||
|
val layoutManager = recyclerView!!.layoutManager as LinearLayoutManager
|
||||||
|
val firstVisibleItem = layoutManager.findFirstCompletelyVisibleItemPosition()
|
||||||
|
val lastVisibleItem = layoutManager.findLastCompletelyVisibleItemPosition()
|
||||||
|
val itemsToShow = position + subItemsCount - lastVisibleItem
|
||||||
|
if (itemsToShow > 0) {
|
||||||
|
val scrollMax: Int = position - firstVisibleItem
|
||||||
|
val scrollMin = max(0, position + subItemsCount - lastVisibleItem)
|
||||||
|
val scrollBy = min(scrollMax, scrollMin)
|
||||||
|
val scrollTo = firstVisibleItem + scrollBy
|
||||||
|
scrollToPosition(scrollTo)
|
||||||
|
} else if (position < firstVisibleItem) {
|
||||||
|
scrollToPosition(position)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun scrollToPosition(position: Int) {
|
||||||
|
recyclerView?.run {
|
||||||
|
postDelayed({
|
||||||
|
layoutManager?.startSmoothScroll(object : LinearSmoothScroller(context) {
|
||||||
|
override fun getVerticalSnapPreference() = SNAP_TO_START
|
||||||
|
override fun calculateSpeedPerPixel(displayMetrics: DisplayMetrics) = MILLISECONDS_PER_INCH / displayMetrics.densityDpi
|
||||||
|
}.apply {
|
||||||
|
targetPosition = position
|
||||||
|
})
|
||||||
|
}, AUTO_SCROLL_DELAY)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,12 +1,18 @@
|
|||||||
package io.github.wulkanowy.ui.base
|
package io.github.wulkanowy.ui.base
|
||||||
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import androidx.annotation.LayoutRes
|
||||||
|
import androidx.viewbinding.ViewBinding
|
||||||
import com.google.android.material.snackbar.Snackbar
|
import com.google.android.material.snackbar.Snackbar
|
||||||
import com.google.android.material.snackbar.Snackbar.LENGTH_LONG
|
import com.google.android.material.snackbar.Snackbar.LENGTH_LONG
|
||||||
import dagger.android.support.DaggerFragment
|
import dagger.android.support.DaggerFragment
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
|
import io.github.wulkanowy.utils.lifecycleAwareVariable
|
||||||
|
|
||||||
abstract class BaseFragment : DaggerFragment(), BaseView {
|
abstract class BaseFragment<VB : ViewBinding>(@LayoutRes layoutId: Int) : DaggerFragment(layoutId),
|
||||||
|
BaseView {
|
||||||
|
|
||||||
|
protected var binding: VB by lifecycleAwareVariable()
|
||||||
|
|
||||||
protected var messageContainer: View? = null
|
protected var messageContainer: View? = null
|
||||||
|
|
||||||
@ -16,7 +22,7 @@ abstract class BaseFragment : DaggerFragment(), BaseView {
|
|||||||
.setAction(R.string.all_details) { if (isAdded) showErrorDetailsDialog(error) }
|
.setAction(R.string.all_details) { if (isAdded) showErrorDetailsDialog(error) }
|
||||||
.show()
|
.show()
|
||||||
} else {
|
} else {
|
||||||
(activity as? BaseActivity<*>)?.showError(text, error)
|
(activity as? BaseActivity<*, *>)?.showError(text, error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,15 +34,15 @@ abstract class BaseFragment : DaggerFragment(), BaseView {
|
|||||||
if (messageContainer != null) {
|
if (messageContainer != null) {
|
||||||
Snackbar.make(messageContainer!!, text, LENGTH_LONG).show()
|
Snackbar.make(messageContainer!!, text, LENGTH_LONG).show()
|
||||||
} else {
|
} else {
|
||||||
(activity as? BaseActivity<*>)?.showMessage(text)
|
(activity as? BaseActivity<*, *>)?.showMessage(text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun showExpiredDialog() {
|
override fun showExpiredDialog() {
|
||||||
(activity as? BaseActivity<*>)?.showExpiredDialog()
|
(activity as? BaseActivity<*, *>)?.showExpiredDialog()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun openClearLoginView() {
|
override fun openClearLoginView() {
|
||||||
(activity as? BaseActivity<*>)?.openClearLoginView()
|
(activity as? BaseActivity<*, *>)?.openClearLoginView()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,19 +6,35 @@ import android.os.Bundle
|
|||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import android.widget.HorizontalScrollView
|
||||||
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.core.content.getSystemService
|
import androidx.core.content.getSystemService
|
||||||
import androidx.fragment.app.DialogFragment
|
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
import kotlinx.android.synthetic.main.dialog_error.*
|
import io.github.wulkanowy.databinding.DialogErrorBinding
|
||||||
|
import io.github.wulkanowy.sdk.exception.FeatureDisabledException
|
||||||
|
import io.github.wulkanowy.sdk.exception.FeatureNotAvailableException
|
||||||
|
import io.github.wulkanowy.sdk.exception.ServiceUnavailableException
|
||||||
|
import io.github.wulkanowy.utils.AppInfo
|
||||||
|
import io.github.wulkanowy.utils.getString
|
||||||
|
import io.github.wulkanowy.utils.openAppInMarket
|
||||||
|
import io.github.wulkanowy.utils.openEmailClient
|
||||||
|
import io.github.wulkanowy.utils.openInternetBrowser
|
||||||
|
import java.io.InterruptedIOException
|
||||||
import java.io.PrintWriter
|
import java.io.PrintWriter
|
||||||
import java.io.StringWriter
|
import java.io.StringWriter
|
||||||
|
import java.net.SocketTimeoutException
|
||||||
|
import java.net.UnknownHostException
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
class ErrorDialog : DialogFragment() {
|
class ErrorDialog : BaseDialogFragment<DialogErrorBinding>() {
|
||||||
|
|
||||||
private lateinit var error: Throwable
|
private lateinit var error: Throwable
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var appInfo: AppInfo
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val ARGUMENT_KEY = "Data"
|
private const val ARGUMENT_KEY = "Data"
|
||||||
|
|
||||||
@ -38,7 +54,7 @@ class ErrorDialog : DialogFragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
||||||
return inflater.inflate(R.layout.dialog_error, container, false)
|
return DialogErrorBinding.inflate(inflater).apply { binding = this }.root
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||||
@ -48,14 +64,56 @@ class ErrorDialog : DialogFragment() {
|
|||||||
error.printStackTrace(PrintWriter(this))
|
error.printStackTrace(PrintWriter(this))
|
||||||
}
|
}
|
||||||
|
|
||||||
errorDialogContent.text = stringWriter.toString()
|
with(binding) {
|
||||||
errorDialogCopy.setOnClickListener {
|
errorDialogContent.text = stringWriter.toString()
|
||||||
val clip = ClipData.newPlainText("wulkanowy", stringWriter.toString())
|
with(errorDialogHorizontalScroll) {
|
||||||
activity?.getSystemService<ClipboardManager>()?.setPrimaryClip(clip)
|
post { fullScroll(HorizontalScrollView.FOCUS_LEFT) }
|
||||||
|
}
|
||||||
|
errorDialogCopy.setOnClickListener {
|
||||||
|
val clip = ClipData.newPlainText("wulkanowy", stringWriter.toString())
|
||||||
|
activity?.getSystemService<ClipboardManager>()?.setPrimaryClip(clip)
|
||||||
|
|
||||||
Toast.makeText(context, R.string.all_copied, LENGTH_LONG).show()
|
Toast.makeText(context, R.string.all_copied, LENGTH_LONG).show()
|
||||||
|
}
|
||||||
|
errorDialogCancel.setOnClickListener { dismiss() }
|
||||||
|
errorDialogReport.setOnClickListener {
|
||||||
|
openConfirmDialog { openEmailClient(stringWriter.toString()) }
|
||||||
|
}
|
||||||
|
errorDialogMessage.text = resources.getString(error)
|
||||||
|
errorDialogReport.isEnabled = when (error) {
|
||||||
|
is UnknownHostException,
|
||||||
|
is InterruptedIOException,
|
||||||
|
is SocketTimeoutException,
|
||||||
|
is ServiceUnavailableException,
|
||||||
|
is FeatureDisabledException,
|
||||||
|
is FeatureNotAvailableException -> false
|
||||||
|
else -> true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
errorDialogCancel.setOnClickListener { dismiss() }
|
}
|
||||||
|
|
||||||
|
private fun openConfirmDialog(callback: () -> Unit) {
|
||||||
|
AlertDialog.Builder(requireContext())
|
||||||
|
.setTitle(R.string.dialog_error_check_update)
|
||||||
|
.setMessage(R.string.dialog_error_check_update_message)
|
||||||
|
.setNeutralButton(R.string.about_feedback) { _, _ -> callback() }
|
||||||
|
.setPositiveButton(R.string.dialog_error_check_update) { _, _ ->
|
||||||
|
requireContext().openAppInMarket(::showMessage)
|
||||||
|
}
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun openEmailClient(content: String) {
|
||||||
|
requireContext().openEmailClient(
|
||||||
|
chooserTitle = getString(R.string.about_feedback),
|
||||||
|
email = "wulkanowyinc@gmail.com",
|
||||||
|
subject = "Zgłoszenie błędu",
|
||||||
|
body = requireContext().getString(R.string.about_feedback_template,
|
||||||
|
"${appInfo.systemManufacturer} ${appInfo.systemModel}", appInfo.systemVersion.toString(), appInfo.versionName
|
||||||
|
) + "\n" + content,
|
||||||
|
onActivityNotFound = {
|
||||||
|
requireContext().openInternetBrowser("https://github.com/wulkanowy/wulkanowy/issues", ::showMessage)
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,17 +2,11 @@ package io.github.wulkanowy.ui.base
|
|||||||
|
|
||||||
import android.content.res.Resources
|
import android.content.res.Resources
|
||||||
import com.chuckerteam.chucker.api.ChuckerCollector
|
import com.chuckerteam.chucker.api.ChuckerCollector
|
||||||
import io.github.wulkanowy.R
|
|
||||||
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.BadCredentialsException
|
||||||
import io.github.wulkanowy.sdk.exception.FeatureDisabledException
|
import io.github.wulkanowy.utils.getString
|
||||||
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.UnknownHostException
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
open class ErrorHandler @Inject constructor(protected val resources: Resources, private val chuckerCollector: ChuckerCollector) {
|
open class ErrorHandler @Inject constructor(protected val resources: Resources, private val chuckerCollector: ChuckerCollector) {
|
||||||
@ -30,18 +24,10 @@ open class ErrorHandler @Inject constructor(protected val resources: Resources,
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected open fun proceed(error: Throwable) {
|
protected open fun proceed(error: Throwable) {
|
||||||
resources.run {
|
when (error) {
|
||||||
when (error) {
|
is ScramblerException, is BadCredentialsException -> onSessionExpired()
|
||||||
is UnknownHostException -> showErrorMessage(getString(R.string.error_no_internet), error)
|
is NoCurrentStudentException -> onNoCurrentStudent()
|
||||||
is SocketTimeoutException -> showErrorMessage(getString(R.string.error_timeout), error)
|
else -> showErrorMessage(resources.getString(error), error)
|
||||||
is NotLoggedInException -> showErrorMessage(getString(R.string.error_login_failed), error)
|
|
||||||
is ServiceUnavailableException -> showErrorMessage(getString(R.string.error_service_unavailable), error)
|
|
||||||
is FeatureDisabledException -> showErrorMessage(getString(R.string.error_feature_disabled), error)
|
|
||||||
is ScramblerException, is BadCredentialsException -> onSessionExpired()
|
|
||||||
is NoCurrentStudentException -> onNoCurrentStudent()
|
|
||||||
is FeatureNotAvailableException -> showErrorMessage(getString(R.string.error_feature_not_available), error)
|
|
||||||
else -> showErrorMessage(getString(R.string.error_unknown), error)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,46 @@
|
|||||||
|
package io.github.wulkanowy.ui.base
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.graphics.PorterDuff
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import io.github.wulkanowy.R
|
||||||
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
|
import io.github.wulkanowy.databinding.ItemAccountBinding
|
||||||
|
import io.github.wulkanowy.utils.getThemeAttrColor
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class WidgetConfigureAdapter @Inject constructor() : RecyclerView.Adapter<WidgetConfigureAdapter.ItemViewHolder>() {
|
||||||
|
|
||||||
|
var items = emptyList<Pair<Student, Boolean>>()
|
||||||
|
|
||||||
|
var onClickListener: (Student) -> Unit = {}
|
||||||
|
|
||||||
|
override fun getItemCount() = items.size
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder(
|
||||||
|
ItemAccountBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||||
|
)
|
||||||
|
|
||||||
|
@SuppressLint("SetTextI18n")
|
||||||
|
override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
|
||||||
|
val (student, isCurrent) = items[position]
|
||||||
|
|
||||||
|
with(holder.binding) {
|
||||||
|
accountItemName.text = "${student.studentName} ${student.className}"
|
||||||
|
accountItemSchool.text = student.schoolName
|
||||||
|
|
||||||
|
with(accountItemImage) {
|
||||||
|
val colorImage = if (isCurrent) context.getThemeAttrColor(R.attr.colorPrimary)
|
||||||
|
else context.getThemeAttrColor(R.attr.colorOnSurface, 153)
|
||||||
|
|
||||||
|
setColorFilter(colorImage, PorterDuff.Mode.SRC_IN)
|
||||||
|
}
|
||||||
|
|
||||||
|
root.setOnClickListener { onClickListener(student) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ItemViewHolder(val binding: ItemAccountBinding) : RecyclerView.ViewHolder(binding.root)
|
||||||
|
}
|
@ -0,0 +1,72 @@
|
|||||||
|
package io.github.wulkanowy.ui.modules.about
|
||||||
|
|
||||||
|
import android.graphics.drawable.Drawable
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.core.content.res.ResourcesCompat
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import io.github.wulkanowy.databinding.ItemAboutBinding
|
||||||
|
import io.github.wulkanowy.databinding.ScrollableHeaderAboutBinding
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class AboutAdapter @Inject constructor() : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||||
|
|
||||||
|
private enum class ViewType(val id: Int) {
|
||||||
|
ITEM_HEADER(1),
|
||||||
|
ITEM_ELEMENT(2)
|
||||||
|
}
|
||||||
|
|
||||||
|
var items = emptyList<Triple<String, String, Drawable?>>()
|
||||||
|
|
||||||
|
var onClickListener: (name: String) -> Unit = {}
|
||||||
|
|
||||||
|
override fun getItemCount() = items.size + 1
|
||||||
|
|
||||||
|
override fun getItemViewType(position: Int) = when (position) {
|
||||||
|
0 -> ViewType.ITEM_HEADER.id
|
||||||
|
else -> ViewType.ITEM_ELEMENT.id
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||||
|
val inflater = LayoutInflater.from(parent.context)
|
||||||
|
|
||||||
|
return when (viewType) {
|
||||||
|
ViewType.ITEM_HEADER.id -> HeaderViewHolder(ScrollableHeaderAboutBinding.inflate(inflater, parent, false))
|
||||||
|
ViewType.ITEM_ELEMENT.id -> ItemViewHolder(ItemAboutBinding.inflate(inflater, parent, false))
|
||||||
|
else -> throw IllegalStateException()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
|
||||||
|
when (holder) {
|
||||||
|
is HeaderViewHolder -> bindHeaderViewHolder(holder.binding)
|
||||||
|
is ItemViewHolder -> bindItemViewHolder(holder.binding, position - 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun bindHeaderViewHolder(binding: ScrollableHeaderAboutBinding) {
|
||||||
|
with(binding.aboutScrollableHeaderIcon) {
|
||||||
|
setImageDrawable(ResourcesCompat.getDrawableForDensity(
|
||||||
|
context.resources, context.applicationInfo.icon, 640, null)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun bindItemViewHolder(binding: ItemAboutBinding, position: Int) {
|
||||||
|
val (title, summary, image) = items[position]
|
||||||
|
|
||||||
|
with(binding) {
|
||||||
|
aboutItemImage.setImageDrawable(image)
|
||||||
|
aboutItemTitle.text = title
|
||||||
|
aboutItemSummary.text = summary
|
||||||
|
|
||||||
|
root.setOnClickListener { onClickListener(title) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class HeaderViewHolder(val binding: ScrollableHeaderAboutBinding) :
|
||||||
|
RecyclerView.ViewHolder(binding.root)
|
||||||
|
|
||||||
|
private class ItemViewHolder(val binding: ItemAboutBinding) :
|
||||||
|
RecyclerView.ViewHolder(binding.root)
|
||||||
|
}
|
@ -2,13 +2,10 @@ package io.github.wulkanowy.ui.modules.about
|
|||||||
|
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
|
||||||
import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager
|
|
||||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
|
import io.github.wulkanowy.databinding.FragmentAboutBinding
|
||||||
import io.github.wulkanowy.ui.base.BaseFragment
|
import io.github.wulkanowy.ui.base.BaseFragment
|
||||||
import io.github.wulkanowy.ui.modules.about.contributor.ContributorFragment
|
import io.github.wulkanowy.ui.modules.about.contributor.ContributorFragment
|
||||||
import io.github.wulkanowy.ui.modules.about.license.LicenseFragment
|
import io.github.wulkanowy.ui.modules.about.license.LicenseFragment
|
||||||
@ -17,19 +14,19 @@ 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.AppInfo
|
import io.github.wulkanowy.utils.AppInfo
|
||||||
import io.github.wulkanowy.utils.getCompatDrawable
|
import io.github.wulkanowy.utils.getCompatDrawable
|
||||||
|
import io.github.wulkanowy.utils.openAppInMarket
|
||||||
import io.github.wulkanowy.utils.openEmailClient
|
import io.github.wulkanowy.utils.openEmailClient
|
||||||
import io.github.wulkanowy.utils.openInternetBrowser
|
import io.github.wulkanowy.utils.openInternetBrowser
|
||||||
import io.github.wulkanowy.utils.setOnItemClickListener
|
|
||||||
import kotlinx.android.synthetic.main.fragment_about.*
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class AboutFragment : BaseFragment(), AboutView, MainView.TitledView {
|
class AboutFragment : BaseFragment<FragmentAboutBinding>(R.layout.fragment_about), AboutView,
|
||||||
|
MainView.TitledView {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var presenter: AboutPresenter
|
lateinit var presenter: AboutPresenter
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var aboutAdapter: FlexibleAdapter<AbstractFlexibleItem<*>>
|
lateinit var aboutAdapter: AboutAdapter
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var appInfo: AppInfo
|
lateinit var appInfo: AppInfo
|
||||||
@ -80,34 +77,34 @@ class AboutFragment : BaseFragment(), AboutView, MainView.TitledView {
|
|||||||
fun newInstance() = AboutFragment()
|
fun newInstance() = AboutFragment()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
|
||||||
return inflater.inflate(R.layout.fragment_about, container, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
binding = FragmentAboutBinding.bind(view)
|
||||||
presenter.onAttachView(this)
|
presenter.onAttachView(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun initView() {
|
override fun initView() {
|
||||||
aboutAdapter.setOnItemClickListener(presenter::onItemSelected)
|
aboutAdapter.onClickListener = presenter::onItemSelected
|
||||||
|
|
||||||
with(aboutRecycler) {
|
with(binding.aboutRecycler) {
|
||||||
layoutManager = SmoothScrollLinearLayoutManager(context)
|
layoutManager = LinearLayoutManager(context)
|
||||||
adapter = aboutAdapter
|
adapter = aboutAdapter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun updateData(header: AboutScrollableHeader, items: List<AboutItem>) {
|
override fun updateData(data: List<Triple<String, String, Drawable?>>) {
|
||||||
with(aboutAdapter) {
|
with(aboutAdapter) {
|
||||||
removeAllScrollableHeaders()
|
items = data
|
||||||
addScrollableHeader(header)
|
notifyDataSetChanged()
|
||||||
updateDataSet(items)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun openAppInMarket() {
|
||||||
|
context?.openAppInMarket(::showMessage)
|
||||||
|
}
|
||||||
|
|
||||||
override fun openLogViewer() {
|
override fun openLogViewer() {
|
||||||
if (appInfo.isDebug) (activity as? MainActivity)?.pushView(LogViewerFragment.newInstance())
|
(activity as? MainActivity)?.pushView(LogViewerFragment.newInstance())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun openDiscordInvite() {
|
override fun openDiscordInvite() {
|
||||||
@ -123,7 +120,7 @@ class AboutFragment : BaseFragment(), AboutView, MainView.TitledView {
|
|||||||
chooserTitle = getString(R.string.about_feedback),
|
chooserTitle = getString(R.string.about_feedback),
|
||||||
email = "wulkanowyinc@gmail.com",
|
email = "wulkanowyinc@gmail.com",
|
||||||
subject = "Zgłoszenie błędu",
|
subject = "Zgłoszenie błędu",
|
||||||
body = requireContext().getString(R.string.about_feedback_template,
|
body = getString(R.string.about_feedback_template,
|
||||||
"${appInfo.systemManufacturer} ${appInfo.systemModel}", appInfo.systemVersion.toString(), appInfo.versionName
|
"${appInfo.systemManufacturer} ${appInfo.systemModel}", appInfo.systemVersion.toString(), appInfo.versionName
|
||||||
),
|
),
|
||||||
onActivityNotFound = {
|
onActivityNotFound = {
|
||||||
|
@ -1,56 +0,0 @@
|
|||||||
package io.github.wulkanowy.ui.modules.about
|
|
||||||
|
|
||||||
import android.graphics.drawable.Drawable
|
|
||||||
import android.view.View
|
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
|
||||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
|
||||||
import eu.davidea.flexibleadapter.items.IFlexible
|
|
||||||
import eu.davidea.viewholders.FlexibleViewHolder
|
|
||||||
import io.github.wulkanowy.R
|
|
||||||
import kotlinx.android.extensions.LayoutContainer
|
|
||||||
import kotlinx.android.synthetic.main.item_about.*
|
|
||||||
|
|
||||||
class AboutItem(
|
|
||||||
val title: String,
|
|
||||||
private val summary: String,
|
|
||||||
private val image: Drawable?
|
|
||||||
) : AbstractFlexibleItem<AboutItem.ViewHolder>() {
|
|
||||||
|
|
||||||
override fun getLayoutRes() = R.layout.item_about
|
|
||||||
|
|
||||||
override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<*>>) = ViewHolder(view, adapter)
|
|
||||||
|
|
||||||
override fun bindViewHolder(adapter: FlexibleAdapter<IFlexible<*>>, holder: ViewHolder, position: Int, payloads: MutableList<Any>) {
|
|
||||||
with(holder) {
|
|
||||||
aboutItemImage.setImageDrawable(image)
|
|
||||||
aboutItemTitle.text = title
|
|
||||||
aboutItemSummary.text = summary
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean {
|
|
||||||
if (this === other) return true
|
|
||||||
if (javaClass != other?.javaClass) return false
|
|
||||||
|
|
||||||
other as AboutItem
|
|
||||||
|
|
||||||
if (title != other.title) return false
|
|
||||||
if (summary != other.summary) return false
|
|
||||||
if (image != other.image) return false
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun hashCode(): Int {
|
|
||||||
var result = title.hashCode()
|
|
||||||
result = 31 * result + summary.hashCode()
|
|
||||||
result = 31 * result + (image?.hashCode() ?: 0)
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
class ViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<*>>) : FlexibleViewHolder(view, adapter),
|
|
||||||
LayoutContainer {
|
|
||||||
|
|
||||||
override val containerView: View? get() = contentView
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,9 +1,9 @@
|
|||||||
package io.github.wulkanowy.ui.modules.about
|
package io.github.wulkanowy.ui.modules.about
|
||||||
|
|
||||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
|
||||||
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
||||||
import io.github.wulkanowy.ui.base.BasePresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||||
|
import io.github.wulkanowy.utils.AppInfo
|
||||||
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
||||||
import io.github.wulkanowy.utils.SchedulersProvider
|
import io.github.wulkanowy.utils.SchedulersProvider
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
@ -13,6 +13,7 @@ class AboutPresenter @Inject constructor(
|
|||||||
schedulers: SchedulersProvider,
|
schedulers: SchedulersProvider,
|
||||||
errorHandler: ErrorHandler,
|
errorHandler: ErrorHandler,
|
||||||
studentRepository: StudentRepository,
|
studentRepository: StudentRepository,
|
||||||
|
private val appInfo: AppInfo,
|
||||||
private val analytics: FirebaseAnalyticsHelper
|
private val analytics: FirebaseAnalyticsHelper
|
||||||
) : BasePresenter<AboutView>(errorHandler, studentRepository, schedulers) {
|
) : BasePresenter<AboutView>(errorHandler, studentRepository, schedulers) {
|
||||||
|
|
||||||
@ -23,13 +24,13 @@ class AboutPresenter @Inject constructor(
|
|||||||
loadData()
|
loadData()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onItemSelected(item: AbstractFlexibleItem<*>) {
|
fun onItemSelected(name: String) {
|
||||||
if (item !is AboutItem) return
|
|
||||||
view?.run {
|
view?.run {
|
||||||
when (item.title) {
|
when (name) {
|
||||||
versionRes?.first -> {
|
versionRes?.first -> {
|
||||||
Timber.i("Opening log viewer")
|
Timber.i("Opening log viewer")
|
||||||
openLogViewer()
|
if (appInfo.isDebug) openLogViewer()
|
||||||
|
else openAppInMarket()
|
||||||
analytics.logEvent("about_open", "name" to "log_viewer")
|
analytics.logEvent("about_open", "name" to "log_viewer")
|
||||||
}
|
}
|
||||||
feedbackRes?.first -> {
|
feedbackRes?.first -> {
|
||||||
@ -73,15 +74,16 @@ class AboutPresenter @Inject constructor(
|
|||||||
|
|
||||||
private fun loadData() {
|
private fun loadData() {
|
||||||
view?.run {
|
view?.run {
|
||||||
updateData(AboutScrollableHeader(), listOfNotNull(
|
updateData(listOfNotNull(
|
||||||
versionRes?.let { (title, summary, image) -> AboutItem(title, summary, image) },
|
versionRes,
|
||||||
creatorsRes?.let { (title, summary, image) -> AboutItem(title, summary, image) },
|
creatorsRes,
|
||||||
feedbackRes?.let { (title, summary, image) -> AboutItem(title, summary, image) },
|
feedbackRes,
|
||||||
faqRes?.let { (title, summary, image) -> AboutItem(title, summary, image) },
|
faqRes,
|
||||||
discordRes?.let { (title, summary, image) -> AboutItem(title, summary, image) },
|
discordRes,
|
||||||
homepageRes?.let { (title, summary, image) -> AboutItem(title, summary, image) },
|
homepageRes,
|
||||||
licensesRes?.let { (title, summary, image) -> AboutItem(title, summary, image) },
|
licensesRes,
|
||||||
privacyRes?.let { (title, summary, image) -> AboutItem(title, summary, image) }))
|
privacyRes
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,41 +0,0 @@
|
|||||||
package io.github.wulkanowy.ui.modules.about
|
|
||||||
|
|
||||||
import android.view.View
|
|
||||||
import androidx.core.content.res.ResourcesCompat
|
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
|
||||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
|
||||||
import eu.davidea.flexibleadapter.items.IFlexible
|
|
||||||
import eu.davidea.viewholders.FlexibleViewHolder
|
|
||||||
import io.github.wulkanowy.R
|
|
||||||
import kotlinx.android.extensions.LayoutContainer
|
|
||||||
import kotlinx.android.synthetic.main.scrollable_header_about.*
|
|
||||||
|
|
||||||
class AboutScrollableHeader : AbstractFlexibleItem<AboutScrollableHeader.ViewHolder>() {
|
|
||||||
|
|
||||||
override fun getLayoutRes() = R.layout.scrollable_header_about
|
|
||||||
|
|
||||||
override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<*>>) = ViewHolder(view, adapter)
|
|
||||||
|
|
||||||
override fun bindViewHolder(adapter: FlexibleAdapter<IFlexible<*>>, holder: ViewHolder, position: Int, payloads: MutableList<Any>) {
|
|
||||||
with(holder) {
|
|
||||||
val context = contentView.context
|
|
||||||
val drawable = ResourcesCompat.getDrawableForDensity(context.resources, context.applicationInfo.icon, 640, null)
|
|
||||||
|
|
||||||
aboutScrollableHeaderIcon.setImageDrawable(drawable)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean {
|
|
||||||
if (this === other) return true
|
|
||||||
if (javaClass != other?.javaClass) return false
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun hashCode() = javaClass.hashCode()
|
|
||||||
|
|
||||||
class ViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<*>>) : FlexibleViewHolder(view, adapter),
|
|
||||||
LayoutContainer {
|
|
||||||
|
|
||||||
override val containerView: View? get() = contentView
|
|
||||||
}
|
|
||||||
}
|
|
@ -23,7 +23,9 @@ interface AboutView : BaseView {
|
|||||||
|
|
||||||
fun initView()
|
fun initView()
|
||||||
|
|
||||||
fun updateData(header: AboutScrollableHeader, items: List<AboutItem>)
|
fun updateData(data: List<Triple<String, String, Drawable?>>)
|
||||||
|
|
||||||
|
fun openAppInMarket()
|
||||||
|
|
||||||
fun openLogViewer()
|
fun openLogViewer()
|
||||||
|
|
||||||
|
@ -0,0 +1,41 @@
|
|||||||
|
package io.github.wulkanowy.ui.modules.about.contributor
|
||||||
|
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import coil.api.load
|
||||||
|
import coil.transform.RoundedCornersTransformation
|
||||||
|
import io.github.wulkanowy.data.pojos.Contributor
|
||||||
|
import io.github.wulkanowy.databinding.ItemContributorBinding
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
class ContributorAdapter @Inject constructor() :
|
||||||
|
RecyclerView.Adapter<ContributorAdapter.ItemViewHolder>() {
|
||||||
|
|
||||||
|
var items = emptyList<Contributor>()
|
||||||
|
|
||||||
|
var onClickListener: (Contributor) -> Unit = {}
|
||||||
|
|
||||||
|
override fun getItemCount() = items.size
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder(
|
||||||
|
ItemContributorBinding.inflate(LayoutInflater.from(parent.context), parent, false)
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
|
||||||
|
val item = items[position]
|
||||||
|
|
||||||
|
with(holder.binding) {
|
||||||
|
creatorItemName.text = item.displayName
|
||||||
|
creatorItemAvatar.load("https://github.com/${item.githubUsername}.png") {
|
||||||
|
transformations(RoundedCornersTransformation(8f))
|
||||||
|
crossfade(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
root.setOnClickListener { onClickListener(item) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ItemViewHolder(val binding: ItemContributorBinding) :
|
||||||
|
RecyclerView.ViewHolder(binding.root)
|
||||||
|
}
|
@ -1,30 +1,27 @@
|
|||||||
package io.github.wulkanowy.ui.modules.about.contributor
|
package io.github.wulkanowy.ui.modules.about.contributor
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.View.GONE
|
import android.view.View.GONE
|
||||||
import android.view.View.VISIBLE
|
import android.view.View.VISIBLE
|
||||||
import android.view.ViewGroup
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
|
||||||
import eu.davidea.flexibleadapter.common.FlexibleItemDecoration
|
|
||||||
import eu.davidea.flexibleadapter.common.SmoothScrollLinearLayoutManager
|
|
||||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
|
import io.github.wulkanowy.data.pojos.Contributor
|
||||||
|
import io.github.wulkanowy.databinding.FragmentContributorBinding
|
||||||
import io.github.wulkanowy.ui.base.BaseFragment
|
import io.github.wulkanowy.ui.base.BaseFragment
|
||||||
import io.github.wulkanowy.ui.modules.main.MainView
|
import io.github.wulkanowy.ui.modules.main.MainView
|
||||||
|
import io.github.wulkanowy.ui.widgets.DividerItemDecoration
|
||||||
import io.github.wulkanowy.utils.openInternetBrowser
|
import io.github.wulkanowy.utils.openInternetBrowser
|
||||||
import io.github.wulkanowy.utils.setOnItemClickListener
|
|
||||||
import kotlinx.android.synthetic.main.fragment_creator.*
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class ContributorFragment : BaseFragment(), ContributorView, MainView.TitledView {
|
class ContributorFragment : BaseFragment<FragmentContributorBinding>(R.layout.fragment_contributor),
|
||||||
|
ContributorView, MainView.TitledView {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var presenter: ContributorPresenter
|
lateinit var presenter: ContributorPresenter
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var creatorsAdapter: FlexibleAdapter<AbstractFlexibleItem<*>>
|
lateinit var creatorsAdapter: ContributorAdapter
|
||||||
|
|
||||||
override val titleStringId get() = R.string.contributors_title
|
override val titleStringId get() = R.string.contributors_title
|
||||||
|
|
||||||
@ -32,29 +29,27 @@ class ContributorFragment : BaseFragment(), ContributorView, MainView.TitledView
|
|||||||
fun newInstance() = ContributorFragment()
|
fun newInstance() = ContributorFragment()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
return inflater.inflate(R.layout.fragment_creator, container, false)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
}
|
binding = FragmentContributorBinding.bind(view)
|
||||||
|
|
||||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
|
||||||
super.onActivityCreated(savedInstanceState)
|
|
||||||
presenter.onAttachView(this)
|
presenter.onAttachView(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun initView() {
|
override fun initView() {
|
||||||
with(creatorRecycler) {
|
with(binding.creatorRecycler) {
|
||||||
layoutManager = SmoothScrollLinearLayoutManager(context)
|
layoutManager = LinearLayoutManager(context)
|
||||||
adapter = creatorsAdapter
|
adapter = creatorsAdapter
|
||||||
addItemDecoration(FlexibleItemDecoration(context)
|
addItemDecoration(DividerItemDecoration(context))
|
||||||
.withDefaultDivider()
|
|
||||||
.withDrawDividerOnLastItem(false))
|
|
||||||
}
|
}
|
||||||
creatorsAdapter.setOnItemClickListener(presenter::onItemSelected)
|
creatorsAdapter.onClickListener = presenter::onItemSelected
|
||||||
creatorSeeMore.setOnClickListener { presenter.onSeeMoreClick() }
|
binding.creatorSeeMore.setOnClickListener { presenter.onSeeMoreClick() }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun updateData(data: List<ContributorItem>) {
|
override fun updateData(data: List<Contributor>) {
|
||||||
creatorsAdapter.updateDataSet(data)
|
with(creatorsAdapter) {
|
||||||
|
items = data
|
||||||
|
notifyDataSetChanged()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun openUserGithubPage(username: String) {
|
override fun openUserGithubPage(username: String) {
|
||||||
@ -66,7 +61,7 @@ class ContributorFragment : BaseFragment(), ContributorView, MainView.TitledView
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun showProgress(show: Boolean) {
|
override fun showProgress(show: Boolean) {
|
||||||
creatorProgress.visibility = if (show) VISIBLE else GONE
|
binding.creatorProgress.visibility = if (show) VISIBLE else GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
|
@ -1,51 +0,0 @@
|
|||||||
package io.github.wulkanowy.ui.modules.about.contributor
|
|
||||||
|
|
||||||
import android.view.View
|
|
||||||
import coil.api.load
|
|
||||||
import coil.transform.RoundedCornersTransformation
|
|
||||||
import eu.davidea.flexibleadapter.FlexibleAdapter
|
|
||||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
|
||||||
import eu.davidea.flexibleadapter.items.IFlexible
|
|
||||||
import eu.davidea.viewholders.FlexibleViewHolder
|
|
||||||
import io.github.wulkanowy.R
|
|
||||||
import io.github.wulkanowy.data.pojos.AppCreator
|
|
||||||
import kotlinx.android.extensions.LayoutContainer
|
|
||||||
import kotlinx.android.synthetic.main.item_contributor.*
|
|
||||||
|
|
||||||
class ContributorItem(val creator: AppCreator) :
|
|
||||||
AbstractFlexibleItem<ContributorItem.ViewHolder>() {
|
|
||||||
|
|
||||||
override fun getLayoutRes() = R.layout.item_contributor
|
|
||||||
|
|
||||||
override fun createViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<*>>) = ViewHolder(view, adapter)
|
|
||||||
|
|
||||||
override fun bindViewHolder(adapter: FlexibleAdapter<IFlexible<*>>, holder: ViewHolder, position: Int, payloads: MutableList<Any>) {
|
|
||||||
with(holder) {
|
|
||||||
creatorItemName.text = creator.displayName
|
|
||||||
|
|
||||||
creatorItemAvatar.load("https://github.com/${creator.githubUsername}.png") {
|
|
||||||
transformations(RoundedCornersTransformation(8f))
|
|
||||||
crossfade(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean {
|
|
||||||
if (this === other) return true
|
|
||||||
if (javaClass != other?.javaClass) return false
|
|
||||||
|
|
||||||
other as ContributorItem
|
|
||||||
|
|
||||||
if (creator != other.creator) return false
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun hashCode() = creator.hashCode()
|
|
||||||
|
|
||||||
class ViewHolder(view: View, adapter: FlexibleAdapter<IFlexible<*>>) : FlexibleViewHolder(view, adapter),
|
|
||||||
LayoutContainer {
|
|
||||||
|
|
||||||
override val containerView: View? get() = contentView
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +1,6 @@
|
|||||||
package io.github.wulkanowy.ui.modules.about.contributor
|
package io.github.wulkanowy.ui.modules.about.contributor
|
||||||
|
|
||||||
import eu.davidea.flexibleadapter.items.AbstractFlexibleItem
|
import io.github.wulkanowy.data.pojos.Contributor
|
||||||
import io.github.wulkanowy.data.repositories.appcreator.AppCreatorRepository
|
import io.github.wulkanowy.data.repositories.appcreator.AppCreatorRepository
|
||||||
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
import io.github.wulkanowy.data.repositories.student.StudentRepository
|
||||||
import io.github.wulkanowy.ui.base.BasePresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
@ -21,9 +21,8 @@ class ContributorPresenter @Inject constructor(
|
|||||||
loadData()
|
loadData()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onItemSelected(item: AbstractFlexibleItem<*>) {
|
fun onItemSelected(contributor: Contributor) {
|
||||||
if (item !is ContributorItem) return
|
view?.openUserGithubPage(contributor.githubUsername)
|
||||||
view?.openUserGithubPage(item.creator.githubUsername)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onSeeMoreClick() {
|
fun onSeeMoreClick() {
|
||||||
@ -32,7 +31,6 @@ class ContributorPresenter @Inject constructor(
|
|||||||
|
|
||||||
private fun loadData() {
|
private fun loadData() {
|
||||||
disposable.add(appCreatorRepository.getAppCreators()
|
disposable.add(appCreatorRepository.getAppCreators()
|
||||||
.map { it.map { creator -> ContributorItem(creator) } }
|
|
||||||
.subscribeOn(schedulers.backgroundThread)
|
.subscribeOn(schedulers.backgroundThread)
|
||||||
.observeOn(schedulers.mainThread)
|
.observeOn(schedulers.mainThread)
|
||||||
.doFinally { view?.showProgress(false) }
|
.doFinally { view?.showProgress(false) }
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user