forked from github/wulkanowy-mirror
Merge branch 'release/1.6.0'
This commit is contained in:
commit
b371fd6709
12
.editorconfig
Normal file
12
.editorconfig
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
[*]
|
||||||
|
charset=utf-8
|
||||||
|
end_of_line=lf
|
||||||
|
insert_final_newline=true
|
||||||
|
indent_style=space
|
||||||
|
indent_size=4
|
||||||
|
|
||||||
|
[*.json]
|
||||||
|
indent_size=2
|
||||||
|
|
||||||
|
[*.{kt,kts}]
|
||||||
|
disabled_rules=import-ordering,no-wildcard-imports
|
2
LICENSE
2
LICENSE
@ -186,7 +186,7 @@
|
|||||||
same "printed page" as the copyright notice for easier
|
same "printed page" as the copyright notice for easier
|
||||||
identification within third-party archives.
|
identification within third-party archives.
|
||||||
|
|
||||||
Copyright 2021 Wulkanowy
|
Copyright 2022 Wulkanowy
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -22,8 +22,8 @@ android {
|
|||||||
testApplicationId "io.github.tests.wulkanowy"
|
testApplicationId "io.github.tests.wulkanowy"
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 31
|
targetSdkVersion 31
|
||||||
versionCode 103
|
versionCode 104
|
||||||
versionName "1.5.0"
|
versionName "1.6.0"
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
|
|
||||||
resValue "string", "app_name", "Wulkanowy"
|
resValue "string", "app_name", "Wulkanowy"
|
||||||
@ -73,6 +73,8 @@ android {
|
|||||||
buildConfigField "String", "MESSAGES_BASE_URL", "\"https://messages.wulkanowy.net.pl\""
|
buildConfigField "String", "MESSAGES_BASE_URL", "\"https://messages.wulkanowy.net.pl\""
|
||||||
}
|
}
|
||||||
debug {
|
debug {
|
||||||
|
minifyEnabled false
|
||||||
|
shrinkResources false
|
||||||
resValue "string", "app_name", "Wulkanowy DEV"
|
resValue "string", "app_name", "Wulkanowy DEV"
|
||||||
applicationIdSuffix ".dev"
|
applicationIdSuffix ".dev"
|
||||||
versionNameSuffix "-dev"
|
versionNameSuffix "-dev"
|
||||||
@ -169,14 +171,14 @@ huaweiPublish {
|
|||||||
ext {
|
ext {
|
||||||
work_manager = "2.7.1"
|
work_manager = "2.7.1"
|
||||||
android_hilt = "1.0.0"
|
android_hilt = "1.0.0"
|
||||||
room = "2.4.0"
|
room = "2.4.2"
|
||||||
chucker = "3.5.2"
|
chucker = "3.5.2"
|
||||||
mockk = "1.12.1"
|
mockk = "1.12.2"
|
||||||
coroutines = "1.6.0"
|
coroutines = "1.6.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation "io.github.wulkanowy:sdk:1.5.0"
|
implementation "io.github.wulkanowy:sdk:1.6.0"
|
||||||
|
|
||||||
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
|
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
|
||||||
|
|
||||||
@ -184,19 +186,19 @@ dependencies {
|
|||||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines"
|
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines"
|
||||||
|
|
||||||
implementation "androidx.core:core-ktx:1.7.0"
|
implementation "androidx.core:core-ktx:1.7.0"
|
||||||
implementation 'androidx.core:core-splashscreen:1.0.0-alpha02'
|
implementation 'androidx.core:core-splashscreen:1.0.0-beta02'
|
||||||
implementation "androidx.activity:activity-ktx:1.4.0"
|
implementation "androidx.activity:activity-ktx:1.4.0"
|
||||||
implementation "androidx.appcompat:appcompat:1.4.0"
|
implementation "androidx.appcompat:appcompat:1.4.1"
|
||||||
implementation "androidx.fragment:fragment-ktx:1.4.0"
|
implementation "androidx.fragment:fragment-ktx:1.4.1"
|
||||||
implementation "androidx.annotation:annotation:1.3.0"
|
implementation "androidx.annotation:annotation:1.3.0"
|
||||||
|
|
||||||
implementation "androidx.preference:preference-ktx:1.1.1"
|
implementation "androidx.preference:preference-ktx:1.2.0"
|
||||||
implementation "androidx.recyclerview:recyclerview:1.2.1"
|
implementation "androidx.recyclerview:recyclerview:1.2.1"
|
||||||
implementation "androidx.viewpager2:viewpager2:1.1.0-beta01"
|
implementation "androidx.viewpager2:viewpager2:1.1.0-beta01"
|
||||||
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
|
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
|
||||||
implementation "androidx.constraintlayout:constraintlayout:2.1.2"
|
implementation "androidx.constraintlayout:constraintlayout:2.1.3"
|
||||||
implementation "androidx.coordinatorlayout:coordinatorlayout:1.1.0"
|
implementation "androidx.coordinatorlayout:coordinatorlayout:1.2.0"
|
||||||
implementation "com.google.android.material:material:1.4.0"
|
implementation "com.google.android.material:material:1.5.0"
|
||||||
implementation "com.github.wulkanowy:material-chips-input:2.3.1"
|
implementation "com.github.wulkanowy:material-chips-input:2.3.1"
|
||||||
implementation "com.github.PhilJay:MPAndroidChart:v3.1.0"
|
implementation "com.github.PhilJay:MPAndroidChart:v3.1.0"
|
||||||
implementation 'com.github.lopspower:CircularImageView:4.2.0'
|
implementation 'com.github.lopspower:CircularImageView:4.2.0'
|
||||||
@ -204,7 +206,7 @@ dependencies {
|
|||||||
implementation "androidx.work:work-runtime-ktx:$work_manager"
|
implementation "androidx.work:work-runtime-ktx:$work_manager"
|
||||||
playImplementation "androidx.work:work-gcm:$work_manager"
|
playImplementation "androidx.work:work-gcm:$work_manager"
|
||||||
|
|
||||||
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.4.0"
|
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.4.1"
|
||||||
|
|
||||||
implementation "androidx.room:room-runtime:$room"
|
implementation "androidx.room:room-runtime:$room"
|
||||||
implementation "androidx.room:room-ktx:$room"
|
implementation "androidx.room:room-ktx:$room"
|
||||||
@ -228,24 +230,25 @@ dependencies {
|
|||||||
implementation "com.mikepenz:aboutlibraries-core:$about_libraries"
|
implementation "com.mikepenz:aboutlibraries-core:$about_libraries"
|
||||||
implementation "io.coil-kt:coil:1.4.0"
|
implementation "io.coil-kt:coil:1.4.0"
|
||||||
implementation "io.github.wulkanowy:AppKillerManager:3.0.0"
|
implementation "io.github.wulkanowy:AppKillerManager:3.0.0"
|
||||||
implementation 'me.xdrop:fuzzywuzzy:1.3.1'
|
implementation 'me.xdrop:fuzzywuzzy:1.4.0'
|
||||||
implementation 'com.fredporciuncula:flow-preferences:1.6.0'
|
implementation 'com.fredporciuncula:flow-preferences:1.6.0'
|
||||||
|
|
||||||
playImplementation platform('com.google.firebase:firebase-bom:29.0.3')
|
playImplementation platform('com.google.firebase:firebase-bom:29.3.0')
|
||||||
playImplementation 'com.google.firebase:firebase-analytics-ktx'
|
playImplementation 'com.google.firebase:firebase-analytics-ktx'
|
||||||
playImplementation 'com.google.firebase:firebase-messaging:'
|
playImplementation 'com.google.firebase:firebase-messaging:'
|
||||||
playImplementation 'com.google.firebase:firebase-crashlytics:'
|
playImplementation 'com.google.firebase:firebase-crashlytics:'
|
||||||
playImplementation 'com.google.android.play:core:1.10.2'
|
playImplementation 'com.google.android.play:core:1.10.3'
|
||||||
playImplementation 'com.google.android.play:core-ktx:1.8.1'
|
playImplementation 'com.google.android.play:core-ktx:1.8.1'
|
||||||
playImplementation 'com.google.android.gms:play-services-ads:20.5.0'
|
playImplementation 'com.google.android.gms:play-services-ads:20.6.0'
|
||||||
|
|
||||||
hmsImplementation 'com.huawei.hms:hianalytics:6.3.2.300'
|
hmsImplementation 'com.huawei.hms:hianalytics:6.4.1.300'
|
||||||
hmsImplementation 'com.huawei.agconnect:agconnect-crash:1.6.3.200'
|
hmsImplementation 'com.huawei.agconnect:agconnect-crash:1.6.5.200'
|
||||||
|
|
||||||
releaseImplementation "com.github.ChuckerTeam.Chucker:library-no-op:$chucker"
|
releaseImplementation "com.github.ChuckerTeam.Chucker:library-no-op:$chucker"
|
||||||
|
|
||||||
debugImplementation "com.github.ChuckerTeam.Chucker:library:$chucker"
|
debugImplementation "com.github.ChuckerTeam.Chucker:library:$chucker"
|
||||||
debugImplementation 'com.github.amitshekhariitbhu.Android-Debug-Database:debug-db:1.0.6'
|
debugImplementation 'com.github.amitshekhariitbhu.Android-Debug-Database:debug-db:1.0.6'
|
||||||
|
debugImplementation 'com.github.haroldadmin:WhatTheStack:1.0.0-alpha04'
|
||||||
|
|
||||||
testImplementation "junit:junit:4.13.2"
|
testImplementation "junit:junit:4.13.2"
|
||||||
testImplementation "io.mockk:mockk:$mockk"
|
testImplementation "io.mockk:mockk:$mockk"
|
||||||
|
2445
app/schemas/io.github.wulkanowy.data.db.AppDatabase/48.json
Normal file
2445
app/schemas/io.github.wulkanowy.data.db.AppDatabase/48.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,23 +1,173 @@
|
|||||||
package io.github.wulkanowy.data
|
package io.github.wulkanowy.data
|
||||||
|
|
||||||
data class Resource<T>(val status: Status, val data: T?, val error: Throwable?) {
|
import kotlinx.coroutines.flow.*
|
||||||
companion object {
|
import kotlinx.coroutines.sync.Mutex
|
||||||
fun <T> success(data: T?): Resource<T> {
|
import kotlinx.coroutines.sync.withLock
|
||||||
return Resource(Status.SUCCESS, data, null)
|
import timber.log.Timber
|
||||||
}
|
|
||||||
|
|
||||||
fun <T> error(error: Throwable?, data: T? = null): Resource<T> {
|
sealed class Resource<T> {
|
||||||
return Resource(Status.ERROR, data, error)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun <T> loading(data: T? = null): Resource<T> {
|
open class Loading<T> : Resource<T>()
|
||||||
return Resource(Status.LOADING, data, null)
|
|
||||||
}
|
data class Intermediate<T>(val data: T) : Loading<T>()
|
||||||
|
|
||||||
|
data class Success<T>(val data: T) : Resource<T>()
|
||||||
|
|
||||||
|
data class Error<T>(val error: Throwable) : Resource<T>()
|
||||||
|
}
|
||||||
|
|
||||||
|
val <T> Resource<T>.dataOrNull: T?
|
||||||
|
get() = when (this) {
|
||||||
|
is Resource.Success -> this.data
|
||||||
|
is Resource.Intermediate -> this.data
|
||||||
|
is Resource.Loading -> null
|
||||||
|
is Resource.Error -> null
|
||||||
|
}
|
||||||
|
|
||||||
|
val <T> Resource<T>.errorOrNull: Throwable?
|
||||||
|
get() = when (this) {
|
||||||
|
is Resource.Error -> this.error
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T> resourceFlow(block: suspend () -> T) = flow {
|
||||||
|
emit(Resource.Loading())
|
||||||
|
emit(Resource.Success(block()))
|
||||||
|
}.catch { emit(Resource.Error(it)) }
|
||||||
|
|
||||||
|
fun <T> flatResourceFlow(block: suspend () -> Flow<Resource<T>>) = flow {
|
||||||
|
emit(Resource.Loading())
|
||||||
|
emitAll(block().filter { it is Resource.Intermediate || it !is Resource.Loading })
|
||||||
|
}.catch { emit(Resource.Error(it)) }
|
||||||
|
|
||||||
|
fun <T, U> Resource<T>.mapData(block: (T) -> U) = when (this) {
|
||||||
|
is Resource.Success -> Resource.Success(block(this.data))
|
||||||
|
is Resource.Intermediate -> Resource.Intermediate(block(this.data))
|
||||||
|
is Resource.Loading -> Resource.Loading()
|
||||||
|
is Resource.Error -> Resource.Error(this.error)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T> Flow<Resource<T>>.logResourceStatus(name: String, showData: Boolean = false) = onEach {
|
||||||
|
val description = when (it) {
|
||||||
|
is Resource.Loading -> "started"
|
||||||
|
is Resource.Intermediate -> "intermediate data received" + if (showData) " (data: `${it.data}`)" else ""
|
||||||
|
is Resource.Success -> "success" + if (showData) " (data: `${it.data}`)" else ""
|
||||||
|
is Resource.Error -> "exception occurred: ${it.error}"
|
||||||
|
}
|
||||||
|
Timber.i("$name: $description")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T, U> Flow<Resource<T>>.mapResourceData(block: (T) -> U) = map {
|
||||||
|
it.mapData(block)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T> Flow<Resource<T>>.onResourceData(block: suspend (T) -> Unit) = onEach {
|
||||||
|
when (it) {
|
||||||
|
is Resource.Success -> block(it.data)
|
||||||
|
is Resource.Intermediate -> block(it.data)
|
||||||
|
is Resource.Error,
|
||||||
|
is Resource.Loading -> Unit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class Status {
|
fun <T> Flow<Resource<T>>.onResourceLoading(block: suspend () -> Unit) = onEach {
|
||||||
LOADING,
|
if (it is Resource.Loading) {
|
||||||
SUCCESS,
|
block()
|
||||||
ERROR
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T> Flow<Resource<T>>.onResourceIntermediate(block: suspend (T) -> Unit) = onEach {
|
||||||
|
if (it is Resource.Intermediate) {
|
||||||
|
block(it.data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T> Flow<Resource<T>>.onResourceSuccess(block: suspend (T) -> Unit) = onEach {
|
||||||
|
if (it is Resource.Success) {
|
||||||
|
block(it.data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T> Flow<Resource<T>>.onResourceError(block: (Throwable) -> Unit) = onEach {
|
||||||
|
if (it is Resource.Error) {
|
||||||
|
block(it.error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T> Flow<Resource<T>>.onResourceNotLoading(block: () -> Unit) = onEach {
|
||||||
|
if (it !is Resource.Loading) {
|
||||||
|
block()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun <T> Flow<Resource<T>>.toFirstResult() = filter { it !is Resource.Loading }.first()
|
||||||
|
|
||||||
|
suspend fun <T> Flow<Resource<T>>.waitForResult() = takeWhile { it is Resource.Loading }.collect()
|
||||||
|
|
||||||
|
inline fun <ResultType, RequestType> networkBoundResource(
|
||||||
|
mutex: Mutex = Mutex(),
|
||||||
|
showSavedOnLoading: Boolean = true,
|
||||||
|
crossinline isResultEmpty: (ResultType) -> Boolean,
|
||||||
|
crossinline query: () -> Flow<ResultType>,
|
||||||
|
crossinline fetch: suspend (ResultType) -> RequestType,
|
||||||
|
crossinline saveFetchResult: suspend (old: ResultType, new: RequestType) -> Unit,
|
||||||
|
crossinline onFetchFailed: (Throwable) -> Unit = { },
|
||||||
|
crossinline shouldFetch: (ResultType) -> Boolean = { true },
|
||||||
|
crossinline filterResult: (ResultType) -> ResultType = { it }
|
||||||
|
) = flow {
|
||||||
|
emit(Resource.Loading())
|
||||||
|
|
||||||
|
val data = query().first()
|
||||||
|
emitAll(if (shouldFetch(data)) {
|
||||||
|
val filteredResult = filterResult(data)
|
||||||
|
|
||||||
|
if (showSavedOnLoading && !isResultEmpty(filteredResult)) {
|
||||||
|
emit(Resource.Intermediate(filteredResult))
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
val newData = fetch(data)
|
||||||
|
mutex.withLock { saveFetchResult(query().first(), newData) }
|
||||||
|
query().map { Resource.Success(filterResult(it)) }
|
||||||
|
} catch (throwable: Throwable) {
|
||||||
|
onFetchFailed(throwable)
|
||||||
|
query().map { Resource.Error(throwable) }
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
query().map { Resource.Success(filterResult(it)) }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmName("networkBoundResourceWithMap")
|
||||||
|
inline fun <ResultType, RequestType, T> networkBoundResource(
|
||||||
|
mutex: Mutex = Mutex(),
|
||||||
|
showSavedOnLoading: Boolean = true,
|
||||||
|
crossinline isResultEmpty: (T) -> Boolean,
|
||||||
|
crossinline query: () -> Flow<ResultType>,
|
||||||
|
crossinline fetch: suspend (ResultType) -> RequestType,
|
||||||
|
crossinline saveFetchResult: suspend (old: ResultType, new: RequestType) -> Unit,
|
||||||
|
crossinline onFetchFailed: (Throwable) -> Unit = { },
|
||||||
|
crossinline shouldFetch: (ResultType) -> Boolean = { true },
|
||||||
|
crossinline mapResult: (ResultType) -> T
|
||||||
|
) = flow {
|
||||||
|
emit(Resource.Loading())
|
||||||
|
|
||||||
|
val data = query().first()
|
||||||
|
emitAll(if (shouldFetch(data)) {
|
||||||
|
val mappedResult = mapResult(data)
|
||||||
|
|
||||||
|
if (showSavedOnLoading && !isResultEmpty(mappedResult)) {
|
||||||
|
emit(Resource.Intermediate(mappedResult))
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
val newData = fetch(data)
|
||||||
|
mutex.withLock { saveFetchResult(query().first(), newData) }
|
||||||
|
query().map { Resource.Success(mapResult(it)) }
|
||||||
|
} catch (throwable: Throwable) {
|
||||||
|
onFetchFailed(throwable)
|
||||||
|
query().map { Resource.Error(throwable) }
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
query().map { Resource.Success(mapResult(it)) }
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
@ -1,72 +1,10 @@
|
|||||||
package io.github.wulkanowy.data.db
|
package io.github.wulkanowy.data.db
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.room.AutoMigration
|
import androidx.room.*
|
||||||
import androidx.room.Database
|
|
||||||
import androidx.room.Room
|
|
||||||
import androidx.room.RoomDatabase
|
|
||||||
import androidx.room.RoomDatabase.JournalMode.TRUNCATE
|
import androidx.room.RoomDatabase.JournalMode.TRUNCATE
|
||||||
import androidx.room.TypeConverters
|
import io.github.wulkanowy.data.db.dao.*
|
||||||
import io.github.wulkanowy.data.db.dao.AdminMessageDao
|
import io.github.wulkanowy.data.db.entities.*
|
||||||
import io.github.wulkanowy.data.db.dao.AttendanceDao
|
|
||||||
import io.github.wulkanowy.data.db.dao.AttendanceSummaryDao
|
|
||||||
import io.github.wulkanowy.data.db.dao.CompletedLessonsDao
|
|
||||||
import io.github.wulkanowy.data.db.dao.ConferenceDao
|
|
||||||
import io.github.wulkanowy.data.db.dao.ExamDao
|
|
||||||
import io.github.wulkanowy.data.db.dao.GradeDao
|
|
||||||
import io.github.wulkanowy.data.db.dao.GradePartialStatisticsDao
|
|
||||||
import io.github.wulkanowy.data.db.dao.GradePointsStatisticsDao
|
|
||||||
import io.github.wulkanowy.data.db.dao.GradeSemesterStatisticsDao
|
|
||||||
import io.github.wulkanowy.data.db.dao.GradeSummaryDao
|
|
||||||
import io.github.wulkanowy.data.db.dao.HomeworkDao
|
|
||||||
import io.github.wulkanowy.data.db.dao.LuckyNumberDao
|
|
||||||
import io.github.wulkanowy.data.db.dao.MessageAttachmentDao
|
|
||||||
import io.github.wulkanowy.data.db.dao.MessagesDao
|
|
||||||
import io.github.wulkanowy.data.db.dao.MobileDeviceDao
|
|
||||||
import io.github.wulkanowy.data.db.dao.NoteDao
|
|
||||||
import io.github.wulkanowy.data.db.dao.NotificationDao
|
|
||||||
import io.github.wulkanowy.data.db.dao.RecipientDao
|
|
||||||
import io.github.wulkanowy.data.db.dao.ReportingUnitDao
|
|
||||||
import io.github.wulkanowy.data.db.dao.SchoolAnnouncementDao
|
|
||||||
import io.github.wulkanowy.data.db.dao.SchoolDao
|
|
||||||
import io.github.wulkanowy.data.db.dao.SemesterDao
|
|
||||||
import io.github.wulkanowy.data.db.dao.StudentDao
|
|
||||||
import io.github.wulkanowy.data.db.dao.StudentInfoDao
|
|
||||||
import io.github.wulkanowy.data.db.dao.SubjectDao
|
|
||||||
import io.github.wulkanowy.data.db.dao.TeacherDao
|
|
||||||
import io.github.wulkanowy.data.db.dao.TimetableAdditionalDao
|
|
||||||
import io.github.wulkanowy.data.db.dao.TimetableDao
|
|
||||||
import io.github.wulkanowy.data.db.dao.TimetableHeaderDao
|
|
||||||
import io.github.wulkanowy.data.db.entities.AdminMessage
|
|
||||||
import io.github.wulkanowy.data.db.entities.Attendance
|
|
||||||
import io.github.wulkanowy.data.db.entities.AttendanceSummary
|
|
||||||
import io.github.wulkanowy.data.db.entities.CompletedLesson
|
|
||||||
import io.github.wulkanowy.data.db.entities.Conference
|
|
||||||
import io.github.wulkanowy.data.db.entities.Exam
|
|
||||||
import io.github.wulkanowy.data.db.entities.Grade
|
|
||||||
import io.github.wulkanowy.data.db.entities.GradePartialStatistics
|
|
||||||
import io.github.wulkanowy.data.db.entities.GradePointsStatistics
|
|
||||||
import io.github.wulkanowy.data.db.entities.GradeSemesterStatistics
|
|
||||||
import io.github.wulkanowy.data.db.entities.GradeSummary
|
|
||||||
import io.github.wulkanowy.data.db.entities.Homework
|
|
||||||
import io.github.wulkanowy.data.db.entities.LuckyNumber
|
|
||||||
import io.github.wulkanowy.data.db.entities.Message
|
|
||||||
import io.github.wulkanowy.data.db.entities.MessageAttachment
|
|
||||||
import io.github.wulkanowy.data.db.entities.MobileDevice
|
|
||||||
import io.github.wulkanowy.data.db.entities.Note
|
|
||||||
import io.github.wulkanowy.data.db.entities.Notification
|
|
||||||
import io.github.wulkanowy.data.db.entities.Recipient
|
|
||||||
import io.github.wulkanowy.data.db.entities.ReportingUnit
|
|
||||||
import io.github.wulkanowy.data.db.entities.School
|
|
||||||
import io.github.wulkanowy.data.db.entities.SchoolAnnouncement
|
|
||||||
import io.github.wulkanowy.data.db.entities.Semester
|
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
|
||||||
import io.github.wulkanowy.data.db.entities.StudentInfo
|
|
||||||
import io.github.wulkanowy.data.db.entities.Subject
|
|
||||||
import io.github.wulkanowy.data.db.entities.Teacher
|
|
||||||
import io.github.wulkanowy.data.db.entities.Timetable
|
|
||||||
import io.github.wulkanowy.data.db.entities.TimetableAdditional
|
|
||||||
import io.github.wulkanowy.data.db.entities.TimetableHeader
|
|
||||||
import io.github.wulkanowy.data.db.migrations.*
|
import io.github.wulkanowy.data.db.migrations.*
|
||||||
import io.github.wulkanowy.utils.AppInfo
|
import io.github.wulkanowy.utils.AppInfo
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
@ -108,6 +46,7 @@ import javax.inject.Singleton
|
|||||||
autoMigrations = [
|
autoMigrations = [
|
||||||
AutoMigration(from = 44, to = 45),
|
AutoMigration(from = 44, to = 45),
|
||||||
AutoMigration(from = 46, to = 47),
|
AutoMigration(from = 46, to = 47),
|
||||||
|
AutoMigration(from = 47, to = 48),
|
||||||
],
|
],
|
||||||
version = AppDatabase.VERSION_SCHEMA,
|
version = AppDatabase.VERSION_SCHEMA,
|
||||||
exportSchema = true
|
exportSchema = true
|
||||||
@ -116,7 +55,7 @@ import javax.inject.Singleton
|
|||||||
abstract class AppDatabase : RoomDatabase() {
|
abstract class AppDatabase : RoomDatabase() {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val VERSION_SCHEMA = 47
|
const val VERSION_SCHEMA = 48
|
||||||
|
|
||||||
fun getMigrations(sharedPrefProvider: SharedPrefProvider, appInfo: AppInfo) = arrayOf(
|
fun getMigrations(sharedPrefProvider: SharedPrefProvider, appInfo: AppInfo) = arrayOf(
|
||||||
Migration2(),
|
Migration2(),
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
package io.github.wulkanowy.data.db
|
package io.github.wulkanowy.data.db
|
||||||
|
|
||||||
import androidx.room.TypeConverter
|
import androidx.room.TypeConverter
|
||||||
|
import io.github.wulkanowy.ui.modules.Destination
|
||||||
import io.github.wulkanowy.utils.toTimestamp
|
import io.github.wulkanowy.utils.toTimestamp
|
||||||
import kotlinx.serialization.SerializationException
|
import kotlinx.serialization.SerializationException
|
||||||
import kotlinx.serialization.decodeFromString
|
import kotlinx.serialization.decodeFromString
|
||||||
import kotlinx.serialization.encodeToString
|
import kotlinx.serialization.encodeToString
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
|
import java.time.*
|
||||||
|
import java.util.*
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import java.time.LocalDate
|
import java.time.LocalDate
|
||||||
import java.time.Month
|
import java.time.Month
|
||||||
@ -58,4 +61,11 @@ class Converters {
|
|||||||
emptyList() // handle errors from old gson Pair serialized data
|
emptyList() // handle errors from old gson Pair serialized data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TypeConverter
|
||||||
|
fun destinationToString(destination: Destination) = json.encodeToString(destination)
|
||||||
|
|
||||||
|
@TypeConverter
|
||||||
|
fun stringToDestination(destination: String): Destination = json.decodeFromString(destination)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,10 @@ abstract class StudentDao {
|
|||||||
@Query("SELECT * FROM Students")
|
@Query("SELECT * FROM Students")
|
||||||
abstract suspend fun loadStudentsWithSemesters(): List<StudentWithSemesters>
|
abstract suspend fun loadStudentsWithSemesters(): List<StudentWithSemesters>
|
||||||
|
|
||||||
|
@Transaction
|
||||||
|
@Query("SELECT * FROM Students WHERE id = :id")
|
||||||
|
abstract suspend fun loadStudentWithSemestersById(id: Long): StudentWithSemesters?
|
||||||
|
|
||||||
@Query("UPDATE Students SET is_current = 1 WHERE id = :id")
|
@Query("UPDATE Students SET is_current = 1 WHERE id = :id")
|
||||||
abstract suspend fun updateCurrent(id: Long)
|
abstract suspend fun updateCurrent(id: Long)
|
||||||
|
|
||||||
|
@ -24,5 +24,8 @@ data class GradeSemesterStatistics(
|
|||||||
var id: Long = 0
|
var id: Long = 0
|
||||||
|
|
||||||
@Transient
|
@Transient
|
||||||
var average: String = ""
|
var classAverage: String = ""
|
||||||
|
|
||||||
|
@Transient
|
||||||
|
var studentAverage: String = ""
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import androidx.room.ColumnInfo
|
|||||||
import androidx.room.Entity
|
import androidx.room.Entity
|
||||||
import androidx.room.PrimaryKey
|
import androidx.room.PrimaryKey
|
||||||
import io.github.wulkanowy.services.sync.notifications.NotificationType
|
import io.github.wulkanowy.services.sync.notifications.NotificationType
|
||||||
|
import io.github.wulkanowy.ui.modules.Destination
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
|
|
||||||
@Entity(tableName = "Notifications")
|
@Entity(tableName = "Notifications")
|
||||||
@ -18,6 +19,9 @@ data class Notification(
|
|||||||
|
|
||||||
val type: NotificationType,
|
val type: NotificationType,
|
||||||
|
|
||||||
|
@ColumnInfo(defaultValue = "{\"type\":\"io.github.wulkanowy.ui.modules.Destination.Dashboard\"}")
|
||||||
|
val destination: Destination,
|
||||||
|
|
||||||
val date: Instant,
|
val date: Instant,
|
||||||
|
|
||||||
val data: String? = null
|
val data: String? = null
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package io.github.wulkanowy.data.pojos
|
package io.github.wulkanowy.data.pojos
|
||||||
|
|
||||||
import android.content.Intent
|
|
||||||
import io.github.wulkanowy.services.sync.notifications.NotificationType
|
import io.github.wulkanowy.services.sync.notifications.NotificationType
|
||||||
|
import io.github.wulkanowy.ui.modules.Destination
|
||||||
|
|
||||||
data class NotificationData(
|
data class NotificationData(
|
||||||
val intentToStart: Intent,
|
val destination: Destination,
|
||||||
val title: String,
|
val title: String,
|
||||||
val content: String
|
val content: String
|
||||||
)
|
)
|
||||||
@ -13,7 +13,7 @@ data class GroupNotificationData(
|
|||||||
val notificationDataList: List<NotificationData>,
|
val notificationDataList: List<NotificationData>,
|
||||||
val title: String,
|
val title: String,
|
||||||
val content: String,
|
val content: String,
|
||||||
val intentToStart: Intent,
|
val destination: Destination,
|
||||||
val type: NotificationType
|
val type: NotificationType
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -3,8 +3,8 @@ package io.github.wulkanowy.data.repositories
|
|||||||
import io.github.wulkanowy.data.api.AdminMessageService
|
import io.github.wulkanowy.data.api.AdminMessageService
|
||||||
import io.github.wulkanowy.data.db.dao.AdminMessageDao
|
import io.github.wulkanowy.data.db.dao.AdminMessageDao
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
|
import io.github.wulkanowy.data.networkBoundResource
|
||||||
import io.github.wulkanowy.utils.AppInfo
|
import io.github.wulkanowy.utils.AppInfo
|
||||||
import io.github.wulkanowy.utils.networkBoundResource
|
|
||||||
import kotlinx.coroutines.sync.Mutex
|
import kotlinx.coroutines.sync.Mutex
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
@ -19,6 +19,7 @@ class AdminMessageRepository @Inject constructor(
|
|||||||
|
|
||||||
suspend fun getAdminMessages(student: Student) = networkBoundResource(
|
suspend fun getAdminMessages(student: Student) = networkBoundResource(
|
||||||
mutex = saveFetchResultMutex,
|
mutex = saveFetchResultMutex,
|
||||||
|
isResultEmpty = { it == null },
|
||||||
query = { adminMessageDao.loadAll() },
|
query = { adminMessageDao.loadAll() },
|
||||||
fetch = { adminMessageService.getAdminMessages() },
|
fetch = { adminMessageService.getAdminMessages() },
|
||||||
shouldFetch = { true },
|
shouldFetch = { true },
|
||||||
|
@ -5,6 +5,7 @@ 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.data.db.entities.Student
|
||||||
import io.github.wulkanowy.data.mappers.mapToEntities
|
import io.github.wulkanowy.data.mappers.mapToEntities
|
||||||
|
import io.github.wulkanowy.data.networkBoundResource
|
||||||
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.*
|
import io.github.wulkanowy.utils.*
|
||||||
@ -36,6 +37,7 @@ class AttendanceRepository @Inject constructor(
|
|||||||
notify: Boolean = false,
|
notify: Boolean = false,
|
||||||
) = networkBoundResource(
|
) = networkBoundResource(
|
||||||
mutex = saveFetchResultMutex,
|
mutex = saveFetchResultMutex,
|
||||||
|
isResultEmpty = { it.isEmpty() },
|
||||||
shouldFetch = {
|
shouldFetch = {
|
||||||
val isExpired = refreshHelper.shouldBeRefreshed(
|
val isExpired = refreshHelper.shouldBeRefreshed(
|
||||||
key = getRefreshKey(cacheKey, semester, start, end)
|
key = getRefreshKey(cacheKey, semester, start, end)
|
||||||
|
@ -4,8 +4,12 @@ import io.github.wulkanowy.data.db.dao.AttendanceSummaryDao
|
|||||||
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.mappers.mapToEntities
|
import io.github.wulkanowy.data.mappers.mapToEntities
|
||||||
|
import io.github.wulkanowy.data.networkBoundResource
|
||||||
import io.github.wulkanowy.sdk.Sdk
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
import io.github.wulkanowy.utils.*
|
import io.github.wulkanowy.utils.AutoRefreshHelper
|
||||||
|
import io.github.wulkanowy.utils.getRefreshKey
|
||||||
|
import io.github.wulkanowy.utils.init
|
||||||
|
import io.github.wulkanowy.utils.uniqueSubtract
|
||||||
import kotlinx.coroutines.sync.Mutex
|
import kotlinx.coroutines.sync.Mutex
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
@ -28,6 +32,7 @@ class AttendanceSummaryRepository @Inject constructor(
|
|||||||
forceRefresh: Boolean,
|
forceRefresh: Boolean,
|
||||||
) = networkBoundResource(
|
) = networkBoundResource(
|
||||||
mutex = saveFetchResultMutex,
|
mutex = saveFetchResultMutex,
|
||||||
|
isResultEmpty = { it.isEmpty() },
|
||||||
shouldFetch = {
|
shouldFetch = {
|
||||||
val isExpired = refreshHelper.shouldBeRefreshed(getRefreshKey(cacheKey, semester))
|
val isExpired = refreshHelper.shouldBeRefreshed(getRefreshKey(cacheKey, semester))
|
||||||
it.isEmpty() || forceRefresh || isExpired
|
it.isEmpty() || forceRefresh || isExpired
|
||||||
|
@ -4,6 +4,7 @@ import io.github.wulkanowy.data.db.dao.CompletedLessonsDao
|
|||||||
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.mappers.mapToEntities
|
import io.github.wulkanowy.data.mappers.mapToEntities
|
||||||
|
import io.github.wulkanowy.data.networkBoundResource
|
||||||
import io.github.wulkanowy.sdk.Sdk
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
import io.github.wulkanowy.utils.*
|
import io.github.wulkanowy.utils.*
|
||||||
import kotlinx.coroutines.sync.Mutex
|
import kotlinx.coroutines.sync.Mutex
|
||||||
@ -30,6 +31,7 @@ class CompletedLessonsRepository @Inject constructor(
|
|||||||
forceRefresh: Boolean,
|
forceRefresh: Boolean,
|
||||||
) = networkBoundResource(
|
) = networkBoundResource(
|
||||||
mutex = saveFetchResultMutex,
|
mutex = saveFetchResultMutex,
|
||||||
|
isResultEmpty = { it.isEmpty() },
|
||||||
shouldFetch = {
|
shouldFetch = {
|
||||||
val isExpired = refreshHelper.shouldBeRefreshed(
|
val isExpired = refreshHelper.shouldBeRefreshed(
|
||||||
key = getRefreshKey(cacheKey, semester, start, end)
|
key = getRefreshKey(cacheKey, semester, start, end)
|
||||||
|
@ -5,8 +5,12 @@ import io.github.wulkanowy.data.db.entities.Conference
|
|||||||
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.mappers.mapToEntities
|
import io.github.wulkanowy.data.mappers.mapToEntities
|
||||||
|
import io.github.wulkanowy.data.networkBoundResource
|
||||||
import io.github.wulkanowy.sdk.Sdk
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
import io.github.wulkanowy.utils.*
|
import io.github.wulkanowy.utils.AutoRefreshHelper
|
||||||
|
import io.github.wulkanowy.utils.getRefreshKey
|
||||||
|
import io.github.wulkanowy.utils.init
|
||||||
|
import io.github.wulkanowy.utils.uniqueSubtract
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.sync.Mutex
|
import kotlinx.coroutines.sync.Mutex
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
@ -32,6 +36,7 @@ class ConferenceRepository @Inject constructor(
|
|||||||
startDate: Instant = Instant.EPOCH,
|
startDate: Instant = Instant.EPOCH,
|
||||||
) = networkBoundResource(
|
) = networkBoundResource(
|
||||||
mutex = saveFetchResultMutex,
|
mutex = saveFetchResultMutex,
|
||||||
|
isResultEmpty = { it.isEmpty() },
|
||||||
shouldFetch = {
|
shouldFetch = {
|
||||||
val isExpired = refreshHelper.shouldBeRefreshed(getRefreshKey(cacheKey, semester))
|
val isExpired = refreshHelper.shouldBeRefreshed(getRefreshKey(cacheKey, semester))
|
||||||
it.isEmpty() || forceRefresh || isExpired
|
it.isEmpty() || forceRefresh || isExpired
|
||||||
|
@ -5,6 +5,7 @@ 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.data.db.entities.Student
|
||||||
import io.github.wulkanowy.data.mappers.mapToEntities
|
import io.github.wulkanowy.data.mappers.mapToEntities
|
||||||
|
import io.github.wulkanowy.data.networkBoundResource
|
||||||
import io.github.wulkanowy.sdk.Sdk
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
import io.github.wulkanowy.utils.*
|
import io.github.wulkanowy.utils.*
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
@ -33,6 +34,7 @@ class ExamRepository @Inject constructor(
|
|||||||
notify: Boolean = false,
|
notify: Boolean = false,
|
||||||
) = networkBoundResource(
|
) = networkBoundResource(
|
||||||
mutex = saveFetchResultMutex,
|
mutex = saveFetchResultMutex,
|
||||||
|
isResultEmpty = { it.isEmpty() },
|
||||||
shouldFetch = {
|
shouldFetch = {
|
||||||
val isExpired = refreshHelper.shouldBeRefreshed(
|
val isExpired = refreshHelper.shouldBeRefreshed(
|
||||||
key = getRefreshKey(cacheKey, semester, start, end)
|
key = getRefreshKey(cacheKey, semester, start, end)
|
||||||
|
@ -7,6 +7,7 @@ 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.data.mappers.mapToEntities
|
import io.github.wulkanowy.data.mappers.mapToEntities
|
||||||
|
import io.github.wulkanowy.data.networkBoundResource
|
||||||
import io.github.wulkanowy.sdk.Sdk
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
import io.github.wulkanowy.utils.*
|
import io.github.wulkanowy.utils.*
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
@ -36,6 +37,10 @@ class GradeRepository @Inject constructor(
|
|||||||
notify: Boolean = false,
|
notify: Boolean = false,
|
||||||
) = networkBoundResource(
|
) = networkBoundResource(
|
||||||
mutex = saveFetchResultMutex,
|
mutex = saveFetchResultMutex,
|
||||||
|
isResultEmpty = {
|
||||||
|
//When details is empty and summary is not, app will not use summary cache - edge case
|
||||||
|
it.first.isEmpty()
|
||||||
|
},
|
||||||
shouldFetch = { (details, summaries) ->
|
shouldFetch = { (details, summaries) ->
|
||||||
val isExpired = refreshHelper.shouldBeRefreshed(getRefreshKey(cacheKey, semester))
|
val isExpired = refreshHelper.shouldBeRefreshed(getRefreshKey(cacheKey, semester))
|
||||||
details.isEmpty() || summaries.isEmpty() || forceRefresh || isExpired
|
details.isEmpty() || summaries.isEmpty() || forceRefresh || isExpired
|
||||||
|
@ -11,8 +11,12 @@ import io.github.wulkanowy.data.mappers.mapPartialToStatisticItems
|
|||||||
import io.github.wulkanowy.data.mappers.mapPointsToStatisticsItems
|
import io.github.wulkanowy.data.mappers.mapPointsToStatisticsItems
|
||||||
import io.github.wulkanowy.data.mappers.mapSemesterToStatisticItems
|
import io.github.wulkanowy.data.mappers.mapSemesterToStatisticItems
|
||||||
import io.github.wulkanowy.data.mappers.mapToEntities
|
import io.github.wulkanowy.data.mappers.mapToEntities
|
||||||
|
import io.github.wulkanowy.data.networkBoundResource
|
||||||
import io.github.wulkanowy.sdk.Sdk
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
import io.github.wulkanowy.utils.*
|
import io.github.wulkanowy.utils.AutoRefreshHelper
|
||||||
|
import io.github.wulkanowy.utils.getRefreshKey
|
||||||
|
import io.github.wulkanowy.utils.init
|
||||||
|
import io.github.wulkanowy.utils.uniqueSubtract
|
||||||
import kotlinx.coroutines.sync.Mutex
|
import kotlinx.coroutines.sync.Mutex
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@ -42,6 +46,7 @@ class GradeStatisticsRepository @Inject constructor(
|
|||||||
forceRefresh: Boolean,
|
forceRefresh: Boolean,
|
||||||
) = networkBoundResource(
|
) = networkBoundResource(
|
||||||
mutex = partialMutex,
|
mutex = partialMutex,
|
||||||
|
isResultEmpty = { it.isEmpty() },
|
||||||
shouldFetch = {
|
shouldFetch = {
|
||||||
val isExpired = refreshHelper.shouldBeRefreshed(
|
val isExpired = refreshHelper.shouldBeRefreshed(
|
||||||
key = getRefreshKey(partialCacheKey, semester)
|
key = getRefreshKey(partialCacheKey, semester)
|
||||||
@ -63,20 +68,16 @@ class GradeStatisticsRepository @Inject constructor(
|
|||||||
mapResult = { items ->
|
mapResult = { items ->
|
||||||
when (subjectName) {
|
when (subjectName) {
|
||||||
"Wszystkie" -> {
|
"Wszystkie" -> {
|
||||||
val numerator = items.map {
|
val summaryItem = GradePartialStatistics(
|
||||||
it.classAverage.replace(",", ".").toDoubleOrNull() ?: .0
|
|
||||||
}.filterNot { it == .0 }
|
|
||||||
(items.reversed() + GradePartialStatistics(
|
|
||||||
studentId = semester.studentId,
|
studentId = semester.studentId,
|
||||||
semesterId = semester.semesterId,
|
semesterId = semester.semesterId,
|
||||||
subject = subjectName,
|
subject = subjectName,
|
||||||
classAverage = if (numerator.isEmpty()) "" else numerator.average().let {
|
classAverage = items.map { it.classAverage }.getSummaryAverage(),
|
||||||
"%.2f".format(Locale.FRANCE, it)
|
studentAverage = items.map { it.studentAverage }.getSummaryAverage(),
|
||||||
},
|
|
||||||
studentAverage = "",
|
|
||||||
classAmounts = items.map { it.classAmounts }.sumGradeAmounts(),
|
classAmounts = items.map { it.classAmounts }.sumGradeAmounts(),
|
||||||
studentAmounts = items.map { it.studentAmounts }.sumGradeAmounts()
|
studentAmounts = items.map { it.studentAmounts }.sumGradeAmounts()
|
||||||
)).reversed()
|
)
|
||||||
|
listOf(summaryItem) + items
|
||||||
}
|
}
|
||||||
else -> items.filter { it.subject == subjectName }
|
else -> items.filter { it.subject == subjectName }
|
||||||
}.mapPartialToStatisticItems()
|
}.mapPartialToStatisticItems()
|
||||||
@ -90,6 +91,7 @@ class GradeStatisticsRepository @Inject constructor(
|
|||||||
forceRefresh: Boolean,
|
forceRefresh: Boolean,
|
||||||
) = networkBoundResource(
|
) = networkBoundResource(
|
||||||
mutex = semesterMutex,
|
mutex = semesterMutex,
|
||||||
|
isResultEmpty = { it.isEmpty() },
|
||||||
shouldFetch = {
|
shouldFetch = {
|
||||||
val isExpired = refreshHelper.shouldBeRefreshed(
|
val isExpired = refreshHelper.shouldBeRefreshed(
|
||||||
key = getRefreshKey(semesterCacheKey, semester)
|
key = getRefreshKey(semesterCacheKey, semester)
|
||||||
@ -112,29 +114,29 @@ class GradeStatisticsRepository @Inject constructor(
|
|||||||
val itemsWithAverage = items.map { item ->
|
val itemsWithAverage = items.map { item ->
|
||||||
item.copy().apply {
|
item.copy().apply {
|
||||||
val denominator = item.amounts.sum()
|
val denominator = item.amounts.sum()
|
||||||
average = if (denominator == 0) "" else {
|
classAverage = if (denominator == 0) "" else {
|
||||||
(item.amounts.mapIndexed { gradeValue, amount ->
|
(item.amounts.mapIndexed { gradeValue, amount ->
|
||||||
(gradeValue + 1) * amount
|
(gradeValue + 1) * amount
|
||||||
}.sum().toDouble() / denominator).let {
|
}.sum().toDouble() / denominator).asAverageString()
|
||||||
"%.2f".format(Locale.FRANCE, it)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
when (subjectName) {
|
when (subjectName) {
|
||||||
"Wszystkie" -> (itemsWithAverage.reversed() + GradeSemesterStatistics(
|
"Wszystkie" -> {
|
||||||
studentId = semester.studentId,
|
val summaryItem = GradeSemesterStatistics(
|
||||||
semesterId = semester.semesterId,
|
studentId = semester.studentId,
|
||||||
subject = subjectName,
|
semesterId = semester.semesterId,
|
||||||
amounts = itemsWithAverage.map { it.amounts }.sumGradeAmounts(),
|
subject = subjectName,
|
||||||
studentGrade = 0
|
amounts = itemsWithAverage.map { it.amounts }.sumGradeAmounts(),
|
||||||
).apply {
|
studentGrade = 0,
|
||||||
average = itemsWithAverage.mapNotNull {
|
).apply {
|
||||||
it.average.replace(",", ".").toDoubleOrNull()
|
classAverage = itemsWithAverage.map { it.classAverage }.getSummaryAverage()
|
||||||
}.average().let {
|
studentAverage = items
|
||||||
"%.2f".format(Locale.FRANCE, it)
|
.mapNotNull { summary -> summary.studentGrade.takeIf { it != 0 } }
|
||||||
|
.average().asAverageString()
|
||||||
}
|
}
|
||||||
}).reversed()
|
listOf(summaryItem) + itemsWithAverage
|
||||||
|
}
|
||||||
else -> itemsWithAverage.filter { it.subject == subjectName }
|
else -> itemsWithAverage.filter { it.subject == subjectName }
|
||||||
}.mapSemesterToStatisticItems()
|
}.mapSemesterToStatisticItems()
|
||||||
}
|
}
|
||||||
@ -147,6 +149,7 @@ class GradeStatisticsRepository @Inject constructor(
|
|||||||
forceRefresh: Boolean,
|
forceRefresh: Boolean,
|
||||||
) = networkBoundResource(
|
) = networkBoundResource(
|
||||||
mutex = pointsMutex,
|
mutex = pointsMutex,
|
||||||
|
isResultEmpty = { it.isEmpty() },
|
||||||
shouldFetch = {
|
shouldFetch = {
|
||||||
val isExpired = refreshHelper.shouldBeRefreshed(getRefreshKey(pointsCacheKey, semester))
|
val isExpired = refreshHelper.shouldBeRefreshed(getRefreshKey(pointsCacheKey, semester))
|
||||||
it.isEmpty() || forceRefresh || isExpired
|
it.isEmpty() || forceRefresh || isExpired
|
||||||
@ -171,6 +174,19 @@ class GradeStatisticsRepository @Inject constructor(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
private fun List<String>.getSummaryAverage(): String {
|
||||||
|
val averages = mapNotNull {
|
||||||
|
it.replace(",", ".").toDoubleOrNull()
|
||||||
|
}
|
||||||
|
|
||||||
|
return averages.average()
|
||||||
|
.asAverageString()
|
||||||
|
.takeIf { averages.isNotEmpty() }
|
||||||
|
.orEmpty()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Double.asAverageString(): String = "%.2f".format(Locale.FRANCE, this)
|
||||||
|
|
||||||
private fun List<List<Int>>.sumGradeAmounts(): List<Int> {
|
private fun List<List<Int>>.sumGradeAmounts(): List<Int> {
|
||||||
val result = mutableListOf(0, 0, 0, 0, 0, 0)
|
val result = mutableListOf(0, 0, 0, 0, 0, 0)
|
||||||
forEach {
|
forEach {
|
||||||
|
@ -5,6 +5,7 @@ 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.data.db.entities.Student
|
||||||
import io.github.wulkanowy.data.mappers.mapToEntities
|
import io.github.wulkanowy.data.mappers.mapToEntities
|
||||||
|
import io.github.wulkanowy.data.networkBoundResource
|
||||||
import io.github.wulkanowy.sdk.Sdk
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
import io.github.wulkanowy.utils.*
|
import io.github.wulkanowy.utils.*
|
||||||
import kotlinx.coroutines.sync.Mutex
|
import kotlinx.coroutines.sync.Mutex
|
||||||
@ -32,6 +33,7 @@ class HomeworkRepository @Inject constructor(
|
|||||||
notify: Boolean = false,
|
notify: Boolean = false,
|
||||||
) = networkBoundResource(
|
) = networkBoundResource(
|
||||||
mutex = saveFetchResultMutex,
|
mutex = saveFetchResultMutex,
|
||||||
|
isResultEmpty = { it.isEmpty() },
|
||||||
shouldFetch = {
|
shouldFetch = {
|
||||||
val isExpired = refreshHelper.shouldBeRefreshed(
|
val isExpired = refreshHelper.shouldBeRefreshed(
|
||||||
key = getRefreshKey(cacheKey, semester, start, end)
|
key = getRefreshKey(cacheKey, semester, start, end)
|
||||||
|
@ -4,9 +4,9 @@ import io.github.wulkanowy.data.db.dao.LuckyNumberDao
|
|||||||
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.data.mappers.mapToEntity
|
import io.github.wulkanowy.data.mappers.mapToEntity
|
||||||
|
import io.github.wulkanowy.data.networkBoundResource
|
||||||
import io.github.wulkanowy.sdk.Sdk
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
import io.github.wulkanowy.utils.init
|
import io.github.wulkanowy.utils.init
|
||||||
import io.github.wulkanowy.utils.networkBoundResource
|
|
||||||
import kotlinx.coroutines.flow.first
|
import kotlinx.coroutines.flow.first
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.coroutines.sync.Mutex
|
import kotlinx.coroutines.sync.Mutex
|
||||||
@ -29,6 +29,7 @@ class LuckyNumberRepository @Inject constructor(
|
|||||||
notify: Boolean = false,
|
notify: Boolean = false,
|
||||||
) = networkBoundResource(
|
) = networkBoundResource(
|
||||||
mutex = saveFetchResultMutex,
|
mutex = saveFetchResultMutex,
|
||||||
|
isResultEmpty = { it == null },
|
||||||
shouldFetch = { it == null || forceRefresh },
|
shouldFetch = { it == null || forceRefresh },
|
||||||
query = { luckyNumberDb.load(student.studentId, now()) },
|
query = { luckyNumberDb.load(student.studentId, now()) },
|
||||||
fetch = {
|
fetch = {
|
||||||
|
@ -7,15 +7,12 @@ import io.github.wulkanowy.data.Resource
|
|||||||
import io.github.wulkanowy.data.db.SharedPrefProvider
|
import io.github.wulkanowy.data.db.SharedPrefProvider
|
||||||
import io.github.wulkanowy.data.db.dao.MessageAttachmentDao
|
import io.github.wulkanowy.data.db.dao.MessageAttachmentDao
|
||||||
import io.github.wulkanowy.data.db.dao.MessagesDao
|
import io.github.wulkanowy.data.db.dao.MessagesDao
|
||||||
import io.github.wulkanowy.data.db.entities.Message
|
import io.github.wulkanowy.data.db.entities.*
|
||||||
import io.github.wulkanowy.data.db.entities.MessageWithAttachment
|
|
||||||
import io.github.wulkanowy.data.db.entities.Recipient
|
|
||||||
import io.github.wulkanowy.data.db.entities.Semester
|
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
|
||||||
import io.github.wulkanowy.data.enums.MessageFolder
|
import io.github.wulkanowy.data.enums.MessageFolder
|
||||||
import io.github.wulkanowy.data.enums.MessageFolder.RECEIVED
|
import io.github.wulkanowy.data.enums.MessageFolder.RECEIVED
|
||||||
import io.github.wulkanowy.data.mappers.mapFromEntities
|
import io.github.wulkanowy.data.mappers.mapFromEntities
|
||||||
import io.github.wulkanowy.data.mappers.mapToEntities
|
import io.github.wulkanowy.data.mappers.mapToEntities
|
||||||
|
import io.github.wulkanowy.data.networkBoundResource
|
||||||
import io.github.wulkanowy.data.pojos.MessageDraft
|
import io.github.wulkanowy.data.pojos.MessageDraft
|
||||||
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
|
||||||
@ -23,7 +20,6 @@ import io.github.wulkanowy.sdk.pojo.SentMessage
|
|||||||
import io.github.wulkanowy.utils.AutoRefreshHelper
|
import io.github.wulkanowy.utils.AutoRefreshHelper
|
||||||
import io.github.wulkanowy.utils.getRefreshKey
|
import io.github.wulkanowy.utils.getRefreshKey
|
||||||
import io.github.wulkanowy.utils.init
|
import io.github.wulkanowy.utils.init
|
||||||
import io.github.wulkanowy.utils.networkBoundResource
|
|
||||||
import io.github.wulkanowy.utils.uniqueSubtract
|
import io.github.wulkanowy.utils.uniqueSubtract
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.sync.Mutex
|
import kotlinx.coroutines.sync.Mutex
|
||||||
@ -59,6 +55,7 @@ class MessageRepository @Inject constructor(
|
|||||||
notify: Boolean = false,
|
notify: Boolean = false,
|
||||||
): Flow<Resource<List<Message>>> = networkBoundResource(
|
): Flow<Resource<List<Message>>> = networkBoundResource(
|
||||||
mutex = saveFetchResultMutex,
|
mutex = saveFetchResultMutex,
|
||||||
|
isResultEmpty = { it.isEmpty() },
|
||||||
shouldFetch = {
|
shouldFetch = {
|
||||||
val isExpired = refreshHelper.shouldBeRefreshed(
|
val isExpired = refreshHelper.shouldBeRefreshed(
|
||||||
key = getRefreshKey(cacheKey, student, folder)
|
key = getRefreshKey(cacheKey, student, folder)
|
||||||
@ -106,8 +103,9 @@ class MessageRepository @Inject constructor(
|
|||||||
message: Message,
|
message: Message,
|
||||||
markAsRead: Boolean = false,
|
markAsRead: Boolean = false,
|
||||||
): Flow<Resource<MessageWithAttachment?>> = networkBoundResource(
|
): Flow<Resource<MessageWithAttachment?>> = networkBoundResource(
|
||||||
|
isResultEmpty = { it?.message?.content.isNullOrBlank() },
|
||||||
shouldFetch = {
|
shouldFetch = {
|
||||||
checkNotNull(it, { "This message no longer exist!" })
|
checkNotNull(it) { "This message no longer exist!" }
|
||||||
Timber.d("Message content in db empty: ${it.message.content.isEmpty()}")
|
Timber.d("Message content in db empty: ${it.message.content.isEmpty()}")
|
||||||
it.message.unread || it.message.content.isEmpty()
|
it.message.unread || it.message.content.isEmpty()
|
||||||
},
|
},
|
||||||
@ -123,7 +121,7 @@ class MessageRepository @Inject constructor(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
saveFetchResult = { old, (downloadedMessage, attachments) ->
|
saveFetchResult = { old, (downloadedMessage, attachments) ->
|
||||||
checkNotNull(old, { "Fetched message no longer exist!" })
|
checkNotNull(old) { "Fetched message no longer exist!" }
|
||||||
messagesDb.updateAll(listOf(old.message.apply {
|
messagesDb.updateAll(listOf(old.message.apply {
|
||||||
id = old.message.id
|
id = old.message.id
|
||||||
unread = !markAsRead
|
unread = !markAsRead
|
||||||
@ -153,20 +151,27 @@ class MessageRepository @Inject constructor(
|
|||||||
recipients = recipients.mapFromEntities()
|
recipients = recipients.mapFromEntities()
|
||||||
)
|
)
|
||||||
|
|
||||||
suspend fun deleteMessage(student: Student, message: Message) {
|
suspend fun deleteMessages(student: Student, messages: List<Message>) {
|
||||||
val isDeleted = sdk.init(student).deleteMessages(
|
val folderId = messages.first().folderId
|
||||||
messages = listOf(message.messageId), message.folderId
|
val isDeleted = sdk.init(student)
|
||||||
)
|
.deleteMessages(messages = messages.map { it.messageId }, folderId = folderId)
|
||||||
|
|
||||||
if (message.folderId != MessageFolder.TRASHED.id && isDeleted) {
|
if (folderId != MessageFolder.TRASHED.id && isDeleted) {
|
||||||
val deletedMessage = message.copy(folderId = MessageFolder.TRASHED.id).apply {
|
val deletedMessages = messages.map {
|
||||||
id = message.id
|
it.copy(folderId = MessageFolder.TRASHED.id)
|
||||||
content = message.content
|
.apply {
|
||||||
|
id = it.id
|
||||||
|
content = it.content
|
||||||
|
}
|
||||||
}
|
}
|
||||||
messagesDb.updateAll(listOf(deletedMessage))
|
|
||||||
} else messagesDb.deleteAll(listOf(message))
|
messagesDb.updateAll(deletedMessages)
|
||||||
|
} else messagesDb.deleteAll(messages)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun deleteMessage(student: Student, message: Message) =
|
||||||
|
deleteMessages(student, listOf(message))
|
||||||
|
|
||||||
var draftMessage: MessageDraft?
|
var draftMessage: MessageDraft?
|
||||||
get() = sharedPrefProvider.getString(context.getString(R.string.pref_key_message_send_draft))
|
get() = sharedPrefProvider.getString(context.getString(R.string.pref_key_message_send_draft))
|
||||||
?.let { json.decodeFromString(it) }
|
?.let { json.decodeFromString(it) }
|
||||||
|
@ -6,9 +6,13 @@ 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.mappers.mapToEntities
|
import io.github.wulkanowy.data.mappers.mapToEntities
|
||||||
import io.github.wulkanowy.data.mappers.mapToMobileDeviceToken
|
import io.github.wulkanowy.data.mappers.mapToMobileDeviceToken
|
||||||
|
import io.github.wulkanowy.data.networkBoundResource
|
||||||
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.*
|
import io.github.wulkanowy.utils.AutoRefreshHelper
|
||||||
|
import io.github.wulkanowy.utils.getRefreshKey
|
||||||
|
import io.github.wulkanowy.utils.init
|
||||||
|
import io.github.wulkanowy.utils.uniqueSubtract
|
||||||
import kotlinx.coroutines.sync.Mutex
|
import kotlinx.coroutines.sync.Mutex
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
@ -30,6 +34,7 @@ class MobileDeviceRepository @Inject constructor(
|
|||||||
forceRefresh: Boolean,
|
forceRefresh: Boolean,
|
||||||
) = networkBoundResource(
|
) = networkBoundResource(
|
||||||
mutex = saveFetchResultMutex,
|
mutex = saveFetchResultMutex,
|
||||||
|
isResultEmpty = { it.isEmpty() },
|
||||||
shouldFetch = {
|
shouldFetch = {
|
||||||
val isExpired = refreshHelper.shouldBeRefreshed(getRefreshKey(cacheKey, student))
|
val isExpired = refreshHelper.shouldBeRefreshed(getRefreshKey(cacheKey, student))
|
||||||
it.isEmpty() || forceRefresh || isExpired
|
it.isEmpty() || forceRefresh || isExpired
|
||||||
|
@ -5,6 +5,7 @@ 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.data.db.entities.Student
|
||||||
import io.github.wulkanowy.data.mappers.mapToEntities
|
import io.github.wulkanowy.data.mappers.mapToEntities
|
||||||
|
import io.github.wulkanowy.data.networkBoundResource
|
||||||
import io.github.wulkanowy.sdk.Sdk
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
import io.github.wulkanowy.utils.*
|
import io.github.wulkanowy.utils.*
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
@ -30,6 +31,7 @@ class NoteRepository @Inject constructor(
|
|||||||
notify: Boolean = false,
|
notify: Boolean = false,
|
||||||
) = networkBoundResource(
|
) = networkBoundResource(
|
||||||
mutex = saveFetchResultMutex,
|
mutex = saveFetchResultMutex,
|
||||||
|
isResultEmpty = { it.isEmpty() },
|
||||||
shouldFetch = {
|
shouldFetch = {
|
||||||
val isExpired = refreshHelper.shouldBeRefreshed(
|
val isExpired = refreshHelper.shouldBeRefreshed(
|
||||||
getRefreshKey(cacheKey, semester)
|
getRefreshKey(cacheKey, semester)
|
||||||
|
@ -4,11 +4,11 @@ import io.github.wulkanowy.data.db.dao.SchoolAnnouncementDao
|
|||||||
import io.github.wulkanowy.data.db.entities.SchoolAnnouncement
|
import io.github.wulkanowy.data.db.entities.SchoolAnnouncement
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import io.github.wulkanowy.data.mappers.mapToEntities
|
import io.github.wulkanowy.data.mappers.mapToEntities
|
||||||
|
import io.github.wulkanowy.data.networkBoundResource
|
||||||
import io.github.wulkanowy.sdk.Sdk
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
import io.github.wulkanowy.utils.AutoRefreshHelper
|
import io.github.wulkanowy.utils.AutoRefreshHelper
|
||||||
import io.github.wulkanowy.utils.getRefreshKey
|
import io.github.wulkanowy.utils.getRefreshKey
|
||||||
import io.github.wulkanowy.utils.init
|
import io.github.wulkanowy.utils.init
|
||||||
import io.github.wulkanowy.utils.networkBoundResource
|
|
||||||
import io.github.wulkanowy.utils.uniqueSubtract
|
import io.github.wulkanowy.utils.uniqueSubtract
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.sync.Mutex
|
import kotlinx.coroutines.sync.Mutex
|
||||||
@ -31,6 +31,7 @@ class SchoolAnnouncementRepository @Inject constructor(
|
|||||||
forceRefresh: Boolean, notify: Boolean = false
|
forceRefresh: Boolean, notify: Boolean = false
|
||||||
) = networkBoundResource(
|
) = networkBoundResource(
|
||||||
mutex = saveFetchResultMutex,
|
mutex = saveFetchResultMutex,
|
||||||
|
isResultEmpty = { it.isEmpty() },
|
||||||
shouldFetch = {
|
shouldFetch = {
|
||||||
val isExpired = refreshHelper.shouldBeRefreshed(getRefreshKey(cacheKey, student))
|
val isExpired = refreshHelper.shouldBeRefreshed(getRefreshKey(cacheKey, student))
|
||||||
it.isEmpty() || forceRefresh || isExpired
|
it.isEmpty() || forceRefresh || isExpired
|
||||||
|
@ -4,11 +4,11 @@ import io.github.wulkanowy.data.db.dao.SchoolDao
|
|||||||
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.mappers.mapToEntity
|
import io.github.wulkanowy.data.mappers.mapToEntity
|
||||||
|
import io.github.wulkanowy.data.networkBoundResource
|
||||||
import io.github.wulkanowy.sdk.Sdk
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
import io.github.wulkanowy.utils.AutoRefreshHelper
|
import io.github.wulkanowy.utils.AutoRefreshHelper
|
||||||
import io.github.wulkanowy.utils.getRefreshKey
|
import io.github.wulkanowy.utils.getRefreshKey
|
||||||
import io.github.wulkanowy.utils.init
|
import io.github.wulkanowy.utils.init
|
||||||
import io.github.wulkanowy.utils.networkBoundResource
|
|
||||||
import kotlinx.coroutines.sync.Mutex
|
import kotlinx.coroutines.sync.Mutex
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
@ -30,6 +30,7 @@ class SchoolRepository @Inject constructor(
|
|||||||
forceRefresh: Boolean,
|
forceRefresh: Boolean,
|
||||||
) = networkBoundResource(
|
) = networkBoundResource(
|
||||||
mutex = saveFetchResultMutex,
|
mutex = saveFetchResultMutex,
|
||||||
|
isResultEmpty = { it == null },
|
||||||
shouldFetch = {
|
shouldFetch = {
|
||||||
val isExpired = refreshHelper.shouldBeRefreshed(
|
val isExpired = refreshHelper.shouldBeRefreshed(
|
||||||
key = getRefreshKey(cacheKey, student)
|
key = getRefreshKey(cacheKey, student)
|
||||||
|
@ -4,9 +4,9 @@ import io.github.wulkanowy.data.db.dao.StudentInfoDao
|
|||||||
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.mappers.mapToEntity
|
import io.github.wulkanowy.data.mappers.mapToEntity
|
||||||
|
import io.github.wulkanowy.data.networkBoundResource
|
||||||
import io.github.wulkanowy.sdk.Sdk
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
import io.github.wulkanowy.utils.init
|
import io.github.wulkanowy.utils.init
|
||||||
import io.github.wulkanowy.utils.networkBoundResource
|
|
||||||
import kotlinx.coroutines.sync.Mutex
|
import kotlinx.coroutines.sync.Mutex
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
@ -25,6 +25,7 @@ class StudentInfoRepository @Inject constructor(
|
|||||||
forceRefresh: Boolean,
|
forceRefresh: Boolean,
|
||||||
) = networkBoundResource(
|
) = networkBoundResource(
|
||||||
mutex = saveFetchResultMutex,
|
mutex = saveFetchResultMutex,
|
||||||
|
isResultEmpty = { it == null },
|
||||||
shouldFetch = { it == null || forceRefresh },
|
shouldFetch = { it == null || forceRefresh },
|
||||||
query = { studentInfoDao.loadStudentInfo(student.studentId) },
|
query = { studentInfoDao.loadStudentInfo(student.studentId) },
|
||||||
fetch = {
|
fetch = {
|
||||||
|
@ -73,6 +73,15 @@ class StudentRepository @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun getSavedStudentById(id: Long, decryptPass: Boolean = true) =
|
||||||
|
studentDb.loadStudentWithSemestersById(id)?.apply {
|
||||||
|
if (decryptPass && Sdk.Mode.valueOf(student.loginMode) != Sdk.Mode.API) {
|
||||||
|
student.password = withContext(dispatchers.io) {
|
||||||
|
decrypt(student.password)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
suspend fun getStudentById(id: Long, decryptPass: Boolean = true): Student {
|
suspend fun getStudentById(id: Long, decryptPass: Boolean = true): Student {
|
||||||
val student = studentDb.loadById(id) ?: throw NoCurrentStudentException()
|
val student = studentDb.loadById(id) ?: throw NoCurrentStudentException()
|
||||||
|
|
||||||
|
@ -4,8 +4,12 @@ import io.github.wulkanowy.data.db.dao.SubjectDao
|
|||||||
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.mappers.mapToEntities
|
import io.github.wulkanowy.data.mappers.mapToEntities
|
||||||
|
import io.github.wulkanowy.data.networkBoundResource
|
||||||
import io.github.wulkanowy.sdk.Sdk
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
import io.github.wulkanowy.utils.*
|
import io.github.wulkanowy.utils.AutoRefreshHelper
|
||||||
|
import io.github.wulkanowy.utils.getRefreshKey
|
||||||
|
import io.github.wulkanowy.utils.init
|
||||||
|
import io.github.wulkanowy.utils.uniqueSubtract
|
||||||
import kotlinx.coroutines.sync.Mutex
|
import kotlinx.coroutines.sync.Mutex
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
@ -27,6 +31,7 @@ class SubjectRepository @Inject constructor(
|
|||||||
forceRefresh: Boolean = false,
|
forceRefresh: Boolean = false,
|
||||||
) = networkBoundResource(
|
) = networkBoundResource(
|
||||||
mutex = saveFetchResultMutex,
|
mutex = saveFetchResultMutex,
|
||||||
|
isResultEmpty = { it.isEmpty() },
|
||||||
shouldFetch = {
|
shouldFetch = {
|
||||||
val isExpired = refreshHelper.shouldBeRefreshed(getRefreshKey(cacheKey, semester))
|
val isExpired = refreshHelper.shouldBeRefreshed(getRefreshKey(cacheKey, semester))
|
||||||
it.isEmpty() || forceRefresh || isExpired
|
it.isEmpty() || forceRefresh || isExpired
|
||||||
|
@ -4,8 +4,12 @@ import io.github.wulkanowy.data.db.dao.TeacherDao
|
|||||||
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.mappers.mapToEntities
|
import io.github.wulkanowy.data.mappers.mapToEntities
|
||||||
|
import io.github.wulkanowy.data.networkBoundResource
|
||||||
import io.github.wulkanowy.sdk.Sdk
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
import io.github.wulkanowy.utils.*
|
import io.github.wulkanowy.utils.AutoRefreshHelper
|
||||||
|
import io.github.wulkanowy.utils.getRefreshKey
|
||||||
|
import io.github.wulkanowy.utils.init
|
||||||
|
import io.github.wulkanowy.utils.uniqueSubtract
|
||||||
import kotlinx.coroutines.sync.Mutex
|
import kotlinx.coroutines.sync.Mutex
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
@ -27,6 +31,7 @@ class TeacherRepository @Inject constructor(
|
|||||||
forceRefresh: Boolean,
|
forceRefresh: Boolean,
|
||||||
) = networkBoundResource(
|
) = networkBoundResource(
|
||||||
mutex = saveFetchResultMutex,
|
mutex = saveFetchResultMutex,
|
||||||
|
isResultEmpty = { it.isEmpty() },
|
||||||
shouldFetch = {
|
shouldFetch = {
|
||||||
val isExpired = refreshHelper.shouldBeRefreshed(getRefreshKey(cacheKey, semester))
|
val isExpired = refreshHelper.shouldBeRefreshed(getRefreshKey(cacheKey, semester))
|
||||||
it.isEmpty() || forceRefresh || isExpired
|
it.isEmpty() || forceRefresh || isExpired
|
||||||
|
@ -5,6 +5,7 @@ import io.github.wulkanowy.data.db.dao.TimetableDao
|
|||||||
import io.github.wulkanowy.data.db.dao.TimetableHeaderDao
|
import io.github.wulkanowy.data.db.dao.TimetableHeaderDao
|
||||||
import io.github.wulkanowy.data.db.entities.*
|
import io.github.wulkanowy.data.db.entities.*
|
||||||
import io.github.wulkanowy.data.mappers.mapToEntities
|
import io.github.wulkanowy.data.mappers.mapToEntities
|
||||||
|
import io.github.wulkanowy.data.networkBoundResource
|
||||||
import io.github.wulkanowy.data.pojos.TimetableFull
|
import io.github.wulkanowy.data.pojos.TimetableFull
|
||||||
import io.github.wulkanowy.sdk.Sdk
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
import io.github.wulkanowy.services.alarm.TimetableNotificationSchedulerHelper
|
import io.github.wulkanowy.services.alarm.TimetableNotificationSchedulerHelper
|
||||||
@ -30,6 +31,10 @@ class TimetableRepository @Inject constructor(
|
|||||||
|
|
||||||
private val cacheKey = "timetable"
|
private val cacheKey = "timetable"
|
||||||
|
|
||||||
|
enum class TimetableType {
|
||||||
|
NORMAL, ADDITIONAL
|
||||||
|
}
|
||||||
|
|
||||||
fun getTimetable(
|
fun getTimetable(
|
||||||
student: Student,
|
student: Student,
|
||||||
semester: Semester,
|
semester: Semester,
|
||||||
@ -37,9 +42,16 @@ class TimetableRepository @Inject constructor(
|
|||||||
end: LocalDate,
|
end: LocalDate,
|
||||||
forceRefresh: Boolean,
|
forceRefresh: Boolean,
|
||||||
refreshAdditional: Boolean = false,
|
refreshAdditional: Boolean = false,
|
||||||
notify: Boolean = false
|
notify: Boolean = false,
|
||||||
|
timetableType: TimetableType = TimetableType.NORMAL
|
||||||
) = networkBoundResource(
|
) = networkBoundResource(
|
||||||
mutex = saveFetchResultMutex,
|
mutex = saveFetchResultMutex,
|
||||||
|
isResultEmpty = {
|
||||||
|
when (timetableType) {
|
||||||
|
TimetableType.NORMAL -> it.lessons.isEmpty()
|
||||||
|
TimetableType.ADDITIONAL -> it.additional.isEmpty()
|
||||||
|
}
|
||||||
|
},
|
||||||
shouldFetch = { (timetable, additional, headers) ->
|
shouldFetch = { (timetable, additional, headers) ->
|
||||||
val refreshKey = getRefreshKey(cacheKey, semester, start, end)
|
val refreshKey = getRefreshKey(cacheKey, semester, start, end)
|
||||||
val isExpired = refreshHelper.shouldBeRefreshed(refreshKey)
|
val isExpired = refreshHelper.shouldBeRefreshed(refreshKey)
|
||||||
|
@ -0,0 +1,32 @@
|
|||||||
|
package io.github.wulkanowy.data.serializers
|
||||||
|
|
||||||
|
import kotlinx.serialization.ExperimentalSerializationApi
|
||||||
|
import kotlinx.serialization.KSerializer
|
||||||
|
import kotlinx.serialization.descriptors.PrimitiveKind
|
||||||
|
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
|
||||||
|
import kotlinx.serialization.descriptors.nullable
|
||||||
|
import kotlinx.serialization.encoding.Decoder
|
||||||
|
import kotlinx.serialization.encoding.Encoder
|
||||||
|
import java.time.LocalDate
|
||||||
|
|
||||||
|
@OptIn(ExperimentalSerializationApi::class)
|
||||||
|
object LocalDateSerializer : KSerializer<LocalDate?> {
|
||||||
|
|
||||||
|
override val descriptor = PrimitiveSerialDescriptor("LocalDate", PrimitiveKind.LONG).nullable
|
||||||
|
|
||||||
|
override fun serialize(encoder: Encoder, value: LocalDate?) {
|
||||||
|
if (value == null) {
|
||||||
|
encoder.encodeNull()
|
||||||
|
} else {
|
||||||
|
encoder.encodeNotNullMark()
|
||||||
|
encoder.encodeLong(value.toEpochDay())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun deserialize(decoder: Decoder): LocalDate? =
|
||||||
|
if (decoder.decodeNotNullMark()) {
|
||||||
|
LocalDate.ofEpochDay(decoder.decodeLong())
|
||||||
|
} else {
|
||||||
|
decoder.decodeNull()
|
||||||
|
}
|
||||||
|
}
|
@ -10,19 +10,18 @@ import androidx.core.app.NotificationCompat
|
|||||||
import androidx.core.app.NotificationManagerCompat
|
import androidx.core.app.NotificationManagerCompat
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
import io.github.wulkanowy.data.Status
|
import io.github.wulkanowy.data.onResourceError
|
||||||
import io.github.wulkanowy.data.repositories.PreferencesRepository
|
import io.github.wulkanowy.data.repositories.PreferencesRepository
|
||||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||||
|
import io.github.wulkanowy.data.resourceFlow
|
||||||
import io.github.wulkanowy.services.sync.channels.UpcomingLessonsChannel.Companion.CHANNEL_ID
|
import io.github.wulkanowy.services.sync.channels.UpcomingLessonsChannel.Companion.CHANNEL_ID
|
||||||
import io.github.wulkanowy.ui.modules.Destination
|
import io.github.wulkanowy.ui.modules.Destination
|
||||||
import io.github.wulkanowy.ui.modules.splash.SplashActivity
|
import io.github.wulkanowy.ui.modules.splash.SplashActivity
|
||||||
import io.github.wulkanowy.utils.PendingIntentCompat
|
import io.github.wulkanowy.utils.PendingIntentCompat
|
||||||
import io.github.wulkanowy.utils.flowWithResource
|
|
||||||
import io.github.wulkanowy.utils.getCompatColor
|
import io.github.wulkanowy.utils.getCompatColor
|
||||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
import kotlinx.coroutines.flow.onEach
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@ -59,7 +58,7 @@ class TimetableNotificationReceiver : BroadcastReceiver() {
|
|||||||
override fun onReceive(context: Context, intent: Intent) {
|
override fun onReceive(context: Context, intent: Intent) {
|
||||||
Timber.d("Receiving intent... ${intent.toUri(0)}")
|
Timber.d("Receiving intent... ${intent.toUri(0)}")
|
||||||
|
|
||||||
flowWithResource {
|
resourceFlow {
|
||||||
val showStudentName = !studentRepository.isOneUniqueStudent()
|
val showStudentName = !studentRepository.isOneUniqueStudent()
|
||||||
val student = studentRepository.getCurrentStudent(false)
|
val student = studentRepository.getCurrentStudent(false)
|
||||||
val studentId = intent.getIntExtra(STUDENT_ID, 0)
|
val studentId = intent.getIntExtra(STUDENT_ID, 0)
|
||||||
@ -69,9 +68,9 @@ class TimetableNotificationReceiver : BroadcastReceiver() {
|
|||||||
} else {
|
} else {
|
||||||
Timber.d("Notification studentId($studentId) differs from current(${student.studentId})")
|
Timber.d("Notification studentId($studentId) differs from current(${student.studentId})")
|
||||||
}
|
}
|
||||||
}.onEach {
|
}
|
||||||
if (it.status == Status.ERROR) Timber.e(it.error!!)
|
.onResourceError { Timber.e(it) }
|
||||||
}.launchIn(GlobalScope)
|
.launchIn(GlobalScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun prepareNotification(context: Context, intent: Intent, showStudentName: Boolean) {
|
private fun prepareNotification(context: Context, intent: Intent, showStudentName: Boolean) {
|
||||||
|
@ -15,6 +15,9 @@ import javax.inject.Singleton
|
|||||||
@Singleton
|
@Singleton
|
||||||
class ShortcutsHelper @Inject constructor(@ApplicationContext private val context: Context) {
|
class ShortcutsHelper @Inject constructor(@ApplicationContext private val context: Context) {
|
||||||
|
|
||||||
|
// Destination cannot be used here as shortcuts
|
||||||
|
// require their intents to only use primitive types (see PersistableBundle.isValidType).
|
||||||
|
|
||||||
private val destinations = mapOf(
|
private val destinations = mapOf(
|
||||||
"grade" to Destination.Grade,
|
"grade" to Destination.Grade,
|
||||||
"attendance" to Destination.Attendance,
|
"attendance" to Destination.Attendance,
|
||||||
|
@ -14,6 +14,7 @@ import io.github.wulkanowy.data.pojos.GroupNotificationData
|
|||||||
import io.github.wulkanowy.data.pojos.NotificationData
|
import io.github.wulkanowy.data.pojos.NotificationData
|
||||||
import io.github.wulkanowy.data.repositories.NotificationRepository
|
import io.github.wulkanowy.data.repositories.NotificationRepository
|
||||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||||
|
import io.github.wulkanowy.ui.modules.splash.SplashActivity
|
||||||
import io.github.wulkanowy.utils.PendingIntentCompat
|
import io.github.wulkanowy.utils.PendingIntentCompat
|
||||||
import io.github.wulkanowy.utils.getCompatBitmap
|
import io.github.wulkanowy.utils.getCompatBitmap
|
||||||
import io.github.wulkanowy.utils.getCompatColor
|
import io.github.wulkanowy.utils.getCompatColor
|
||||||
@ -47,7 +48,7 @@ class AppNotificationManager @Inject constructor(
|
|||||||
PendingIntent.getActivity(
|
PendingIntent.getActivity(
|
||||||
context,
|
context,
|
||||||
Random.nextInt(),
|
Random.nextInt(),
|
||||||
notificationData.intentToStart,
|
SplashActivity.getStartIntent(context, notificationData.destination),
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntentCompat.FLAG_IMMUTABLE
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntentCompat.FLAG_IMMUTABLE
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -92,7 +93,7 @@ class AppNotificationManager @Inject constructor(
|
|||||||
PendingIntent.getActivity(
|
PendingIntent.getActivity(
|
||||||
context,
|
context,
|
||||||
Random.nextInt(),
|
Random.nextInt(),
|
||||||
notificationData.intentToStart,
|
SplashActivity.getStartIntent(context, notificationData.destination),
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntentCompat.FLAG_IMMUTABLE
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntentCompat.FLAG_IMMUTABLE
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -146,7 +147,7 @@ class AppNotificationManager @Inject constructor(
|
|||||||
PendingIntent.getActivity(
|
PendingIntent.getActivity(
|
||||||
context,
|
context,
|
||||||
Random.nextInt(),
|
Random.nextInt(),
|
||||||
groupNotificationData.intentToStart,
|
SplashActivity.getStartIntent(context, groupNotificationData.destination),
|
||||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntentCompat.FLAG_IMMUTABLE
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntentCompat.FLAG_IMMUTABLE
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -168,6 +169,7 @@ class AppNotificationManager @Inject constructor(
|
|||||||
studentId = student.id,
|
studentId = student.id,
|
||||||
title = notificationData.title,
|
title = notificationData.title,
|
||||||
content = notificationData.content,
|
content = notificationData.content,
|
||||||
|
destination = notificationData.destination,
|
||||||
type = notificationType,
|
type = notificationType,
|
||||||
date = Instant.now(),
|
date = Instant.now(),
|
||||||
)
|
)
|
||||||
|
@ -8,7 +8,6 @@ import io.github.wulkanowy.data.db.entities.Timetable
|
|||||||
import io.github.wulkanowy.data.pojos.GroupNotificationData
|
import io.github.wulkanowy.data.pojos.GroupNotificationData
|
||||||
import io.github.wulkanowy.data.pojos.NotificationData
|
import io.github.wulkanowy.data.pojos.NotificationData
|
||||||
import io.github.wulkanowy.ui.modules.Destination
|
import io.github.wulkanowy.ui.modules.Destination
|
||||||
import io.github.wulkanowy.ui.modules.splash.SplashActivity
|
|
||||||
import io.github.wulkanowy.utils.getPlural
|
import io.github.wulkanowy.utils.getPlural
|
||||||
import io.github.wulkanowy.utils.toFormattedString
|
import io.github.wulkanowy.utils.toFormattedString
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
@ -23,8 +22,9 @@ class ChangeTimetableNotification @Inject constructor(
|
|||||||
suspend fun notify(items: List<Timetable>, student: Student) {
|
suspend fun notify(items: List<Timetable>, student: Student) {
|
||||||
val currentTime = Instant.now()
|
val currentTime = Instant.now()
|
||||||
val changedLessons = items.filter { (it.canceled || it.changes) && it.start > currentTime }
|
val changedLessons = items.filter { (it.canceled || it.changes) && it.start > currentTime }
|
||||||
val notificationDataList = changedLessons.groupBy { it.date }
|
val lessonsByDate = changedLessons.groupBy { it.date }
|
||||||
.map { (date, lessons) ->
|
val notificationDataList = lessonsByDate
|
||||||
|
.flatMap { (date, lessons) ->
|
||||||
getNotificationContents(date, lessons).map {
|
getNotificationContents(date, lessons).map {
|
||||||
NotificationData(
|
NotificationData(
|
||||||
title = context.getPlural(
|
title = context.getPlural(
|
||||||
@ -32,14 +32,10 @@ class ChangeTimetableNotification @Inject constructor(
|
|||||||
1
|
1
|
||||||
),
|
),
|
||||||
content = it,
|
content = it,
|
||||||
intentToStart = SplashActivity.getStartIntent(
|
destination = Destination.Timetable(date)
|
||||||
context = context,
|
|
||||||
destination = Destination.Timetable(date)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.flatten()
|
|
||||||
.ifEmpty { return }
|
.ifEmpty { return }
|
||||||
|
|
||||||
val groupNotificationData = GroupNotificationData(
|
val groupNotificationData = GroupNotificationData(
|
||||||
@ -53,7 +49,7 @@ class ChangeTimetableNotification @Inject constructor(
|
|||||||
changedLessons.size,
|
changedLessons.size,
|
||||||
changedLessons.size
|
changedLessons.size
|
||||||
),
|
),
|
||||||
intentToStart = SplashActivity.getStartIntent(context, Destination.Timetable()),
|
destination = Destination.Timetable(lessonsByDate.toSortedMap().firstKey()),
|
||||||
type = NotificationType.CHANGE_TIMETABLE
|
type = NotificationType.CHANGE_TIMETABLE
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ class NewAttendanceNotification @Inject constructor(
|
|||||||
NotificationData(
|
NotificationData(
|
||||||
title = context.getPlural(R.plurals.attendance_notify_new_items_title, 1),
|
title = context.getPlural(R.plurals.attendance_notify_new_items_title, 1),
|
||||||
content = it,
|
content = it,
|
||||||
intentToStart = SplashActivity.getStartIntent(context, Destination.Attendance)
|
destination = Destination.Attendance
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ class NewAttendanceNotification @Inject constructor(
|
|||||||
notificationDataList.size,
|
notificationDataList.size,
|
||||||
notificationDataList.size
|
notificationDataList.size
|
||||||
),
|
),
|
||||||
intentToStart = SplashActivity.getStartIntent(context, Destination.Attendance),
|
destination = Destination.Attendance,
|
||||||
type = NotificationType.NEW_ATTENDANCE
|
type = NotificationType.NEW_ATTENDANCE
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ class NewConferenceNotification @Inject constructor(
|
|||||||
NotificationData(
|
NotificationData(
|
||||||
title = context.getPlural(R.plurals.conference_notify_new_item_title, 1),
|
title = context.getPlural(R.plurals.conference_notify_new_item_title, 1),
|
||||||
content = it,
|
content = it,
|
||||||
intentToStart = SplashActivity.getStartIntent(context, Destination.Conference)
|
destination = Destination.Conference
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,7 +43,7 @@ class NewConferenceNotification @Inject constructor(
|
|||||||
lines.size,
|
lines.size,
|
||||||
lines.size
|
lines.size
|
||||||
),
|
),
|
||||||
intentToStart = SplashActivity.getStartIntent(context, Destination.Conference),
|
destination = Destination.Conference,
|
||||||
type = NotificationType.NEW_CONFERENCE
|
type = NotificationType.NEW_CONFERENCE
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ class NewExamNotification @Inject constructor(
|
|||||||
NotificationData(
|
NotificationData(
|
||||||
title = context.getPlural(R.plurals.exam_notify_new_item_title, 1),
|
title = context.getPlural(R.plurals.exam_notify_new_item_title, 1),
|
||||||
content = it,
|
content = it,
|
||||||
intentToStart = SplashActivity.getStartIntent(context, Destination.Exam),
|
destination = Destination.Exam,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,7 +43,7 @@ class NewExamNotification @Inject constructor(
|
|||||||
lines.size,
|
lines.size,
|
||||||
lines.size
|
lines.size
|
||||||
),
|
),
|
||||||
intentToStart = SplashActivity.getStartIntent(context, Destination.Exam),
|
destination = Destination.Exam,
|
||||||
type = NotificationType.NEW_EXAM
|
type = NotificationType.NEW_EXAM
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ class NewGradeNotification @Inject constructor(
|
|||||||
append("${it.subject}: ${it.entry}")
|
append("${it.subject}: ${it.entry}")
|
||||||
if (it.comment.isNotBlank()) append(" (${it.comment})")
|
if (it.comment.isNotBlank()) append(" (${it.comment})")
|
||||||
},
|
},
|
||||||
intentToStart = SplashActivity.getStartIntent(context, Destination.Grade),
|
destination = Destination.Grade,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,7 +34,7 @@ class NewGradeNotification @Inject constructor(
|
|||||||
notificationDataList = notificationDataList,
|
notificationDataList = notificationDataList,
|
||||||
title = context.getPlural(R.plurals.grade_new_items, items.size),
|
title = context.getPlural(R.plurals.grade_new_items, items.size),
|
||||||
content = context.getPlural(R.plurals.grade_notify_new_items, items.size, items.size),
|
content = context.getPlural(R.plurals.grade_notify_new_items, items.size, items.size),
|
||||||
intentToStart = SplashActivity.getStartIntent(context, Destination.Grade),
|
destination = Destination.Grade,
|
||||||
type = NotificationType.NEW_GRADE_DETAILS
|
type = NotificationType.NEW_GRADE_DETAILS
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ class NewGradeNotification @Inject constructor(
|
|||||||
NotificationData(
|
NotificationData(
|
||||||
title = context.getPlural(R.plurals.grade_new_items_predicted, 1),
|
title = context.getPlural(R.plurals.grade_new_items_predicted, 1),
|
||||||
content = "${it.subject}: ${it.predictedGrade}",
|
content = "${it.subject}: ${it.predictedGrade}",
|
||||||
intentToStart = SplashActivity.getStartIntent(context, Destination.Grade),
|
destination = Destination.Grade,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,7 +58,7 @@ class NewGradeNotification @Inject constructor(
|
|||||||
items.size,
|
items.size,
|
||||||
items.size
|
items.size
|
||||||
),
|
),
|
||||||
intentToStart = SplashActivity.getStartIntent(context, Destination.Grade),
|
destination = Destination.Grade,
|
||||||
type = NotificationType.NEW_GRADE_PREDICTED
|
type = NotificationType.NEW_GRADE_PREDICTED
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -70,7 +70,7 @@ class NewGradeNotification @Inject constructor(
|
|||||||
NotificationData(
|
NotificationData(
|
||||||
title = context.getPlural(R.plurals.grade_new_items_final, 1),
|
title = context.getPlural(R.plurals.grade_new_items_final, 1),
|
||||||
content = "${it.subject}: ${it.finalGrade}",
|
content = "${it.subject}: ${it.finalGrade}",
|
||||||
intentToStart = SplashActivity.getStartIntent(context, Destination.Grade),
|
destination = Destination.Grade,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,7 +82,7 @@ class NewGradeNotification @Inject constructor(
|
|||||||
items.size,
|
items.size,
|
||||||
items.size
|
items.size
|
||||||
),
|
),
|
||||||
intentToStart = SplashActivity.getStartIntent(context, Destination.Grade),
|
destination = Destination.Grade,
|
||||||
type = NotificationType.NEW_GRADE_FINAL
|
type = NotificationType.NEW_GRADE_FINAL
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ class NewHomeworkNotification @Inject constructor(
|
|||||||
NotificationData(
|
NotificationData(
|
||||||
title = context.getPlural(R.plurals.homework_notify_new_item_title, 1),
|
title = context.getPlural(R.plurals.homework_notify_new_item_title, 1),
|
||||||
content = it,
|
content = it,
|
||||||
intentToStart = SplashActivity.getStartIntent(context, Destination.Homework),
|
destination = Destination.Homework,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ class NewHomeworkNotification @Inject constructor(
|
|||||||
lines.size,
|
lines.size,
|
||||||
lines.size
|
lines.size
|
||||||
),
|
),
|
||||||
intentToStart = SplashActivity.getStartIntent(context, Destination.Homework),
|
destination = Destination.Homework,
|
||||||
type = NotificationType.NEW_HOMEWORK,
|
type = NotificationType.NEW_HOMEWORK,
|
||||||
notificationDataList = notificationDataList
|
notificationDataList = notificationDataList
|
||||||
)
|
)
|
||||||
|
@ -22,7 +22,7 @@ class NewLuckyNumberNotification @Inject constructor(
|
|||||||
R.string.lucky_number_notify_new_item,
|
R.string.lucky_number_notify_new_item,
|
||||||
item.luckyNumber.toString()
|
item.luckyNumber.toString()
|
||||||
),
|
),
|
||||||
intentToStart = SplashActivity.getStartIntent(context, Destination.LuckyNumber)
|
destination = Destination.LuckyNumber
|
||||||
)
|
)
|
||||||
|
|
||||||
appNotificationManager.sendSingleNotification(
|
appNotificationManager.sendSingleNotification(
|
||||||
|
@ -22,7 +22,7 @@ class NewMessageNotification @Inject constructor(
|
|||||||
NotificationData(
|
NotificationData(
|
||||||
title = context.getPlural(R.plurals.message_new_items, 1),
|
title = context.getPlural(R.plurals.message_new_items, 1),
|
||||||
content = "${it.sender}: ${it.subject}",
|
content = "${it.sender}: ${it.subject}",
|
||||||
intentToStart = SplashActivity.getStartIntent(context, Destination.Message),
|
destination = Destination.Message,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,7 +30,7 @@ class NewMessageNotification @Inject constructor(
|
|||||||
notificationDataList = notificationDataList,
|
notificationDataList = notificationDataList,
|
||||||
title = context.getPlural(R.plurals.message_new_items, items.size),
|
title = context.getPlural(R.plurals.message_new_items, items.size),
|
||||||
content = context.getPlural(R.plurals.message_notify_new_items, items.size, items.size),
|
content = context.getPlural(R.plurals.message_notify_new_items, items.size, items.size),
|
||||||
intentToStart = SplashActivity.getStartIntent(context, Destination.Message),
|
destination = Destination.Message,
|
||||||
type = NotificationType.NEW_MESSAGE
|
type = NotificationType.NEW_MESSAGE
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -29,13 +29,13 @@ class NewNoteNotification @Inject constructor(
|
|||||||
NotificationData(
|
NotificationData(
|
||||||
title = context.getPlural(titleRes, 1),
|
title = context.getPlural(titleRes, 1),
|
||||||
content = "${it.teacher}: ${it.category}",
|
content = "${it.teacher}: ${it.category}",
|
||||||
intentToStart = SplashActivity.getStartIntent(context, Destination.Note),
|
destination = Destination.Note,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val groupNotificationData = GroupNotificationData(
|
val groupNotificationData = GroupNotificationData(
|
||||||
notificationDataList = notificationDataList,
|
notificationDataList = notificationDataList,
|
||||||
intentToStart = SplashActivity.getStartIntent(context, Destination.Note),
|
destination = Destination.Note,
|
||||||
title = context.getPlural(R.plurals.note_new_items, items.size),
|
title = context.getPlural(R.plurals.note_new_items, items.size),
|
||||||
content = context.getPlural(R.plurals.note_notify_new_items, items.size, items.size),
|
content = context.getPlural(R.plurals.note_notify_new_items, items.size, items.size),
|
||||||
type = NotificationType.NEW_NOTE
|
type = NotificationType.NEW_NOTE
|
||||||
|
@ -21,10 +21,7 @@ class NewSchoolAnnouncementNotification @Inject constructor(
|
|||||||
suspend fun notify(items: List<SchoolAnnouncement>, student: Student) {
|
suspend fun notify(items: List<SchoolAnnouncement>, student: Student) {
|
||||||
val notificationDataList = items.map {
|
val notificationDataList = items.map {
|
||||||
NotificationData(
|
NotificationData(
|
||||||
intentToStart = SplashActivity.getStartIntent(
|
destination = Destination.SchoolAnnouncement,
|
||||||
context = context,
|
|
||||||
destination = Destination.SchoolAnnouncement
|
|
||||||
),
|
|
||||||
title = context.getPlural(
|
title = context.getPlural(
|
||||||
R.plurals.school_announcement_notify_new_item_title,
|
R.plurals.school_announcement_notify_new_item_title,
|
||||||
1
|
1
|
||||||
@ -34,10 +31,7 @@ class NewSchoolAnnouncementNotification @Inject constructor(
|
|||||||
}
|
}
|
||||||
val groupNotificationData = GroupNotificationData(
|
val groupNotificationData = GroupNotificationData(
|
||||||
type = NotificationType.NEW_ANNOUNCEMENT,
|
type = NotificationType.NEW_ANNOUNCEMENT,
|
||||||
intentToStart = SplashActivity.getStartIntent(
|
destination = Destination.SchoolAnnouncement,
|
||||||
context = context,
|
|
||||||
destination = Destination.SchoolAnnouncement
|
|
||||||
),
|
|
||||||
title = context.getPlural(
|
title = context.getPlural(
|
||||||
R.plurals.school_announcement_notify_new_item_title,
|
R.plurals.school_announcement_notify_new_item_title,
|
||||||
items.size
|
items.size
|
||||||
|
@ -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.AttendanceSummaryRepository
|
import io.github.wulkanowy.data.repositories.AttendanceSummaryRepository
|
||||||
import io.github.wulkanowy.utils.waitForResult
|
import io.github.wulkanowy.data.waitForResult
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class AttendanceSummaryWork @Inject constructor(
|
class AttendanceSummaryWork @Inject constructor(
|
||||||
|
@ -3,9 +3,9 @@ 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.AttendanceRepository
|
import io.github.wulkanowy.data.repositories.AttendanceRepository
|
||||||
|
import io.github.wulkanowy.data.waitForResult
|
||||||
import io.github.wulkanowy.services.sync.notifications.NewAttendanceNotification
|
import io.github.wulkanowy.services.sync.notifications.NewAttendanceNotification
|
||||||
import io.github.wulkanowy.utils.previousOrSameSchoolDay
|
import io.github.wulkanowy.utils.previousOrSameSchoolDay
|
||||||
import io.github.wulkanowy.utils.waitForResult
|
|
||||||
import kotlinx.coroutines.flow.first
|
import kotlinx.coroutines.flow.first
|
||||||
import java.time.LocalDate.now
|
import java.time.LocalDate.now
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
@ -3,9 +3,9 @@ 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.CompletedLessonsRepository
|
import io.github.wulkanowy.data.repositories.CompletedLessonsRepository
|
||||||
|
import io.github.wulkanowy.data.waitForResult
|
||||||
import io.github.wulkanowy.utils.monday
|
import io.github.wulkanowy.utils.monday
|
||||||
import io.github.wulkanowy.utils.sunday
|
import io.github.wulkanowy.utils.sunday
|
||||||
import io.github.wulkanowy.utils.waitForResult
|
|
||||||
import java.time.LocalDate.now
|
import java.time.LocalDate.now
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@ -3,8 +3,8 @@ 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.ConferenceRepository
|
import io.github.wulkanowy.data.repositories.ConferenceRepository
|
||||||
|
import io.github.wulkanowy.data.waitForResult
|
||||||
import io.github.wulkanowy.services.sync.notifications.NewConferenceNotification
|
import io.github.wulkanowy.services.sync.notifications.NewConferenceNotification
|
||||||
import io.github.wulkanowy.utils.waitForResult
|
|
||||||
import kotlinx.coroutines.flow.first
|
import kotlinx.coroutines.flow.first
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@ -3,8 +3,8 @@ 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.ExamRepository
|
import io.github.wulkanowy.data.repositories.ExamRepository
|
||||||
|
import io.github.wulkanowy.data.waitForResult
|
||||||
import io.github.wulkanowy.services.sync.notifications.NewExamNotification
|
import io.github.wulkanowy.services.sync.notifications.NewExamNotification
|
||||||
import io.github.wulkanowy.utils.waitForResult
|
|
||||||
import kotlinx.coroutines.flow.first
|
import kotlinx.coroutines.flow.first
|
||||||
import java.time.LocalDate.now
|
import java.time.LocalDate.now
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
@ -3,7 +3,8 @@ 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.GradeStatisticsRepository
|
import io.github.wulkanowy.data.repositories.GradeStatisticsRepository
|
||||||
import io.github.wulkanowy.utils.waitForResult
|
import io.github.wulkanowy.data.waitForResult
|
||||||
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class GradeStatisticsWork @Inject constructor(
|
class GradeStatisticsWork @Inject constructor(
|
||||||
|
@ -3,8 +3,8 @@ 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.GradeRepository
|
import io.github.wulkanowy.data.repositories.GradeRepository
|
||||||
|
import io.github.wulkanowy.data.waitForResult
|
||||||
import io.github.wulkanowy.services.sync.notifications.NewGradeNotification
|
import io.github.wulkanowy.services.sync.notifications.NewGradeNotification
|
||||||
import io.github.wulkanowy.utils.waitForResult
|
|
||||||
import kotlinx.coroutines.flow.first
|
import kotlinx.coroutines.flow.first
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@ -3,9 +3,9 @@ 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.HomeworkRepository
|
import io.github.wulkanowy.data.repositories.HomeworkRepository
|
||||||
|
import io.github.wulkanowy.data.waitForResult
|
||||||
import io.github.wulkanowy.services.sync.notifications.NewHomeworkNotification
|
import io.github.wulkanowy.services.sync.notifications.NewHomeworkNotification
|
||||||
import io.github.wulkanowy.utils.nextOrSameSchoolDay
|
import io.github.wulkanowy.utils.nextOrSameSchoolDay
|
||||||
import io.github.wulkanowy.utils.waitForResult
|
|
||||||
import kotlinx.coroutines.flow.first
|
import kotlinx.coroutines.flow.first
|
||||||
import java.time.LocalDate.now
|
import java.time.LocalDate.now
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
@ -3,8 +3,8 @@ 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.LuckyNumberRepository
|
import io.github.wulkanowy.data.repositories.LuckyNumberRepository
|
||||||
|
import io.github.wulkanowy.data.waitForResult
|
||||||
import io.github.wulkanowy.services.sync.notifications.NewLuckyNumberNotification
|
import io.github.wulkanowy.services.sync.notifications.NewLuckyNumberNotification
|
||||||
import io.github.wulkanowy.utils.waitForResult
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class LuckyNumberWork @Inject constructor(
|
class LuckyNumberWork @Inject constructor(
|
||||||
|
@ -4,8 +4,8 @@ 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.enums.MessageFolder.RECEIVED
|
import io.github.wulkanowy.data.enums.MessageFolder.RECEIVED
|
||||||
import io.github.wulkanowy.data.repositories.MessageRepository
|
import io.github.wulkanowy.data.repositories.MessageRepository
|
||||||
|
import io.github.wulkanowy.data.waitForResult
|
||||||
import io.github.wulkanowy.services.sync.notifications.NewMessageNotification
|
import io.github.wulkanowy.services.sync.notifications.NewMessageNotification
|
||||||
import io.github.wulkanowy.utils.waitForResult
|
|
||||||
import kotlinx.coroutines.flow.first
|
import kotlinx.coroutines.flow.first
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@ -3,8 +3,8 @@ 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.NoteRepository
|
import io.github.wulkanowy.data.repositories.NoteRepository
|
||||||
|
import io.github.wulkanowy.data.waitForResult
|
||||||
import io.github.wulkanowy.services.sync.notifications.NewNoteNotification
|
import io.github.wulkanowy.services.sync.notifications.NewNoteNotification
|
||||||
import io.github.wulkanowy.utils.waitForResult
|
|
||||||
import kotlinx.coroutines.flow.first
|
import kotlinx.coroutines.flow.first
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@ -3,8 +3,8 @@ 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.SchoolAnnouncementRepository
|
import io.github.wulkanowy.data.repositories.SchoolAnnouncementRepository
|
||||||
|
import io.github.wulkanowy.data.waitForResult
|
||||||
import io.github.wulkanowy.services.sync.notifications.NewSchoolAnnouncementNotification
|
import io.github.wulkanowy.services.sync.notifications.NewSchoolAnnouncementNotification
|
||||||
import io.github.wulkanowy.utils.waitForResult
|
|
||||||
import kotlinx.coroutines.flow.first
|
import kotlinx.coroutines.flow.first
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@ -3,7 +3,8 @@ 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.TeacherRepository
|
import io.github.wulkanowy.data.repositories.TeacherRepository
|
||||||
import io.github.wulkanowy.utils.waitForResult
|
import io.github.wulkanowy.data.waitForResult
|
||||||
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class TeacherWork @Inject constructor(private val teacherRepository: TeacherRepository) : Work {
|
class TeacherWork @Inject constructor(private val teacherRepository: TeacherRepository) : Work {
|
||||||
|
@ -3,9 +3,9 @@ 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.TimetableRepository
|
import io.github.wulkanowy.data.repositories.TimetableRepository
|
||||||
|
import io.github.wulkanowy.data.waitForResult
|
||||||
import io.github.wulkanowy.services.sync.notifications.ChangeTimetableNotification
|
import io.github.wulkanowy.services.sync.notifications.ChangeTimetableNotification
|
||||||
import io.github.wulkanowy.utils.nextOrSameSchoolDay
|
import io.github.wulkanowy.utils.nextOrSameSchoolDay
|
||||||
import io.github.wulkanowy.utils.waitForResult
|
|
||||||
import kotlinx.coroutines.flow.first
|
import kotlinx.coroutines.flow.first
|
||||||
import java.time.LocalDate.now
|
import java.time.LocalDate.now
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
@ -1,17 +1,10 @@
|
|||||||
package io.github.wulkanowy.ui.base
|
package io.github.wulkanowy.ui.base
|
||||||
|
|
||||||
import io.github.wulkanowy.data.Status
|
|
||||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||||
import io.github.wulkanowy.utils.flowWithResource
|
import kotlinx.coroutines.*
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.Job
|
|
||||||
import kotlinx.coroutines.SupervisorJob
|
|
||||||
import kotlinx.coroutines.cancelChildren
|
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.catch
|
import kotlinx.coroutines.flow.catch
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
import kotlinx.coroutines.flow.onEach
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
open class BasePresenter<T : BaseView>(
|
open class BasePresenter<T : BaseView>(
|
||||||
@ -37,28 +30,28 @@ open class BasePresenter<T : BaseView>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun onExpiredLoginSelected() {
|
fun onExpiredLoginSelected() {
|
||||||
flowWithResource {
|
Timber.i("Attempt to switch the student after the session expires")
|
||||||
val student = studentRepository.getCurrentStudent(false)
|
|
||||||
studentRepository.logoutStudent(student)
|
|
||||||
|
|
||||||
val students = studentRepository.getSavedStudents(false)
|
presenterScope.launch {
|
||||||
if (students.isNotEmpty()) {
|
runCatching {
|
||||||
Timber.i("Switching current student")
|
val student = studentRepository.getCurrentStudent(false)
|
||||||
studentRepository.switchStudent(students[0])
|
studentRepository.logoutStudent(student)
|
||||||
|
|
||||||
|
val students = studentRepository.getSavedStudents(false)
|
||||||
|
if (students.isNotEmpty()) {
|
||||||
|
Timber.i("Switching current student")
|
||||||
|
studentRepository.switchStudent(students[0])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}.onEach {
|
.onFailure {
|
||||||
when (it.status) {
|
Timber.i("Switch student result: An exception occurred")
|
||||||
Status.LOADING -> Timber.i("Attempt to switch the student after the session expires")
|
errorHandler.dispatch(it)
|
||||||
Status.SUCCESS -> {
|
}
|
||||||
|
.onSuccess {
|
||||||
Timber.i("Switch student result: Open login view")
|
Timber.i("Switch student result: Open login view")
|
||||||
view?.openClearLoginView()
|
view?.openClearLoginView()
|
||||||
}
|
}
|
||||||
Status.ERROR -> {
|
}
|
||||||
Timber.i("Switch student result: An exception occurred")
|
|
||||||
errorHandler.dispatch(it.error!!)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}.launch("expired")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <T> Flow<T>.launch(individualJobTag: String = "load"): Job {
|
fun <T> Flow<T>.launch(individualJobTag: String = "load"): Job {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package io.github.wulkanowy.ui.modules
|
package io.github.wulkanowy.ui.modules
|
||||||
|
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
|
import io.github.wulkanowy.data.serializers.LocalDateSerializer
|
||||||
import io.github.wulkanowy.ui.modules.attendance.AttendanceFragment
|
import io.github.wulkanowy.ui.modules.attendance.AttendanceFragment
|
||||||
import io.github.wulkanowy.ui.modules.conference.ConferenceFragment
|
import io.github.wulkanowy.ui.modules.conference.ConferenceFragment
|
||||||
import io.github.wulkanowy.ui.modules.dashboard.DashboardFragment
|
import io.github.wulkanowy.ui.modules.dashboard.DashboardFragment
|
||||||
@ -14,18 +15,19 @@ import io.github.wulkanowy.ui.modules.note.NoteFragment
|
|||||||
import io.github.wulkanowy.ui.modules.schoolandteachers.school.SchoolFragment
|
import io.github.wulkanowy.ui.modules.schoolandteachers.school.SchoolFragment
|
||||||
import io.github.wulkanowy.ui.modules.schoolannouncement.SchoolAnnouncementFragment
|
import io.github.wulkanowy.ui.modules.schoolannouncement.SchoolAnnouncementFragment
|
||||||
import io.github.wulkanowy.ui.modules.timetable.TimetableFragment
|
import io.github.wulkanowy.ui.modules.timetable.TimetableFragment
|
||||||
import java.io.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import java.time.LocalDate
|
import java.time.LocalDate
|
||||||
|
|
||||||
sealed interface Destination : Serializable {
|
@Serializable
|
||||||
|
sealed class Destination private constructor() : java.io.Serializable {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Type in children classes have to be as getter to avoid null in enums
|
Type in children classes have to be as getter to avoid null in enums
|
||||||
https://stackoverflow.com/questions/68866453/kotlin-enum-val-is-returning-null-despite-being-set-at-compile-time
|
https://stackoverflow.com/questions/68866453/kotlin-enum-val-is-returning-null-despite-being-set-at-compile-time
|
||||||
*/
|
*/
|
||||||
val type: Type
|
abstract val type: Type
|
||||||
|
|
||||||
val fragment: Fragment
|
abstract val fragment: Fragment
|
||||||
|
|
||||||
enum class Type(val defaultDestination: Destination) {
|
enum class Type(val defaultDestination: Destination) {
|
||||||
DASHBOARD(Dashboard),
|
DASHBOARD(Dashboard),
|
||||||
@ -43,94 +45,84 @@ sealed interface Destination : Serializable {
|
|||||||
MESSAGE(Message);
|
MESSAGE(Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
object Dashboard : Destination {
|
@Serializable
|
||||||
|
object Dashboard : Destination() {
|
||||||
override val type get() = Type.DASHBOARD
|
override val type get() = Type.DASHBOARD
|
||||||
|
|
||||||
override val fragment get() = DashboardFragment.newInstance()
|
override val fragment get() = DashboardFragment.newInstance()
|
||||||
}
|
}
|
||||||
|
|
||||||
object Grade : Destination {
|
@Serializable
|
||||||
|
object Grade : Destination() {
|
||||||
override val type get() = Type.GRADE
|
override val type get() = Type.GRADE
|
||||||
|
|
||||||
override val fragment get() = GradeFragment.newInstance()
|
override val fragment get() = GradeFragment.newInstance()
|
||||||
}
|
}
|
||||||
|
|
||||||
object Attendance : Destination {
|
@Serializable
|
||||||
|
object Attendance : Destination() {
|
||||||
override val type get() = Type.ATTENDANCE
|
override val type get() = Type.ATTENDANCE
|
||||||
|
|
||||||
override val fragment get() = AttendanceFragment.newInstance()
|
override val fragment get() = AttendanceFragment.newInstance()
|
||||||
}
|
}
|
||||||
|
|
||||||
object Exam : Destination {
|
@Serializable
|
||||||
|
object Exam : Destination() {
|
||||||
override val type get() = Type.EXAM
|
override val type get() = Type.EXAM
|
||||||
|
|
||||||
override val fragment get() = ExamFragment.newInstance()
|
override val fragment get() = ExamFragment.newInstance()
|
||||||
}
|
}
|
||||||
|
|
||||||
data class Timetable(val date: LocalDate? = null) : Destination {
|
@Serializable
|
||||||
|
data class Timetable(
|
||||||
|
@Serializable(with = LocalDateSerializer::class)
|
||||||
|
private val date: LocalDate? = null
|
||||||
|
) : Destination() {
|
||||||
override val type get() = Type.TIMETABLE
|
override val type get() = Type.TIMETABLE
|
||||||
|
|
||||||
override val fragment get() = TimetableFragment.newInstance(date)
|
override val fragment get() = TimetableFragment.newInstance(date)
|
||||||
}
|
}
|
||||||
|
|
||||||
object Homework : Destination {
|
@Serializable
|
||||||
|
object Homework : Destination() {
|
||||||
override val type get() = Type.HOMEWORK
|
override val type get() = Type.HOMEWORK
|
||||||
|
|
||||||
override val fragment get() = HomeworkFragment.newInstance()
|
override val fragment get() = HomeworkFragment.newInstance()
|
||||||
}
|
}
|
||||||
|
|
||||||
object Note : Destination {
|
@Serializable
|
||||||
|
object Note : Destination() {
|
||||||
override val type get() = Type.NOTE
|
override val type get() = Type.NOTE
|
||||||
|
|
||||||
override val fragment get() = NoteFragment.newInstance()
|
override val fragment get() = NoteFragment.newInstance()
|
||||||
}
|
}
|
||||||
|
|
||||||
object Conference : Destination {
|
@Serializable
|
||||||
|
object Conference : Destination() {
|
||||||
override val type get() = Type.CONFERENCE
|
override val type get() = Type.CONFERENCE
|
||||||
|
|
||||||
override val fragment get() = ConferenceFragment.newInstance()
|
override val fragment get() = ConferenceFragment.newInstance()
|
||||||
}
|
}
|
||||||
|
|
||||||
object SchoolAnnouncement : Destination {
|
@Serializable
|
||||||
|
object SchoolAnnouncement : Destination() {
|
||||||
override val type get() = Type.SCHOOL_ANNOUNCEMENT
|
override val type get() = Type.SCHOOL_ANNOUNCEMENT
|
||||||
|
|
||||||
override val fragment get() = SchoolAnnouncementFragment.newInstance()
|
override val fragment get() = SchoolAnnouncementFragment.newInstance()
|
||||||
}
|
}
|
||||||
|
|
||||||
object School : Destination {
|
@Serializable
|
||||||
|
object School : Destination() {
|
||||||
override val type get() = Type.SCHOOL
|
override val type get() = Type.SCHOOL
|
||||||
|
|
||||||
override val fragment get() = SchoolFragment.newInstance()
|
override val fragment get() = SchoolFragment.newInstance()
|
||||||
}
|
}
|
||||||
|
|
||||||
object LuckyNumber : Destination {
|
@Serializable
|
||||||
|
object LuckyNumber : Destination() {
|
||||||
override val type get() = Type.LUCKY_NUMBER
|
override val type get() = Type.LUCKY_NUMBER
|
||||||
|
|
||||||
override val fragment get() = LuckyNumberFragment.newInstance()
|
override val fragment get() = LuckyNumberFragment.newInstance()
|
||||||
}
|
}
|
||||||
|
|
||||||
object More : Destination {
|
@Serializable
|
||||||
|
object More : Destination() {
|
||||||
override val type get() = Type.MORE
|
override val type get() = Type.MORE
|
||||||
|
|
||||||
override val fragment get() = MoreFragment.newInstance()
|
override val fragment get() = MoreFragment.newInstance()
|
||||||
}
|
}
|
||||||
|
|
||||||
object Message : Destination {
|
@Serializable
|
||||||
|
object Message : Destination() {
|
||||||
override val type get() = Type.MESSAGE
|
override val type get() = Type.MESSAGE
|
||||||
|
|
||||||
override val fragment get() = MessageFragment.newInstance()
|
override val fragment get() = MessageFragment.newInstance()
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,13 +1,11 @@
|
|||||||
package io.github.wulkanowy.ui.modules.about.contributor
|
package io.github.wulkanowy.ui.modules.about.contributor
|
||||||
|
|
||||||
import io.github.wulkanowy.data.Status
|
import io.github.wulkanowy.data.*
|
||||||
import io.github.wulkanowy.data.pojos.Contributor
|
import io.github.wulkanowy.data.pojos.Contributor
|
||||||
import io.github.wulkanowy.data.repositories.AppCreatorRepository
|
import io.github.wulkanowy.data.repositories.AppCreatorRepository
|
||||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
import io.github.wulkanowy.data.repositories.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.flowWithResource
|
|
||||||
import kotlinx.coroutines.flow.onEach
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class ContributorPresenter @Inject constructor(
|
class ContributorPresenter @Inject constructor(
|
||||||
@ -31,15 +29,11 @@ class ContributorPresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun loadData() {
|
private fun loadData() {
|
||||||
flowWithResource { appCreatorRepository.getAppCreators() }.onEach {
|
resourceFlow { appCreatorRepository.getAppCreators() }
|
||||||
when (it.status) {
|
.onResourceLoading { view?.showProgress(true) }
|
||||||
Status.LOADING -> view?.showProgress(true)
|
.onResourceSuccess { view?.updateData(it) }
|
||||||
Status.SUCCESS -> view?.run {
|
.onResourceNotLoading { view?.showProgress(false) }
|
||||||
showProgress(false)
|
.onResourceError { errorHandler.dispatch(it) }
|
||||||
updateData(it.data!!)
|
.launch()
|
||||||
}
|
|
||||||
Status.ERROR -> errorHandler.dispatch(it.error!!)
|
|
||||||
}
|
|
||||||
}.launch()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,12 @@
|
|||||||
package io.github.wulkanowy.ui.modules.about.license
|
package io.github.wulkanowy.ui.modules.about.license
|
||||||
|
|
||||||
import com.mikepenz.aboutlibraries.entity.Library
|
import com.mikepenz.aboutlibraries.entity.Library
|
||||||
import io.github.wulkanowy.data.Status
|
|
||||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
import io.github.wulkanowy.data.repositories.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.DispatchersProvider
|
import io.github.wulkanowy.utils.DispatchersProvider
|
||||||
import io.github.wulkanowy.utils.afterLoading
|
import kotlinx.coroutines.launch
|
||||||
import io.github.wulkanowy.utils.flowWithResource
|
|
||||||
import kotlinx.coroutines.flow.onEach
|
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import timber.log.Timber
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class LicensePresenter @Inject constructor(
|
class LicensePresenter @Inject constructor(
|
||||||
@ -30,18 +26,16 @@ class LicensePresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun loadData() {
|
private fun loadData() {
|
||||||
flowWithResource {
|
presenterScope.launch {
|
||||||
withContext(dispatchers.io) {
|
runCatching {
|
||||||
view?.appLibraries.orEmpty()
|
withContext(dispatchers.io) {
|
||||||
|
view?.appLibraries.orEmpty()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}.onEach {
|
.onFailure { errorHandler.dispatch(it) }
|
||||||
when (it.status) {
|
.onSuccess { view?.updateData(it) }
|
||||||
Status.LOADING -> Timber.d("License data load started")
|
|
||||||
Status.SUCCESS -> view?.updateData(it.data!!)
|
|
||||||
Status.ERROR -> errorHandler.dispatch(it.error!!)
|
|
||||||
}
|
|
||||||
}.afterLoading {
|
|
||||||
view?.showProgress(false)
|
view?.showProgress(false)
|
||||||
}.launch()
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
package io.github.wulkanowy.ui.modules.account
|
package io.github.wulkanowy.ui.modules.account
|
||||||
|
|
||||||
import io.github.wulkanowy.data.Status
|
|
||||||
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
|
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
|
||||||
|
import io.github.wulkanowy.data.logResourceStatus
|
||||||
|
import io.github.wulkanowy.data.onResourceError
|
||||||
|
import io.github.wulkanowy.data.onResourceSuccess
|
||||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||||
|
import io.github.wulkanowy.data.resourceFlow
|
||||||
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.flowWithResource
|
|
||||||
import kotlinx.coroutines.flow.onEach
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@ -32,20 +33,10 @@ class AccountPresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun loadData() {
|
private fun loadData() {
|
||||||
flowWithResource { studentRepository.getSavedStudents(false) }
|
resourceFlow { studentRepository.getSavedStudents(false) }
|
||||||
.onEach {
|
.logResourceStatus("load account data")
|
||||||
when (it.status) {
|
.onResourceSuccess { view?.updateData(createAccountItems(it)) }
|
||||||
Status.LOADING -> Timber.i("Loading account data started")
|
.onResourceError(errorHandler::dispatch)
|
||||||
Status.SUCCESS -> {
|
|
||||||
Timber.i("Loading account result: Success")
|
|
||||||
view?.updateData(createAccountItems(it.data!!))
|
|
||||||
}
|
|
||||||
Status.ERROR -> {
|
|
||||||
Timber.i("Loading account result: An exception occurred")
|
|
||||||
errorHandler.dispatch(it.error!!)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.launch("load")
|
.launch("load")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package io.github.wulkanowy.ui.modules.account.accountdetails
|
package io.github.wulkanowy.ui.modules.account.accountdetails
|
||||||
|
|
||||||
import io.github.wulkanowy.data.Resource
|
import io.github.wulkanowy.data.*
|
||||||
import io.github.wulkanowy.data.Status
|
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
|
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
|
||||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||||
@ -9,10 +8,6 @@ import io.github.wulkanowy.services.sync.SyncManager
|
|||||||
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.ui.modules.studentinfo.StudentInfoView
|
import io.github.wulkanowy.ui.modules.studentinfo.StudentInfoView
|
||||||
import io.github.wulkanowy.utils.afterLoading
|
|
||||||
import io.github.wulkanowy.utils.flowWithResource
|
|
||||||
import kotlinx.coroutines.flow.map
|
|
||||||
import kotlinx.coroutines.flow.onEach
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@ -51,40 +46,25 @@ class AccountDetailsPresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun loadData() {
|
private fun loadData() {
|
||||||
flowWithResource { studentRepository.getSavedStudents() }
|
resourceFlow { studentRepository.getSavedStudentById(studentId ?: -1) }
|
||||||
.map { studentWithSemesters ->
|
.logResourceStatus("loading account details view")
|
||||||
Resource(
|
.onResourceLoading {
|
||||||
data = studentWithSemesters.data?.single { it.student.id == studentId },
|
view?.run {
|
||||||
status = studentWithSemesters.status,
|
showProgress(true)
|
||||||
error = studentWithSemesters.error
|
showContent(false)
|
||||||
)
|
|
||||||
}
|
|
||||||
.onEach {
|
|
||||||
when (it.status) {
|
|
||||||
Status.LOADING -> {
|
|
||||||
view?.run {
|
|
||||||
showProgress(true)
|
|
||||||
showContent(false)
|
|
||||||
}
|
|
||||||
Timber.i("Loading account details view started")
|
|
||||||
}
|
|
||||||
Status.SUCCESS -> {
|
|
||||||
Timber.i("Loading account details view result: Success")
|
|
||||||
studentWithSemesters = it.data
|
|
||||||
view?.run {
|
|
||||||
showAccountData(studentWithSemesters!!.student)
|
|
||||||
enableSelectStudentButton(!studentWithSemesters!!.student.isCurrent)
|
|
||||||
showContent(true)
|
|
||||||
showErrorView(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Status.ERROR -> {
|
|
||||||
Timber.i("Loading account details view result: An exception occurred")
|
|
||||||
errorHandler.dispatch(it.error!!)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.afterLoading { view?.showProgress(false) }
|
.onResourceSuccess {
|
||||||
|
studentWithSemesters = it
|
||||||
|
view?.run {
|
||||||
|
showAccountData(studentWithSemesters!!.student)
|
||||||
|
enableSelectStudentButton(!studentWithSemesters!!.student.isCurrent)
|
||||||
|
showContent(true)
|
||||||
|
showErrorView(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.onResourceNotLoading { view?.showProgress(false) }
|
||||||
|
.onResourceError(errorHandler::dispatch)
|
||||||
.launch()
|
.launch()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,22 +85,12 @@ class AccountDetailsPresenter @Inject constructor(
|
|||||||
|
|
||||||
Timber.i("Select student ${studentWithSemesters!!.student.id}")
|
Timber.i("Select student ${studentWithSemesters!!.student.id}")
|
||||||
|
|
||||||
flowWithResource { studentRepository.switchStudent(studentWithSemesters!!) }
|
resourceFlow { studentRepository.switchStudent(studentWithSemesters!!) }
|
||||||
.onEach {
|
.logResourceStatus("change student")
|
||||||
when (it.status) {
|
.onResourceSuccess { view?.recreateMainView() }
|
||||||
Status.LOADING -> Timber.i("Attempt to change a student")
|
.onResourceNotLoading { view?.popViewToMain() }
|
||||||
Status.SUCCESS -> {
|
.onResourceError(errorHandler::dispatch)
|
||||||
Timber.i("Change a student result: Success")
|
.launch("switch")
|
||||||
view?.recreateMainView()
|
|
||||||
}
|
|
||||||
Status.ERROR -> {
|
|
||||||
Timber.i("Change a student result: An exception occurred")
|
|
||||||
errorHandler.dispatch(it.error!!)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}.afterLoading {
|
|
||||||
view?.popViewToMain()
|
|
||||||
}.launch("switch")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onRemoveSelected() {
|
fun onRemoveSelected() {
|
||||||
@ -131,7 +101,7 @@ class AccountDetailsPresenter @Inject constructor(
|
|||||||
fun onLogoutConfirm() {
|
fun onLogoutConfirm() {
|
||||||
if (studentWithSemesters == null) return
|
if (studentWithSemesters == null) return
|
||||||
|
|
||||||
flowWithResource {
|
resourceFlow {
|
||||||
val studentToLogout = studentWithSemesters!!.student
|
val studentToLogout = studentWithSemesters!!.student
|
||||||
|
|
||||||
studentRepository.logoutStudent(studentToLogout)
|
studentRepository.logoutStudent(studentToLogout)
|
||||||
@ -141,13 +111,13 @@ class AccountDetailsPresenter @Inject constructor(
|
|||||||
studentRepository.switchStudent(students[0])
|
studentRepository.switchStudent(students[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
return@flowWithResource students
|
students
|
||||||
}.onEach {
|
}
|
||||||
when (it.status) {
|
.logResourceStatus("logout user")
|
||||||
Status.LOADING -> Timber.i("Attempt to logout user")
|
.onResourceSuccess {
|
||||||
Status.SUCCESS -> view?.run {
|
view?.run {
|
||||||
when {
|
when {
|
||||||
it.data!!.isEmpty() -> {
|
it.isEmpty() -> {
|
||||||
Timber.i("Logout result: Open login view")
|
Timber.i("Logout result: Open login view")
|
||||||
syncManager.stopSyncWorker()
|
syncManager.stopSyncWorker()
|
||||||
openClearLoginView()
|
openClearLoginView()
|
||||||
@ -162,18 +132,16 @@ class AccountDetailsPresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Status.ERROR -> {
|
}
|
||||||
Timber.i("Logout result: An exception occurred")
|
.onResourceNotLoading {
|
||||||
errorHandler.dispatch(it.error!!)
|
if (studentWithSemesters?.student?.isCurrent == true) {
|
||||||
|
view?.popViewToMain()
|
||||||
|
} else {
|
||||||
|
view?.popViewToAccounts()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.afterLoading {
|
.onResourceError(errorHandler::dispatch)
|
||||||
if (studentWithSemesters?.student?.isCurrent == true) {
|
.launch("logout")
|
||||||
view?.popViewToMain()
|
|
||||||
} else {
|
|
||||||
view?.popViewToAccounts()
|
|
||||||
}
|
|
||||||
}.launch("logout")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showErrorViewOnError(message: String, error: Throwable) {
|
private fun showErrorViewOnError(message: String, error: Throwable) {
|
||||||
|
@ -1,15 +1,12 @@
|
|||||||
package io.github.wulkanowy.ui.modules.account.accountedit
|
package io.github.wulkanowy.ui.modules.account.accountedit
|
||||||
|
|
||||||
import io.github.wulkanowy.data.Status
|
import io.github.wulkanowy.data.*
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import io.github.wulkanowy.data.db.entities.StudentNickAndAvatar
|
import io.github.wulkanowy.data.db.entities.StudentNickAndAvatar
|
||||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
import io.github.wulkanowy.data.repositories.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.AppInfo
|
||||||
import io.github.wulkanowy.utils.afterLoading
|
|
||||||
import io.github.wulkanowy.utils.flowWithResource
|
|
||||||
import kotlinx.coroutines.flow.onEach
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@ -38,43 +35,26 @@ class AccountEditPresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun loadData() {
|
private fun loadData() {
|
||||||
flowWithResource {
|
resourceFlow { studentRepository.getStudentById(student.id, false).avatarColor }
|
||||||
studentRepository.getStudentById(student.id, false).avatarColor
|
.logResourceStatus("load student")
|
||||||
}.onEach { resource ->
|
.onResourceSuccess { view?.updateSelectedColorData(it.toInt()) }
|
||||||
when (resource.status) {
|
.onResourceError(errorHandler::dispatch)
|
||||||
Status.LOADING -> Timber.i("Attempt to load student")
|
.launch("load_data")
|
||||||
Status.SUCCESS -> {
|
|
||||||
view?.updateSelectedColorData(resource.data?.toInt()!!)
|
|
||||||
Timber.i("Attempt to load student: Success")
|
|
||||||
}
|
|
||||||
Status.ERROR -> {
|
|
||||||
Timber.i("Attempt to load student: An exception occurred")
|
|
||||||
errorHandler.dispatch(resource.error!!)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}.launch("load_data")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun changeStudentNickAndAvatar(nick: String, avatarColor: Int) {
|
fun changeStudentNickAndAvatar(nick: String, avatarColor: Int) {
|
||||||
flowWithResource {
|
resourceFlow {
|
||||||
val studentNick =
|
val studentNick = StudentNickAndAvatar(
|
||||||
StudentNickAndAvatar(nick = nick.trim(), avatarColor = avatarColor.toLong())
|
nick = nick.trim(),
|
||||||
.apply { id = student.id }
|
avatarColor = avatarColor.toLong()
|
||||||
|
).apply { id = student.id }
|
||||||
|
|
||||||
studentRepository.updateStudentNickAndAvatar(studentNick)
|
studentRepository.updateStudentNickAndAvatar(studentNick)
|
||||||
}.onEach {
|
|
||||||
when (it.status) {
|
|
||||||
Status.LOADING -> Timber.i("Attempt to change a student nick and avatar")
|
|
||||||
Status.SUCCESS -> {
|
|
||||||
Timber.i("Change a student nick and avatar result: Success")
|
|
||||||
view?.recreateMainView()
|
|
||||||
}
|
|
||||||
Status.ERROR -> {
|
|
||||||
Timber.i("Change a student nick and avatar result: An exception occurred")
|
|
||||||
errorHandler.dispatch(it.error!!)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.afterLoading { view?.popView() }
|
.logResourceStatus("change student nick and avatar")
|
||||||
|
.onResourceSuccess { view?.recreateMainView() }
|
||||||
|
.onResourceNotLoading { view?.popView() }
|
||||||
|
.onResourceError(errorHandler::dispatch)
|
||||||
.launch("update_student")
|
.launch("update_student")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,11 @@
|
|||||||
package io.github.wulkanowy.ui.modules.account.accountquick
|
package io.github.wulkanowy.ui.modules.account.accountquick
|
||||||
|
|
||||||
import io.github.wulkanowy.data.Status
|
import io.github.wulkanowy.data.*
|
||||||
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
|
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
|
||||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
import io.github.wulkanowy.data.repositories.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.ui.modules.account.AccountItem
|
import io.github.wulkanowy.ui.modules.account.AccountItem
|
||||||
import io.github.wulkanowy.utils.afterLoading
|
|
||||||
import io.github.wulkanowy.utils.flowWithResource
|
|
||||||
import kotlinx.coroutines.flow.onEach
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@ -43,21 +40,11 @@ class AccountQuickPresenter @Inject constructor(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
flowWithResource { studentRepository.switchStudent(studentWithSemesters) }
|
resourceFlow { studentRepository.switchStudent(studentWithSemesters) }
|
||||||
.onEach {
|
.logResourceStatus("change student")
|
||||||
when (it.status) {
|
.onResourceSuccess { view?.recreateMainView() }
|
||||||
Status.LOADING -> Timber.i("Attempt to change a student")
|
.onResourceNotLoading { view?.popView() }
|
||||||
Status.SUCCESS -> {
|
.onResourceError(errorHandler::dispatch)
|
||||||
Timber.i("Change a student result: Success")
|
|
||||||
view?.recreateMainView()
|
|
||||||
}
|
|
||||||
Status.ERROR -> {
|
|
||||||
Timber.i("Change a student result: An exception occurred")
|
|
||||||
errorHandler.dispatch(it.error!!)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.afterLoading { view?.popView() }
|
|
||||||
.launch("switch")
|
.launch("switch")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,14 +2,8 @@ package io.github.wulkanowy.ui.modules.attendance
|
|||||||
|
|
||||||
import android.content.DialogInterface.BUTTON_POSITIVE
|
import android.content.DialogInterface.BUTTON_POSITIVE
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.*
|
||||||
import android.view.Menu
|
import android.view.View.*
|
||||||
import android.view.MenuInflater
|
|
||||||
import android.view.MenuItem
|
|
||||||
import android.view.View
|
|
||||||
import android.view.View.GONE
|
|
||||||
import android.view.View.INVISIBLE
|
|
||||||
import android.view.View.VISIBLE
|
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.appcompat.view.ActionMode
|
import androidx.appcompat.view.ActionMode
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
@ -68,7 +62,7 @@ class AttendanceFragment : BaseFragment<FragmentAttendanceBinding>(R.layout.frag
|
|||||||
private val actionModeCallback = object : ActionMode.Callback {
|
private val actionModeCallback = object : ActionMode.Callback {
|
||||||
override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
|
override fun onCreateActionMode(mode: ActionMode, menu: Menu): Boolean {
|
||||||
val inflater = mode.menuInflater
|
val inflater = mode.menuInflater
|
||||||
inflater.inflate(R.menu.context_menu_excuse, menu)
|
inflater.inflate(R.menu.context_menu_attendance, menu)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package io.github.wulkanowy.ui.modules.attendance
|
package io.github.wulkanowy.ui.modules.attendance
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import io.github.wulkanowy.data.Status
|
import io.github.wulkanowy.data.*
|
||||||
import io.github.wulkanowy.data.db.entities.Attendance
|
import io.github.wulkanowy.data.db.entities.Attendance
|
||||||
import io.github.wulkanowy.data.repositories.AttendanceRepository
|
import io.github.wulkanowy.data.repositories.AttendanceRepository
|
||||||
import io.github.wulkanowy.data.repositories.PreferencesRepository
|
import io.github.wulkanowy.data.repositories.PreferencesRepository
|
||||||
@ -9,18 +9,7 @@ import io.github.wulkanowy.data.repositories.SemesterRepository
|
|||||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
import io.github.wulkanowy.data.repositories.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.AnalyticsHelper
|
import io.github.wulkanowy.utils.*
|
||||||
import io.github.wulkanowy.utils.afterLoading
|
|
||||||
import io.github.wulkanowy.utils.capitalise
|
|
||||||
import io.github.wulkanowy.utils.flowWithResource
|
|
||||||
import io.github.wulkanowy.utils.flowWithResourceIn
|
|
||||||
import io.github.wulkanowy.utils.getLastSchoolDayIfHoliday
|
|
||||||
import io.github.wulkanowy.utils.isExcusableOrNotExcused
|
|
||||||
import io.github.wulkanowy.utils.isHolidays
|
|
||||||
import io.github.wulkanowy.utils.nextSchoolDay
|
|
||||||
import io.github.wulkanowy.utils.previousOrSameSchoolDay
|
|
||||||
import io.github.wulkanowy.utils.previousSchoolDay
|
|
||||||
import io.github.wulkanowy.utils.toFormattedString
|
|
||||||
import kotlinx.coroutines.flow.catch
|
import kotlinx.coroutines.flow.catch
|
||||||
import kotlinx.coroutines.flow.flow
|
import kotlinx.coroutines.flow.flow
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
@ -213,93 +202,77 @@ class AttendancePresenter @Inject constructor(
|
|||||||
|
|
||||||
var isParent = false
|
var isParent = false
|
||||||
|
|
||||||
flowWithResourceIn {
|
flatResourceFlow {
|
||||||
val student = studentRepository.getCurrentStudent()
|
val student = studentRepository.getCurrentStudent()
|
||||||
isParent = student.isParent
|
isParent = student.isParent
|
||||||
|
|
||||||
val semester = semesterRepository.getCurrentSemester(student)
|
val semester = semesterRepository.getCurrentSemester(student)
|
||||||
attendanceRepository.getAttendance(
|
attendanceRepository.getAttendance(
|
||||||
student,
|
student = student,
|
||||||
semester,
|
semester = semester,
|
||||||
currentDate,
|
start = currentDate,
|
||||||
currentDate,
|
end = currentDate,
|
||||||
forceRefresh
|
forceRefresh = forceRefresh
|
||||||
)
|
)
|
||||||
}.onEach {
|
}
|
||||||
when (it.status) {
|
.logResourceStatus("load attendance")
|
||||||
Status.LOADING -> {
|
.onResourceLoading {
|
||||||
view?.showExcuseButton(false)
|
view?.showExcuseButton(false)
|
||||||
if (!it.data.isNullOrEmpty()) {
|
}
|
||||||
val filteredAttendance = if (prefRepository.isShowPresent) {
|
.mapResourceData {
|
||||||
it.data
|
if (prefRepository.isShowPresent) {
|
||||||
} else {
|
it
|
||||||
it.data.filter { item -> !item.presence }
|
} else {
|
||||||
}
|
it.filter { item -> !item.presence }
|
||||||
|
}.sortedBy { item -> item.number }
|
||||||
view?.run {
|
}
|
||||||
enableSwipe(true)
|
.onResourceData {
|
||||||
showRefresh(true)
|
view?.run {
|
||||||
showProgress(false)
|
enableSwipe(true)
|
||||||
showErrorView(false)
|
showProgress(false)
|
||||||
showEmpty(filteredAttendance.isEmpty())
|
showErrorView(false)
|
||||||
showContent(filteredAttendance.isNotEmpty())
|
showEmpty(it.isEmpty())
|
||||||
updateData(filteredAttendance.sortedBy { item -> item.number })
|
showContent(it.isNotEmpty())
|
||||||
}
|
updateData(it)
|
||||||
}
|
|
||||||
}
|
|
||||||
Status.SUCCESS -> {
|
|
||||||
Timber.i("Loading attendance result: Success")
|
|
||||||
val filteredAttendance = if (prefRepository.isShowPresent) {
|
|
||||||
it.data.orEmpty()
|
|
||||||
} else {
|
|
||||||
it.data?.filter { item -> !item.presence }.orEmpty()
|
|
||||||
}
|
|
||||||
|
|
||||||
isVulcanExcusedFunctionEnabled =
|
|
||||||
filteredAttendance.any { item -> item.excusable }
|
|
||||||
|
|
||||||
view?.apply {
|
|
||||||
updateData(filteredAttendance.sortedBy { item -> item.number })
|
|
||||||
showEmpty(filteredAttendance.isEmpty())
|
|
||||||
showErrorView(false)
|
|
||||||
showContent(filteredAttendance.isNotEmpty())
|
|
||||||
val anyExcusables = filteredAttendance.any { it.isExcusableOrNotExcused }
|
|
||||||
showExcuseButton(anyExcusables && (isParent || isVulcanExcusedFunctionEnabled))
|
|
||||||
}
|
|
||||||
analytics.logEvent(
|
|
||||||
"load_data",
|
|
||||||
"type" to "attendance",
|
|
||||||
"items" to it.data!!.size
|
|
||||||
)
|
|
||||||
}
|
|
||||||
Status.ERROR -> {
|
|
||||||
Timber.i("Loading attendance result: An exception occurred")
|
|
||||||
errorHandler.dispatch(it.error!!)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.afterLoading {
|
.onResourceIntermediate { view?.showRefresh(true) }
|
||||||
view?.run {
|
.onResourceSuccess {
|
||||||
showRefresh(false)
|
isVulcanExcusedFunctionEnabled = it.any { item -> item.excusable }
|
||||||
showProgress(false)
|
val anyExcusables = it.any { it.isExcusableOrNotExcused }
|
||||||
enableSwipe(true)
|
view?.showExcuseButton(anyExcusables && (isParent || isVulcanExcusedFunctionEnabled))
|
||||||
|
|
||||||
|
analytics.logEvent(
|
||||||
|
"load_data",
|
||||||
|
"type" to "attendance",
|
||||||
|
"items" to it.size
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}.launch()
|
.onResourceNotLoading {
|
||||||
|
view?.run {
|
||||||
|
showRefresh(false)
|
||||||
|
showProgress(false)
|
||||||
|
enableSwipe(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.onResourceError(errorHandler::dispatch)
|
||||||
|
.launch()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun excuseAbsence(reason: String?, toExcuseList: List<Attendance>) {
|
private fun excuseAbsence(reason: String?, toExcuseList: List<Attendance>) {
|
||||||
flowWithResource {
|
resourceFlow {
|
||||||
val student = studentRepository.getCurrentStudent()
|
val student = studentRepository.getCurrentStudent()
|
||||||
val semester = semesterRepository.getCurrentSemester(student)
|
val semester = semesterRepository.getCurrentSemester(student)
|
||||||
attendanceRepository.excuseForAbsence(student, semester, toExcuseList, reason)
|
attendanceRepository.excuseForAbsence(student, semester, toExcuseList, reason)
|
||||||
}.onEach {
|
}.onEach {
|
||||||
when (it.status) {
|
when (it) {
|
||||||
Status.LOADING -> view?.run {
|
is Resource.Loading -> view?.run {
|
||||||
Timber.i("Excusing absence started")
|
Timber.i("Excusing absence started")
|
||||||
showProgress(true)
|
showProgress(true)
|
||||||
showContent(false)
|
showContent(false)
|
||||||
showExcuseButton(false)
|
showExcuseButton(false)
|
||||||
}
|
}
|
||||||
Status.SUCCESS -> {
|
is Resource.Success -> {
|
||||||
Timber.i("Excusing for absence result: Success")
|
Timber.i("Excusing for absence result: Success")
|
||||||
analytics.logEvent("excuse_absence", "items" to attendanceToExcuseList.size)
|
analytics.logEvent("excuse_absence", "items" to attendanceToExcuseList.size)
|
||||||
attendanceToExcuseList.clear()
|
attendanceToExcuseList.clear()
|
||||||
@ -311,9 +284,9 @@ class AttendancePresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
loadData(forceRefresh = true)
|
loadData(forceRefresh = true)
|
||||||
}
|
}
|
||||||
Status.ERROR -> {
|
is Resource.Error -> {
|
||||||
Timber.i("Excusing for absence result: An exception occurred")
|
Timber.i("Excusing for absence result: An exception occurred")
|
||||||
errorHandler.dispatch(it.error!!)
|
errorHandler.dispatch(it.error)
|
||||||
loadData()
|
loadData()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,7 @@ class AttendanceSummaryFragment :
|
|||||||
binding.attendanceSummarySubjectsContainer.elevation = requireContext().dpToPx(1f)
|
binding.attendanceSummarySubjectsContainer.elevation = requireContext().dpToPx(1f)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun updateSubjects(data: ArrayList<String>) {
|
override fun updateSubjects(data: Collection<String>) {
|
||||||
with(subjectsAdapter) {
|
with(subjectsAdapter) {
|
||||||
clear()
|
clear()
|
||||||
addAll(data)
|
addAll(data)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package io.github.wulkanowy.ui.modules.attendance.summary
|
package io.github.wulkanowy.ui.modules.attendance.summary
|
||||||
|
|
||||||
import io.github.wulkanowy.data.Status
|
import io.github.wulkanowy.data.*
|
||||||
import io.github.wulkanowy.data.db.entities.AttendanceSummary
|
import io.github.wulkanowy.data.db.entities.AttendanceSummary
|
||||||
import io.github.wulkanowy.data.db.entities.Subject
|
import io.github.wulkanowy.data.db.entities.Subject
|
||||||
import io.github.wulkanowy.data.repositories.AttendanceSummaryRepository
|
import io.github.wulkanowy.data.repositories.AttendanceSummaryRepository
|
||||||
@ -10,9 +10,6 @@ import io.github.wulkanowy.data.repositories.SubjectRepository
|
|||||||
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.AnalyticsHelper
|
import io.github.wulkanowy.utils.AnalyticsHelper
|
||||||
import io.github.wulkanowy.utils.afterLoading
|
|
||||||
import io.github.wulkanowy.utils.flowWithResourceIn
|
|
||||||
import kotlinx.coroutines.flow.onEach
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.time.Month
|
import java.time.Month
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@ -75,11 +72,9 @@ class AttendanceSummaryPresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun loadData(subjectId: Int, forceRefresh: Boolean = false) {
|
private fun loadData(subjectId: Int, forceRefresh: Boolean = false) {
|
||||||
Timber.i("Loading attendance summary data started")
|
|
||||||
|
|
||||||
currentSubjectId = subjectId
|
currentSubjectId = subjectId
|
||||||
|
|
||||||
flowWithResourceIn {
|
flatResourceFlow {
|
||||||
val student = studentRepository.getCurrentStudent()
|
val student = studentRepository.getCurrentStudent()
|
||||||
val semester = semesterRepository.getCurrentSemester(student)
|
val semester = semesterRepository.getCurrentSemester(student)
|
||||||
|
|
||||||
@ -89,47 +84,37 @@ class AttendanceSummaryPresenter @Inject constructor(
|
|||||||
subjectId = subjectId,
|
subjectId = subjectId,
|
||||||
forceRefresh = forceRefresh
|
forceRefresh = forceRefresh
|
||||||
)
|
)
|
||||||
}.onEach {
|
}
|
||||||
when (it.status) {
|
.logResourceStatus("load attendance summary")
|
||||||
Status.LOADING -> {
|
.mapResourceData(this::sortItems)
|
||||||
if (!it.data.isNullOrEmpty()) {
|
.onResourceData {
|
||||||
view?.run {
|
view?.run {
|
||||||
enableSwipe(true)
|
enableSwipe(true)
|
||||||
showRefresh(true)
|
showProgress(false)
|
||||||
showProgress(false)
|
showErrorView(false)
|
||||||
showContent(true)
|
showContent(it.isNotEmpty())
|
||||||
showErrorView(false)
|
showEmpty(it.isEmpty())
|
||||||
updateDataSet(sortItems(it.data))
|
updateDataSet(it)
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Status.SUCCESS -> {
|
|
||||||
Timber.i("Loading attendance summary result: Success")
|
|
||||||
view?.apply {
|
|
||||||
showErrorView(false)
|
|
||||||
showEmpty(it.data!!.isEmpty())
|
|
||||||
showContent(it.data.isNotEmpty())
|
|
||||||
updateDataSet(sortItems(it.data))
|
|
||||||
}
|
|
||||||
analytics.logEvent(
|
|
||||||
"load_data",
|
|
||||||
"type" to "attendance_summary",
|
|
||||||
"items" to it.data!!.size,
|
|
||||||
"item_id" to subjectId
|
|
||||||
)
|
|
||||||
}
|
|
||||||
Status.ERROR -> {
|
|
||||||
Timber.i("Loading attendance summary result: An exception occurred")
|
|
||||||
errorHandler.dispatch(it.error!!)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.afterLoading {
|
.onResourceIntermediate { view?.showRefresh(true) }
|
||||||
view?.run {
|
.onResourceSuccess {
|
||||||
showRefresh(false)
|
analytics.logEvent(
|
||||||
showProgress(false)
|
"load_data",
|
||||||
enableSwipe(true)
|
"type" to "attendance_summary",
|
||||||
|
"items" to it.size,
|
||||||
|
"item_id" to subjectId
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}.launch()
|
.onResourceNotLoading {
|
||||||
|
view?.run {
|
||||||
|
showProgress(false)
|
||||||
|
showRefresh(false)
|
||||||
|
enableSwipe(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.onResourceError(errorHandler::dispatch)
|
||||||
|
.launch()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun sortItems(items: List<AttendanceSummary>) = items.sortedByDescending { item ->
|
private fun sortItems(items: List<AttendanceSummary>) = items.sortedByDescending { item ->
|
||||||
@ -148,27 +133,20 @@ class AttendanceSummaryPresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun loadSubjects() {
|
private fun loadSubjects() {
|
||||||
flowWithResourceIn {
|
flatResourceFlow {
|
||||||
val student = studentRepository.getCurrentStudent()
|
val student = studentRepository.getCurrentStudent()
|
||||||
val semester = semesterRepository.getCurrentSemester(student)
|
val semester = semesterRepository.getCurrentSemester(student)
|
||||||
subjectRepository.getSubjects(student, semester)
|
subjectRepository.getSubjects(student, semester)
|
||||||
}.onEach {
|
}
|
||||||
when (it.status) {
|
.logResourceStatus("load attendance summary subjects")
|
||||||
Status.LOADING -> Timber.i("Loading attendance summary subjects started")
|
.onResourceData {
|
||||||
Status.SUCCESS -> {
|
subjects = it
|
||||||
subjects = it.data!!
|
view?.run {
|
||||||
|
view?.updateSubjects(it.map { subject -> subject.name }.toList())
|
||||||
Timber.i("Loading attendance summary subjects result: Success")
|
showSubjects(true)
|
||||||
view?.run {
|
|
||||||
view?.updateSubjects(ArrayList(it.data.map { subject -> subject.name }))
|
|
||||||
showSubjects(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Status.ERROR -> {
|
|
||||||
Timber.i("Loading attendance summary subjects result: An exception occurred")
|
|
||||||
errorHandler.dispatch(it.error!!)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.launch("subjects")
|
.onResourceError(errorHandler::dispatch)
|
||||||
|
.launch("subjects")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ interface AttendanceSummaryView : BaseView {
|
|||||||
|
|
||||||
fun updateDataSet(data: List<AttendanceSummary>)
|
fun updateDataSet(data: List<AttendanceSummary>)
|
||||||
|
|
||||||
fun updateSubjects(data: ArrayList<String>)
|
fun updateSubjects(data: Collection<String>)
|
||||||
|
|
||||||
fun showSubjects(show: Boolean)
|
fun showSubjects(show: Boolean)
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package io.github.wulkanowy.ui.modules.conference
|
package io.github.wulkanowy.ui.modules.conference
|
||||||
|
|
||||||
import io.github.wulkanowy.data.Status
|
import io.github.wulkanowy.data.*
|
||||||
import io.github.wulkanowy.data.db.entities.Conference
|
import io.github.wulkanowy.data.db.entities.Conference
|
||||||
import io.github.wulkanowy.data.repositories.ConferenceRepository
|
import io.github.wulkanowy.data.repositories.ConferenceRepository
|
||||||
import io.github.wulkanowy.data.repositories.SemesterRepository
|
import io.github.wulkanowy.data.repositories.SemesterRepository
|
||||||
@ -8,9 +8,6 @@ import io.github.wulkanowy.data.repositories.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.AnalyticsHelper
|
import io.github.wulkanowy.utils.AnalyticsHelper
|
||||||
import io.github.wulkanowy.utils.afterLoading
|
|
||||||
import io.github.wulkanowy.utils.flowWithResourceIn
|
|
||||||
import kotlinx.coroutines.flow.onEach
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@ -64,50 +61,39 @@ class ConferencePresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun loadData(forceRefresh: Boolean = false) {
|
private fun loadData(forceRefresh: Boolean = false) {
|
||||||
Timber.i("Loading conference data started")
|
flatResourceFlow {
|
||||||
|
|
||||||
flowWithResourceIn {
|
|
||||||
val student = studentRepository.getCurrentStudent()
|
val student = studentRepository.getCurrentStudent()
|
||||||
val semester = semesterRepository.getCurrentSemester(student)
|
val semester = semesterRepository.getCurrentSemester(student)
|
||||||
conferenceRepository.getConferences(student, semester, forceRefresh)
|
conferenceRepository.getConferences(student, semester, forceRefresh)
|
||||||
}.onEach {
|
}
|
||||||
when (it.status) {
|
.logResourceStatus("load conference data")
|
||||||
Status.LOADING -> {
|
.mapResourceData { it.sortedByDescending { conference -> conference.date } }
|
||||||
if (!it.data.isNullOrEmpty()) {
|
.onResourceData {
|
||||||
view?.run {
|
view?.run {
|
||||||
enableSwipe(true)
|
enableSwipe(true)
|
||||||
showRefresh(true)
|
showProgress(false)
|
||||||
showProgress(false)
|
showErrorView(false)
|
||||||
showContent(true)
|
showContent(it.isNotEmpty())
|
||||||
updateData(it.data.sortedByDescending { conference -> conference.date })
|
showEmpty(it.isEmpty())
|
||||||
}
|
updateData(it)
|
||||||
}
|
|
||||||
}
|
|
||||||
Status.SUCCESS -> {
|
|
||||||
Timber.i("Loading conference result: Success")
|
|
||||||
view?.run {
|
|
||||||
updateData(it.data!!.sortedByDescending { conference -> conference.date })
|
|
||||||
showContent(it.data.isNotEmpty())
|
|
||||||
showEmpty(it.data.isEmpty())
|
|
||||||
showErrorView(false)
|
|
||||||
}
|
|
||||||
analytics.logEvent(
|
|
||||||
"load_data",
|
|
||||||
"type" to "conferences",
|
|
||||||
"items" to it.data!!.size
|
|
||||||
)
|
|
||||||
}
|
|
||||||
Status.ERROR -> {
|
|
||||||
Timber.i("Loading conference result: An exception occurred")
|
|
||||||
errorHandler.dispatch(it.error!!)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.afterLoading {
|
.onResourceIntermediate { view?.showRefresh(true) }
|
||||||
view?.run {
|
.onResourceSuccess {
|
||||||
showRefresh(false)
|
analytics.logEvent(
|
||||||
showProgress(false)
|
"load_data",
|
||||||
enableSwipe(true)
|
"type" to "conferences",
|
||||||
|
"items" to it.size
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}.launch()
|
.onResourceNotLoading {
|
||||||
|
view?.run {
|
||||||
|
enableSwipe(true)
|
||||||
|
showProgress(false)
|
||||||
|
showRefresh(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.onResourceError(errorHandler::dispatch)
|
||||||
|
.launch()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -204,4 +204,4 @@ class DashboardFragment : BaseFragment<FragmentDashboardBinding>(R.layout.fragme
|
|||||||
presenter.onDetachView()
|
presenter.onDetachView()
|
||||||
super.onDestroyView()
|
super.onDestroyView()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package io.github.wulkanowy.ui.modules.dashboard
|
package io.github.wulkanowy.ui.modules.dashboard
|
||||||
|
|
||||||
import io.github.wulkanowy.data.Resource
|
import io.github.wulkanowy.data.*
|
||||||
import io.github.wulkanowy.data.Status
|
|
||||||
import io.github.wulkanowy.data.db.entities.AdminMessage
|
import io.github.wulkanowy.data.db.entities.AdminMessage
|
||||||
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
|
||||||
@ -10,7 +9,6 @@ import io.github.wulkanowy.data.repositories.*
|
|||||||
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.calculatePercentage
|
import io.github.wulkanowy.utils.calculatePercentage
|
||||||
import io.github.wulkanowy.utils.flowWithResourceIn
|
|
||||||
import io.github.wulkanowy.utils.nextOrSameSchoolDay
|
import io.github.wulkanowy.utils.nextOrSameSchoolDay
|
||||||
import kotlinx.coroutines.flow.*
|
import kotlinx.coroutines.flow.*
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@ -225,27 +223,26 @@ class DashboardPresenter @Inject constructor(
|
|||||||
val semester = semesterRepository.getCurrentSemester(student)
|
val semester = semesterRepository.getCurrentSemester(student)
|
||||||
val selectedTiles = preferencesRepository.selectedDashboardTiles
|
val selectedTiles = preferencesRepository.selectedDashboardTiles
|
||||||
|
|
||||||
|
val flowSuccess = flowOf(Resource.Success(null))
|
||||||
val luckyNumberFlow = luckyNumberRepository.getLuckyNumber(student, forceRefresh)
|
val luckyNumberFlow = luckyNumberRepository.getLuckyNumber(student, forceRefresh)
|
||||||
.map {
|
.mapResourceData {
|
||||||
if (it.data == null) {
|
it ?: LuckyNumber(0, LocalDate.now(), 0)
|
||||||
it.copy(data = LuckyNumber(0, LocalDate.now(), 0))
|
|
||||||
} else it
|
|
||||||
}
|
}
|
||||||
.takeIf { DashboardItem.Tile.LUCKY_NUMBER in selectedTiles } ?: flowOf(null)
|
.takeIf { DashboardItem.Tile.LUCKY_NUMBER in selectedTiles } ?: flowSuccess
|
||||||
|
|
||||||
val messageFLow = messageRepository.getMessages(
|
val messageFLow = messageRepository.getMessages(
|
||||||
student = student,
|
student = student,
|
||||||
semester = semester,
|
semester = semester,
|
||||||
folder = MessageFolder.RECEIVED,
|
folder = MessageFolder.RECEIVED,
|
||||||
forceRefresh = forceRefresh
|
forceRefresh = forceRefresh
|
||||||
).takeIf { DashboardItem.Tile.MESSAGES in selectedTiles } ?: flowOf(null)
|
).takeIf { DashboardItem.Tile.MESSAGES in selectedTiles } ?: flowSuccess
|
||||||
|
|
||||||
val attendanceFlow = attendanceSummaryRepository.getAttendanceSummary(
|
val attendanceFlow = attendanceSummaryRepository.getAttendanceSummary(
|
||||||
student = student,
|
student = student,
|
||||||
semester = semester,
|
semester = semester,
|
||||||
subjectId = -1,
|
subjectId = -1,
|
||||||
forceRefresh = forceRefresh
|
forceRefresh = forceRefresh
|
||||||
).takeIf { DashboardItem.Tile.ATTENDANCE in selectedTiles } ?: flowOf(null)
|
).takeIf { DashboardItem.Tile.ATTENDANCE in selectedTiles } ?: flowSuccess
|
||||||
|
|
||||||
emitAll(
|
emitAll(
|
||||||
combine(
|
combine(
|
||||||
@ -253,16 +250,13 @@ class DashboardPresenter @Inject constructor(
|
|||||||
messageFLow,
|
messageFLow,
|
||||||
attendanceFlow
|
attendanceFlow
|
||||||
) { luckyNumberResource, messageResource, attendanceResource ->
|
) { luckyNumberResource, messageResource, attendanceResource ->
|
||||||
val error =
|
val resList = listOf(luckyNumberResource, messageResource, attendanceResource)
|
||||||
luckyNumberResource?.error ?: messageResource?.error ?: attendanceResource?.error
|
resList.firstNotNullOfOrNull { it.errorOrNull }?.let { throw it }
|
||||||
error?.let { throw it }
|
val isLoading = resList.any { it is Resource.Loading }
|
||||||
|
|
||||||
val luckyNumber = luckyNumberResource?.data?.luckyNumber
|
val luckyNumber = luckyNumberResource.dataOrNull?.luckyNumber
|
||||||
val messageCount = messageResource?.data?.count { it.unread }
|
val messageCount = messageResource.dataOrNull?.count { it.unread }
|
||||||
val attendancePercentage = attendanceResource?.data?.calculatePercentage()
|
val attendancePercentage = attendanceResource.dataOrNull?.calculatePercentage()
|
||||||
|
|
||||||
val isLoading =
|
|
||||||
luckyNumberResource?.status == Status.LOADING || messageResource?.status == Status.LOADING || attendanceResource?.status == Status.LOADING
|
|
||||||
|
|
||||||
DashboardItem.HorizontalGroup(
|
DashboardItem.HorizontalGroup(
|
||||||
isLoading = isLoading,
|
isLoading = isLoading,
|
||||||
@ -295,72 +289,69 @@ class DashboardPresenter @Inject constructor(
|
|||||||
)
|
)
|
||||||
errorHandler.dispatch(it)
|
errorHandler.dispatch(it)
|
||||||
}
|
}
|
||||||
.launch("horizontal_group")
|
.launch("horizontal_group ${if (forceRefresh) "-forceRefresh" else ""}")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadGrades(student: Student, forceRefresh: Boolean) {
|
private fun loadGrades(student: Student, forceRefresh: Boolean) {
|
||||||
flowWithResourceIn {
|
flatResourceFlow {
|
||||||
val semester = semesterRepository.getCurrentSemester(student)
|
val semester = semesterRepository.getCurrentSemester(student)
|
||||||
|
|
||||||
gradeRepository.getGrades(student, semester, forceRefresh)
|
gradeRepository.getGrades(student, semester, forceRefresh)
|
||||||
}.map { originalResource ->
|
}
|
||||||
val filteredSubjectWithGrades = originalResource.data?.first
|
.mapResourceData { (details, _) ->
|
||||||
.orEmpty()
|
val filteredSubjectWithGrades = details
|
||||||
.filter { it.date >= LocalDate.now().minusDays(7) }
|
.filter { it.date >= LocalDate.now().minusDays(7) }
|
||||||
.groupBy { it.subject }
|
.groupBy { it.subject }
|
||||||
.mapValues { entry ->
|
.mapValues { entry ->
|
||||||
entry.value
|
entry.value
|
||||||
.take(5)
|
.take(5)
|
||||||
.sortedByDescending { it.date }
|
.sortedByDescending { it.date }
|
||||||
}
|
}
|
||||||
.toList()
|
.toList()
|
||||||
.sortedByDescending { (_, grades) -> grades[0].date }
|
.sortedByDescending { (_, grades) -> grades[0].date }
|
||||||
.toMap()
|
.toMap()
|
||||||
|
|
||||||
Resource(
|
filteredSubjectWithGrades
|
||||||
status = originalResource.status,
|
}
|
||||||
data = filteredSubjectWithGrades.takeIf { originalResource.data != null },
|
.onEach {
|
||||||
error = originalResource.error
|
when (it) {
|
||||||
)
|
is Resource.Loading -> {
|
||||||
}.onEach {
|
Timber.i("Loading dashboard grades data started")
|
||||||
when (it.status) {
|
if (forceRefresh) return@onEach
|
||||||
Status.LOADING -> {
|
updateData(
|
||||||
Timber.i("Loading dashboard grades data started")
|
DashboardItem.Grades(
|
||||||
if (forceRefresh) return@onEach
|
subjectWithGrades = it.dataOrNull,
|
||||||
|
gradeTheme = preferencesRepository.gradeColorTheme,
|
||||||
|
isLoading = true
|
||||||
|
), forceRefresh
|
||||||
|
)
|
||||||
|
|
||||||
updateData(
|
if (!it.dataOrNull.isNullOrEmpty()) {
|
||||||
DashboardItem.Grades(
|
firstLoadedItemList += DashboardItem.Type.GRADES
|
||||||
subjectWithGrades = it.data,
|
}
|
||||||
gradeTheme = preferencesRepository.gradeColorTheme,
|
}
|
||||||
isLoading = true
|
is Resource.Success -> {
|
||||||
), forceRefresh
|
Timber.i("Loading dashboard grades result: Success")
|
||||||
)
|
updateData(
|
||||||
|
DashboardItem.Grades(
|
||||||
if (!it.data.isNullOrEmpty()) {
|
subjectWithGrades = it.data,
|
||||||
firstLoadedItemList += DashboardItem.Type.GRADES
|
gradeTheme = preferencesRepository.gradeColorTheme
|
||||||
|
),
|
||||||
|
forceRefresh
|
||||||
|
)
|
||||||
|
}
|
||||||
|
is Resource.Error -> {
|
||||||
|
Timber.i("Loading dashboard grades result: An exception occurred")
|
||||||
|
errorHandler.dispatch(it.error)
|
||||||
|
updateData(DashboardItem.Grades(error = it.error), forceRefresh)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Status.SUCCESS -> {
|
|
||||||
Timber.i("Loading dashboard grades result: Success")
|
|
||||||
updateData(
|
|
||||||
DashboardItem.Grades(
|
|
||||||
subjectWithGrades = it.data,
|
|
||||||
gradeTheme = preferencesRepository.gradeColorTheme
|
|
||||||
),
|
|
||||||
forceRefresh
|
|
||||||
)
|
|
||||||
}
|
|
||||||
Status.ERROR -> {
|
|
||||||
Timber.i("Loading dashboard grades result: An exception occurred")
|
|
||||||
errorHandler.dispatch(it.error!!)
|
|
||||||
updateData(DashboardItem.Grades(error = it.error), forceRefresh)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}.launch("dashboard_grades")
|
.launchWithUniqueRefreshJob("dashboard_grades", forceRefresh)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadLessons(student: Student, forceRefresh: Boolean) {
|
private fun loadLessons(student: Student, forceRefresh: Boolean) {
|
||||||
flowWithResourceIn {
|
flatResourceFlow {
|
||||||
val semester = semesterRepository.getCurrentSemester(student)
|
val semester = semesterRepository.getCurrentSemester(student)
|
||||||
val date = LocalDate.now().nextOrSameSchoolDay
|
val date = LocalDate.now().nextOrSameSchoolDay
|
||||||
|
|
||||||
@ -371,40 +362,41 @@ class DashboardPresenter @Inject constructor(
|
|||||||
end = date.plusDays(1),
|
end = date.plusDays(1),
|
||||||
forceRefresh = forceRefresh
|
forceRefresh = forceRefresh
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
.onEach {
|
||||||
|
when (it) {
|
||||||
|
is Resource.Loading -> {
|
||||||
|
Timber.i("Loading dashboard lessons data started")
|
||||||
|
if (forceRefresh) return@onEach
|
||||||
|
updateData(
|
||||||
|
DashboardItem.Lessons(it.dataOrNull, isLoading = true),
|
||||||
|
forceRefresh
|
||||||
|
)
|
||||||
|
|
||||||
}.onEach {
|
if (!it.dataOrNull?.lessons.isNullOrEmpty()) {
|
||||||
when (it.status) {
|
firstLoadedItemList += DashboardItem.Type.LESSONS
|
||||||
Status.LOADING -> {
|
}
|
||||||
Timber.i("Loading dashboard lessons data started")
|
}
|
||||||
if (forceRefresh) return@onEach
|
is Resource.Success -> {
|
||||||
updateData(
|
Timber.i("Loading dashboard lessons result: Success")
|
||||||
DashboardItem.Lessons(it.data, isLoading = true),
|
updateData(
|
||||||
forceRefresh
|
DashboardItem.Lessons(it.data), forceRefresh
|
||||||
)
|
)
|
||||||
|
}
|
||||||
if (!it.data?.lessons.isNullOrEmpty()) {
|
is Resource.Error -> {
|
||||||
firstLoadedItemList += DashboardItem.Type.LESSONS
|
Timber.i("Loading dashboard lessons result: An exception occurred")
|
||||||
|
errorHandler.dispatch(it.error)
|
||||||
|
updateData(
|
||||||
|
DashboardItem.Lessons(error = it.error), forceRefresh
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Status.SUCCESS -> {
|
|
||||||
Timber.i("Loading dashboard lessons result: Success")
|
|
||||||
updateData(
|
|
||||||
DashboardItem.Lessons(it.data), forceRefresh
|
|
||||||
)
|
|
||||||
}
|
|
||||||
Status.ERROR -> {
|
|
||||||
Timber.i("Loading dashboard lessons result: An exception occurred")
|
|
||||||
errorHandler.dispatch(it.error!!)
|
|
||||||
updateData(
|
|
||||||
DashboardItem.Lessons(error = it.error), forceRefresh
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}.launch("dashboard_lessons")
|
.launchWithUniqueRefreshJob("dashboard_lessons", forceRefresh)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadHomework(student: Student, forceRefresh: Boolean) {
|
private fun loadHomework(student: Student, forceRefresh: Boolean) {
|
||||||
flowWithResourceIn {
|
flatResourceFlow {
|
||||||
val semester = semesterRepository.getCurrentSemester(student)
|
val semester = semesterRepository.getCurrentSemester(student)
|
||||||
val date = LocalDate.now().nextOrSameSchoolDay
|
val date = LocalDate.now().nextOrSameSchoolDay
|
||||||
|
|
||||||
@ -415,73 +407,79 @@ class DashboardPresenter @Inject constructor(
|
|||||||
end = date,
|
end = date,
|
||||||
forceRefresh = forceRefresh
|
forceRefresh = forceRefresh
|
||||||
)
|
)
|
||||||
}.map { homeworkResource ->
|
}
|
||||||
val currentDate = LocalDate.now()
|
.mapResourceData { homework ->
|
||||||
|
val currentDate = LocalDate.now()
|
||||||
|
|
||||||
val filteredHomework = homeworkResource.data
|
val filteredHomework = homework.filter {
|
||||||
?.filter { (it.date.isAfter(currentDate) || it.date == currentDate) && !it.isDone }
|
(it.date.isAfter(currentDate) || it.date == currentDate) && !it.isDone
|
||||||
?.sortedBy { it.date }
|
}.sortedBy { it.date }
|
||||||
|
|
||||||
homeworkResource.copy(data = filteredHomework)
|
filteredHomework
|
||||||
}.onEach {
|
}
|
||||||
when (it.status) {
|
.onEach {
|
||||||
Status.LOADING -> {
|
when (it) {
|
||||||
Timber.i("Loading dashboard homework data started")
|
is Resource.Loading -> {
|
||||||
if (forceRefresh) return@onEach
|
Timber.i("Loading dashboard homework data started")
|
||||||
updateData(
|
if (forceRefresh) return@onEach
|
||||||
DashboardItem.Homework(it.data ?: emptyList(), isLoading = true),
|
val data = it.dataOrNull.orEmpty()
|
||||||
forceRefresh
|
updateData(
|
||||||
)
|
DashboardItem.Homework(data, isLoading = true),
|
||||||
|
forceRefresh
|
||||||
|
)
|
||||||
|
|
||||||
if (!it.data.isNullOrEmpty()) {
|
if (data.isNotEmpty()) {
|
||||||
firstLoadedItemList += DashboardItem.Type.HOMEWORK
|
firstLoadedItemList += DashboardItem.Type.HOMEWORK
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is Resource.Success -> {
|
||||||
|
Timber.i("Loading dashboard homework result: Success")
|
||||||
|
updateData(DashboardItem.Homework(it.data), forceRefresh)
|
||||||
|
}
|
||||||
|
is Resource.Error -> {
|
||||||
|
Timber.i("Loading dashboard homework result: An exception occurred")
|
||||||
|
errorHandler.dispatch(it.error)
|
||||||
|
updateData(DashboardItem.Homework(error = it.error), forceRefresh)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Status.SUCCESS -> {
|
|
||||||
Timber.i("Loading dashboard homework result: Success")
|
|
||||||
updateData(DashboardItem.Homework(it.data ?: emptyList()), forceRefresh)
|
|
||||||
}
|
|
||||||
Status.ERROR -> {
|
|
||||||
Timber.i("Loading dashboard homework result: An exception occurred")
|
|
||||||
errorHandler.dispatch(it.error!!)
|
|
||||||
updateData(DashboardItem.Homework(error = it.error), forceRefresh)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}.launch("dashboard_homework")
|
.launchWithUniqueRefreshJob("dashboard_homework", forceRefresh)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadSchoolAnnouncements(student: Student, forceRefresh: Boolean) {
|
private fun loadSchoolAnnouncements(student: Student, forceRefresh: Boolean) {
|
||||||
flowWithResourceIn {
|
flatResourceFlow {
|
||||||
schoolAnnouncementRepository.getSchoolAnnouncements(student, forceRefresh)
|
schoolAnnouncementRepository.getSchoolAnnouncements(student, forceRefresh)
|
||||||
}.onEach {
|
}
|
||||||
when (it.status) {
|
.onEach {
|
||||||
Status.LOADING -> {
|
when (it) {
|
||||||
Timber.i("Loading dashboard announcements data started")
|
is Resource.Loading -> {
|
||||||
if (forceRefresh) return@onEach
|
Timber.i("Loading dashboard announcements data started")
|
||||||
updateData(
|
if (forceRefresh) return@onEach
|
||||||
DashboardItem.Announcements(it.data ?: emptyList(), isLoading = true),
|
updateData(
|
||||||
forceRefresh
|
DashboardItem.Announcements(it.dataOrNull.orEmpty(), isLoading = true),
|
||||||
)
|
forceRefresh
|
||||||
|
)
|
||||||
|
|
||||||
if (!it.data.isNullOrEmpty()) {
|
if (!it.dataOrNull.isNullOrEmpty()) {
|
||||||
firstLoadedItemList += DashboardItem.Type.ANNOUNCEMENTS
|
firstLoadedItemList += DashboardItem.Type.ANNOUNCEMENTS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is Resource.Success -> {
|
||||||
|
Timber.i("Loading dashboard announcements result: Success")
|
||||||
|
updateData(DashboardItem.Announcements(it.data), forceRefresh)
|
||||||
|
}
|
||||||
|
is Resource.Error -> {
|
||||||
|
Timber.i("Loading dashboard announcements result: An exception occurred")
|
||||||
|
errorHandler.dispatch(it.error)
|
||||||
|
updateData(DashboardItem.Announcements(error = it.error), forceRefresh)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Status.SUCCESS -> {
|
|
||||||
Timber.i("Loading dashboard announcements result: Success")
|
|
||||||
updateData(DashboardItem.Announcements(it.data ?: emptyList()), forceRefresh)
|
|
||||||
}
|
|
||||||
Status.ERROR -> {
|
|
||||||
Timber.i("Loading dashboard announcements result: An exception occurred")
|
|
||||||
errorHandler.dispatch(it.error!!)
|
|
||||||
updateData(DashboardItem.Announcements(error = it.error), forceRefresh)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}.launch("dashboard_announcements")
|
.launchWithUniqueRefreshJob("dashboard_announcements", forceRefresh)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadExams(student: Student, forceRefresh: Boolean) {
|
private fun loadExams(student: Student, forceRefresh: Boolean) {
|
||||||
flowWithResourceIn {
|
flatResourceFlow {
|
||||||
val semester = semesterRepository.getCurrentSemester(student)
|
val semester = semesterRepository.getCurrentSemester(student)
|
||||||
|
|
||||||
examRepository.getExams(
|
examRepository.getExams(
|
||||||
@ -492,40 +490,37 @@ class DashboardPresenter @Inject constructor(
|
|||||||
forceRefresh = forceRefresh
|
forceRefresh = forceRefresh
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
.map { examResource ->
|
.mapResourceData { exams -> exams.sortedBy { exam -> exam.date } }
|
||||||
val sortedExams = examResource.data?.sortedBy { it.date }
|
|
||||||
|
|
||||||
examResource.copy(data = sortedExams)
|
|
||||||
}
|
|
||||||
.onEach {
|
.onEach {
|
||||||
when (it.status) {
|
when (it) {
|
||||||
Status.LOADING -> {
|
is Resource.Loading -> {
|
||||||
Timber.i("Loading dashboard exams data started")
|
Timber.i("Loading dashboard exams data started")
|
||||||
if (forceRefresh) return@onEach
|
if (forceRefresh) return@onEach
|
||||||
updateData(
|
updateData(
|
||||||
DashboardItem.Exams(it.data.orEmpty(), isLoading = true),
|
DashboardItem.Exams(it.dataOrNull.orEmpty(), isLoading = true),
|
||||||
forceRefresh
|
forceRefresh
|
||||||
)
|
)
|
||||||
|
|
||||||
if (!it.data.isNullOrEmpty()) {
|
if (!it.dataOrNull.isNullOrEmpty()) {
|
||||||
firstLoadedItemList += DashboardItem.Type.EXAMS
|
firstLoadedItemList += DashboardItem.Type.EXAMS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Status.SUCCESS -> {
|
is Resource.Success -> {
|
||||||
Timber.i("Loading dashboard exams result: Success")
|
Timber.i("Loading dashboard exams result: Success")
|
||||||
updateData(DashboardItem.Exams(it.data ?: emptyList()), forceRefresh)
|
updateData(DashboardItem.Exams(it.data), forceRefresh)
|
||||||
}
|
}
|
||||||
Status.ERROR -> {
|
is Resource.Error -> {
|
||||||
Timber.i("Loading dashboard exams result: An exception occurred")
|
Timber.i("Loading dashboard exams result: An exception occurred")
|
||||||
errorHandler.dispatch(it.error!!)
|
errorHandler.dispatch(it.error)
|
||||||
updateData(DashboardItem.Exams(error = it.error), forceRefresh)
|
updateData(DashboardItem.Exams(error = it.error), forceRefresh)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.launch("dashboard_exams")
|
}
|
||||||
|
.launchWithUniqueRefreshJob("dashboard_exams", forceRefresh)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadConferences(student: Student, forceRefresh: Boolean) {
|
private fun loadConferences(student: Student, forceRefresh: Boolean) {
|
||||||
flowWithResourceIn {
|
flatResourceFlow {
|
||||||
val semester = semesterRepository.getCurrentSemester(student)
|
val semester = semesterRepository.getCurrentSemester(student)
|
||||||
|
|
||||||
conferenceRepository.getConferences(
|
conferenceRepository.getConferences(
|
||||||
@ -534,59 +529,62 @@ class DashboardPresenter @Inject constructor(
|
|||||||
forceRefresh = forceRefresh,
|
forceRefresh = forceRefresh,
|
||||||
startDate = Instant.now(),
|
startDate = Instant.now(),
|
||||||
)
|
)
|
||||||
}.onEach {
|
}
|
||||||
when (it.status) {
|
.onEach {
|
||||||
Status.LOADING -> {
|
when (it) {
|
||||||
Timber.i("Loading dashboard conferences data started")
|
is Resource.Loading -> {
|
||||||
if (forceRefresh) return@onEach
|
Timber.i("Loading dashboard conferences data started")
|
||||||
updateData(
|
if (forceRefresh) return@onEach
|
||||||
DashboardItem.Conferences(it.data ?: emptyList(), isLoading = true),
|
updateData(
|
||||||
forceRefresh
|
DashboardItem.Conferences(it.dataOrNull.orEmpty(), isLoading = true),
|
||||||
)
|
forceRefresh
|
||||||
|
)
|
||||||
|
|
||||||
if (!it.data.isNullOrEmpty()) {
|
if (!it.dataOrNull.isNullOrEmpty()) {
|
||||||
firstLoadedItemList += DashboardItem.Type.CONFERENCES
|
firstLoadedItemList += DashboardItem.Type.CONFERENCES
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is Resource.Success -> {
|
||||||
|
Timber.i("Loading dashboard conferences result: Success")
|
||||||
|
updateData(DashboardItem.Conferences(it.data), forceRefresh)
|
||||||
|
}
|
||||||
|
is Resource.Error -> {
|
||||||
|
Timber.i("Loading dashboard conferences result: An exception occurred")
|
||||||
|
errorHandler.dispatch(it.error)
|
||||||
|
updateData(DashboardItem.Conferences(error = it.error), forceRefresh)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Status.SUCCESS -> {
|
|
||||||
Timber.i("Loading dashboard conferences result: Success")
|
|
||||||
updateData(DashboardItem.Conferences(it.data ?: emptyList()), forceRefresh)
|
|
||||||
}
|
|
||||||
Status.ERROR -> {
|
|
||||||
Timber.i("Loading dashboard conferences result: An exception occurred")
|
|
||||||
errorHandler.dispatch(it.error!!)
|
|
||||||
updateData(DashboardItem.Conferences(error = it.error), forceRefresh)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}.launch("dashboard_conferences")
|
.launchWithUniqueRefreshJob("dashboard_conferences", forceRefresh)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadAdminMessage(student: Student, forceRefresh: Boolean) {
|
private fun loadAdminMessage(student: Student, forceRefresh: Boolean) {
|
||||||
flowWithResourceIn { adminMessageRepository.getAdminMessages(student) }
|
flatResourceFlow { adminMessageRepository.getAdminMessages(student) }
|
||||||
.map {
|
.filter {
|
||||||
val isDismissed = it.data?.id in preferencesRepository.dismissedAdminMessageIds
|
val data = it.dataOrNull ?: return@filter true
|
||||||
it.copy(data = it.data.takeUnless { isDismissed })
|
val isDismissed = data.id in preferencesRepository.dismissedAdminMessageIds
|
||||||
|
!isDismissed
|
||||||
}
|
}
|
||||||
.onEach {
|
.onEach {
|
||||||
when (it.status) {
|
when (it) {
|
||||||
Status.LOADING -> {
|
is Resource.Loading -> {
|
||||||
Timber.i("Loading dashboard admin message data started")
|
Timber.i("Loading dashboard admin message data started")
|
||||||
if (forceRefresh) return@onEach
|
if (forceRefresh) return@onEach
|
||||||
updateData(DashboardItem.AdminMessages(), forceRefresh)
|
updateData(DashboardItem.AdminMessages(), forceRefresh)
|
||||||
}
|
}
|
||||||
Status.SUCCESS -> {
|
is Resource.Success -> {
|
||||||
Timber.i("Loading dashboard admin message result: Success")
|
Timber.i("Loading dashboard admin message result: Success")
|
||||||
updateData(
|
updateData(
|
||||||
dashboardItem = DashboardItem.AdminMessages(adminMessage = it.data),
|
dashboardItem = DashboardItem.AdminMessages(adminMessage = it.data),
|
||||||
forceRefresh = forceRefresh
|
forceRefresh = forceRefresh
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Status.ERROR -> {
|
is Resource.Error -> {
|
||||||
Timber.i("Loading dashboard admin message result: An exception occurred")
|
Timber.i("Loading dashboard admin message result: An exception occurred")
|
||||||
errorHandler.dispatch(it.error!!)
|
errorHandler.dispatch(it.error)
|
||||||
updateData(
|
updateData(
|
||||||
dashboardItem = DashboardItem.AdminMessages(
|
dashboardItem = DashboardItem.AdminMessages(
|
||||||
adminMessage = it.data,
|
adminMessage = null,
|
||||||
error = it.error
|
error = it.error
|
||||||
),
|
),
|
||||||
forceRefresh = forceRefresh
|
forceRefresh = forceRefresh
|
||||||
@ -594,7 +592,7 @@ class DashboardPresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.launch("dashboard_admin_messages")
|
.launchWithUniqueRefreshJob("dashboard_admin_messages", forceRefresh)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateData(dashboardItem: DashboardItem, forceRefresh: Boolean) {
|
private fun updateData(dashboardItem: DashboardItem, forceRefresh: Boolean) {
|
||||||
@ -733,4 +731,18 @@ class DashboardPresenter @Inject constructor(
|
|||||||
dashboardItemsPosition?.getOrDefault(tile.type, defaultPosition) ?: tile.type.ordinal
|
dashboardItemsPosition?.getOrDefault(tile.type, defaultPosition) ?: tile.type.ordinal
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
private fun Flow<Resource<*>>.launchWithUniqueRefreshJob(name: String, forceRefresh: Boolean) {
|
||||||
|
val jobName = if (forceRefresh) "$name-forceRefresh" else name
|
||||||
|
|
||||||
|
if (forceRefresh) {
|
||||||
|
onEach {
|
||||||
|
if (it is Resource.Success) {
|
||||||
|
cancelJobs(jobName)
|
||||||
|
}
|
||||||
|
}.launch(jobName)
|
||||||
|
} else {
|
||||||
|
launch(jobName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
package io.github.wulkanowy.ui.modules.debug.logviewer
|
package io.github.wulkanowy.ui.modules.debug.logviewer
|
||||||
|
|
||||||
import io.github.wulkanowy.data.Status
|
import io.github.wulkanowy.data.Resource
|
||||||
import io.github.wulkanowy.data.repositories.LoggerRepository
|
import io.github.wulkanowy.data.repositories.LoggerRepository
|
||||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||||
|
import io.github.wulkanowy.data.resourceFlow
|
||||||
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.flowWithResource
|
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@ -23,19 +23,21 @@ class LogViewerPresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun onShareLogsSelected(): Boolean {
|
fun onShareLogsSelected(): Boolean {
|
||||||
flowWithResource { loggerRepository.getLogFiles() }.onEach {
|
resourceFlow { loggerRepository.getLogFiles() }
|
||||||
when (it.status) {
|
.onEach {
|
||||||
Status.LOADING -> Timber.d("Loading logs files started")
|
when (it) {
|
||||||
Status.SUCCESS -> {
|
is Resource.Loading -> Timber.d("Loading logs files started")
|
||||||
Timber.i("Loading logs files result: ${it.data!!.joinToString { file -> file.name }}")
|
is Resource.Success -> {
|
||||||
view?.shareLogs(it.data)
|
Timber.i("Loading logs files result: ${it.data.joinToString { file -> file.name }}")
|
||||||
}
|
view?.shareLogs(it.data)
|
||||||
Status.ERROR -> {
|
}
|
||||||
Timber.i("Loading logs files result: An exception occurred")
|
is Resource.Error -> {
|
||||||
errorHandler.dispatch(it.error!!)
|
Timber.i("Loading logs files result: An exception occurred")
|
||||||
|
errorHandler.dispatch(it.error)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.launch("share")
|
.launch("share")
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,18 +46,20 @@ class LogViewerPresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun loadLogFile() {
|
private fun loadLogFile() {
|
||||||
flowWithResource { loggerRepository.getLastLogLines() }.onEach {
|
resourceFlow { loggerRepository.getLastLogLines() }
|
||||||
when (it.status) {
|
.onEach {
|
||||||
Status.LOADING -> Timber.d("Loading last log file started")
|
when (it) {
|
||||||
Status.SUCCESS -> {
|
is Resource.Loading -> Timber.d("Loading last log file started")
|
||||||
Timber.i("Loading last log file result: load ${it.data!!.size} lines")
|
is Resource.Success -> {
|
||||||
view?.setLines(it.data)
|
Timber.i("Loading last log file result: load ${it.data.size} lines")
|
||||||
}
|
view?.setLines(it.data)
|
||||||
Status.ERROR -> {
|
}
|
||||||
Timber.i("Loading last log file result: An exception occurred")
|
is Resource.Error -> {
|
||||||
errorHandler.dispatch(it.error!!)
|
Timber.i("Loading last log file result: An exception occurred")
|
||||||
|
errorHandler.dispatch(it.error)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.launch("file")
|
.launch("file")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,8 +25,8 @@ private fun generateTimetable(subject: String, room: String, roomOld: String) =
|
|||||||
diaryId = 0,
|
diaryId = 0,
|
||||||
date = LocalDate.now().minusDays(Random.nextLong(0, 8)),
|
date = LocalDate.now().minusDays(Random.nextLong(0, 8)),
|
||||||
number = 1,
|
number = 1,
|
||||||
start = Instant.now(),
|
start = Instant.now().plus(Duration.ofHours(1)),
|
||||||
end = Instant.now().plus(Duration.ofHours(1)),
|
end = Instant.now(),
|
||||||
subjectOld = "",
|
subjectOld = "",
|
||||||
group = "",
|
group = "",
|
||||||
room = room,
|
room = room,
|
||||||
|
@ -5,10 +5,13 @@ import android.view.LayoutInflater
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.fragment.app.DialogFragment
|
import androidx.fragment.app.DialogFragment
|
||||||
|
import io.github.wulkanowy.R
|
||||||
import io.github.wulkanowy.data.db.entities.Exam
|
import io.github.wulkanowy.data.db.entities.Exam
|
||||||
import io.github.wulkanowy.databinding.DialogExamBinding
|
import io.github.wulkanowy.databinding.DialogExamBinding
|
||||||
import io.github.wulkanowy.utils.lifecycleAwareVariable
|
import io.github.wulkanowy.utils.lifecycleAwareVariable
|
||||||
|
import io.github.wulkanowy.utils.openCalendarEventAdd
|
||||||
import io.github.wulkanowy.utils.toFormattedString
|
import io.github.wulkanowy.utils.toFormattedString
|
||||||
|
import java.time.LocalTime
|
||||||
|
|
||||||
class ExamDialog : DialogFragment() {
|
class ExamDialog : DialogFragment() {
|
||||||
|
|
||||||
@ -46,10 +49,21 @@ class ExamDialog : DialogFragment() {
|
|||||||
examDialogSubjectValue.text = exam.subject
|
examDialogSubjectValue.text = exam.subject
|
||||||
examDialogTypeValue.text = exam.type
|
examDialogTypeValue.text = exam.type
|
||||||
examDialogTeacherValue.text = exam.teacher
|
examDialogTeacherValue.text = exam.teacher
|
||||||
examDialogDateValue.text = exam.entryDate.toFormattedString()
|
examDialogEntryDateValue.text = exam.entryDate.toFormattedString()
|
||||||
examDialogDescriptionValue.text = exam.description
|
examDialogDeadlineDateValue.text = exam.date.toFormattedString()
|
||||||
|
examDialogDescriptionValue.text = exam.description.ifBlank {
|
||||||
|
getString(R.string.all_no_data)
|
||||||
|
}
|
||||||
|
|
||||||
examDialogClose.setOnClickListener { dismiss() }
|
examDialogClose.setOnClickListener { dismiss() }
|
||||||
|
examDialogAddToCalendar.setOnClickListener {
|
||||||
|
requireContext().openCalendarEventAdd(
|
||||||
|
title = "${exam.subject} - ${exam.type}",
|
||||||
|
description = exam.description,
|
||||||
|
start = exam.date.atTime(LocalTime.of(8, 0)),
|
||||||
|
end = exam.date.atTime(LocalTime.of(8, 45)),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,21 +1,13 @@
|
|||||||
package io.github.wulkanowy.ui.modules.exam
|
package io.github.wulkanowy.ui.modules.exam
|
||||||
|
|
||||||
import io.github.wulkanowy.data.Status
|
import io.github.wulkanowy.data.*
|
||||||
import io.github.wulkanowy.data.db.entities.Exam
|
import io.github.wulkanowy.data.db.entities.Exam
|
||||||
import io.github.wulkanowy.data.repositories.ExamRepository
|
import io.github.wulkanowy.data.repositories.ExamRepository
|
||||||
import io.github.wulkanowy.data.repositories.SemesterRepository
|
import io.github.wulkanowy.data.repositories.SemesterRepository
|
||||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
import io.github.wulkanowy.data.repositories.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.AnalyticsHelper
|
import io.github.wulkanowy.utils.*
|
||||||
import io.github.wulkanowy.utils.afterLoading
|
|
||||||
import io.github.wulkanowy.utils.flowWithResourceIn
|
|
||||||
import io.github.wulkanowy.utils.getLastSchoolDayIfHoliday
|
|
||||||
import io.github.wulkanowy.utils.isHolidays
|
|
||||||
import io.github.wulkanowy.utils.monday
|
|
||||||
import io.github.wulkanowy.utils.nextOrSameSchoolDay
|
|
||||||
import io.github.wulkanowy.utils.sunday
|
|
||||||
import io.github.wulkanowy.utils.toFormattedString
|
|
||||||
import kotlinx.coroutines.flow.catch
|
import kotlinx.coroutines.flow.catch
|
||||||
import kotlinx.coroutines.flow.flow
|
import kotlinx.coroutines.flow.flow
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
@ -86,61 +78,57 @@ class ExamPresenter @Inject constructor(
|
|||||||
flow {
|
flow {
|
||||||
val student = studentRepository.getCurrentStudent()
|
val student = studentRepository.getCurrentStudent()
|
||||||
emit(semesterRepository.getCurrentSemester(student))
|
emit(semesterRepository.getCurrentSemester(student))
|
||||||
}.catch {
|
}
|
||||||
Timber.i("Loading semester result: An exception occurred")
|
.catch { Timber.i("Loading semester result: An exception occurred") }
|
||||||
}.onEach {
|
.onEach {
|
||||||
baseDate = baseDate.getLastSchoolDayIfHoliday(it.schoolYear)
|
baseDate = baseDate.getLastSchoolDayIfHoliday(it.schoolYear)
|
||||||
currentDate = baseDate
|
currentDate = baseDate
|
||||||
reloadNavigation()
|
reloadNavigation()
|
||||||
}.launch("holidays")
|
}
|
||||||
|
.launch("holidays")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadData(forceRefresh: Boolean = false) {
|
private fun loadData(forceRefresh: Boolean = false) {
|
||||||
Timber.i("Loading exam data started")
|
flatResourceFlow {
|
||||||
|
|
||||||
flowWithResourceIn {
|
|
||||||
val student = studentRepository.getCurrentStudent()
|
val student = studentRepository.getCurrentStudent()
|
||||||
val semester = semesterRepository.getCurrentSemester(student)
|
val semester = semesterRepository.getCurrentSemester(student)
|
||||||
examRepository.getExams(student, semester, currentDate.monday, currentDate.sunday, forceRefresh)
|
examRepository.getExams(
|
||||||
}.onEach {
|
student = student,
|
||||||
when (it.status) {
|
semester = semester,
|
||||||
Status.LOADING -> {
|
start = currentDate.monday,
|
||||||
if (!it.data.isNullOrEmpty()) {
|
end = currentDate.sunday,
|
||||||
view?.run {
|
forceRefresh = forceRefresh
|
||||||
enableSwipe(true)
|
)
|
||||||
showRefresh(true)
|
}
|
||||||
showProgress(false)
|
.logResourceStatus("load exam data")
|
||||||
showContent(true)
|
.mapResourceData { createExamItems(it) }
|
||||||
updateData(createExamItems(it.data))
|
.onResourceData {
|
||||||
}
|
view?.run {
|
||||||
}
|
enableSwipe(true)
|
||||||
}
|
showProgress(false)
|
||||||
Status.SUCCESS -> {
|
showErrorView(false)
|
||||||
Timber.i("Loading exam result: Success")
|
showContent(it.isNotEmpty())
|
||||||
view?.apply {
|
showEmpty(it.isEmpty())
|
||||||
updateData(createExamItems(it.data!!))
|
updateData(it)
|
||||||
showEmpty(it.data.isEmpty())
|
|
||||||
showErrorView(false)
|
|
||||||
showContent(it.data.isNotEmpty())
|
|
||||||
}
|
|
||||||
analytics.logEvent(
|
|
||||||
"load_data",
|
|
||||||
"type" to "exam",
|
|
||||||
"items" to it.data!!.size
|
|
||||||
)
|
|
||||||
}
|
|
||||||
Status.ERROR -> {
|
|
||||||
Timber.i("Loading exam result: An exception occurred")
|
|
||||||
errorHandler.dispatch(it.error!!)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.afterLoading {
|
.onResourceIntermediate { view?.showRefresh(true) }
|
||||||
view?.run {
|
.onResourceSuccess {
|
||||||
showRefresh(false)
|
analytics.logEvent(
|
||||||
showProgress(false)
|
"load_data",
|
||||||
enableSwipe(true)
|
"type" to "exam",
|
||||||
|
"items" to it.size
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}.launch()
|
.onResourceNotLoading {
|
||||||
|
view?.run {
|
||||||
|
enableSwipe(true)
|
||||||
|
showProgress(false)
|
||||||
|
showRefresh(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.onResourceError(errorHandler::dispatch)
|
||||||
|
.launch()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showErrorViewOnError(message: String, error: Throwable) {
|
private fun showErrorViewOnError(message: String, error: Throwable) {
|
||||||
@ -181,8 +169,10 @@ class ExamPresenter @Inject constructor(
|
|||||||
view?.apply {
|
view?.apply {
|
||||||
showPreButton(!currentDate.minusDays(7).isHolidays)
|
showPreButton(!currentDate.minusDays(7).isHolidays)
|
||||||
showNextButton(!currentDate.plusDays(7).isHolidays)
|
showNextButton(!currentDate.plusDays(7).isHolidays)
|
||||||
updateNavigationWeek("${currentDate.monday.toFormattedString("dd.MM")} - " +
|
updateNavigationWeek(
|
||||||
currentDate.sunday.toFormattedString("dd.MM"))
|
"${currentDate.monday.toFormattedString("dd.MM")} - " +
|
||||||
|
currentDate.sunday.toFormattedString("dd.MM")
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package io.github.wulkanowy.ui.modules.grade
|
package io.github.wulkanowy.ui.modules.grade
|
||||||
|
|
||||||
import io.github.wulkanowy.data.Resource
|
import io.github.wulkanowy.data.*
|
||||||
import io.github.wulkanowy.data.Status
|
|
||||||
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.GradeSummary
|
||||||
import io.github.wulkanowy.data.db.entities.Semester
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
@ -10,17 +9,13 @@ import io.github.wulkanowy.data.repositories.GradeRepository
|
|||||||
import io.github.wulkanowy.data.repositories.PreferencesRepository
|
import io.github.wulkanowy.data.repositories.PreferencesRepository
|
||||||
import io.github.wulkanowy.data.repositories.SemesterRepository
|
import io.github.wulkanowy.data.repositories.SemesterRepository
|
||||||
import io.github.wulkanowy.sdk.Sdk
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
import io.github.wulkanowy.ui.modules.grade.GradeAverageMode.ALL_YEAR
|
import io.github.wulkanowy.ui.modules.grade.GradeAverageMode.*
|
||||||
import io.github.wulkanowy.ui.modules.grade.GradeAverageMode.BOTH_SEMESTERS
|
|
||||||
import io.github.wulkanowy.ui.modules.grade.GradeAverageMode.ONE_SEMESTER
|
|
||||||
import io.github.wulkanowy.utils.calcAverage
|
import io.github.wulkanowy.utils.calcAverage
|
||||||
import io.github.wulkanowy.utils.changeModifier
|
import io.github.wulkanowy.utils.changeModifier
|
||||||
import io.github.wulkanowy.utils.flowWithResourceIn
|
|
||||||
import kotlinx.coroutines.FlowPreview
|
import kotlinx.coroutines.FlowPreview
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.combine
|
import kotlinx.coroutines.flow.combine
|
||||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||||
import kotlinx.coroutines.flow.map
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@OptIn(FlowPreview::class)
|
@OptIn(FlowPreview::class)
|
||||||
@ -37,7 +32,7 @@ class GradeAverageProvider @Inject constructor(
|
|||||||
private val isOptionalArithmeticAverage get() = preferencesRepository.isOptionalArithmeticAverage
|
private val isOptionalArithmeticAverage get() = preferencesRepository.isOptionalArithmeticAverage
|
||||||
|
|
||||||
fun getGradesDetailsWithAverage(student: Student, semesterId: Int, forceRefresh: Boolean) =
|
fun getGradesDetailsWithAverage(student: Student, semesterId: Int, forceRefresh: Boolean) =
|
||||||
flowWithResourceIn {
|
flatResourceFlow {
|
||||||
val semesters = semesterRepository.getSemesters(student)
|
val semesters = semesterRepository.getSemesters(student)
|
||||||
|
|
||||||
when (preferencesRepository.gradeAverageMode) {
|
when (preferencesRepository.gradeAverageMode) {
|
||||||
@ -83,17 +78,17 @@ class GradeAverageProvider @Inject constructor(
|
|||||||
val firstSemesterGradeSubjects = getGradeSubjects(student, firstSemester, forceRefresh)
|
val firstSemesterGradeSubjects = getGradeSubjects(student, firstSemester, forceRefresh)
|
||||||
|
|
||||||
return selectedSemesterGradeSubjects.combine(firstSemesterGradeSubjects) { secondSemesterGradeSubject, firstSemesterGradeSubject ->
|
return selectedSemesterGradeSubjects.combine(firstSemesterGradeSubjects) { secondSemesterGradeSubject, firstSemesterGradeSubject ->
|
||||||
if (firstSemesterGradeSubject.status == Status.ERROR) {
|
if (firstSemesterGradeSubject.errorOrNull != null) {
|
||||||
return@combine firstSemesterGradeSubject
|
return@combine firstSemesterGradeSubject
|
||||||
}
|
}
|
||||||
|
|
||||||
val isAnyVulcanAverageInFirstSemester =
|
val isAnyVulcanAverageInFirstSemester =
|
||||||
firstSemesterGradeSubject.data.orEmpty().any { it.isVulcanAverage }
|
firstSemesterGradeSubject.dataOrNull.orEmpty().any { it.isVulcanAverage }
|
||||||
val isAnyVulcanAverageInSecondSemester =
|
val isAnyVulcanAverageInSecondSemester =
|
||||||
secondSemesterGradeSubject.data.orEmpty().any { it.isVulcanAverage }
|
secondSemesterGradeSubject.dataOrNull.orEmpty().any { it.isVulcanAverage }
|
||||||
|
|
||||||
val updatedData = secondSemesterGradeSubject.data?.map { secondSemesterSubject ->
|
val updatedData = secondSemesterGradeSubject.dataOrNull?.map { secondSemesterSubject ->
|
||||||
val firstSemesterSubject = firstSemesterGradeSubject.data.orEmpty()
|
val firstSemesterSubject = firstSemesterGradeSubject.dataOrNull.orEmpty()
|
||||||
.singleOrNull { it.subject == secondSemesterSubject.subject }
|
.singleOrNull { it.subject == secondSemesterSubject.subject }
|
||||||
|
|
||||||
val updatedAverage = if (averageMode == ALL_YEAR) {
|
val updatedAverage = if (averageMode == ALL_YEAR) {
|
||||||
@ -115,7 +110,7 @@ class GradeAverageProvider @Inject constructor(
|
|||||||
}
|
}
|
||||||
secondSemesterSubject.copy(average = updatedAverage)
|
secondSemesterSubject.copy(average = updatedAverage)
|
||||||
}
|
}
|
||||||
secondSemesterGradeSubject.copy(data = updatedData)
|
secondSemesterGradeSubject.mapData { updatedData!! }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,20 +139,20 @@ class GradeAverageProvider @Inject constructor(
|
|||||||
isGradeAverageForceCalc: Boolean,
|
isGradeAverageForceCalc: Boolean,
|
||||||
secondSemesterSubject: GradeSubject,
|
secondSemesterSubject: GradeSubject,
|
||||||
firstSemesterSubject: GradeSubject?
|
firstSemesterSubject: GradeSubject?
|
||||||
): Double {
|
): Double = if (!isAnyVulcanAverage || isGradeAverageForceCalc) {
|
||||||
val divider = if (secondSemesterSubject.grades.any { it.weightValue > .0 }) 2 else 1
|
val divider = if (secondSemesterSubject.grades.any { it.weightValue > .0 }) 2 else 1
|
||||||
|
|
||||||
return if (!isAnyVulcanAverage || isGradeAverageForceCalc) {
|
val secondSemesterAverage = secondSemesterSubject.grades.updateModifiers(student)
|
||||||
val secondSemesterAverage =
|
.calcAverage(isOptionalArithmeticAverage)
|
||||||
secondSemesterSubject.grades.updateModifiers(student)
|
val firstSemesterAverage = firstSemesterSubject?.grades?.updateModifiers(student)
|
||||||
.calcAverage(isOptionalArithmeticAverage)
|
?.calcAverage(isOptionalArithmeticAverage) ?: secondSemesterAverage
|
||||||
val firstSemesterAverage = firstSemesterSubject?.grades?.updateModifiers(student)
|
|
||||||
?.calcAverage(isOptionalArithmeticAverage) ?: secondSemesterAverage
|
|
||||||
|
|
||||||
(secondSemesterAverage + firstSemesterAverage) / divider
|
(secondSemesterAverage + firstSemesterAverage) / divider
|
||||||
} else {
|
} else {
|
||||||
(secondSemesterSubject.average + (firstSemesterSubject?.average ?: secondSemesterSubject.average)) / divider
|
val divider = if (secondSemesterSubject.average > 0) 2 else 1
|
||||||
}
|
|
||||||
|
(secondSemesterSubject.average + (firstSemesterSubject?.average
|
||||||
|
?: secondSemesterSubject.average)) / divider
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getGradeSubjects(
|
private fun getGradeSubjects(
|
||||||
@ -168,17 +163,17 @@ class GradeAverageProvider @Inject constructor(
|
|||||||
val isGradeAverageForceCalc = preferencesRepository.gradeAverageForceCalc
|
val isGradeAverageForceCalc = preferencesRepository.gradeAverageForceCalc
|
||||||
|
|
||||||
return gradeRepository.getGrades(student, semester, forceRefresh = forceRefresh)
|
return gradeRepository.getGrades(student, semester, forceRefresh = forceRefresh)
|
||||||
.map { res ->
|
.mapResourceData { res ->
|
||||||
val (details, summaries) = res.data ?: null to null
|
val (details, summaries) = res
|
||||||
val isAnyAverage = summaries.orEmpty().any { it.average != .0 }
|
val isAnyAverage = summaries.any { it.average != .0 }
|
||||||
val allGrades = details.orEmpty().groupBy { it.subject }
|
val allGrades = details.groupBy { it.subject }
|
||||||
|
|
||||||
val items = summaries?.emulateEmptySummaries(
|
val items = summaries.emulateEmptySummaries(
|
||||||
student = student,
|
student = student,
|
||||||
semester = semester,
|
semester = semester,
|
||||||
grades = allGrades.toList(),
|
grades = allGrades.toList(),
|
||||||
calcAverage = isAnyAverage
|
calcAverage = isAnyAverage
|
||||||
)?.map { summary ->
|
).map { summary ->
|
||||||
val grades = allGrades[summary.subject].orEmpty()
|
val grades = allGrades[summary.subject].orEmpty()
|
||||||
GradeSubject(
|
GradeSubject(
|
||||||
subject = summary.subject,
|
subject = summary.subject,
|
||||||
@ -192,7 +187,7 @@ class GradeAverageProvider @Inject constructor(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
Resource(res.status, items, res.error)
|
items
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
package io.github.wulkanowy.ui.modules.grade
|
package io.github.wulkanowy.ui.modules.grade
|
||||||
|
|
||||||
import io.github.wulkanowy.data.Status
|
|
||||||
import io.github.wulkanowy.data.db.entities.Semester
|
import io.github.wulkanowy.data.db.entities.Semester
|
||||||
|
import io.github.wulkanowy.data.logResourceStatus
|
||||||
|
import io.github.wulkanowy.data.onResourceData
|
||||||
|
import io.github.wulkanowy.data.onResourceError
|
||||||
import io.github.wulkanowy.data.repositories.SemesterRepository
|
import io.github.wulkanowy.data.repositories.SemesterRepository
|
||||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||||
|
import io.github.wulkanowy.data.resourceFlow
|
||||||
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.AnalyticsHelper
|
import io.github.wulkanowy.utils.AnalyticsHelper
|
||||||
import io.github.wulkanowy.utils.flowWithResource
|
|
||||||
import io.github.wulkanowy.utils.getCurrentOrLast
|
import io.github.wulkanowy.utils.getCurrentOrLast
|
||||||
import kotlinx.coroutines.delay
|
|
||||||
import kotlinx.coroutines.flow.onEach
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@ -99,32 +99,26 @@ class GradePresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun loadData() {
|
private fun loadData() {
|
||||||
flowWithResource {
|
resourceFlow {
|
||||||
val student = studentRepository.getCurrentStudent()
|
val student = studentRepository.getCurrentStudent()
|
||||||
semesterRepository.getSemesters(student, refreshOnNoCurrent = true)
|
semesterRepository.getSemesters(student, refreshOnNoCurrent = true)
|
||||||
}.onEach {
|
}
|
||||||
when (it.status) {
|
.logResourceStatus("load grade data")
|
||||||
Status.LOADING -> Timber.i("Loading grade data started")
|
.onResourceData {
|
||||||
Status.SUCCESS -> {
|
val current = it.getCurrentOrLast()
|
||||||
val current = it.data!!.getCurrentOrLast()
|
selectedIndex = if (selectedIndex == 0) current.semesterName else selectedIndex
|
||||||
selectedIndex = if (selectedIndex == 0) current.semesterName else selectedIndex
|
schoolYear = current.schoolYear
|
||||||
schoolYear = current.schoolYear
|
semesters = it.filter { semester -> semester.diaryId == current.diaryId }
|
||||||
semesters = it.data.filter { semester -> semester.diaryId == current.diaryId }
|
view?.setCurrentSemesterName(current.semesterName, schoolYear)
|
||||||
view?.setCurrentSemesterName(current.semesterName, schoolYear)
|
view?.run {
|
||||||
|
Timber.i("Loading grade data: Attempt load index $currentPageIndex")
|
||||||
view?.run {
|
loadChild(currentPageIndex)
|
||||||
Timber.i("Loading grade result: Attempt load index $currentPageIndex")
|
showErrorView(false)
|
||||||
loadChild(currentPageIndex)
|
showSemesterSwitch(true)
|
||||||
showErrorView(false)
|
|
||||||
showSemesterSwitch(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Status.ERROR -> {
|
|
||||||
Timber.i("Loading grade result: An exception occurred")
|
|
||||||
errorHandler.dispatch(it.error!!)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.launch()
|
.onResourceError(errorHandler::dispatch)
|
||||||
|
.launch()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showErrorViewOnError(message: String, error: Throwable) {
|
private fun showErrorViewOnError(message: String, error: Throwable) {
|
||||||
|
@ -10,11 +10,8 @@ import io.github.wulkanowy.R
|
|||||||
import io.github.wulkanowy.data.db.entities.Grade
|
import io.github.wulkanowy.data.db.entities.Grade
|
||||||
import io.github.wulkanowy.data.enums.GradeColorTheme
|
import io.github.wulkanowy.data.enums.GradeColorTheme
|
||||||
import io.github.wulkanowy.databinding.DialogGradeBinding
|
import io.github.wulkanowy.databinding.DialogGradeBinding
|
||||||
import io.github.wulkanowy.utils.colorStringId
|
import io.github.wulkanowy.utils.*
|
||||||
import io.github.wulkanowy.utils.getBackgroundColor
|
|
||||||
import io.github.wulkanowy.utils.getGradeColor
|
|
||||||
import io.github.wulkanowy.utils.lifecycleAwareVariable
|
|
||||||
import io.github.wulkanowy.utils.toFormattedString
|
|
||||||
|
|
||||||
class GradeDetailsDialog : DialogFragment() {
|
class GradeDetailsDialog : DialogFragment() {
|
||||||
|
|
||||||
@ -80,9 +77,7 @@ class GradeDetailsDialog : DialogFragment() {
|
|||||||
setBackgroundResource(grade.getBackgroundColor(gradeColorTheme))
|
setBackgroundResource(grade.getBackgroundColor(gradeColorTheme))
|
||||||
}
|
}
|
||||||
|
|
||||||
gradeDialogTeacherValue.text = if (grade.teacher.isBlank()) {
|
gradeDialogTeacherValue.text = grade.teacher.ifBlank { getString(R.string.all_no_data) }
|
||||||
getString(R.string.all_no_data)
|
|
||||||
} else grade.teacher
|
|
||||||
|
|
||||||
gradeDialogDescriptionValue.text = grade.run {
|
gradeDialogDescriptionValue.text = grade.run {
|
||||||
when {
|
when {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package io.github.wulkanowy.ui.modules.grade.details
|
package io.github.wulkanowy.ui.modules.grade.details
|
||||||
|
|
||||||
import io.github.wulkanowy.data.Status
|
import io.github.wulkanowy.data.*
|
||||||
import io.github.wulkanowy.data.db.entities.Grade
|
import io.github.wulkanowy.data.db.entities.Grade
|
||||||
import io.github.wulkanowy.data.enums.GradeExpandMode
|
import io.github.wulkanowy.data.enums.GradeExpandMode
|
||||||
import io.github.wulkanowy.data.enums.GradeSortingMode.ALPHABETIC
|
import io.github.wulkanowy.data.enums.GradeSortingMode.ALPHABETIC
|
||||||
@ -14,12 +14,8 @@ import io.github.wulkanowy.ui.base.ErrorHandler
|
|||||||
import io.github.wulkanowy.ui.modules.grade.GradeAverageProvider
|
import io.github.wulkanowy.ui.modules.grade.GradeAverageProvider
|
||||||
import io.github.wulkanowy.ui.modules.grade.GradeSubject
|
import io.github.wulkanowy.ui.modules.grade.GradeSubject
|
||||||
import io.github.wulkanowy.utils.AnalyticsHelper
|
import io.github.wulkanowy.utils.AnalyticsHelper
|
||||||
import io.github.wulkanowy.utils.afterLoading
|
|
||||||
import io.github.wulkanowy.utils.flowWithResource
|
|
||||||
import io.github.wulkanowy.utils.flowWithResourceIn
|
|
||||||
import kotlinx.coroutines.flow.catch
|
import kotlinx.coroutines.flow.catch
|
||||||
import kotlinx.coroutines.flow.first
|
import kotlinx.coroutines.flow.first
|
||||||
import kotlinx.coroutines.flow.onEach
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@ -71,7 +67,7 @@ class GradeDetailsPresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun onMarkAsReadSelected(): Boolean {
|
fun onMarkAsReadSelected(): Boolean {
|
||||||
flowWithResource {
|
resourceFlow {
|
||||||
val student = studentRepository.getCurrentStudent()
|
val student = studentRepository.getCurrentStudent()
|
||||||
val semesters = semesterRepository.getSemesters(student)
|
val semesters = semesterRepository.getSemesters(student)
|
||||||
val semester = semesters.first { item -> item.semesterId == currentSemesterId }
|
val semester = semesters.first { item -> item.semesterId == currentSemesterId }
|
||||||
@ -79,19 +75,11 @@ class GradeDetailsPresenter @Inject constructor(
|
|||||||
|
|
||||||
Timber.i("Mark as read ${unreadGrades.size} grades")
|
Timber.i("Mark as read ${unreadGrades.size} grades")
|
||||||
gradeRepository.updateGrades(unreadGrades.map { it.apply { isRead = true } })
|
gradeRepository.updateGrades(unreadGrades.map { it.apply { isRead = true } })
|
||||||
}.onEach {
|
}
|
||||||
when (it.status) {
|
.logResourceStatus("mark grades as read")
|
||||||
Status.LOADING -> Timber.i("Select mark grades as read")
|
.onResourceSuccess { loadData(currentSemesterId, false) }
|
||||||
Status.SUCCESS -> {
|
.onResourceError(errorHandler::dispatch)
|
||||||
Timber.i("Mark as read result: Success")
|
.launch("mark")
|
||||||
loadData(currentSemesterId, false)
|
|
||||||
}
|
|
||||||
Status.ERROR -> {
|
|
||||||
Timber.i("Mark as read result: An exception occurred")
|
|
||||||
errorHandler.dispatch(it.error!!)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}.launch("mark")
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,71 +126,49 @@ class GradeDetailsPresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun loadData(semesterId: Int, forceRefresh: Boolean) {
|
private fun loadData(semesterId: Int, forceRefresh: Boolean) {
|
||||||
Timber.i("Loading grade details data started")
|
flatResourceFlow {
|
||||||
|
|
||||||
flowWithResourceIn {
|
|
||||||
val student = studentRepository.getCurrentStudent()
|
val student = studentRepository.getCurrentStudent()
|
||||||
averageProvider.getGradesDetailsWithAverage(student, semesterId, forceRefresh)
|
averageProvider.getGradesDetailsWithAverage(student, semesterId, forceRefresh)
|
||||||
}.onEach {
|
}
|
||||||
Timber.d("Loading grade details status: ${it.status}, data: ${it.data != null}")
|
.logResourceStatus("load grade details")
|
||||||
when (it.status) {
|
.onResourceData {
|
||||||
Status.LOADING -> {
|
view?.run {
|
||||||
val items = createGradeItems(it.data.orEmpty())
|
enableSwipe(true)
|
||||||
if (items.isNotEmpty()) {
|
showProgress(false)
|
||||||
Timber.i("Loading grade details result: load cached data")
|
showErrorView(false)
|
||||||
view?.run {
|
showContent(it.isNotEmpty())
|
||||||
updateNewGradesAmount(it.data.orEmpty())
|
showEmpty(it.isEmpty())
|
||||||
enableSwipe(true)
|
updateNewGradesAmount(it)
|
||||||
showRefresh(true)
|
|
||||||
showProgress(false)
|
|
||||||
showEmpty(false)
|
|
||||||
showContent(true)
|
|
||||||
updateData(
|
|
||||||
data = items,
|
|
||||||
expandMode = preferencesRepository.gradeExpandMode,
|
|
||||||
gradeColorTheme = preferencesRepository.gradeColorTheme
|
|
||||||
)
|
|
||||||
notifyParentDataLoaded(semesterId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Status.SUCCESS -> {
|
|
||||||
Timber.i("Loading grade details result: Success")
|
|
||||||
updateNewGradesAmount(it.data!!)
|
|
||||||
updateMarkAsDoneButton()
|
updateMarkAsDoneButton()
|
||||||
val items = createGradeItems(it.data)
|
updateData(
|
||||||
view?.run {
|
data = createGradeItems(it),
|
||||||
showEmpty(items.isEmpty())
|
expandMode = preferencesRepository.gradeExpandMode,
|
||||||
showErrorView(false)
|
preferencesRepository.gradeColorTheme
|
||||||
showContent(items.isNotEmpty())
|
|
||||||
updateData(
|
|
||||||
data = items,
|
|
||||||
expandMode = preferencesRepository.gradeExpandMode,
|
|
||||||
gradeColorTheme = preferencesRepository.gradeColorTheme
|
|
||||||
)
|
|
||||||
}
|
|
||||||
analytics.logEvent(
|
|
||||||
"load_data",
|
|
||||||
"type" to "grade_details",
|
|
||||||
"items" to it.data.size
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Status.ERROR -> {
|
}
|
||||||
Timber.i("Loading grade details result: An exception occurred")
|
.onResourceIntermediate { view?.showRefresh(true) }
|
||||||
errorHandler.dispatch(it.error!!)
|
.onResourceSuccess {
|
||||||
|
analytics.logEvent(
|
||||||
|
"load_data",
|
||||||
|
"type" to "grade_details",
|
||||||
|
"items" to it.size
|
||||||
|
)
|
||||||
|
}
|
||||||
|
.onResourceNotLoading {
|
||||||
|
view?.run {
|
||||||
|
enableSwipe(true)
|
||||||
|
showRefresh(false)
|
||||||
|
showProgress(false)
|
||||||
|
notifyParentDataLoaded(semesterId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.afterLoading {
|
.catch {
|
||||||
view?.run {
|
errorHandler.dispatch(it)
|
||||||
showRefresh(false)
|
view?.notifyParentDataLoaded(semesterId)
|
||||||
showProgress(false)
|
|
||||||
enableSwipe(true)
|
|
||||||
notifyParentDataLoaded(semesterId)
|
|
||||||
}
|
}
|
||||||
}.catch {
|
.onResourceError(errorHandler::dispatch)
|
||||||
errorHandler.dispatch(it)
|
.launch()
|
||||||
view?.notifyParentDataLoaded(semesterId)
|
|
||||||
}.launch()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateNewGradesAmount(grades: List<GradeSubject>) {
|
private fun updateNewGradesAmount(grades: List<GradeSubject>) {
|
||||||
@ -267,15 +233,9 @@ class GradeDetailsPresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun updateGrade(grade: Grade) {
|
private fun updateGrade(grade: Grade) {
|
||||||
flowWithResource { gradeRepository.updateGrade(grade) }.onEach {
|
resourceFlow { gradeRepository.updateGrade(grade) }
|
||||||
when (it.status) {
|
.logResourceStatus("update grade result ${grade.id}")
|
||||||
Status.LOADING -> Timber.i("Attempt to update grade ${grade.id}")
|
.onResourceError(errorHandler::dispatch)
|
||||||
Status.SUCCESS -> Timber.i("Update grade result: Success")
|
.launch("update")
|
||||||
Status.ERROR -> {
|
|
||||||
Timber.i("Update grade result: An exception occurred")
|
|
||||||
errorHandler.dispatch(it.error!!)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}.launch("update")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,12 +9,7 @@ import androidx.core.content.ContextCompat
|
|||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.github.mikephil.charting.components.Legend
|
import com.github.mikephil.charting.components.Legend
|
||||||
import com.github.mikephil.charting.components.LegendEntry
|
import com.github.mikephil.charting.components.LegendEntry
|
||||||
import com.github.mikephil.charting.data.BarData
|
import com.github.mikephil.charting.data.*
|
||||||
import com.github.mikephil.charting.data.BarDataSet
|
|
||||||
import com.github.mikephil.charting.data.BarEntry
|
|
||||||
import com.github.mikephil.charting.data.PieData
|
|
||||||
import com.github.mikephil.charting.data.PieDataSet
|
|
||||||
import com.github.mikephil.charting.data.PieEntry
|
|
||||||
import com.github.mikephil.charting.formatter.ValueFormatter
|
import com.github.mikephil.charting.formatter.ValueFormatter
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
import io.github.wulkanowy.data.db.entities.GradePartialStatistics
|
import io.github.wulkanowy.data.db.entities.GradePartialStatistics
|
||||||
@ -136,20 +131,50 @@ class GradeStatisticsAdapter @Inject constructor() :
|
|||||||
binding: ItemGradeStatisticsPieBinding,
|
binding: ItemGradeStatisticsPieBinding,
|
||||||
partials: GradePartialStatistics
|
partials: GradePartialStatistics
|
||||||
) {
|
) {
|
||||||
bindPieChart(binding, partials.subject, partials.classAverage, partials.classAmounts)
|
val studentAverage = partials.studentAverage.takeIf { it.isNotEmpty() }?.let {
|
||||||
|
binding.root.context.getString(R.string.grade_statistics_student_average, it)
|
||||||
|
}
|
||||||
|
bindPieChart(
|
||||||
|
binding = binding,
|
||||||
|
subject = partials.subject,
|
||||||
|
average = partials.classAverage,
|
||||||
|
studentValue = studentAverage,
|
||||||
|
amounts = partials.classAmounts
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun bindSemesterChart(
|
private fun bindSemesterChart(
|
||||||
binding: ItemGradeStatisticsPieBinding,
|
binding: ItemGradeStatisticsPieBinding,
|
||||||
semester: GradeSemesterStatistics
|
semester: GradeSemesterStatistics
|
||||||
) {
|
) {
|
||||||
bindPieChart(binding, semester.subject, semester.average, semester.amounts)
|
val studentAverage = semester.studentAverage.takeIf { it.isNotBlank() }
|
||||||
|
val studentGrade = semester.studentGrade.takeIf { it != 0 }
|
||||||
|
|
||||||
|
val studentValue = when {
|
||||||
|
studentAverage != null -> binding.root.context.getString(
|
||||||
|
R.string.grade_statistics_student_average,
|
||||||
|
studentAverage
|
||||||
|
)
|
||||||
|
studentGrade != null -> binding.root.context.getString(
|
||||||
|
R.string.grade_statistics_student_grade,
|
||||||
|
studentGrade.toString()
|
||||||
|
)
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
bindPieChart(
|
||||||
|
binding = binding,
|
||||||
|
subject = semester.subject,
|
||||||
|
average = semester.classAverage,
|
||||||
|
studentValue = studentValue,
|
||||||
|
amounts = semester.amounts
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun bindPieChart(
|
private fun bindPieChart(
|
||||||
binding: ItemGradeStatisticsPieBinding,
|
binding: ItemGradeStatisticsPieBinding,
|
||||||
subject: String,
|
subject: String,
|
||||||
average: String,
|
average: String,
|
||||||
|
studentValue: String?,
|
||||||
amounts: List<Int>
|
amounts: List<Int>
|
||||||
) {
|
) {
|
||||||
with(binding.gradeStatisticsPieTitle) {
|
with(binding.gradeStatisticsPieTitle) {
|
||||||
@ -208,13 +233,13 @@ class GradeStatisticsAdapter @Inject constructor() :
|
|||||||
val numberOfGradesString = amounts.fold(0) { acc, it -> acc + it }
|
val numberOfGradesString = amounts.fold(0) { acc, it -> acc + it }
|
||||||
.let { resources.getQuantityString(R.plurals.grade_number_item, it, it) }
|
.let { resources.getQuantityString(R.plurals.grade_number_item, it, it) }
|
||||||
val averageString =
|
val averageString =
|
||||||
binding.root.context.getString(R.string.grade_statistics_average, average)
|
binding.root.context.getString(R.string.grade_statistics_class_average, average)
|
||||||
|
|
||||||
minAngleForSlices = 25f
|
minAngleForSlices = 25f
|
||||||
description.isEnabled = false
|
description.isEnabled = false
|
||||||
centerText =
|
centerText =
|
||||||
numberOfGradesString + ("\n\n" + averageString).takeIf { average.isNotBlank() }
|
numberOfGradesString + ("\n\n" + averageString).takeIf { average.isNotBlank() }
|
||||||
.orEmpty()
|
.orEmpty() + studentValue?.let { "\n$it" }.orEmpty()
|
||||||
|
|
||||||
setHoleColor(context.getThemeAttrColor(android.R.attr.windowBackground))
|
setHoleColor(context.getThemeAttrColor(android.R.attr.windowBackground))
|
||||||
setCenterTextColor(context.getThemeAttrColor(android.R.attr.textColorPrimary))
|
setCenterTextColor(context.getThemeAttrColor(android.R.attr.textColorPrimary))
|
||||||
|
@ -1,19 +1,12 @@
|
|||||||
package io.github.wulkanowy.ui.modules.grade.statistics
|
package io.github.wulkanowy.ui.modules.grade.statistics
|
||||||
|
|
||||||
import io.github.wulkanowy.data.Status
|
import io.github.wulkanowy.data.*
|
||||||
import io.github.wulkanowy.data.db.entities.Subject
|
import io.github.wulkanowy.data.db.entities.Subject
|
||||||
import io.github.wulkanowy.data.pojos.GradeStatisticsItem
|
import io.github.wulkanowy.data.pojos.GradeStatisticsItem
|
||||||
import io.github.wulkanowy.data.repositories.GradeStatisticsRepository
|
import io.github.wulkanowy.data.repositories.*
|
||||||
import io.github.wulkanowy.data.repositories.PreferencesRepository
|
|
||||||
import io.github.wulkanowy.data.repositories.SemesterRepository
|
|
||||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
|
||||||
import io.github.wulkanowy.data.repositories.SubjectRepository
|
|
||||||
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.AnalyticsHelper
|
import io.github.wulkanowy.utils.AnalyticsHelper
|
||||||
import io.github.wulkanowy.utils.afterLoading
|
|
||||||
import io.github.wulkanowy.utils.flowWithResourceIn
|
|
||||||
import kotlinx.coroutines.flow.onEach
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@ -125,33 +118,26 @@ class GradeStatisticsPresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun loadSubjects() {
|
private fun loadSubjects() {
|
||||||
flowWithResourceIn {
|
flatResourceFlow {
|
||||||
val student = studentRepository.getCurrentStudent()
|
val student = studentRepository.getCurrentStudent()
|
||||||
val semester = semesterRepository.getCurrentSemester(student)
|
val semester = semesterRepository.getCurrentSemester(student)
|
||||||
subjectRepository.getSubjects(student, semester)
|
subjectRepository.getSubjects(student, semester)
|
||||||
}.onEach {
|
}
|
||||||
when (it.status) {
|
.logResourceStatus("load grade stats subjects")
|
||||||
Status.LOADING -> Timber.i("Loading grade stats subjects started")
|
.onResourceData {
|
||||||
Status.SUCCESS -> {
|
subjects = it
|
||||||
subjects = requireNotNull(it.data)
|
view?.run {
|
||||||
Timber.i("Loading grade stats subjects result: Success")
|
showSubjects(!preferencesRepository.showAllSubjectsOnStatisticsList)
|
||||||
|
updateSubjects(
|
||||||
view?.run {
|
data = it.map { subject -> subject.name },
|
||||||
showSubjects(!preferencesRepository.showAllSubjectsOnStatisticsList)
|
selectedIndex = it.indexOfFirst { subject ->
|
||||||
updateSubjects(
|
subject.name == currentSubjectName
|
||||||
data = it.data.map { subject -> subject.name },
|
},
|
||||||
selectedIndex = it.data.indexOfFirst { subject ->
|
)
|
||||||
subject.name == currentSubjectName
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Status.ERROR -> {
|
|
||||||
Timber.i("Loading grade stats subjects result: An exception occurred")
|
|
||||||
errorHandler.dispatch(it.error!!)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.launch("subjects")
|
.onResourceError(errorHandler::dispatch)
|
||||||
|
.launch("subjects")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadDataByType(
|
private fun loadDataByType(
|
||||||
@ -168,7 +154,7 @@ class GradeStatisticsPresenter @Inject constructor(
|
|||||||
else -> subjectName
|
else -> subjectName
|
||||||
}
|
}
|
||||||
|
|
||||||
flowWithResourceIn {
|
flatResourceFlow {
|
||||||
val student = studentRepository.getCurrentStudent()
|
val student = studentRepository.getCurrentStudent()
|
||||||
val semesters = semesterRepository.getSemesters(student)
|
val semesters = semesterRepository.getSemesters(student)
|
||||||
val semester = semesters.first { item -> item.semesterId == semesterId }
|
val semester = semesters.first { item -> item.semesterId == semesterId }
|
||||||
@ -201,58 +187,43 @@ class GradeStatisticsPresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.onEach {
|
}
|
||||||
when (it.status) {
|
.logResourceStatus("load grade stats data")
|
||||||
Status.LOADING -> {
|
.mapResourceData {
|
||||||
val isNoContent = it.data == null || checkIsNoContent(it.data, type)
|
val isNoContent = checkIsNoContent(it, type)
|
||||||
if (!isNoContent) {
|
if (isNoContent) emptyList() else it
|
||||||
view?.run {
|
}
|
||||||
showEmpty(isNoContent)
|
.onResourceData {
|
||||||
showErrorView(false)
|
view?.run {
|
||||||
enableSwipe(true)
|
enableSwipe(true)
|
||||||
showRefresh(true)
|
showProgress(false)
|
||||||
showProgress(false)
|
showErrorView(false)
|
||||||
updateData(
|
showEmpty(it.isEmpty())
|
||||||
newItems = if (isNoContent) emptyList() else it.data!!,
|
updateData(
|
||||||
newTheme = preferencesRepository.gradeColorTheme,
|
newItems = it,
|
||||||
showAllSubjectsOnStatisticsList = preferencesRepository.showAllSubjectsOnStatisticsList,
|
newTheme = preferencesRepository.gradeColorTheme,
|
||||||
)
|
showAllSubjectsOnStatisticsList = preferencesRepository.showAllSubjectsOnStatisticsList
|
||||||
showSubjects(!preferencesRepository.showAllSubjectsOnStatisticsList)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Status.SUCCESS -> {
|
|
||||||
Timber.i("Loading grade stats result: Success")
|
|
||||||
view?.run {
|
|
||||||
val isNoContent = checkIsNoContent(it.data!!, type)
|
|
||||||
showEmpty(isNoContent)
|
|
||||||
showErrorView(false)
|
|
||||||
updateData(
|
|
||||||
newItems = if (isNoContent) emptyList() else it.data,
|
|
||||||
newTheme = preferencesRepository.gradeColorTheme,
|
|
||||||
showAllSubjectsOnStatisticsList = preferencesRepository.showAllSubjectsOnStatisticsList,
|
|
||||||
)
|
|
||||||
showSubjects(!preferencesRepository.showAllSubjectsOnStatisticsList)
|
|
||||||
}
|
|
||||||
analytics.logEvent(
|
|
||||||
"load_data",
|
|
||||||
"type" to "grade_statistics",
|
|
||||||
"items" to it.data!!.size
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Status.ERROR -> {
|
}
|
||||||
Timber.i("Loading grade stats result: An exception occurred")
|
.onResourceIntermediate { view?.showRefresh(true) }
|
||||||
errorHandler.dispatch(it.error!!)
|
.onResourceSuccess {
|
||||||
|
analytics.logEvent(
|
||||||
|
"load_data",
|
||||||
|
"type" to "grade_statistics",
|
||||||
|
"items" to it.size
|
||||||
|
)
|
||||||
|
}
|
||||||
|
.onResourceNotLoading {
|
||||||
|
view?.run {
|
||||||
|
enableSwipe(true)
|
||||||
|
showRefresh(false)
|
||||||
|
showProgress(false)
|
||||||
|
notifyParentDataLoaded(semesterId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.afterLoading {
|
.onResourceError(errorHandler::dispatch)
|
||||||
view?.run {
|
.launch("load")
|
||||||
showRefresh(false)
|
|
||||||
showProgress(false)
|
|
||||||
enableSwipe(true)
|
|
||||||
notifyParentDataLoaded(semesterId)
|
|
||||||
}
|
|
||||||
}.launch("load")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun checkIsNoContent(
|
private fun checkIsNoContent(
|
||||||
@ -267,7 +238,8 @@ class GradeStatisticsPresenter @Inject constructor(
|
|||||||
items.firstOrNull()?.partial?.classAmounts.orEmpty().sum() == 0
|
items.firstOrNull()?.partial?.classAmounts.orEmpty().sum() == 0
|
||||||
}
|
}
|
||||||
GradeStatisticsItem.DataType.POINTS -> {
|
GradeStatisticsItem.DataType.POINTS -> {
|
||||||
items.firstOrNull()?.points?.let { points -> points.student == .0 && points.others == .0 } ?: false
|
items.firstOrNull()?.points?.let { points -> points.student == .0 && points.others == .0 }
|
||||||
|
?: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package io.github.wulkanowy.ui.modules.grade.summary
|
package io.github.wulkanowy.ui.modules.grade.summary
|
||||||
|
|
||||||
import io.github.wulkanowy.data.Status
|
import io.github.wulkanowy.data.*
|
||||||
import io.github.wulkanowy.data.db.entities.GradeSummary
|
import io.github.wulkanowy.data.db.entities.GradeSummary
|
||||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||||
import io.github.wulkanowy.ui.base.BasePresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
@ -8,9 +8,6 @@ import io.github.wulkanowy.ui.base.ErrorHandler
|
|||||||
import io.github.wulkanowy.ui.modules.grade.GradeAverageProvider
|
import io.github.wulkanowy.ui.modules.grade.GradeAverageProvider
|
||||||
import io.github.wulkanowy.ui.modules.grade.GradeSubject
|
import io.github.wulkanowy.ui.modules.grade.GradeSubject
|
||||||
import io.github.wulkanowy.utils.AnalyticsHelper
|
import io.github.wulkanowy.utils.AnalyticsHelper
|
||||||
import io.github.wulkanowy.utils.afterLoading
|
|
||||||
import io.github.wulkanowy.utils.flowWithResourceIn
|
|
||||||
import kotlinx.coroutines.flow.onEach
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@ -37,56 +34,40 @@ class GradeSummaryPresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun loadData(semesterId: Int, forceRefresh: Boolean) {
|
private fun loadData(semesterId: Int, forceRefresh: Boolean) {
|
||||||
Timber.i("Loading grade summary started")
|
flatResourceFlow {
|
||||||
|
|
||||||
flowWithResourceIn {
|
|
||||||
val student = studentRepository.getCurrentStudent()
|
val student = studentRepository.getCurrentStudent()
|
||||||
averageProvider.getGradesDetailsWithAverage(student, semesterId, forceRefresh)
|
averageProvider.getGradesDetailsWithAverage(student, semesterId, forceRefresh)
|
||||||
}.onEach {
|
}
|
||||||
Timber.d("Loading grade summary status: ${it.status}, data: ${it.data != null}")
|
.logResourceStatus("load grade summary", showData = true)
|
||||||
when (it.status) {
|
.mapResourceData { createGradeSummaryItems(it) }
|
||||||
Status.LOADING -> {
|
.onResourceData {
|
||||||
val items = createGradeSummaryItems(it.data.orEmpty())
|
view?.run {
|
||||||
if (items.isNotEmpty()) {
|
enableSwipe(true)
|
||||||
Timber.i("Loading grade summary result: load cached data")
|
showProgress(false)
|
||||||
view?.run {
|
showErrorView(false)
|
||||||
enableSwipe(true)
|
showContent(it.isNotEmpty())
|
||||||
showRefresh(true)
|
showEmpty(it.isEmpty())
|
||||||
showProgress(false)
|
updateData(it)
|
||||||
showEmpty(false)
|
|
||||||
showContent(true)
|
|
||||||
updateData(items)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Status.SUCCESS -> {
|
|
||||||
Timber.i("Loading grade summary result: Success")
|
|
||||||
val items = createGradeSummaryItems(it.data!!)
|
|
||||||
view?.run {
|
|
||||||
showEmpty(items.isEmpty())
|
|
||||||
showContent(items.isNotEmpty())
|
|
||||||
showErrorView(false)
|
|
||||||
updateData(items)
|
|
||||||
}
|
|
||||||
analytics.logEvent(
|
|
||||||
"load_data",
|
|
||||||
"type" to "grade_summary",
|
|
||||||
"items" to it.data.size
|
|
||||||
)
|
|
||||||
}
|
|
||||||
Status.ERROR -> {
|
|
||||||
Timber.i("Loading grade summary result: An exception occurred")
|
|
||||||
errorHandler.dispatch(it.error!!)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.afterLoading {
|
.onResourceIntermediate { view?.showRefresh(true) }
|
||||||
view?.run {
|
.onResourceSuccess {
|
||||||
showRefresh(false)
|
analytics.logEvent(
|
||||||
showProgress(false)
|
"load_data",
|
||||||
enableSwipe(true)
|
"type" to "grade_summary",
|
||||||
notifyParentDataLoaded(semesterId)
|
"items" to it.size
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}.launch()
|
.onResourceNotLoading {
|
||||||
|
view?.run {
|
||||||
|
enableSwipe(true)
|
||||||
|
showRefresh(false)
|
||||||
|
showProgress(false)
|
||||||
|
notifyParentDataLoaded(semesterId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.onResourceError(errorHandler::dispatch)
|
||||||
|
.launch()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showErrorViewOnError(message: String, error: Throwable) {
|
private fun showErrorViewOnError(message: String, error: Throwable) {
|
||||||
@ -153,9 +134,9 @@ class GradeSummaryPresenter @Inject constructor(
|
|||||||
private fun checkEmpty(gradeSummary: GradeSubject): Boolean {
|
private fun checkEmpty(gradeSummary: GradeSubject): Boolean {
|
||||||
return gradeSummary.run {
|
return gradeSummary.run {
|
||||||
summary.finalGrade.isBlank()
|
summary.finalGrade.isBlank()
|
||||||
&& summary.predictedGrade.isBlank()
|
&& summary.predictedGrade.isBlank()
|
||||||
&& average == .0
|
&& average == .0
|
||||||
&& points.isBlank()
|
&& points.isBlank()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,21 +1,13 @@
|
|||||||
package io.github.wulkanowy.ui.modules.homework
|
package io.github.wulkanowy.ui.modules.homework
|
||||||
|
|
||||||
import io.github.wulkanowy.data.Status
|
import io.github.wulkanowy.data.*
|
||||||
import io.github.wulkanowy.data.db.entities.Homework
|
import io.github.wulkanowy.data.db.entities.Homework
|
||||||
import io.github.wulkanowy.data.repositories.HomeworkRepository
|
import io.github.wulkanowy.data.repositories.HomeworkRepository
|
||||||
import io.github.wulkanowy.data.repositories.SemesterRepository
|
import io.github.wulkanowy.data.repositories.SemesterRepository
|
||||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
import io.github.wulkanowy.data.repositories.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.AnalyticsHelper
|
import io.github.wulkanowy.utils.*
|
||||||
import io.github.wulkanowy.utils.afterLoading
|
|
||||||
import io.github.wulkanowy.utils.flowWithResourceIn
|
|
||||||
import io.github.wulkanowy.utils.getLastSchoolDayIfHoliday
|
|
||||||
import io.github.wulkanowy.utils.isHolidays
|
|
||||||
import io.github.wulkanowy.utils.monday
|
|
||||||
import io.github.wulkanowy.utils.nextOrSameSchoolDay
|
|
||||||
import io.github.wulkanowy.utils.sunday
|
|
||||||
import io.github.wulkanowy.utils.toFormattedString
|
|
||||||
import kotlinx.coroutines.flow.catch
|
import kotlinx.coroutines.flow.catch
|
||||||
import kotlinx.coroutines.flow.flow
|
import kotlinx.coroutines.flow.flow
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
@ -89,61 +81,59 @@ class HomeworkPresenter @Inject constructor(
|
|||||||
flow {
|
flow {
|
||||||
val student = studentRepository.getCurrentStudent()
|
val student = studentRepository.getCurrentStudent()
|
||||||
emit(semesterRepository.getCurrentSemester(student))
|
emit(semesterRepository.getCurrentSemester(student))
|
||||||
}.catch {
|
}
|
||||||
Timber.i("Loading semester result: An exception occurred")
|
.catch { Timber.i("Loading semester result: An exception occurred") }
|
||||||
}.onEach {
|
.onEach {
|
||||||
baseDate = baseDate.getLastSchoolDayIfHoliday(it.schoolYear)
|
baseDate = baseDate.getLastSchoolDayIfHoliday(it.schoolYear)
|
||||||
currentDate = baseDate
|
currentDate = baseDate
|
||||||
reloadNavigation()
|
reloadNavigation()
|
||||||
}.launch("holidays")
|
}
|
||||||
|
.launch("holidays")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadData(forceRefresh: Boolean = false) {
|
private fun loadData(forceRefresh: Boolean = false) {
|
||||||
Timber.i("Loading homework data started")
|
Timber.i("Loading homework data started")
|
||||||
|
|
||||||
flowWithResourceIn {
|
flatResourceFlow {
|
||||||
val student = studentRepository.getCurrentStudent()
|
val student = studentRepository.getCurrentStudent()
|
||||||
val semester = semesterRepository.getCurrentSemester(student)
|
val semester = semesterRepository.getCurrentSemester(student)
|
||||||
homeworkRepository.getHomework(student, semester, currentDate, currentDate, forceRefresh)
|
homeworkRepository.getHomework(
|
||||||
}.onEach {
|
student = student,
|
||||||
when (it.status) {
|
semester = semester,
|
||||||
Status.LOADING -> {
|
start = currentDate,
|
||||||
if (!it.data.isNullOrEmpty()) {
|
end = currentDate,
|
||||||
view?.run {
|
forceRefresh = forceRefresh
|
||||||
enableSwipe(true)
|
)
|
||||||
showRefresh(true)
|
}
|
||||||
showProgress(false)
|
.logResourceStatus("loading homework")
|
||||||
showContent(true)
|
.mapResourceData { createHomeworkItem(it) }
|
||||||
updateData(createHomeworkItem(it.data))
|
.onResourceData {
|
||||||
}
|
view?.run {
|
||||||
}
|
enableSwipe(true)
|
||||||
}
|
showProgress(false)
|
||||||
Status.SUCCESS -> {
|
showErrorView(false)
|
||||||
Timber.i("Loading homework result: Success")
|
showContent(it.isNotEmpty())
|
||||||
view?.apply {
|
showEmpty(it.isEmpty())
|
||||||
updateData(createHomeworkItem(it.data!!))
|
updateData(it)
|
||||||
showEmpty(it.data.isEmpty())
|
|
||||||
showErrorView(false)
|
|
||||||
showContent(it.data.isNotEmpty())
|
|
||||||
}
|
|
||||||
analytics.logEvent(
|
|
||||||
"load_data",
|
|
||||||
"type" to "homework",
|
|
||||||
"items" to it.data!!.size
|
|
||||||
)
|
|
||||||
}
|
|
||||||
Status.ERROR -> {
|
|
||||||
Timber.i("Loading homework result: An exception occurred")
|
|
||||||
errorHandler.dispatch(it.error!!)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.afterLoading {
|
.onResourceIntermediate { view?.showRefresh(true) }
|
||||||
view?.run {
|
.onResourceSuccess {
|
||||||
showRefresh(false)
|
analytics.logEvent(
|
||||||
showProgress(false)
|
"load_data",
|
||||||
enableSwipe(true)
|
"type" to "homework",
|
||||||
|
"items" to it.size
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}.launch()
|
.onResourceNotLoading {
|
||||||
|
view?.run {
|
||||||
|
enableSwipe(true)
|
||||||
|
showProgress(false)
|
||||||
|
showRefresh(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.onResourceError(errorHandler::dispatch)
|
||||||
|
.launch()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showErrorViewOnError(message: String, error: Throwable) {
|
private fun showErrorViewOnError(message: String, error: Throwable) {
|
||||||
@ -159,9 +149,10 @@ class HomeworkPresenter @Inject constructor(
|
|||||||
|
|
||||||
private fun createHomeworkItem(items: List<Homework>): List<HomeworkItem<*>> {
|
private fun createHomeworkItem(items: List<Homework>): List<HomeworkItem<*>> {
|
||||||
return items.groupBy { it.date }.toSortedMap().map { (date, exams) ->
|
return items.groupBy { it.date }.toSortedMap().map { (date, exams) ->
|
||||||
listOf(HomeworkItem(date, HomeworkItem.ViewType.HEADER)) + exams.reversed().map { exam ->
|
listOf(HomeworkItem(date, HomeworkItem.ViewType.HEADER)) + exams.reversed()
|
||||||
HomeworkItem(exam, HomeworkItem.ViewType.ITEM)
|
.map { exam ->
|
||||||
}
|
HomeworkItem(exam, HomeworkItem.ViewType.ITEM)
|
||||||
|
}
|
||||||
}.flatten()
|
}.flatten()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,8 +175,10 @@ class HomeworkPresenter @Inject constructor(
|
|||||||
view?.apply {
|
view?.apply {
|
||||||
showPreButton(!currentDate.minusDays(7).isHolidays)
|
showPreButton(!currentDate.minusDays(7).isHolidays)
|
||||||
showNextButton(!currentDate.plusDays(7).isHolidays)
|
showNextButton(!currentDate.plusDays(7).isHolidays)
|
||||||
updateNavigationWeek("${currentDate.monday.toFormattedString("dd.MM")} - " +
|
updateNavigationWeek(
|
||||||
currentDate.sunday.toFormattedString("dd.MM"))
|
"${currentDate.monday.toFormattedString("dd.MM")} - " +
|
||||||
|
currentDate.sunday.toFormattedString("dd.MM")
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,16 @@
|
|||||||
package io.github.wulkanowy.ui.modules.homework.add
|
package io.github.wulkanowy.ui.modules.homework.add
|
||||||
|
|
||||||
import io.github.wulkanowy.data.Status
|
|
||||||
import io.github.wulkanowy.data.db.entities.Homework
|
import io.github.wulkanowy.data.db.entities.Homework
|
||||||
|
import io.github.wulkanowy.data.logResourceStatus
|
||||||
|
import io.github.wulkanowy.data.onResourceError
|
||||||
|
import io.github.wulkanowy.data.onResourceSuccess
|
||||||
import io.github.wulkanowy.data.repositories.HomeworkRepository
|
import io.github.wulkanowy.data.repositories.HomeworkRepository
|
||||||
import io.github.wulkanowy.data.repositories.SemesterRepository
|
import io.github.wulkanowy.data.repositories.SemesterRepository
|
||||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||||
|
import io.github.wulkanowy.data.resourceFlow
|
||||||
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.flowWithResource
|
|
||||||
import io.github.wulkanowy.utils.toLocalDate
|
import io.github.wulkanowy.utils.toLocalDate
|
||||||
import kotlinx.coroutines.flow.onEach
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.time.LocalDate
|
import java.time.LocalDate
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@ -55,7 +56,7 @@ class HomeworkAddPresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun saveHomework(subject: String, teacher: String, date: LocalDate, content: String) {
|
private fun saveHomework(subject: String, teacher: String, date: LocalDate, content: String) {
|
||||||
flowWithResource {
|
resourceFlow {
|
||||||
val student = studentRepository.getCurrentStudent()
|
val student = studentRepository.getCurrentStudent()
|
||||||
val semester = semesterRepository.getCurrentSemester(student)
|
val semester = semesterRepository.getCurrentSemester(student)
|
||||||
val entryDate = LocalDate.now()
|
val entryDate = LocalDate.now()
|
||||||
@ -72,21 +73,15 @@ class HomeworkAddPresenter @Inject constructor(
|
|||||||
attachments = emptyList(),
|
attachments = emptyList(),
|
||||||
).apply { isAddedByUser = true }
|
).apply { isAddedByUser = true }
|
||||||
)
|
)
|
||||||
}.onEach {
|
}
|
||||||
when (it.status) {
|
.logResourceStatus("homework insert")
|
||||||
Status.LOADING -> Timber.i("Homework insert start")
|
.onResourceSuccess {
|
||||||
Status.SUCCESS -> {
|
view?.run {
|
||||||
Timber.i("Homework insert: Success")
|
showSuccessMessage()
|
||||||
view?.run {
|
closeDialog()
|
||||||
showSuccessMessage()
|
|
||||||
closeDialog()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Status.ERROR -> {
|
|
||||||
Timber.i("Homework insert result: An exception occurred")
|
|
||||||
errorHandler.dispatch(it.error!!)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.launch("add_homework")
|
.onResourceError(errorHandler::dispatch)
|
||||||
|
.launch("add_homework")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,16 @@
|
|||||||
package io.github.wulkanowy.ui.modules.homework.details
|
package io.github.wulkanowy.ui.modules.homework.details
|
||||||
|
|
||||||
import io.github.wulkanowy.data.Status
|
|
||||||
import io.github.wulkanowy.data.db.entities.Homework
|
import io.github.wulkanowy.data.db.entities.Homework
|
||||||
|
import io.github.wulkanowy.data.logResourceStatus
|
||||||
|
import io.github.wulkanowy.data.onResourceError
|
||||||
|
import io.github.wulkanowy.data.onResourceSuccess
|
||||||
import io.github.wulkanowy.data.repositories.HomeworkRepository
|
import io.github.wulkanowy.data.repositories.HomeworkRepository
|
||||||
import io.github.wulkanowy.data.repositories.PreferencesRepository
|
import io.github.wulkanowy.data.repositories.PreferencesRepository
|
||||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||||
|
import io.github.wulkanowy.data.resourceFlow
|
||||||
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.AnalyticsHelper
|
import io.github.wulkanowy.utils.AnalyticsHelper
|
||||||
import io.github.wulkanowy.utils.flowWithResource
|
|
||||||
import kotlinx.coroutines.flow.onEach
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@ -34,38 +35,26 @@ class HomeworkDetailsPresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun deleteHomework(homework: Homework) {
|
fun deleteHomework(homework: Homework) {
|
||||||
flowWithResource { homeworkRepository.deleteHomework(homework) }.onEach {
|
resourceFlow { homeworkRepository.deleteHomework(homework) }
|
||||||
when (it.status) {
|
.logResourceStatus("homework delete")
|
||||||
Status.LOADING -> Timber.i("Homework delete start")
|
.onResourceSuccess {
|
||||||
Status.SUCCESS -> {
|
view?.run {
|
||||||
Timber.i("Homework delete: Success")
|
showMessage(homeworkDeleteSuccess)
|
||||||
view?.run {
|
closeDialog()
|
||||||
showMessage(homeworkDeleteSuccess)
|
|
||||||
closeDialog()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Status.ERROR -> {
|
|
||||||
Timber.i("Homework delete result: An exception occurred")
|
|
||||||
errorHandler.dispatch(it.error!!)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.launch("delete")
|
.onResourceError(errorHandler::dispatch)
|
||||||
|
.launch("delete")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun toggleDone(homework: Homework) {
|
fun toggleDone(homework: Homework) {
|
||||||
flowWithResource { homeworkRepository.toggleDone(homework) }.onEach {
|
resourceFlow { homeworkRepository.toggleDone(homework) }
|
||||||
when (it.status) {
|
.logResourceStatus("homework details update")
|
||||||
Status.LOADING -> Timber.i("Homework details update start")
|
.onResourceSuccess {
|
||||||
Status.SUCCESS -> {
|
view?.updateMarkAsDoneLabel(homework.isDone)
|
||||||
Timber.i("Homework details update: Success")
|
analytics.logEvent("homework_mark_as_done")
|
||||||
view?.updateMarkAsDoneLabel(homework.isDone)
|
|
||||||
analytics.logEvent("homework_mark_as_done")
|
|
||||||
}
|
|
||||||
Status.ERROR -> {
|
|
||||||
Timber.i("Homework details update result: An exception occurred")
|
|
||||||
errorHandler.dispatch(it.error!!)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}.launch("toggle")
|
.onResourceError(errorHandler::dispatch)
|
||||||
|
.launch("toggle")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,16 @@
|
|||||||
package io.github.wulkanowy.ui.modules.login.advanced
|
package io.github.wulkanowy.ui.modules.login.advanced
|
||||||
|
|
||||||
import io.github.wulkanowy.data.Status
|
import io.github.wulkanowy.data.Resource
|
||||||
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
|
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
|
||||||
|
import io.github.wulkanowy.data.logResourceStatus
|
||||||
|
import io.github.wulkanowy.data.onResourceNotLoading
|
||||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||||
|
import io.github.wulkanowy.data.resourceFlow
|
||||||
import io.github.wulkanowy.sdk.Sdk
|
import io.github.wulkanowy.sdk.Sdk
|
||||||
import io.github.wulkanowy.ui.base.BasePresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
import io.github.wulkanowy.ui.modules.login.LoginData
|
import io.github.wulkanowy.ui.modules.login.LoginData
|
||||||
import io.github.wulkanowy.ui.modules.login.LoginErrorHandler
|
import io.github.wulkanowy.ui.modules.login.LoginErrorHandler
|
||||||
import io.github.wulkanowy.utils.AnalyticsHelper
|
import io.github.wulkanowy.utils.AnalyticsHelper
|
||||||
import io.github.wulkanowy.utils.afterLoading
|
|
||||||
import io.github.wulkanowy.utils.flowWithResource
|
|
||||||
import io.github.wulkanowy.utils.ifNullOrBlank
|
import io.github.wulkanowy.utils.ifNullOrBlank
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
@ -129,20 +130,20 @@ class LoginAdvancedPresenter @Inject constructor(
|
|||||||
fun onSignInClick() {
|
fun onSignInClick() {
|
||||||
if (!validateCredentials()) return
|
if (!validateCredentials()) return
|
||||||
|
|
||||||
flowWithResource { getStudentsAppropriatesToLoginType() }.onEach {
|
resourceFlow { getStudentsAppropriatesToLoginType() }
|
||||||
when (it.status) {
|
.logResourceStatus("login")
|
||||||
Status.LOADING -> view?.run {
|
.onEach {
|
||||||
Timber.i("Login started")
|
when (it) {
|
||||||
hideSoftKeyboard()
|
is Resource.Loading -> view?.run {
|
||||||
showProgress(true)
|
hideSoftKeyboard()
|
||||||
showContent(false)
|
showProgress(true)
|
||||||
}
|
showContent(false)
|
||||||
Status.SUCCESS -> {
|
}
|
||||||
Timber.i("Login result: Success")
|
is Resource.Success -> {
|
||||||
analytics.logEvent(
|
analytics.logEvent(
|
||||||
"registration_form",
|
"registration_form",
|
||||||
"success" to true,
|
"success" to true,
|
||||||
"students" to it.data!!.size,
|
"students" to it.data.size,
|
||||||
"error" to "No error"
|
"error" to "No error"
|
||||||
)
|
)
|
||||||
val loginData = LoginData(
|
val loginData = LoginData(
|
||||||
@ -154,23 +155,22 @@ class LoginAdvancedPresenter @Inject constructor(
|
|||||||
0 -> view?.navigateToSymbol(loginData)
|
0 -> view?.navigateToSymbol(loginData)
|
||||||
else -> view?.navigateToStudentSelect(it.data)
|
else -> view?.navigateToStudentSelect(it.data)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
is Resource.Error -> {
|
||||||
|
analytics.logEvent(
|
||||||
|
"registration_form",
|
||||||
|
"success" to false, "students" to -1,
|
||||||
|
"error" to it.error.message.ifNullOrBlank { "No message" }
|
||||||
|
)
|
||||||
|
loginErrorHandler.dispatch(it.error)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Status.ERROR -> {
|
}.onResourceNotLoading {
|
||||||
Timber.i("Login result: An exception occurred")
|
view?.apply {
|
||||||
analytics.logEvent(
|
showProgress(false)
|
||||||
"registration_form",
|
showContent(true)
|
||||||
"success" to false, "students" to -1,
|
|
||||||
"error" to it.error!!.message.ifNullOrBlank { "No message" }
|
|
||||||
)
|
|
||||||
loginErrorHandler.dispatch(it.error)
|
|
||||||
}
|
}
|
||||||
}
|
}.launch("login")
|
||||||
}.afterLoading {
|
|
||||||
view?.apply {
|
|
||||||
showProgress(false)
|
|
||||||
showContent(true)
|
|
||||||
}
|
|
||||||
}.launch("login")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun getStudentsAppropriatesToLoginType(): List<StudentWithSemesters> {
|
private suspend fun getStudentsAppropriatesToLoginType(): List<StudentWithSemesters> {
|
||||||
|
@ -1,16 +1,13 @@
|
|||||||
package io.github.wulkanowy.ui.modules.login.form
|
package io.github.wulkanowy.ui.modules.login.form
|
||||||
|
|
||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
import io.github.wulkanowy.data.Status
|
import io.github.wulkanowy.data.*
|
||||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||||
import io.github.wulkanowy.ui.base.BasePresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
import io.github.wulkanowy.ui.modules.login.LoginData
|
import io.github.wulkanowy.ui.modules.login.LoginData
|
||||||
import io.github.wulkanowy.ui.modules.login.LoginErrorHandler
|
import io.github.wulkanowy.ui.modules.login.LoginErrorHandler
|
||||||
import io.github.wulkanowy.utils.AnalyticsHelper
|
import io.github.wulkanowy.utils.AnalyticsHelper
|
||||||
import io.github.wulkanowy.utils.afterLoading
|
|
||||||
import io.github.wulkanowy.utils.flowWithResource
|
|
||||||
import io.github.wulkanowy.utils.ifNullOrBlank
|
import io.github.wulkanowy.utils.ifNullOrBlank
|
||||||
import kotlinx.coroutines.flow.onEach
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@ -75,7 +72,7 @@ class LoginFormPresenter @Inject constructor(
|
|||||||
|
|
||||||
val username = view?.formUsernameValue.orEmpty().trim()
|
val username = view?.formUsernameValue.orEmpty().trim()
|
||||||
if ("@" in username && "@vulcan" !in username) {
|
if ("@" in username && "@vulcan" !in username) {
|
||||||
val hosts = view?.getHostsValues().orEmpty().map { it.toUri().host to it }.toMap()
|
val hosts = view?.getHostsValues().orEmpty().associateBy { it.toUri().host }
|
||||||
val usernameHost = username.substringAfter("@")
|
val usernameHost = username.substringAfter("@")
|
||||||
|
|
||||||
hosts[usernameHost]?.let {
|
hosts[usernameHost]?.let {
|
||||||
@ -95,54 +92,54 @@ class LoginFormPresenter @Inject constructor(
|
|||||||
|
|
||||||
if (!validateCredentials(email, password, host)) return
|
if (!validateCredentials(email, password, host)) return
|
||||||
|
|
||||||
flowWithResource {
|
resourceFlow {
|
||||||
studentRepository.getStudentsScrapper(
|
studentRepository.getStudentsScrapper(
|
||||||
email = email,
|
email = email,
|
||||||
password = password,
|
password = password,
|
||||||
scrapperBaseUrl = host,
|
scrapperBaseUrl = host,
|
||||||
symbol = symbol
|
symbol = symbol
|
||||||
)
|
)
|
||||||
}.onEach {
|
}
|
||||||
when (it.status) {
|
.logResourceStatus("login")
|
||||||
Status.LOADING -> view?.run {
|
.onResourceLoading {
|
||||||
Timber.i("Login started")
|
view?.run {
|
||||||
hideSoftKeyboard()
|
hideSoftKeyboard()
|
||||||
showProgress(true)
|
showProgress(true)
|
||||||
showContent(false)
|
showContent(false)
|
||||||
}
|
}
|
||||||
Status.SUCCESS -> {
|
}
|
||||||
Timber.i("Login result: Success")
|
.onResourceSuccess {
|
||||||
analytics.logEvent(
|
when (it.size) {
|
||||||
"registration_form",
|
0 -> view?.navigateToSymbol(LoginData(email, password, host))
|
||||||
"success" to true,
|
else -> view?.navigateToStudentSelect(it)
|
||||||
"students" to it.data!!.size,
|
|
||||||
"scrapperBaseUrl" to host,
|
|
||||||
"error" to "No error"
|
|
||||||
)
|
|
||||||
when (it.data.size) {
|
|
||||||
0 -> view?.navigateToSymbol(LoginData(email, password, host))
|
|
||||||
else -> view?.navigateToStudentSelect(it.data)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Status.ERROR -> {
|
analytics.logEvent(
|
||||||
Timber.i("Login result: An exception occurred")
|
"registration_form",
|
||||||
analytics.logEvent(
|
"success" to true,
|
||||||
"registration_form",
|
"students" to it.size,
|
||||||
"success" to false,
|
"scrapperBaseUrl" to host,
|
||||||
"students" to -1,
|
"error" to "No error"
|
||||||
"scrapperBaseUrl" to host,
|
)
|
||||||
"error" to it.error!!.message.ifNullOrBlank { "No message" })
|
}
|
||||||
loginErrorHandler.dispatch(it.error)
|
.onResourceNotLoading {
|
||||||
lastError = it.error
|
view?.apply {
|
||||||
view?.showContact(true)
|
showProgress(false)
|
||||||
|
showContent(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.afterLoading {
|
.onResourceError {
|
||||||
view?.apply {
|
loginErrorHandler.dispatch(it)
|
||||||
showProgress(false)
|
lastError = it
|
||||||
showContent(true)
|
view?.showContact(true)
|
||||||
|
analytics.logEvent(
|
||||||
|
"registration_form",
|
||||||
|
"success" to false,
|
||||||
|
"students" to -1,
|
||||||
|
"scrapperBaseUrl" to host,
|
||||||
|
"error" to it.message.ifNullOrBlank { "No message" }
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}.launch("login")
|
.launch("login")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onFaqClick() {
|
fun onFaqClick() {
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
package io.github.wulkanowy.ui.modules.login.recover
|
package io.github.wulkanowy.ui.modules.login.recover
|
||||||
|
|
||||||
import io.github.wulkanowy.data.Status
|
import io.github.wulkanowy.data.Resource
|
||||||
|
import io.github.wulkanowy.data.onResourceNotLoading
|
||||||
import io.github.wulkanowy.data.repositories.RecoverRepository
|
import io.github.wulkanowy.data.repositories.RecoverRepository
|
||||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||||
|
import io.github.wulkanowy.data.resourceFlow
|
||||||
import io.github.wulkanowy.ui.base.BasePresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
import io.github.wulkanowy.utils.AnalyticsHelper
|
import io.github.wulkanowy.utils.AnalyticsHelper
|
||||||
import io.github.wulkanowy.utils.afterLoading
|
|
||||||
import io.github.wulkanowy.utils.flowWithResource
|
|
||||||
import io.github.wulkanowy.utils.ifNullOrBlank
|
import io.github.wulkanowy.utils.ifNullOrBlank
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
@ -57,24 +57,28 @@ class LoginRecoverPresenter @Inject constructor(
|
|||||||
|
|
||||||
if (!validateInput(username, host)) return
|
if (!validateInput(username, host)) return
|
||||||
|
|
||||||
flowWithResource { recoverRepository.getReCaptchaSiteKey(host, symbol.ifBlank { "Default" }) }.onEach {
|
resourceFlow {
|
||||||
when (it.status) {
|
recoverRepository.getReCaptchaSiteKey(
|
||||||
Status.LOADING -> view?.run {
|
host,
|
||||||
|
symbol.ifBlank { "Default" })
|
||||||
|
}.onEach {
|
||||||
|
when (it) {
|
||||||
|
is Resource.Loading -> view?.run {
|
||||||
hideSoftKeyboard()
|
hideSoftKeyboard()
|
||||||
showRecoverForm(false)
|
showRecoverForm(false)
|
||||||
showProgress(true)
|
showProgress(true)
|
||||||
showErrorView(false)
|
showErrorView(false)
|
||||||
showCaptcha(false)
|
showCaptcha(false)
|
||||||
}
|
}
|
||||||
Status.SUCCESS -> view?.run {
|
is Resource.Success -> view?.run {
|
||||||
loadReCaptcha(url = it.data!!.first, siteKey = it.data.second)
|
loadReCaptcha(url = it.data.first, siteKey = it.data.second)
|
||||||
showProgress(false)
|
showProgress(false)
|
||||||
showErrorView(false)
|
showErrorView(false)
|
||||||
showCaptcha(true)
|
showCaptcha(true)
|
||||||
}
|
}
|
||||||
Status.ERROR -> {
|
is Resource.Error -> {
|
||||||
Timber.i("Obtain captcha site key result: An exception occurred")
|
Timber.i("Obtain captcha site key result: An exception occurred")
|
||||||
errorHandler.dispatch(it.error!!)
|
errorHandler.dispatch(it.error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.launch("captcha")
|
}.launch("captcha")
|
||||||
@ -101,26 +105,43 @@ class LoginRecoverPresenter @Inject constructor(
|
|||||||
val host = view?.recoverHostValue.orEmpty()
|
val host = view?.recoverHostValue.orEmpty()
|
||||||
val symbol = view?.formHostSymbol.ifNullOrBlank { "Default" }
|
val symbol = view?.formHostSymbol.ifNullOrBlank { "Default" }
|
||||||
|
|
||||||
flowWithResource { recoverRepository.sendRecoverRequest(host, symbol, username, reCaptchaResponse) }.onEach {
|
resourceFlow {
|
||||||
when (it.status) {
|
recoverRepository.sendRecoverRequest(
|
||||||
Status.LOADING -> view?.run {
|
host,
|
||||||
|
symbol,
|
||||||
|
username,
|
||||||
|
reCaptchaResponse
|
||||||
|
)
|
||||||
|
}.onEach {
|
||||||
|
when (it) {
|
||||||
|
is Resource.Loading -> view?.run {
|
||||||
showProgress(true)
|
showProgress(true)
|
||||||
showRecoverForm(false)
|
showRecoverForm(false)
|
||||||
showCaptcha(false)
|
showCaptcha(false)
|
||||||
}
|
}
|
||||||
Status.SUCCESS -> view?.run {
|
is Resource.Success -> view?.run {
|
||||||
showSuccessView(true)
|
showSuccessView(true)
|
||||||
setSuccessTitle(it.data!!.substringBefore(". "))
|
setSuccessTitle(it.data.substringBefore(". "))
|
||||||
setSuccessMessage(it.data.substringAfter(". "))
|
setSuccessMessage(it.data.substringAfter(". "))
|
||||||
analytics.logEvent("account_recover", "register" to host, "symbol" to symbol, "success" to true)
|
analytics.logEvent(
|
||||||
|
"account_recover",
|
||||||
|
"register" to host,
|
||||||
|
"symbol" to symbol,
|
||||||
|
"success" to true
|
||||||
|
)
|
||||||
}
|
}
|
||||||
Status.ERROR -> {
|
is Resource.Error -> {
|
||||||
Timber.i("Send recover request result: An exception occurred")
|
Timber.i("Send recover request result: An exception occurred")
|
||||||
errorHandler.dispatch(it.error!!)
|
errorHandler.dispatch(it.error)
|
||||||
analytics.logEvent("account_recover", "register" to host, "symbol" to symbol, "success" to false)
|
analytics.logEvent(
|
||||||
|
"account_recover",
|
||||||
|
"register" to host,
|
||||||
|
"symbol" to symbol,
|
||||||
|
"success" to false
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.afterLoading {
|
}.onResourceNotLoading {
|
||||||
view?.showProgress(false)
|
view?.showProgress(false)
|
||||||
}.launch("verified")
|
}.launch("verified")
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
package io.github.wulkanowy.ui.modules.login.studentselect
|
package io.github.wulkanowy.ui.modules.login.studentselect
|
||||||
|
|
||||||
import io.github.wulkanowy.data.Status
|
import io.github.wulkanowy.data.Resource
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
|
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
|
||||||
|
import io.github.wulkanowy.data.logResourceStatus
|
||||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||||
|
import io.github.wulkanowy.data.resourceFlow
|
||||||
import io.github.wulkanowy.services.sync.SyncManager
|
import io.github.wulkanowy.services.sync.SyncManager
|
||||||
import io.github.wulkanowy.ui.base.BasePresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
import io.github.wulkanowy.ui.modules.login.LoginErrorHandler
|
import io.github.wulkanowy.ui.modules.login.LoginErrorHandler
|
||||||
import io.github.wulkanowy.utils.AnalyticsHelper
|
import io.github.wulkanowy.utils.AnalyticsHelper
|
||||||
import io.github.wulkanowy.utils.flowWithResource
|
|
||||||
import io.github.wulkanowy.utils.ifNullOrBlank
|
import io.github.wulkanowy.utils.ifNullOrBlank
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
@ -66,16 +67,16 @@ class LoginStudentSelectPresenter @Inject constructor(
|
|||||||
private fun loadData(studentsWithSemesters: List<StudentWithSemesters>) {
|
private fun loadData(studentsWithSemesters: List<StudentWithSemesters>) {
|
||||||
resetSelectedState()
|
resetSelectedState()
|
||||||
|
|
||||||
flowWithResource { studentRepository.getSavedStudents(false) }.onEach {
|
resourceFlow { studentRepository.getSavedStudents(false) }.onEach {
|
||||||
when (it.status) {
|
when (it) {
|
||||||
Status.LOADING -> Timber.d("Login student select students load started")
|
is Resource.Loading -> Timber.d("Login student select students load started")
|
||||||
Status.SUCCESS -> view?.updateData(studentsWithSemesters.map { studentWithSemesters ->
|
is Resource.Success -> view?.updateData(studentsWithSemesters.map { studentWithSemesters ->
|
||||||
studentWithSemesters to it.data!!.any { item ->
|
studentWithSemesters to it.data.any { item ->
|
||||||
compareStudents(studentWithSemesters.student, item.student)
|
compareStudents(studentWithSemesters.student, item.student)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
Status.ERROR -> {
|
is Resource.Error -> {
|
||||||
errorHandler.dispatch(it.error!!)
|
errorHandler.dispatch(it.error)
|
||||||
lastError = it.error
|
lastError = it.error
|
||||||
view?.updateData(studentsWithSemesters.map { student -> student to false })
|
view?.updateData(studentsWithSemesters.map { student -> student to false })
|
||||||
}
|
}
|
||||||
@ -89,29 +90,27 @@ class LoginStudentSelectPresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun registerStudents(studentsWithSemesters: List<StudentWithSemesters>) {
|
private fun registerStudents(studentsWithSemesters: List<StudentWithSemesters>) {
|
||||||
flowWithResource { studentRepository.saveStudents(studentsWithSemesters) }
|
resourceFlow { studentRepository.saveStudents(studentsWithSemesters) }
|
||||||
|
.logResourceStatus("registration")
|
||||||
.onEach {
|
.onEach {
|
||||||
when (it.status) {
|
when (it) {
|
||||||
Status.LOADING -> view?.run {
|
is Resource.Loading -> view?.run {
|
||||||
Timber.i("Registration started")
|
|
||||||
showProgress(true)
|
showProgress(true)
|
||||||
showContent(false)
|
showContent(false)
|
||||||
}
|
}
|
||||||
Status.SUCCESS -> {
|
is Resource.Success -> {
|
||||||
Timber.i("Registration result: Success")
|
|
||||||
syncManager.startOneTimeSyncWorker(quiet = true)
|
syncManager.startOneTimeSyncWorker(quiet = true)
|
||||||
view?.openMainView()
|
view?.openMainView()
|
||||||
logRegisterEvent(studentsWithSemesters)
|
logRegisterEvent(studentsWithSemesters)
|
||||||
}
|
}
|
||||||
Status.ERROR -> {
|
is Resource.Error -> {
|
||||||
Timber.i("Registration result: An exception occurred ")
|
|
||||||
view?.apply {
|
view?.apply {
|
||||||
showProgress(false)
|
showProgress(false)
|
||||||
showContent(true)
|
showContent(true)
|
||||||
showContact(true)
|
showContact(true)
|
||||||
}
|
}
|
||||||
lastError = it.error
|
lastError = it.error
|
||||||
loginErrorHandler.dispatch(it.error!!)
|
loginErrorHandler.dispatch(it.error)
|
||||||
logRegisterEvent(studentsWithSemesters, it.error)
|
logRegisterEvent(studentsWithSemesters, it.error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
package io.github.wulkanowy.ui.modules.login.symbol
|
package io.github.wulkanowy.ui.modules.login.symbol
|
||||||
|
|
||||||
import io.github.wulkanowy.data.Status
|
import io.github.wulkanowy.data.Resource
|
||||||
|
import io.github.wulkanowy.data.onResourceNotLoading
|
||||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||||
|
import io.github.wulkanowy.data.resourceFlow
|
||||||
import io.github.wulkanowy.ui.base.BasePresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
import io.github.wulkanowy.ui.modules.login.LoginData
|
import io.github.wulkanowy.ui.modules.login.LoginData
|
||||||
import io.github.wulkanowy.ui.modules.login.LoginErrorHandler
|
import io.github.wulkanowy.ui.modules.login.LoginErrorHandler
|
||||||
import io.github.wulkanowy.utils.AnalyticsHelper
|
import io.github.wulkanowy.utils.AnalyticsHelper
|
||||||
import io.github.wulkanowy.utils.afterLoading
|
|
||||||
import io.github.wulkanowy.utils.flowWithResource
|
|
||||||
import io.github.wulkanowy.utils.ifNullOrBlank
|
import io.github.wulkanowy.utils.ifNullOrBlank
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
@ -45,7 +45,7 @@ class LoginSymbolPresenter @Inject constructor(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
flowWithResource {
|
resourceFlow {
|
||||||
studentRepository.getStudentsScrapper(
|
studentRepository.getStudentsScrapper(
|
||||||
email = loginData.login,
|
email = loginData.login,
|
||||||
password = loginData.password,
|
password = loginData.password,
|
||||||
@ -53,15 +53,15 @@ class LoginSymbolPresenter @Inject constructor(
|
|||||||
symbol = symbol,
|
symbol = symbol,
|
||||||
)
|
)
|
||||||
}.onEach {
|
}.onEach {
|
||||||
when (it.status) {
|
when (it) {
|
||||||
Status.LOADING -> view?.run {
|
is Resource.Loading -> view?.run {
|
||||||
Timber.i("Login with symbol started")
|
Timber.i("Login with symbol started")
|
||||||
hideSoftKeyboard()
|
hideSoftKeyboard()
|
||||||
showProgress(true)
|
showProgress(true)
|
||||||
showContent(false)
|
showContent(false)
|
||||||
}
|
}
|
||||||
Status.SUCCESS -> {
|
is Resource.Success -> {
|
||||||
when (it.data?.size) {
|
when (it.data.size) {
|
||||||
0 -> {
|
0 -> {
|
||||||
Timber.i("Login with symbol result: Empty student list")
|
Timber.i("Login with symbol result: Empty student list")
|
||||||
view?.run {
|
view?.run {
|
||||||
@ -77,13 +77,13 @@ class LoginSymbolPresenter @Inject constructor(
|
|||||||
analytics.logEvent(
|
analytics.logEvent(
|
||||||
"registration_symbol",
|
"registration_symbol",
|
||||||
"success" to true,
|
"success" to true,
|
||||||
"students" to it.data!!.size,
|
"students" to it.data.size,
|
||||||
"scrapperBaseUrl" to loginData.baseUrl,
|
"scrapperBaseUrl" to loginData.baseUrl,
|
||||||
"symbol" to symbol,
|
"symbol" to symbol,
|
||||||
"error" to "No error"
|
"error" to "No error"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Status.ERROR -> {
|
is Resource.Error -> {
|
||||||
Timber.i("Login with symbol result: An exception occurred")
|
Timber.i("Login with symbol result: An exception occurred")
|
||||||
analytics.logEvent(
|
analytics.logEvent(
|
||||||
"registration_symbol",
|
"registration_symbol",
|
||||||
@ -91,14 +91,14 @@ class LoginSymbolPresenter @Inject constructor(
|
|||||||
"students" to -1,
|
"students" to -1,
|
||||||
"scrapperBaseUrl" to loginData.baseUrl,
|
"scrapperBaseUrl" to loginData.baseUrl,
|
||||||
"symbol" to symbol,
|
"symbol" to symbol,
|
||||||
"error" to it.error!!.message.ifNullOrBlank { "No message" }
|
"error" to it.error.message.ifNullOrBlank { "No message" }
|
||||||
)
|
)
|
||||||
loginErrorHandler.dispatch(it.error)
|
loginErrorHandler.dispatch(it.error)
|
||||||
lastError = it.error
|
lastError = it.error
|
||||||
view?.showContact(true)
|
view?.showContact(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.afterLoading {
|
}.onResourceNotLoading {
|
||||||
view?.apply {
|
view?.apply {
|
||||||
showProgress(false)
|
showProgress(false)
|
||||||
showContent(true)
|
showContent(true)
|
||||||
|
@ -1,14 +1,11 @@
|
|||||||
package io.github.wulkanowy.ui.modules.luckynumber
|
package io.github.wulkanowy.ui.modules.luckynumber
|
||||||
|
|
||||||
import io.github.wulkanowy.data.Status
|
import io.github.wulkanowy.data.*
|
||||||
import io.github.wulkanowy.data.repositories.LuckyNumberRepository
|
import io.github.wulkanowy.data.repositories.LuckyNumberRepository
|
||||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
import io.github.wulkanowy.data.repositories.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.AnalyticsHelper
|
import io.github.wulkanowy.utils.AnalyticsHelper
|
||||||
import io.github.wulkanowy.utils.afterLoading
|
|
||||||
import io.github.wulkanowy.utils.flowWithResourceIn
|
|
||||||
import kotlinx.coroutines.flow.onEach
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@ -34,47 +31,45 @@ class LuckyNumberPresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun loadData(forceRefresh: Boolean = false) {
|
private fun loadData(forceRefresh: Boolean = false) {
|
||||||
flowWithResourceIn {
|
flatResourceFlow {
|
||||||
val student = studentRepository.getCurrentStudent()
|
val student = studentRepository.getCurrentStudent()
|
||||||
luckyNumberRepository.getLuckyNumber(student, forceRefresh)
|
luckyNumberRepository.getLuckyNumber(student, forceRefresh)
|
||||||
}.onEach {
|
}
|
||||||
when (it.status) {
|
.logResourceStatus("load lucky number")
|
||||||
Status.LOADING -> Timber.i("Loading lucky number started")
|
.onResourceData {
|
||||||
Status.SUCCESS -> {
|
if (it != null) {
|
||||||
if (it.data != null) {
|
view?.apply {
|
||||||
Timber.i("Loading lucky number result: Success")
|
updateData(it)
|
||||||
view?.apply {
|
showContent(true)
|
||||||
updateData(it.data)
|
showEmpty(false)
|
||||||
showContent(true)
|
showErrorView(false)
|
||||||
showEmpty(false)
|
}
|
||||||
showErrorView(false)
|
} else {
|
||||||
}
|
view?.run {
|
||||||
analytics.logEvent(
|
showContent(false)
|
||||||
"load_item",
|
showEmpty(true)
|
||||||
"type" to "lucky_number",
|
showErrorView(false)
|
||||||
"number" to it.data.luckyNumber
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
Timber.i("Loading lucky number result: No lucky number found")
|
|
||||||
view?.run {
|
|
||||||
showContent(false)
|
|
||||||
showEmpty(true)
|
|
||||||
showErrorView(false)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Status.ERROR -> {
|
}
|
||||||
Timber.i("Loading lucky number result: An exception occurred")
|
.onResourceSuccess {
|
||||||
errorHandler.dispatch(it.error!!)
|
if (it != null) {
|
||||||
|
analytics.logEvent(
|
||||||
|
"load_item",
|
||||||
|
"type" to "lucky_number",
|
||||||
|
"number" to it.luckyNumber
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.afterLoading {
|
.onResourceNotLoading {
|
||||||
view?.run {
|
view?.run {
|
||||||
hideRefresh()
|
hideRefresh()
|
||||||
showProgress(false)
|
showProgress(false)
|
||||||
enableSwipe(true)
|
enableSwipe(true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}.launch()
|
.onResourceError(errorHandler::dispatch)
|
||||||
|
.launch()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showErrorViewOnError(message: String, error: Throwable) {
|
private fun showErrorViewOnError(message: String, error: Throwable) {
|
||||||
|
@ -1,24 +1,12 @@
|
|||||||
package io.github.wulkanowy.ui.modules.luckynumber.history
|
package io.github.wulkanowy.ui.modules.luckynumber.history
|
||||||
|
|
||||||
import io.github.wulkanowy.data.Status
|
|
||||||
import io.github.wulkanowy.data.repositories.LuckyNumberRepository
|
import io.github.wulkanowy.data.repositories.LuckyNumberRepository
|
||||||
import io.github.wulkanowy.data.repositories.SemesterRepository
|
import io.github.wulkanowy.data.repositories.SemesterRepository
|
||||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
import io.github.wulkanowy.data.repositories.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.AnalyticsHelper
|
import io.github.wulkanowy.utils.*
|
||||||
import io.github.wulkanowy.utils.afterLoading
|
import kotlinx.coroutines.flow.*
|
||||||
import io.github.wulkanowy.utils.flowWithResource
|
|
||||||
import io.github.wulkanowy.utils.getLastSchoolDayIfHoliday
|
|
||||||
import io.github.wulkanowy.utils.isHolidays
|
|
||||||
import io.github.wulkanowy.utils.monday
|
|
||||||
import io.github.wulkanowy.utils.previousOrSameSchoolDay
|
|
||||||
import io.github.wulkanowy.utils.sunday
|
|
||||||
import io.github.wulkanowy.utils.toFormattedString
|
|
||||||
import kotlinx.coroutines.flow.catch
|
|
||||||
import kotlinx.coroutines.flow.first
|
|
||||||
import kotlinx.coroutines.flow.flow
|
|
||||||
import kotlinx.coroutines.flow.onEach
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.time.LocalDate
|
import java.time.LocalDate
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@ -52,55 +40,51 @@ class LuckyNumberHistoryPresenter @Inject constructor(
|
|||||||
flow {
|
flow {
|
||||||
val student = studentRepository.getCurrentStudent()
|
val student = studentRepository.getCurrentStudent()
|
||||||
emit(semesterRepository.getCurrentSemester(student))
|
emit(semesterRepository.getCurrentSemester(student))
|
||||||
}.catch {
|
}
|
||||||
Timber.i("Loading semester result: An exception occurred")
|
.catch { Timber.i("Loading semester result: An exception occurred") }
|
||||||
}.onEach {
|
.onEach {
|
||||||
currentDate = currentDate.getLastSchoolDayIfHoliday(it.schoolYear)
|
currentDate = currentDate.getLastSchoolDayIfHoliday(it.schoolYear)
|
||||||
reloadNavigation()
|
reloadNavigation()
|
||||||
}.launch("holidays")
|
}
|
||||||
|
.launch("holidays")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadData() {
|
private fun loadData() {
|
||||||
flowWithResource {
|
flow {
|
||||||
val student = studentRepository.getCurrentStudent()
|
val student = studentRepository.getCurrentStudent()
|
||||||
luckyNumberRepository.getLuckyNumberHistory(student, currentDate.monday, currentDate.sunday)
|
emitAll(
|
||||||
}.onEach {
|
luckyNumberRepository.getLuckyNumberHistory(
|
||||||
when (it.status) {
|
student = student,
|
||||||
Status.LOADING -> Timber.i("Loading lucky number history started")
|
start = currentDate.monday,
|
||||||
Status.SUCCESS -> {
|
end = currentDate.sunday
|
||||||
if (!it.data?.first().isNullOrEmpty()) {
|
)
|
||||||
Timber.i("Loading lucky number result: Success")
|
)
|
||||||
view?.apply {
|
}
|
||||||
updateData(it.data!!.first())
|
.onEach {
|
||||||
showContent(true)
|
if (!it.isNullOrEmpty()) {
|
||||||
showEmpty(false)
|
view?.apply {
|
||||||
showErrorView(false)
|
updateData(it)
|
||||||
showProgress(false)
|
showContent(true)
|
||||||
}
|
showEmpty(false)
|
||||||
analytics.logEvent(
|
showErrorView(false)
|
||||||
"load_items",
|
showProgress(false)
|
||||||
"type" to "lucky_number_history",
|
}
|
||||||
"numbers" to it.data
|
} else {
|
||||||
)
|
view?.run {
|
||||||
} else {
|
showContent(false)
|
||||||
Timber.i("Loading lucky number history result: No lucky numbers found")
|
showEmpty(true)
|
||||||
view?.run {
|
showErrorView(false)
|
||||||
showContent(false)
|
showProgress(false)
|
||||||
showEmpty(true)
|
|
||||||
showErrorView(false)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Status.ERROR -> {
|
|
||||||
Timber.i("Loading lucky number history result: An exception occurred")
|
analytics.logEvent(
|
||||||
errorHandler.dispatch(it.error!!)
|
"load_items",
|
||||||
}
|
"type" to "lucky_number_history",
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}.afterLoading {
|
.catch { errorHandler.dispatch(it) }
|
||||||
view?.run {
|
.launchIn(presenterScope)
|
||||||
showProgress(false)
|
|
||||||
}
|
|
||||||
}.launch()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showErrorViewOnError(message: String, error: Throwable) {
|
private fun showErrorViewOnError(message: String, error: Throwable) {
|
||||||
@ -143,8 +127,10 @@ class LuckyNumberHistoryPresenter @Inject constructor(
|
|||||||
view?.apply {
|
view?.apply {
|
||||||
showPreButton(!currentDate.minusDays(7).isHolidays)
|
showPreButton(!currentDate.minusDays(7).isHolidays)
|
||||||
showNextButton(!currentDate.plusDays(7).isHolidays)
|
showNextButton(!currentDate.plusDays(7).isHolidays)
|
||||||
updateNavigationWeek("${currentDate.monday.toFormattedString("dd.MM")} - " +
|
updateNavigationWeek(
|
||||||
currentDate.sunday.toFormattedString("dd.MM"))
|
"${currentDate.monday.toFormattedString("dd.MM")} - " +
|
||||||
|
currentDate.sunday.toFormattedString("dd.MM")
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
package io.github.wulkanowy.ui.modules.luckynumberwidget
|
package io.github.wulkanowy.ui.modules.luckynumberwidget
|
||||||
|
|
||||||
import io.github.wulkanowy.data.Status
|
import io.github.wulkanowy.data.Resource
|
||||||
import io.github.wulkanowy.data.db.SharedPrefProvider
|
import io.github.wulkanowy.data.db.SharedPrefProvider
|
||||||
import io.github.wulkanowy.data.db.entities.Student
|
import io.github.wulkanowy.data.db.entities.Student
|
||||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||||
|
import io.github.wulkanowy.data.resourceFlow
|
||||||
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.ui.modules.luckynumberwidget.LuckyNumberWidgetProvider.Companion.getStudentWidgetKey
|
import io.github.wulkanowy.ui.modules.luckynumberwidget.LuckyNumberWidgetProvider.Companion.getStudentWidgetKey
|
||||||
import io.github.wulkanowy.ui.modules.luckynumberwidget.LuckyNumberWidgetProvider.Companion.getThemeWidgetKey
|
import io.github.wulkanowy.ui.modules.luckynumberwidget.LuckyNumberWidgetProvider.Companion.getThemeWidgetKey
|
||||||
import io.github.wulkanowy.utils.flowWithResource
|
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@ -47,16 +47,15 @@ class LuckyNumberWidgetConfigurePresenter @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun loadData() {
|
private fun loadData() {
|
||||||
flowWithResource { studentRepository.getSavedStudents(false) }.onEach {
|
resourceFlow { studentRepository.getSavedStudents(false) }.onEach {
|
||||||
when (it.status) {
|
when (it) {
|
||||||
Status.LOADING -> Timber.d("Lucky number widget configure students data load")
|
is Resource.Loading -> Timber.d("Lucky number widget configure students data load")
|
||||||
Status.SUCCESS -> {
|
is Resource.Success -> {
|
||||||
val selectedStudentId = appWidgetId?.let { id ->
|
val selectedStudentId = appWidgetId?.let { id ->
|
||||||
sharedPref.getLong(getStudentWidgetKey(id), 0)
|
sharedPref.getLong(getStudentWidgetKey(id), 0)
|
||||||
} ?: -1
|
} ?: -1
|
||||||
|
|
||||||
when {
|
when {
|
||||||
it.data!!.isEmpty() -> view?.openLoginView()
|
it.data.isEmpty() -> view?.openLoginView()
|
||||||
it.data.size == 1 -> {
|
it.data.size == 1 -> {
|
||||||
selectedStudent = it.data.single().student
|
selectedStudent = it.data.single().student
|
||||||
view?.showThemeDialog()
|
view?.showThemeDialog()
|
||||||
@ -64,7 +63,7 @@ class LuckyNumberWidgetConfigurePresenter @Inject constructor(
|
|||||||
else -> view?.updateData(it.data, selectedStudentId)
|
else -> view?.updateData(it.data, selectedStudentId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Status.ERROR -> errorHandler.dispatch(it.error!!)
|
is Resource.Error -> errorHandler.dispatch(it.error)
|
||||||
}
|
}
|
||||||
}.launch()
|
}.launch()
|
||||||
}
|
}
|
||||||
|
@ -13,14 +13,17 @@ import android.view.View.VISIBLE
|
|||||||
import android.widget.RemoteViews
|
import android.widget.RemoteViews
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import io.github.wulkanowy.R
|
import io.github.wulkanowy.R
|
||||||
|
import io.github.wulkanowy.data.Resource
|
||||||
|
import io.github.wulkanowy.data.dataOrNull
|
||||||
import io.github.wulkanowy.data.db.SharedPrefProvider
|
import io.github.wulkanowy.data.db.SharedPrefProvider
|
||||||
|
import io.github.wulkanowy.data.db.entities.LuckyNumber
|
||||||
import io.github.wulkanowy.data.exceptions.NoCurrentStudentException
|
import io.github.wulkanowy.data.exceptions.NoCurrentStudentException
|
||||||
import io.github.wulkanowy.data.repositories.LuckyNumberRepository
|
import io.github.wulkanowy.data.repositories.LuckyNumberRepository
|
||||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||||
|
import io.github.wulkanowy.data.toFirstResult
|
||||||
import io.github.wulkanowy.ui.modules.Destination
|
import io.github.wulkanowy.ui.modules.Destination
|
||||||
import io.github.wulkanowy.ui.modules.splash.SplashActivity
|
import io.github.wulkanowy.ui.modules.splash.SplashActivity
|
||||||
import io.github.wulkanowy.utils.PendingIntentCompat
|
import io.github.wulkanowy.utils.PendingIntentCompat
|
||||||
import io.github.wulkanowy.utils.toFirstResult
|
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@ -66,12 +69,16 @@ class LuckyNumberWidgetProvider : AppWidgetProvider() {
|
|||||||
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntentCompat.FLAG_IMMUTABLE
|
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntentCompat.FLAG_IMMUTABLE
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (luckyNumber is Resource.Error) {
|
||||||
|
Timber.e("Error loading lucky number for widget", luckyNumber.error)
|
||||||
|
}
|
||||||
|
|
||||||
val remoteView =
|
val remoteView =
|
||||||
RemoteViews(context.packageName, getCorrectLayoutId(appWidgetId, context))
|
RemoteViews(context.packageName, getCorrectLayoutId(appWidgetId, context))
|
||||||
.apply {
|
.apply {
|
||||||
setTextViewText(
|
setTextViewText(
|
||||||
R.id.luckyNumberWidgetNumber,
|
R.id.luckyNumberWidgetNumber,
|
||||||
luckyNumber?.luckyNumber?.toString() ?: "#"
|
luckyNumber.dataOrNull?.toString() ?: "#"
|
||||||
)
|
)
|
||||||
setOnClickPendingIntent(R.id.luckyNumberWidgetContainer, appIntent)
|
setOnClickPendingIntent(R.id.luckyNumberWidgetContainer, appIntent)
|
||||||
}
|
}
|
||||||
@ -167,14 +174,17 @@ class LuckyNumberWidgetProvider : AppWidgetProvider() {
|
|||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
|
||||||
currentStudent?.let {
|
if (currentStudent != null) {
|
||||||
luckyNumberRepository.getLuckyNumber(it, false).toFirstResult().data
|
luckyNumberRepository.getLuckyNumber(currentStudent, forceRefresh = false)
|
||||||
|
.toFirstResult()
|
||||||
|
} else {
|
||||||
|
Resource.Success<LuckyNumber?>(null)
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
if (e.cause !is NoCurrentStudentException) {
|
if (e.cause !is NoCurrentStudentException) {
|
||||||
Timber.e(e, "An error has occurred in lucky number provider")
|
Timber.e(e, "An error has occurred in lucky number provider")
|
||||||
}
|
}
|
||||||
null
|
Resource.Error(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,16 +23,7 @@ import io.github.wulkanowy.databinding.ActivityMainBinding
|
|||||||
import io.github.wulkanowy.ui.base.BaseActivity
|
import io.github.wulkanowy.ui.base.BaseActivity
|
||||||
import io.github.wulkanowy.ui.modules.Destination
|
import io.github.wulkanowy.ui.modules.Destination
|
||||||
import io.github.wulkanowy.ui.modules.account.accountquick.AccountQuickDialog
|
import io.github.wulkanowy.ui.modules.account.accountquick.AccountQuickDialog
|
||||||
import io.github.wulkanowy.utils.AnalyticsHelper
|
import io.github.wulkanowy.utils.*
|
||||||
import io.github.wulkanowy.utils.AppInfo
|
|
||||||
import io.github.wulkanowy.utils.InAppReviewHelper
|
|
||||||
import io.github.wulkanowy.utils.UpdateHelper
|
|
||||||
import io.github.wulkanowy.utils.createNameInitialsDrawable
|
|
||||||
import io.github.wulkanowy.utils.dpToPx
|
|
||||||
import io.github.wulkanowy.utils.getThemeAttrColor
|
|
||||||
import io.github.wulkanowy.utils.nickOrName
|
|
||||||
import io.github.wulkanowy.utils.safelyPopFragments
|
|
||||||
import io.github.wulkanowy.utils.setOnViewChangeListener
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@ -169,8 +160,12 @@ class MainActivity : BaseActivity<MainPresenter, ActivityMainBinding>(), MainVie
|
|||||||
.setIcon(R.drawable.ic_main_more)
|
.setIcon(R.drawable.ic_main_more)
|
||||||
}
|
}
|
||||||
selectedItemId = startMenuIndex
|
selectedItemId = startMenuIndex
|
||||||
setOnItemSelectedListener { presenter.onTabSelected(it.itemId, false) }
|
setOnItemSelectedListener {
|
||||||
setOnItemReselectedListener { presenter.onTabSelected(it.itemId, true) }
|
this@MainActivity.presenter.onTabSelected(it.itemId, false)
|
||||||
|
}
|
||||||
|
setOnItemReselectedListener {
|
||||||
|
this@MainActivity.presenter.onTabSelected(it.itemId, true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,8 +173,10 @@ class MainActivity : BaseActivity<MainPresenter, ActivityMainBinding>(), MainVie
|
|||||||
caller: PreferenceFragmentCompat,
|
caller: PreferenceFragmentCompat,
|
||||||
pref: Preference
|
pref: Preference
|
||||||
): Boolean {
|
): Boolean {
|
||||||
val fragment =
|
val fragment = supportFragmentManager.fragmentFactory.instantiate(
|
||||||
supportFragmentManager.fragmentFactory.instantiate(classLoader, pref.fragment)
|
classLoader,
|
||||||
|
pref.fragment.toString()
|
||||||
|
)
|
||||||
pushView(fragment)
|
pushView(fragment)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
package io.github.wulkanowy.ui.modules.main
|
package io.github.wulkanowy.ui.modules.main
|
||||||
|
|
||||||
import io.github.wulkanowy.data.Status
|
|
||||||
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
|
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
|
||||||
|
import io.github.wulkanowy.data.logResourceStatus
|
||||||
|
import io.github.wulkanowy.data.onResourceError
|
||||||
|
import io.github.wulkanowy.data.onResourceSuccess
|
||||||
import io.github.wulkanowy.data.repositories.PreferencesRepository
|
import io.github.wulkanowy.data.repositories.PreferencesRepository
|
||||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||||
|
import io.github.wulkanowy.data.resourceFlow
|
||||||
import io.github.wulkanowy.services.sync.SyncManager
|
import io.github.wulkanowy.services.sync.SyncManager
|
||||||
import io.github.wulkanowy.ui.base.BasePresenter
|
import io.github.wulkanowy.ui.base.BasePresenter
|
||||||
import io.github.wulkanowy.ui.base.BaseView
|
import io.github.wulkanowy.ui.base.BaseView
|
||||||
@ -16,8 +19,6 @@ import io.github.wulkanowy.ui.modules.message.MessageView
|
|||||||
import io.github.wulkanowy.ui.modules.schoolandteachers.SchoolAndTeachersView
|
import io.github.wulkanowy.ui.modules.schoolandteachers.SchoolAndTeachersView
|
||||||
import io.github.wulkanowy.ui.modules.studentinfo.StudentInfoView
|
import io.github.wulkanowy.ui.modules.studentinfo.StudentInfoView
|
||||||
import io.github.wulkanowy.utils.AnalyticsHelper
|
import io.github.wulkanowy.utils.AnalyticsHelper
|
||||||
import io.github.wulkanowy.utils.flowWithResource
|
|
||||||
import kotlinx.coroutines.flow.onEach
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
@ -75,20 +76,14 @@ class MainPresenter @Inject constructor(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
flowWithResource { studentRepository.getSavedStudents(false) }
|
resourceFlow { studentRepository.getSavedStudents(false) }
|
||||||
.onEach { resource ->
|
.logResourceStatus("load student avatar")
|
||||||
when (resource.status) {
|
.onResourceSuccess {
|
||||||
Status.LOADING -> Timber.i("Loading student avatar data started")
|
studentsWitSemesters = it
|
||||||
Status.SUCCESS -> {
|
showCurrentStudentAvatar()
|
||||||
studentsWitSemesters = resource.data
|
}
|
||||||
showCurrentStudentAvatar()
|
.onResourceError(errorHandler::dispatch)
|
||||||
}
|
.launch("avatar")
|
||||||
Status.ERROR -> {
|
|
||||||
Timber.i("Loading student avatar result: An exception occurred")
|
|
||||||
errorHandler.dispatch(resource.error!!)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}.launch("avatar")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onViewChange(destinationView: BaseView) {
|
fun onViewChange(destinationView: BaseView) {
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user