forked from github/wulkanowy-mirror
Resource refactor (#1589)
This commit is contained in:
parent
042b66ca5c
commit
20dde6e896
@ -1,23 +1,173 @@
|
||||
package io.github.wulkanowy.data
|
||||
|
||||
data class Resource<T>(val status: Status, val data: T?, val error: Throwable?) {
|
||||
companion object {
|
||||
fun <T> success(data: T?): Resource<T> {
|
||||
return Resource(Status.SUCCESS, data, null)
|
||||
}
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
import timber.log.Timber
|
||||
|
||||
fun <T> error(error: Throwable?, data: T? = null): Resource<T> {
|
||||
return Resource(Status.ERROR, data, error)
|
||||
}
|
||||
sealed class Resource<T> {
|
||||
|
||||
fun <T> loading(data: T? = null): Resource<T> {
|
||||
return Resource(Status.LOADING, data, null)
|
||||
}
|
||||
open class Loading<T> : Resource<T>()
|
||||
|
||||
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 {
|
||||
LOADING,
|
||||
SUCCESS,
|
||||
ERROR
|
||||
fun <T> Flow<Resource<T>>.onResourceLoading(block: suspend () -> Unit) = onEach {
|
||||
if (it is Resource.Loading) {
|
||||
block()
|
||||
}
|
||||
}
|
||||
|
||||
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)) }
|
||||
})
|
||||
}
|
||||
|
@ -33,6 +33,10 @@ abstract class StudentDao {
|
||||
@Query("SELECT * FROM Students")
|
||||
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")
|
||||
abstract suspend fun updateCurrent(id: Long)
|
||||
|
||||
|
@ -3,8 +3,8 @@ package io.github.wulkanowy.data.repositories
|
||||
import io.github.wulkanowy.data.api.AdminMessageService
|
||||
import io.github.wulkanowy.data.db.dao.AdminMessageDao
|
||||
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.networkBoundResource
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
@ -19,6 +19,7 @@ class AdminMessageRepository @Inject constructor(
|
||||
|
||||
suspend fun getAdminMessages(student: Student) = networkBoundResource(
|
||||
mutex = saveFetchResultMutex,
|
||||
isResultEmpty = { it == null },
|
||||
query = { adminMessageDao.loadAll() },
|
||||
fetch = { adminMessageService.getAdminMessages() },
|
||||
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.Student
|
||||
import io.github.wulkanowy.data.mappers.mapToEntities
|
||||
import io.github.wulkanowy.data.networkBoundResource
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
import io.github.wulkanowy.sdk.pojo.Absent
|
||||
import io.github.wulkanowy.utils.*
|
||||
@ -36,6 +37,7 @@ class AttendanceRepository @Inject constructor(
|
||||
notify: Boolean = false,
|
||||
) = networkBoundResource(
|
||||
mutex = saveFetchResultMutex,
|
||||
isResultEmpty = { it.isEmpty() },
|
||||
shouldFetch = {
|
||||
val isExpired = refreshHelper.shouldBeRefreshed(
|
||||
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.Student
|
||||
import io.github.wulkanowy.data.mappers.mapToEntities
|
||||
import io.github.wulkanowy.data.networkBoundResource
|
||||
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 javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
@ -28,6 +32,7 @@ class AttendanceSummaryRepository @Inject constructor(
|
||||
forceRefresh: Boolean,
|
||||
) = networkBoundResource(
|
||||
mutex = saveFetchResultMutex,
|
||||
isResultEmpty = { it.isEmpty() },
|
||||
shouldFetch = {
|
||||
val isExpired = refreshHelper.shouldBeRefreshed(getRefreshKey(cacheKey, semester))
|
||||
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.Student
|
||||
import io.github.wulkanowy.data.mappers.mapToEntities
|
||||
import io.github.wulkanowy.data.networkBoundResource
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
import io.github.wulkanowy.utils.*
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
@ -30,6 +31,7 @@ class CompletedLessonsRepository @Inject constructor(
|
||||
forceRefresh: Boolean,
|
||||
) = networkBoundResource(
|
||||
mutex = saveFetchResultMutex,
|
||||
isResultEmpty = { it.isEmpty() },
|
||||
shouldFetch = {
|
||||
val isExpired = refreshHelper.shouldBeRefreshed(
|
||||
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.Student
|
||||
import io.github.wulkanowy.data.mappers.mapToEntities
|
||||
import io.github.wulkanowy.data.networkBoundResource
|
||||
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.sync.Mutex
|
||||
import java.time.Instant
|
||||
@ -32,6 +36,7 @@ class ConferenceRepository @Inject constructor(
|
||||
startDate: Instant = Instant.EPOCH,
|
||||
) = networkBoundResource(
|
||||
mutex = saveFetchResultMutex,
|
||||
isResultEmpty = { it.isEmpty() },
|
||||
shouldFetch = {
|
||||
val isExpired = refreshHelper.shouldBeRefreshed(getRefreshKey(cacheKey, semester))
|
||||
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.Student
|
||||
import io.github.wulkanowy.data.mappers.mapToEntities
|
||||
import io.github.wulkanowy.data.networkBoundResource
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
import io.github.wulkanowy.utils.*
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
@ -33,6 +34,7 @@ class ExamRepository @Inject constructor(
|
||||
notify: Boolean = false,
|
||||
) = networkBoundResource(
|
||||
mutex = saveFetchResultMutex,
|
||||
isResultEmpty = { it.isEmpty() },
|
||||
shouldFetch = {
|
||||
val isExpired = refreshHelper.shouldBeRefreshed(
|
||||
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.Student
|
||||
import io.github.wulkanowy.data.mappers.mapToEntities
|
||||
import io.github.wulkanowy.data.networkBoundResource
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
import io.github.wulkanowy.utils.*
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
@ -36,6 +37,10 @@ class GradeRepository @Inject constructor(
|
||||
notify: Boolean = false,
|
||||
) = networkBoundResource(
|
||||
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) ->
|
||||
val isExpired = refreshHelper.shouldBeRefreshed(getRefreshKey(cacheKey, semester))
|
||||
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.mapSemesterToStatisticItems
|
||||
import io.github.wulkanowy.data.mappers.mapToEntities
|
||||
import io.github.wulkanowy.data.networkBoundResource
|
||||
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 java.util.*
|
||||
import javax.inject.Inject
|
||||
@ -42,6 +46,7 @@ class GradeStatisticsRepository @Inject constructor(
|
||||
forceRefresh: Boolean,
|
||||
) = networkBoundResource(
|
||||
mutex = partialMutex,
|
||||
isResultEmpty = { it.isEmpty() },
|
||||
shouldFetch = {
|
||||
val isExpired = refreshHelper.shouldBeRefreshed(
|
||||
key = getRefreshKey(partialCacheKey, semester)
|
||||
@ -86,6 +91,7 @@ class GradeStatisticsRepository @Inject constructor(
|
||||
forceRefresh: Boolean,
|
||||
) = networkBoundResource(
|
||||
mutex = semesterMutex,
|
||||
isResultEmpty = { it.isEmpty() },
|
||||
shouldFetch = {
|
||||
val isExpired = refreshHelper.shouldBeRefreshed(
|
||||
key = getRefreshKey(semesterCacheKey, semester)
|
||||
@ -143,6 +149,7 @@ class GradeStatisticsRepository @Inject constructor(
|
||||
forceRefresh: Boolean,
|
||||
) = networkBoundResource(
|
||||
mutex = pointsMutex,
|
||||
isResultEmpty = { it.isEmpty() },
|
||||
shouldFetch = {
|
||||
val isExpired = refreshHelper.shouldBeRefreshed(getRefreshKey(pointsCacheKey, semester))
|
||||
it.isEmpty() || forceRefresh || isExpired
|
||||
|
@ -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.Student
|
||||
import io.github.wulkanowy.data.mappers.mapToEntities
|
||||
import io.github.wulkanowy.data.networkBoundResource
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
import io.github.wulkanowy.utils.*
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
@ -32,6 +33,7 @@ class HomeworkRepository @Inject constructor(
|
||||
notify: Boolean = false,
|
||||
) = networkBoundResource(
|
||||
mutex = saveFetchResultMutex,
|
||||
isResultEmpty = { it.isEmpty() },
|
||||
shouldFetch = {
|
||||
val isExpired = refreshHelper.shouldBeRefreshed(
|
||||
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.Student
|
||||
import io.github.wulkanowy.data.mappers.mapToEntity
|
||||
import io.github.wulkanowy.data.networkBoundResource
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
import io.github.wulkanowy.utils.init
|
||||
import io.github.wulkanowy.utils.networkBoundResource
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
@ -29,6 +29,7 @@ class LuckyNumberRepository @Inject constructor(
|
||||
notify: Boolean = false,
|
||||
) = networkBoundResource(
|
||||
mutex = saveFetchResultMutex,
|
||||
isResultEmpty = { it == null },
|
||||
shouldFetch = { it == null || forceRefresh },
|
||||
query = { luckyNumberDb.load(student.studentId, now()) },
|
||||
fetch = {
|
||||
|
@ -7,15 +7,12 @@ import io.github.wulkanowy.data.Resource
|
||||
import io.github.wulkanowy.data.db.SharedPrefProvider
|
||||
import io.github.wulkanowy.data.db.dao.MessageAttachmentDao
|
||||
import io.github.wulkanowy.data.db.dao.MessagesDao
|
||||
import io.github.wulkanowy.data.db.entities.Message
|
||||
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.db.entities.*
|
||||
import io.github.wulkanowy.data.enums.MessageFolder
|
||||
import io.github.wulkanowy.data.enums.MessageFolder.RECEIVED
|
||||
import io.github.wulkanowy.data.mappers.mapFromEntities
|
||||
import io.github.wulkanowy.data.mappers.mapToEntities
|
||||
import io.github.wulkanowy.data.networkBoundResource
|
||||
import io.github.wulkanowy.data.pojos.MessageDraft
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
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.getRefreshKey
|
||||
import io.github.wulkanowy.utils.init
|
||||
import io.github.wulkanowy.utils.networkBoundResource
|
||||
import io.github.wulkanowy.utils.uniqueSubtract
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
@ -59,6 +55,7 @@ class MessageRepository @Inject constructor(
|
||||
notify: Boolean = false,
|
||||
): Flow<Resource<List<Message>>> = networkBoundResource(
|
||||
mutex = saveFetchResultMutex,
|
||||
isResultEmpty = { it.isEmpty() },
|
||||
shouldFetch = {
|
||||
val isExpired = refreshHelper.shouldBeRefreshed(
|
||||
key = getRefreshKey(cacheKey, student, folder)
|
||||
@ -106,8 +103,9 @@ class MessageRepository @Inject constructor(
|
||||
message: Message,
|
||||
markAsRead: Boolean = false,
|
||||
): Flow<Resource<MessageWithAttachment?>> = networkBoundResource(
|
||||
isResultEmpty = { it == null },
|
||||
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()}")
|
||||
it.message.unread || it.message.content.isEmpty()
|
||||
},
|
||||
@ -123,7 +121,7 @@ class MessageRepository @Inject constructor(
|
||||
}
|
||||
},
|
||||
saveFetchResult = { old, (downloadedMessage, attachments) ->
|
||||
checkNotNull(old, { "Fetched message no longer exist!" })
|
||||
checkNotNull(old) { "Fetched message no longer exist!" }
|
||||
messagesDb.updateAll(listOf(old.message.apply {
|
||||
id = old.message.id
|
||||
unread = !markAsRead
|
||||
|
@ -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.mappers.mapToEntities
|
||||
import io.github.wulkanowy.data.mappers.mapToMobileDeviceToken
|
||||
import io.github.wulkanowy.data.networkBoundResource
|
||||
import io.github.wulkanowy.data.pojos.MobileDeviceToken
|
||||
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 javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
@ -30,6 +34,7 @@ class MobileDeviceRepository @Inject constructor(
|
||||
forceRefresh: Boolean,
|
||||
) = networkBoundResource(
|
||||
mutex = saveFetchResultMutex,
|
||||
isResultEmpty = { it.isEmpty() },
|
||||
shouldFetch = {
|
||||
val isExpired = refreshHelper.shouldBeRefreshed(getRefreshKey(cacheKey, student))
|
||||
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.Student
|
||||
import io.github.wulkanowy.data.mappers.mapToEntities
|
||||
import io.github.wulkanowy.data.networkBoundResource
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
import io.github.wulkanowy.utils.*
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
@ -30,6 +31,7 @@ class NoteRepository @Inject constructor(
|
||||
notify: Boolean = false,
|
||||
) = networkBoundResource(
|
||||
mutex = saveFetchResultMutex,
|
||||
isResultEmpty = { it.isEmpty() },
|
||||
shouldFetch = {
|
||||
val isExpired = refreshHelper.shouldBeRefreshed(
|
||||
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.Student
|
||||
import io.github.wulkanowy.data.mappers.mapToEntities
|
||||
import io.github.wulkanowy.data.networkBoundResource
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
import io.github.wulkanowy.utils.AutoRefreshHelper
|
||||
import io.github.wulkanowy.utils.getRefreshKey
|
||||
import io.github.wulkanowy.utils.init
|
||||
import io.github.wulkanowy.utils.networkBoundResource
|
||||
import io.github.wulkanowy.utils.uniqueSubtract
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
@ -31,6 +31,7 @@ class SchoolAnnouncementRepository @Inject constructor(
|
||||
forceRefresh: Boolean, notify: Boolean = false
|
||||
) = networkBoundResource(
|
||||
mutex = saveFetchResultMutex,
|
||||
isResultEmpty = { it.isEmpty() },
|
||||
shouldFetch = {
|
||||
val isExpired = refreshHelper.shouldBeRefreshed(getRefreshKey(cacheKey, student))
|
||||
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.Student
|
||||
import io.github.wulkanowy.data.mappers.mapToEntity
|
||||
import io.github.wulkanowy.data.networkBoundResource
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
import io.github.wulkanowy.utils.AutoRefreshHelper
|
||||
import io.github.wulkanowy.utils.getRefreshKey
|
||||
import io.github.wulkanowy.utils.init
|
||||
import io.github.wulkanowy.utils.networkBoundResource
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
@ -30,6 +30,7 @@ class SchoolRepository @Inject constructor(
|
||||
forceRefresh: Boolean,
|
||||
) = networkBoundResource(
|
||||
mutex = saveFetchResultMutex,
|
||||
isResultEmpty = { it == null },
|
||||
shouldFetch = {
|
||||
val isExpired = refreshHelper.shouldBeRefreshed(
|
||||
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.Student
|
||||
import io.github.wulkanowy.data.mappers.mapToEntity
|
||||
import io.github.wulkanowy.data.networkBoundResource
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
import io.github.wulkanowy.utils.init
|
||||
import io.github.wulkanowy.utils.networkBoundResource
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
@ -25,6 +25,7 @@ class StudentInfoRepository @Inject constructor(
|
||||
forceRefresh: Boolean,
|
||||
) = networkBoundResource(
|
||||
mutex = saveFetchResultMutex,
|
||||
isResultEmpty = { it == null },
|
||||
shouldFetch = { it == null || forceRefresh },
|
||||
query = { studentInfoDao.loadStudentInfo(student.studentId) },
|
||||
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 {
|
||||
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.Student
|
||||
import io.github.wulkanowy.data.mappers.mapToEntities
|
||||
import io.github.wulkanowy.data.networkBoundResource
|
||||
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 javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
@ -27,6 +31,7 @@ class SubjectRepository @Inject constructor(
|
||||
forceRefresh: Boolean = false,
|
||||
) = networkBoundResource(
|
||||
mutex = saveFetchResultMutex,
|
||||
isResultEmpty = { it.isEmpty() },
|
||||
shouldFetch = {
|
||||
val isExpired = refreshHelper.shouldBeRefreshed(getRefreshKey(cacheKey, semester))
|
||||
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.Student
|
||||
import io.github.wulkanowy.data.mappers.mapToEntities
|
||||
import io.github.wulkanowy.data.networkBoundResource
|
||||
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 javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
@ -27,6 +31,7 @@ class TeacherRepository @Inject constructor(
|
||||
forceRefresh: Boolean,
|
||||
) = networkBoundResource(
|
||||
mutex = saveFetchResultMutex,
|
||||
isResultEmpty = { it.isEmpty() },
|
||||
shouldFetch = {
|
||||
val isExpired = refreshHelper.shouldBeRefreshed(getRefreshKey(cacheKey, semester))
|
||||
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.entities.*
|
||||
import io.github.wulkanowy.data.mappers.mapToEntities
|
||||
import io.github.wulkanowy.data.networkBoundResource
|
||||
import io.github.wulkanowy.data.pojos.TimetableFull
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
import io.github.wulkanowy.services.alarm.TimetableNotificationSchedulerHelper
|
||||
@ -30,6 +31,10 @@ class TimetableRepository @Inject constructor(
|
||||
|
||||
private val cacheKey = "timetable"
|
||||
|
||||
enum class TimetableType {
|
||||
NORMAL, ADDITIONAL
|
||||
}
|
||||
|
||||
fun getTimetable(
|
||||
student: Student,
|
||||
semester: Semester,
|
||||
@ -37,9 +42,16 @@ class TimetableRepository @Inject constructor(
|
||||
end: LocalDate,
|
||||
forceRefresh: Boolean,
|
||||
refreshAdditional: Boolean = false,
|
||||
notify: Boolean = false
|
||||
notify: Boolean = false,
|
||||
timetableType: TimetableType = TimetableType.NORMAL
|
||||
) = networkBoundResource(
|
||||
mutex = saveFetchResultMutex,
|
||||
isResultEmpty = {
|
||||
when (timetableType) {
|
||||
TimetableType.NORMAL -> it.lessons.isEmpty()
|
||||
TimetableType.ADDITIONAL -> it.additional.isEmpty()
|
||||
}
|
||||
},
|
||||
shouldFetch = { (timetable, additional, headers) ->
|
||||
val refreshKey = getRefreshKey(cacheKey, semester, start, end)
|
||||
val isExpired = refreshHelper.shouldBeRefreshed(refreshKey)
|
||||
|
@ -10,19 +10,18 @@ import androidx.core.app.NotificationCompat
|
||||
import androidx.core.app.NotificationManagerCompat
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
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.StudentRepository
|
||||
import io.github.wulkanowy.data.resourceFlow
|
||||
import io.github.wulkanowy.services.sync.channels.UpcomingLessonsChannel.Companion.CHANNEL_ID
|
||||
import io.github.wulkanowy.ui.modules.Destination
|
||||
import io.github.wulkanowy.ui.modules.splash.SplashActivity
|
||||
import io.github.wulkanowy.utils.PendingIntentCompat
|
||||
import io.github.wulkanowy.utils.flowWithResource
|
||||
import io.github.wulkanowy.utils.getCompatColor
|
||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
@ -59,7 +58,7 @@ class TimetableNotificationReceiver : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
Timber.d("Receiving intent... ${intent.toUri(0)}")
|
||||
|
||||
flowWithResource {
|
||||
resourceFlow {
|
||||
val showStudentName = !studentRepository.isOneUniqueStudent()
|
||||
val student = studentRepository.getCurrentStudent(false)
|
||||
val studentId = intent.getIntExtra(STUDENT_ID, 0)
|
||||
@ -69,9 +68,9 @@ class TimetableNotificationReceiver : BroadcastReceiver() {
|
||||
} else {
|
||||
Timber.d("Notification studentId($studentId) differs from current(${student.studentId})")
|
||||
}
|
||||
}.onEach {
|
||||
if (it.status == Status.ERROR) Timber.e(it.error!!)
|
||||
}.launchIn(GlobalScope)
|
||||
}
|
||||
.onResourceError { Timber.e(it) }
|
||||
.launchIn(GlobalScope)
|
||||
}
|
||||
|
||||
private fun prepareNotification(context: Context, intent: Intent, showStudentName: Boolean) {
|
||||
|
@ -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.Student
|
||||
import io.github.wulkanowy.data.repositories.AttendanceSummaryRepository
|
||||
import io.github.wulkanowy.utils.waitForResult
|
||||
import io.github.wulkanowy.data.waitForResult
|
||||
import javax.inject.Inject
|
||||
|
||||
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.Student
|
||||
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.utils.previousOrSameSchoolDay
|
||||
import io.github.wulkanowy.utils.waitForResult
|
||||
import kotlinx.coroutines.flow.first
|
||||
import java.time.LocalDate.now
|
||||
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.Student
|
||||
import io.github.wulkanowy.data.repositories.CompletedLessonsRepository
|
||||
import io.github.wulkanowy.data.waitForResult
|
||||
import io.github.wulkanowy.utils.monday
|
||||
import io.github.wulkanowy.utils.sunday
|
||||
import io.github.wulkanowy.utils.waitForResult
|
||||
import java.time.LocalDate.now
|
||||
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.Student
|
||||
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.utils.waitForResult
|
||||
import kotlinx.coroutines.flow.first
|
||||
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.Student
|
||||
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.utils.waitForResult
|
||||
import kotlinx.coroutines.flow.first
|
||||
import java.time.LocalDate.now
|
||||
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.Student
|
||||
import io.github.wulkanowy.data.repositories.GradeStatisticsRepository
|
||||
import io.github.wulkanowy.utils.waitForResult
|
||||
import io.github.wulkanowy.data.waitForResult
|
||||
|
||||
import javax.inject.Inject
|
||||
|
||||
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.Student
|
||||
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.utils.waitForResult
|
||||
import kotlinx.coroutines.flow.first
|
||||
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.Student
|
||||
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.utils.nextOrSameSchoolDay
|
||||
import io.github.wulkanowy.utils.waitForResult
|
||||
import kotlinx.coroutines.flow.first
|
||||
import java.time.LocalDate.now
|
||||
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.Student
|
||||
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.utils.waitForResult
|
||||
import javax.inject.Inject
|
||||
|
||||
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.enums.MessageFolder.RECEIVED
|
||||
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.utils.waitForResult
|
||||
import kotlinx.coroutines.flow.first
|
||||
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.Student
|
||||
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.utils.waitForResult
|
||||
import kotlinx.coroutines.flow.first
|
||||
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.Student
|
||||
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.utils.waitForResult
|
||||
import kotlinx.coroutines.flow.first
|
||||
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.Student
|
||||
import io.github.wulkanowy.data.repositories.TeacherRepository
|
||||
import io.github.wulkanowy.utils.waitForResult
|
||||
import io.github.wulkanowy.data.waitForResult
|
||||
|
||||
import javax.inject.Inject
|
||||
|
||||
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.Student
|
||||
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.utils.nextOrSameSchoolDay
|
||||
import io.github.wulkanowy.utils.waitForResult
|
||||
import kotlinx.coroutines.flow.first
|
||||
import java.time.LocalDate.now
|
||||
import javax.inject.Inject
|
||||
|
@ -1,17 +1,10 @@
|
||||
package io.github.wulkanowy.ui.base
|
||||
|
||||
import io.github.wulkanowy.data.Status
|
||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||
import io.github.wulkanowy.utils.flowWithResource
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.SupervisorJob
|
||||
import kotlinx.coroutines.cancelChildren
|
||||
import kotlinx.coroutines.*
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.catch
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import timber.log.Timber
|
||||
|
||||
open class BasePresenter<T : BaseView>(
|
||||
@ -37,28 +30,28 @@ open class BasePresenter<T : BaseView>(
|
||||
}
|
||||
|
||||
fun onExpiredLoginSelected() {
|
||||
flowWithResource {
|
||||
val student = studentRepository.getCurrentStudent(false)
|
||||
studentRepository.logoutStudent(student)
|
||||
Timber.i("Attempt to switch the student after the session expires")
|
||||
|
||||
val students = studentRepository.getSavedStudents(false)
|
||||
if (students.isNotEmpty()) {
|
||||
Timber.i("Switching current student")
|
||||
studentRepository.switchStudent(students[0])
|
||||
presenterScope.launch {
|
||||
runCatching {
|
||||
val student = studentRepository.getCurrentStudent(false)
|
||||
studentRepository.logoutStudent(student)
|
||||
|
||||
val students = studentRepository.getSavedStudents(false)
|
||||
if (students.isNotEmpty()) {
|
||||
Timber.i("Switching current student")
|
||||
studentRepository.switchStudent(students[0])
|
||||
}
|
||||
}
|
||||
}.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> Timber.i("Attempt to switch the student after the session expires")
|
||||
Status.SUCCESS -> {
|
||||
.onFailure {
|
||||
Timber.i("Switch student result: An exception occurred")
|
||||
errorHandler.dispatch(it)
|
||||
}
|
||||
.onSuccess {
|
||||
Timber.i("Switch student result: Open login view")
|
||||
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 {
|
||||
|
@ -1,13 +1,11 @@
|
||||
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.repositories.AppCreatorRepository
|
||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||
import io.github.wulkanowy.ui.base.BasePresenter
|
||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||
import io.github.wulkanowy.utils.flowWithResource
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import javax.inject.Inject
|
||||
|
||||
class ContributorPresenter @Inject constructor(
|
||||
@ -31,15 +29,11 @@ class ContributorPresenter @Inject constructor(
|
||||
}
|
||||
|
||||
private fun loadData() {
|
||||
flowWithResource { appCreatorRepository.getAppCreators() }.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> view?.showProgress(true)
|
||||
Status.SUCCESS -> view?.run {
|
||||
showProgress(false)
|
||||
updateData(it.data!!)
|
||||
}
|
||||
Status.ERROR -> errorHandler.dispatch(it.error!!)
|
||||
}
|
||||
}.launch()
|
||||
resourceFlow { appCreatorRepository.getAppCreators() }
|
||||
.onResourceLoading { view?.showProgress(true) }
|
||||
.onResourceSuccess { view?.updateData(it) }
|
||||
.onResourceNotLoading { view?.showProgress(false) }
|
||||
.onResourceError { errorHandler.dispatch(it) }
|
||||
.launch()
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,12 @@
|
||||
package io.github.wulkanowy.ui.modules.about.license
|
||||
|
||||
import com.mikepenz.aboutlibraries.entity.Library
|
||||
import io.github.wulkanowy.data.Status
|
||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||
import io.github.wulkanowy.ui.base.BasePresenter
|
||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||
import io.github.wulkanowy.utils.DispatchersProvider
|
||||
import io.github.wulkanowy.utils.afterLoading
|
||||
import io.github.wulkanowy.utils.flowWithResource
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
class LicensePresenter @Inject constructor(
|
||||
@ -30,18 +26,16 @@ class LicensePresenter @Inject constructor(
|
||||
}
|
||||
|
||||
private fun loadData() {
|
||||
flowWithResource {
|
||||
withContext(dispatchers.io) {
|
||||
view?.appLibraries.orEmpty()
|
||||
presenterScope.launch {
|
||||
runCatching {
|
||||
withContext(dispatchers.io) {
|
||||
view?.appLibraries.orEmpty()
|
||||
}
|
||||
}
|
||||
}.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> Timber.d("License data load started")
|
||||
Status.SUCCESS -> view?.updateData(it.data!!)
|
||||
Status.ERROR -> errorHandler.dispatch(it.error!!)
|
||||
}
|
||||
}.afterLoading {
|
||||
.onFailure { errorHandler.dispatch(it) }
|
||||
.onSuccess { view?.updateData(it) }
|
||||
|
||||
view?.showProgress(false)
|
||||
}.launch()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +1,13 @@
|
||||
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.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.resourceFlow
|
||||
import io.github.wulkanowy.ui.base.BasePresenter
|
||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||
import io.github.wulkanowy.utils.flowWithResource
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
@ -32,20 +33,10 @@ class AccountPresenter @Inject constructor(
|
||||
}
|
||||
|
||||
private fun loadData() {
|
||||
flowWithResource { studentRepository.getSavedStudents(false) }
|
||||
.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> Timber.i("Loading account data started")
|
||||
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!!)
|
||||
}
|
||||
}
|
||||
}
|
||||
resourceFlow { studentRepository.getSavedStudents(false) }
|
||||
.logResourceStatus("load account data")
|
||||
.onResourceSuccess { view?.updateData(createAccountItems(it)) }
|
||||
.onResourceError(errorHandler::dispatch)
|
||||
.launch("load")
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
package io.github.wulkanowy.ui.modules.account.accountdetails
|
||||
|
||||
import io.github.wulkanowy.data.Resource
|
||||
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.StudentWithSemesters
|
||||
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.ErrorHandler
|
||||
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 javax.inject.Inject
|
||||
|
||||
@ -51,40 +46,25 @@ class AccountDetailsPresenter @Inject constructor(
|
||||
}
|
||||
|
||||
private fun loadData() {
|
||||
flowWithResource { studentRepository.getSavedStudents() }
|
||||
.map { studentWithSemesters ->
|
||||
Resource(
|
||||
data = studentWithSemesters.data?.single { it.student.id == studentId },
|
||||
status = studentWithSemesters.status,
|
||||
error = studentWithSemesters.error
|
||||
)
|
||||
}
|
||||
.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!!)
|
||||
}
|
||||
resourceFlow { studentRepository.getSavedStudentById(studentId ?: -1) }
|
||||
.logResourceStatus("loading account details view")
|
||||
.onResourceLoading {
|
||||
view?.run {
|
||||
showProgress(true)
|
||||
showContent(false)
|
||||
}
|
||||
}
|
||||
.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()
|
||||
}
|
||||
|
||||
@ -105,22 +85,12 @@ class AccountDetailsPresenter @Inject constructor(
|
||||
|
||||
Timber.i("Select student ${studentWithSemesters!!.student.id}")
|
||||
|
||||
flowWithResource { studentRepository.switchStudent(studentWithSemesters!!) }
|
||||
.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> Timber.i("Attempt to change a student")
|
||||
Status.SUCCESS -> {
|
||||
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?.popViewToMain()
|
||||
}.launch("switch")
|
||||
resourceFlow { studentRepository.switchStudent(studentWithSemesters!!) }
|
||||
.logResourceStatus("change student")
|
||||
.onResourceSuccess { view?.recreateMainView() }
|
||||
.onResourceNotLoading { view?.popViewToMain() }
|
||||
.onResourceError(errorHandler::dispatch)
|
||||
.launch("switch")
|
||||
}
|
||||
|
||||
fun onRemoveSelected() {
|
||||
@ -131,7 +101,7 @@ class AccountDetailsPresenter @Inject constructor(
|
||||
fun onLogoutConfirm() {
|
||||
if (studentWithSemesters == null) return
|
||||
|
||||
flowWithResource {
|
||||
resourceFlow {
|
||||
val studentToLogout = studentWithSemesters!!.student
|
||||
|
||||
studentRepository.logoutStudent(studentToLogout)
|
||||
@ -141,13 +111,13 @@ class AccountDetailsPresenter @Inject constructor(
|
||||
studentRepository.switchStudent(students[0])
|
||||
}
|
||||
|
||||
return@flowWithResource students
|
||||
}.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> Timber.i("Attempt to logout user")
|
||||
Status.SUCCESS -> view?.run {
|
||||
students
|
||||
}
|
||||
.logResourceStatus("logout user")
|
||||
.onResourceSuccess {
|
||||
view?.run {
|
||||
when {
|
||||
it.data!!.isEmpty() -> {
|
||||
it.isEmpty() -> {
|
||||
Timber.i("Logout result: Open login view")
|
||||
syncManager.stopSyncWorker()
|
||||
openClearLoginView()
|
||||
@ -162,18 +132,16 @@ class AccountDetailsPresenter @Inject constructor(
|
||||
}
|
||||
}
|
||||
}
|
||||
Status.ERROR -> {
|
||||
Timber.i("Logout result: An exception occurred")
|
||||
errorHandler.dispatch(it.error!!)
|
||||
}
|
||||
.onResourceNotLoading {
|
||||
if (studentWithSemesters?.student?.isCurrent == true) {
|
||||
view?.popViewToMain()
|
||||
} else {
|
||||
view?.popViewToAccounts()
|
||||
}
|
||||
}
|
||||
}.afterLoading {
|
||||
if (studentWithSemesters?.student?.isCurrent == true) {
|
||||
view?.popViewToMain()
|
||||
} else {
|
||||
view?.popViewToAccounts()
|
||||
}
|
||||
}.launch("logout")
|
||||
.onResourceError(errorHandler::dispatch)
|
||||
.launch("logout")
|
||||
}
|
||||
|
||||
private fun showErrorViewOnError(message: String, error: Throwable) {
|
||||
|
@ -1,15 +1,12 @@
|
||||
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.StudentNickAndAvatar
|
||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||
import io.github.wulkanowy.ui.base.BasePresenter
|
||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||
import io.github.wulkanowy.utils.AppInfo
|
||||
import io.github.wulkanowy.utils.afterLoading
|
||||
import io.github.wulkanowy.utils.flowWithResource
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
@ -38,43 +35,26 @@ class AccountEditPresenter @Inject constructor(
|
||||
}
|
||||
|
||||
private fun loadData() {
|
||||
flowWithResource {
|
||||
studentRepository.getStudentById(student.id, false).avatarColor
|
||||
}.onEach { resource ->
|
||||
when (resource.status) {
|
||||
Status.LOADING -> Timber.i("Attempt to load student")
|
||||
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")
|
||||
resourceFlow { studentRepository.getStudentById(student.id, false).avatarColor }
|
||||
.logResourceStatus("load student")
|
||||
.onResourceSuccess { view?.updateSelectedColorData(it.toInt()) }
|
||||
.onResourceError(errorHandler::dispatch)
|
||||
.launch("load_data")
|
||||
}
|
||||
|
||||
fun changeStudentNickAndAvatar(nick: String, avatarColor: Int) {
|
||||
flowWithResource {
|
||||
val studentNick =
|
||||
StudentNickAndAvatar(nick = nick.trim(), avatarColor = avatarColor.toLong())
|
||||
.apply { id = student.id }
|
||||
resourceFlow {
|
||||
val studentNick = StudentNickAndAvatar(
|
||||
nick = nick.trim(),
|
||||
avatarColor = avatarColor.toLong()
|
||||
).apply { id = student.id }
|
||||
|
||||
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")
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,11 @@
|
||||
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.repositories.StudentRepository
|
||||
import io.github.wulkanowy.ui.base.BasePresenter
|
||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||
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 javax.inject.Inject
|
||||
|
||||
@ -43,21 +40,11 @@ class AccountQuickPresenter @Inject constructor(
|
||||
return
|
||||
}
|
||||
|
||||
flowWithResource { studentRepository.switchStudent(studentWithSemesters) }
|
||||
.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> Timber.i("Attempt to change a student")
|
||||
Status.SUCCESS -> {
|
||||
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() }
|
||||
resourceFlow { studentRepository.switchStudent(studentWithSemesters) }
|
||||
.logResourceStatus("change student")
|
||||
.onResourceSuccess { view?.recreateMainView() }
|
||||
.onResourceNotLoading { view?.popView() }
|
||||
.onResourceError(errorHandler::dispatch)
|
||||
.launch("switch")
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
package io.github.wulkanowy.ui.modules.attendance
|
||||
|
||||
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.repositories.AttendanceRepository
|
||||
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.ui.base.BasePresenter
|
||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||
import io.github.wulkanowy.utils.AnalyticsHelper
|
||||
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 io.github.wulkanowy.utils.*
|
||||
import kotlinx.coroutines.flow.catch
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
@ -213,93 +202,77 @@ class AttendancePresenter @Inject constructor(
|
||||
|
||||
var isParent = false
|
||||
|
||||
flowWithResourceIn {
|
||||
flatResourceFlow {
|
||||
val student = studentRepository.getCurrentStudent()
|
||||
isParent = student.isParent
|
||||
|
||||
val semester = semesterRepository.getCurrentSemester(student)
|
||||
attendanceRepository.getAttendance(
|
||||
student,
|
||||
semester,
|
||||
currentDate,
|
||||
currentDate,
|
||||
forceRefresh
|
||||
student = student,
|
||||
semester = semester,
|
||||
start = currentDate,
|
||||
end = currentDate,
|
||||
forceRefresh = forceRefresh
|
||||
)
|
||||
}.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> {
|
||||
view?.showExcuseButton(false)
|
||||
if (!it.data.isNullOrEmpty()) {
|
||||
val filteredAttendance = if (prefRepository.isShowPresent) {
|
||||
it.data
|
||||
} else {
|
||||
it.data.filter { item -> !item.presence }
|
||||
}
|
||||
|
||||
view?.run {
|
||||
enableSwipe(true)
|
||||
showRefresh(true)
|
||||
showProgress(false)
|
||||
showErrorView(false)
|
||||
showEmpty(filteredAttendance.isEmpty())
|
||||
showContent(filteredAttendance.isNotEmpty())
|
||||
updateData(filteredAttendance.sortedBy { item -> item.number })
|
||||
}
|
||||
}
|
||||
}
|
||||
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!!)
|
||||
}
|
||||
.logResourceStatus("load attendance")
|
||||
.onResourceLoading {
|
||||
view?.showExcuseButton(false)
|
||||
}
|
||||
.mapResourceData {
|
||||
if (prefRepository.isShowPresent) {
|
||||
it
|
||||
} else {
|
||||
it.filter { item -> !item.presence }
|
||||
}.sortedBy { item -> item.number }
|
||||
}
|
||||
.onResourceData {
|
||||
view?.run {
|
||||
enableSwipe(true)
|
||||
showProgress(false)
|
||||
showErrorView(false)
|
||||
showEmpty(it.isEmpty())
|
||||
showContent(it.isNotEmpty())
|
||||
updateData(it)
|
||||
}
|
||||
}
|
||||
}.afterLoading {
|
||||
view?.run {
|
||||
showRefresh(false)
|
||||
showProgress(false)
|
||||
enableSwipe(true)
|
||||
.onResourceIntermediate { view?.showRefresh(true) }
|
||||
.onResourceSuccess {
|
||||
isVulcanExcusedFunctionEnabled = it.any { item -> item.excusable }
|
||||
val anyExcusables = it.any { it.isExcusableOrNotExcused }
|
||||
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>) {
|
||||
flowWithResource {
|
||||
resourceFlow {
|
||||
val student = studentRepository.getCurrentStudent()
|
||||
val semester = semesterRepository.getCurrentSemester(student)
|
||||
attendanceRepository.excuseForAbsence(student, semester, toExcuseList, reason)
|
||||
}.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> view?.run {
|
||||
when (it) {
|
||||
is Resource.Loading -> view?.run {
|
||||
Timber.i("Excusing absence started")
|
||||
showProgress(true)
|
||||
showContent(false)
|
||||
showExcuseButton(false)
|
||||
}
|
||||
Status.SUCCESS -> {
|
||||
is Resource.Success -> {
|
||||
Timber.i("Excusing for absence result: Success")
|
||||
analytics.logEvent("excuse_absence", "items" to attendanceToExcuseList.size)
|
||||
attendanceToExcuseList.clear()
|
||||
@ -311,9 +284,9 @@ class AttendancePresenter @Inject constructor(
|
||||
}
|
||||
loadData(forceRefresh = true)
|
||||
}
|
||||
Status.ERROR -> {
|
||||
is Resource.Error -> {
|
||||
Timber.i("Excusing for absence result: An exception occurred")
|
||||
errorHandler.dispatch(it.error!!)
|
||||
errorHandler.dispatch(it.error)
|
||||
loadData()
|
||||
}
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ class AttendanceSummaryFragment :
|
||||
binding.attendanceSummarySubjectsContainer.elevation = requireContext().dpToPx(1f)
|
||||
}
|
||||
|
||||
override fun updateSubjects(data: ArrayList<String>) {
|
||||
override fun updateSubjects(data: Collection<String>) {
|
||||
with(subjectsAdapter) {
|
||||
clear()
|
||||
addAll(data)
|
||||
|
@ -1,6 +1,6 @@
|
||||
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.Subject
|
||||
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.ErrorHandler
|
||||
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 java.time.Month
|
||||
import javax.inject.Inject
|
||||
@ -75,11 +72,9 @@ class AttendanceSummaryPresenter @Inject constructor(
|
||||
}
|
||||
|
||||
private fun loadData(subjectId: Int, forceRefresh: Boolean = false) {
|
||||
Timber.i("Loading attendance summary data started")
|
||||
|
||||
currentSubjectId = subjectId
|
||||
|
||||
flowWithResourceIn {
|
||||
flatResourceFlow {
|
||||
val student = studentRepository.getCurrentStudent()
|
||||
val semester = semesterRepository.getCurrentSemester(student)
|
||||
|
||||
@ -89,47 +84,37 @@ class AttendanceSummaryPresenter @Inject constructor(
|
||||
subjectId = subjectId,
|
||||
forceRefresh = forceRefresh
|
||||
)
|
||||
}.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> {
|
||||
if (!it.data.isNullOrEmpty()) {
|
||||
view?.run {
|
||||
enableSwipe(true)
|
||||
showRefresh(true)
|
||||
showProgress(false)
|
||||
showContent(true)
|
||||
showErrorView(false)
|
||||
updateDataSet(sortItems(it.data))
|
||||
}
|
||||
}
|
||||
}
|
||||
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!!)
|
||||
}
|
||||
.logResourceStatus("load attendance summary")
|
||||
.mapResourceData(this::sortItems)
|
||||
.onResourceData {
|
||||
view?.run {
|
||||
enableSwipe(true)
|
||||
showProgress(false)
|
||||
showErrorView(false)
|
||||
showContent(it.isNotEmpty())
|
||||
showEmpty(it.isEmpty())
|
||||
updateDataSet(it)
|
||||
}
|
||||
}
|
||||
}.afterLoading {
|
||||
view?.run {
|
||||
showRefresh(false)
|
||||
showProgress(false)
|
||||
enableSwipe(true)
|
||||
.onResourceIntermediate { view?.showRefresh(true) }
|
||||
.onResourceSuccess {
|
||||
analytics.logEvent(
|
||||
"load_data",
|
||||
"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 ->
|
||||
@ -148,27 +133,20 @@ class AttendanceSummaryPresenter @Inject constructor(
|
||||
}
|
||||
|
||||
private fun loadSubjects() {
|
||||
flowWithResourceIn {
|
||||
flatResourceFlow {
|
||||
val student = studentRepository.getCurrentStudent()
|
||||
val semester = semesterRepository.getCurrentSemester(student)
|
||||
subjectRepository.getSubjects(student, semester)
|
||||
}.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> Timber.i("Loading attendance summary subjects started")
|
||||
Status.SUCCESS -> {
|
||||
subjects = it.data!!
|
||||
|
||||
Timber.i("Loading attendance summary subjects result: Success")
|
||||
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!!)
|
||||
}
|
||||
.logResourceStatus("load attendance summary subjects")
|
||||
.onResourceData {
|
||||
subjects = it
|
||||
view?.run {
|
||||
view?.updateSubjects(it.map { subject -> subject.name }.toList())
|
||||
showSubjects(true)
|
||||
}
|
||||
}
|
||||
}.launch("subjects")
|
||||
.onResourceError(errorHandler::dispatch)
|
||||
.launch("subjects")
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ interface AttendanceSummaryView : BaseView {
|
||||
|
||||
fun updateDataSet(data: List<AttendanceSummary>)
|
||||
|
||||
fun updateSubjects(data: ArrayList<String>)
|
||||
fun updateSubjects(data: Collection<String>)
|
||||
|
||||
fun showSubjects(show: Boolean)
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
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.repositories.ConferenceRepository
|
||||
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.ErrorHandler
|
||||
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 javax.inject.Inject
|
||||
|
||||
@ -64,50 +61,39 @@ class ConferencePresenter @Inject constructor(
|
||||
}
|
||||
|
||||
private fun loadData(forceRefresh: Boolean = false) {
|
||||
Timber.i("Loading conference data started")
|
||||
|
||||
flowWithResourceIn {
|
||||
flatResourceFlow {
|
||||
val student = studentRepository.getCurrentStudent()
|
||||
val semester = semesterRepository.getCurrentSemester(student)
|
||||
conferenceRepository.getConferences(student, semester, forceRefresh)
|
||||
}.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> {
|
||||
if (!it.data.isNullOrEmpty()) {
|
||||
view?.run {
|
||||
enableSwipe(true)
|
||||
showRefresh(true)
|
||||
showProgress(false)
|
||||
showContent(true)
|
||||
updateData(it.data.sortedByDescending { conference -> conference.date })
|
||||
}
|
||||
}
|
||||
}
|
||||
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!!)
|
||||
}
|
||||
.logResourceStatus("load conference data")
|
||||
.mapResourceData { it.sortedByDescending { conference -> conference.date } }
|
||||
.onResourceData {
|
||||
view?.run {
|
||||
enableSwipe(true)
|
||||
showProgress(false)
|
||||
showErrorView(false)
|
||||
showContent(it.isNotEmpty())
|
||||
showEmpty(it.isEmpty())
|
||||
updateData(it)
|
||||
}
|
||||
}
|
||||
}.afterLoading {
|
||||
view?.run {
|
||||
showRefresh(false)
|
||||
showProgress(false)
|
||||
enableSwipe(true)
|
||||
.onResourceIntermediate { view?.showRefresh(true) }
|
||||
.onResourceSuccess {
|
||||
analytics.logEvent(
|
||||
"load_data",
|
||||
"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()
|
||||
super.onDestroyView()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package io.github.wulkanowy.ui.modules.dashboard
|
||||
|
||||
import io.github.wulkanowy.data.Resource
|
||||
import io.github.wulkanowy.data.Status
|
||||
import io.github.wulkanowy.data.*
|
||||
import io.github.wulkanowy.data.db.entities.AdminMessage
|
||||
import io.github.wulkanowy.data.db.entities.LuckyNumber
|
||||
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.ErrorHandler
|
||||
import io.github.wulkanowy.utils.calculatePercentage
|
||||
import io.github.wulkanowy.utils.flowWithResourceIn
|
||||
import io.github.wulkanowy.utils.nextOrSameSchoolDay
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.launch
|
||||
@ -104,7 +102,7 @@ class DashboardPresenter @Inject constructor(
|
||||
forceRefresh: Boolean
|
||||
) = dashboardTilesToLoad.filter { newItemToLoad ->
|
||||
dashboardLoadedTiles.none { it == newItemToLoad } || forceRefresh
|
||||
|| newItemToLoad == DashboardItem.Tile.ADMIN_MESSAGE
|
||||
|| newItemToLoad == DashboardItem.Tile.ADMIN_MESSAGE
|
||||
}
|
||||
|
||||
private fun removeUnselectedTiles(tilesToLoad: List<DashboardItem.Tile>) {
|
||||
@ -225,27 +223,26 @@ class DashboardPresenter @Inject constructor(
|
||||
val semester = semesterRepository.getCurrentSemester(student)
|
||||
val selectedTiles = preferencesRepository.selectedDashboardTiles
|
||||
|
||||
val flowSuccess = flowOf(Resource.Success(null))
|
||||
val luckyNumberFlow = luckyNumberRepository.getLuckyNumber(student, forceRefresh)
|
||||
.map {
|
||||
if (it.data == null) {
|
||||
it.copy(data = LuckyNumber(0, LocalDate.now(), 0))
|
||||
} else it
|
||||
.mapResourceData {
|
||||
it ?: LuckyNumber(0, LocalDate.now(), 0)
|
||||
}
|
||||
.takeIf { DashboardItem.Tile.LUCKY_NUMBER in selectedTiles } ?: flowOf(null)
|
||||
.takeIf { DashboardItem.Tile.LUCKY_NUMBER in selectedTiles } ?: flowSuccess
|
||||
|
||||
val messageFLow = messageRepository.getMessages(
|
||||
student = student,
|
||||
semester = semester,
|
||||
folder = MessageFolder.RECEIVED,
|
||||
forceRefresh = forceRefresh
|
||||
).takeIf { DashboardItem.Tile.MESSAGES in selectedTiles } ?: flowOf(null)
|
||||
).takeIf { DashboardItem.Tile.MESSAGES in selectedTiles } ?: flowSuccess
|
||||
|
||||
val attendanceFlow = attendanceSummaryRepository.getAttendanceSummary(
|
||||
student = student,
|
||||
semester = semester,
|
||||
subjectId = -1,
|
||||
forceRefresh = forceRefresh
|
||||
).takeIf { DashboardItem.Tile.ATTENDANCE in selectedTiles } ?: flowOf(null)
|
||||
).takeIf { DashboardItem.Tile.ATTENDANCE in selectedTiles } ?: flowSuccess
|
||||
|
||||
emitAll(
|
||||
combine(
|
||||
@ -253,17 +250,13 @@ class DashboardPresenter @Inject constructor(
|
||||
messageFLow,
|
||||
attendanceFlow
|
||||
) { luckyNumberResource, messageResource, attendanceResource ->
|
||||
val error =
|
||||
luckyNumberResource?.error ?: messageResource?.error
|
||||
?: attendanceResource?.error
|
||||
error?.let { throw it }
|
||||
val resList = listOf(luckyNumberResource, messageResource, attendanceResource)
|
||||
resList.firstNotNullOfOrNull { it.errorOrNull }?.let { throw it }
|
||||
val isLoading = resList.any { it is Resource.Loading }
|
||||
|
||||
val luckyNumber = luckyNumberResource?.data?.luckyNumber
|
||||
val messageCount = messageResource?.data?.count { it.unread }
|
||||
val attendancePercentage = attendanceResource?.data?.calculatePercentage()
|
||||
|
||||
val isLoading =
|
||||
luckyNumberResource?.status == Status.LOADING || messageResource?.status == Status.LOADING || attendanceResource?.status == Status.LOADING
|
||||
val luckyNumber = luckyNumberResource.dataOrNull?.luckyNumber
|
||||
val messageCount = messageResource.dataOrNull?.count { it.unread }
|
||||
val attendancePercentage = attendanceResource.dataOrNull?.calculatePercentage()
|
||||
|
||||
DashboardItem.HorizontalGroup(
|
||||
isLoading = isLoading,
|
||||
@ -300,68 +293,65 @@ class DashboardPresenter @Inject constructor(
|
||||
}
|
||||
|
||||
private fun loadGrades(student: Student, forceRefresh: Boolean) {
|
||||
flowWithResourceIn {
|
||||
flatResourceFlow {
|
||||
val semester = semesterRepository.getCurrentSemester(student)
|
||||
|
||||
gradeRepository.getGrades(student, semester, forceRefresh)
|
||||
}.map { originalResource ->
|
||||
val filteredSubjectWithGrades = originalResource.data?.first
|
||||
.orEmpty()
|
||||
.filter { it.date >= LocalDate.now().minusDays(7) }
|
||||
.groupBy { it.subject }
|
||||
.mapValues { entry ->
|
||||
entry.value
|
||||
.take(5)
|
||||
.sortedByDescending { it.date }
|
||||
}
|
||||
.toList()
|
||||
.sortedByDescending { (_, grades) -> grades[0].date }
|
||||
.toMap()
|
||||
}
|
||||
.mapResourceData { (details, _) ->
|
||||
val filteredSubjectWithGrades = details
|
||||
.filter { it.date >= LocalDate.now().minusDays(7) }
|
||||
.groupBy { it.subject }
|
||||
.mapValues { entry ->
|
||||
entry.value
|
||||
.take(5)
|
||||
.sortedByDescending { it.date }
|
||||
}
|
||||
.toList()
|
||||
.sortedByDescending { (_, grades) -> grades[0].date }
|
||||
.toMap()
|
||||
|
||||
Resource(
|
||||
status = originalResource.status,
|
||||
data = filteredSubjectWithGrades.takeIf { originalResource.data != null },
|
||||
error = originalResource.error
|
||||
)
|
||||
}.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> {
|
||||
Timber.i("Loading dashboard grades data started")
|
||||
if (forceRefresh) return@onEach
|
||||
filteredSubjectWithGrades
|
||||
}
|
||||
.onEach {
|
||||
when (it) {
|
||||
is Resource.Loading -> {
|
||||
Timber.i("Loading dashboard grades data started")
|
||||
if (forceRefresh) return@onEach
|
||||
updateData(
|
||||
DashboardItem.Grades(
|
||||
subjectWithGrades = it.dataOrNull,
|
||||
gradeTheme = preferencesRepository.gradeColorTheme,
|
||||
isLoading = true
|
||||
), forceRefresh
|
||||
)
|
||||
|
||||
updateData(
|
||||
DashboardItem.Grades(
|
||||
subjectWithGrades = it.data,
|
||||
gradeTheme = preferencesRepository.gradeColorTheme,
|
||||
isLoading = true
|
||||
), forceRefresh
|
||||
)
|
||||
|
||||
if (!it.data.isNullOrEmpty()) {
|
||||
firstLoadedItemList += DashboardItem.Type.GRADES
|
||||
if (!it.dataOrNull.isNullOrEmpty()) {
|
||||
firstLoadedItemList += DashboardItem.Type.GRADES
|
||||
}
|
||||
}
|
||||
is Resource.Success -> {
|
||||
Timber.i("Loading dashboard grades result: Success")
|
||||
updateData(
|
||||
DashboardItem.Grades(
|
||||
subjectWithGrades = it.data,
|
||||
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)
|
||||
}
|
||||
}
|
||||
}.launchWithUniqueRefreshJob("dashboard_grades", forceRefresh)
|
||||
.launchWithUniqueRefreshJob("dashboard_grades", forceRefresh)
|
||||
}
|
||||
|
||||
private fun loadLessons(student: Student, forceRefresh: Boolean) {
|
||||
flowWithResourceIn {
|
||||
flatResourceFlow {
|
||||
val semester = semesterRepository.getCurrentSemester(student)
|
||||
val date = LocalDate.now().nextOrSameSchoolDay
|
||||
|
||||
@ -372,40 +362,41 @@ class DashboardPresenter @Inject constructor(
|
||||
end = date.plusDays(1),
|
||||
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 {
|
||||
when (it.status) {
|
||||
Status.LOADING -> {
|
||||
Timber.i("Loading dashboard lessons data started")
|
||||
if (forceRefresh) return@onEach
|
||||
updateData(
|
||||
DashboardItem.Lessons(it.data, isLoading = true),
|
||||
forceRefresh
|
||||
)
|
||||
|
||||
if (!it.data?.lessons.isNullOrEmpty()) {
|
||||
firstLoadedItemList += DashboardItem.Type.LESSONS
|
||||
if (!it.dataOrNull?.lessons.isNullOrEmpty()) {
|
||||
firstLoadedItemList += DashboardItem.Type.LESSONS
|
||||
}
|
||||
}
|
||||
is Resource.Success -> {
|
||||
Timber.i("Loading dashboard lessons result: Success")
|
||||
updateData(
|
||||
DashboardItem.Lessons(it.data), forceRefresh
|
||||
)
|
||||
}
|
||||
is Resource.Error -> {
|
||||
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
|
||||
)
|
||||
}
|
||||
}
|
||||
}.launchWithUniqueRefreshJob("dashboard_lessons", forceRefresh)
|
||||
.launchWithUniqueRefreshJob("dashboard_lessons", forceRefresh)
|
||||
}
|
||||
|
||||
private fun loadHomework(student: Student, forceRefresh: Boolean) {
|
||||
flowWithResourceIn {
|
||||
flatResourceFlow {
|
||||
val semester = semesterRepository.getCurrentSemester(student)
|
||||
val date = LocalDate.now().nextOrSameSchoolDay
|
||||
|
||||
@ -416,73 +407,79 @@ class DashboardPresenter @Inject constructor(
|
||||
end = date,
|
||||
forceRefresh = forceRefresh
|
||||
)
|
||||
}.map { homeworkResource ->
|
||||
val currentDate = LocalDate.now()
|
||||
}
|
||||
.mapResourceData { homework ->
|
||||
val currentDate = LocalDate.now()
|
||||
|
||||
val filteredHomework = homeworkResource.data
|
||||
?.filter { (it.date.isAfter(currentDate) || it.date == currentDate) && !it.isDone }
|
||||
?.sortedBy { it.date }
|
||||
val filteredHomework = homework.filter {
|
||||
(it.date.isAfter(currentDate) || it.date == currentDate) && !it.isDone
|
||||
}.sortedBy { it.date }
|
||||
|
||||
homeworkResource.copy(data = filteredHomework)
|
||||
}.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> {
|
||||
Timber.i("Loading dashboard homework data started")
|
||||
if (forceRefresh) return@onEach
|
||||
updateData(
|
||||
DashboardItem.Homework(it.data ?: emptyList(), isLoading = true),
|
||||
forceRefresh
|
||||
)
|
||||
filteredHomework
|
||||
}
|
||||
.onEach {
|
||||
when (it) {
|
||||
is Resource.Loading -> {
|
||||
Timber.i("Loading dashboard homework data started")
|
||||
if (forceRefresh) return@onEach
|
||||
val data = it.dataOrNull.orEmpty()
|
||||
updateData(
|
||||
DashboardItem.Homework(data, isLoading = true),
|
||||
forceRefresh
|
||||
)
|
||||
|
||||
if (!it.data.isNullOrEmpty()) {
|
||||
firstLoadedItemList += DashboardItem.Type.HOMEWORK
|
||||
if (data.isNotEmpty()) {
|
||||
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)
|
||||
}
|
||||
}
|
||||
}.launchWithUniqueRefreshJob("dashboard_homework", forceRefresh)
|
||||
.launchWithUniqueRefreshJob("dashboard_homework", forceRefresh)
|
||||
}
|
||||
|
||||
private fun loadSchoolAnnouncements(student: Student, forceRefresh: Boolean) {
|
||||
flowWithResourceIn {
|
||||
flatResourceFlow {
|
||||
schoolAnnouncementRepository.getSchoolAnnouncements(student, forceRefresh)
|
||||
}.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> {
|
||||
Timber.i("Loading dashboard announcements data started")
|
||||
if (forceRefresh) return@onEach
|
||||
updateData(
|
||||
DashboardItem.Announcements(it.data ?: emptyList(), isLoading = true),
|
||||
forceRefresh
|
||||
)
|
||||
}
|
||||
.onEach {
|
||||
when (it) {
|
||||
is Resource.Loading -> {
|
||||
Timber.i("Loading dashboard announcements data started")
|
||||
if (forceRefresh) return@onEach
|
||||
updateData(
|
||||
DashboardItem.Announcements(it.dataOrNull.orEmpty(), isLoading = true),
|
||||
forceRefresh
|
||||
)
|
||||
|
||||
if (!it.data.isNullOrEmpty()) {
|
||||
firstLoadedItemList += DashboardItem.Type.ANNOUNCEMENTS
|
||||
if (!it.dataOrNull.isNullOrEmpty()) {
|
||||
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)
|
||||
}
|
||||
}
|
||||
}.launchWithUniqueRefreshJob("dashboard_announcements", forceRefresh)
|
||||
.launchWithUniqueRefreshJob("dashboard_announcements", forceRefresh)
|
||||
}
|
||||
|
||||
private fun loadExams(student: Student, forceRefresh: Boolean) {
|
||||
flowWithResourceIn {
|
||||
flatResourceFlow {
|
||||
val semester = semesterRepository.getCurrentSemester(student)
|
||||
|
||||
examRepository.getExams(
|
||||
@ -493,40 +490,37 @@ class DashboardPresenter @Inject constructor(
|
||||
forceRefresh = forceRefresh
|
||||
)
|
||||
}
|
||||
.map { examResource ->
|
||||
val sortedExams = examResource.data?.sortedBy { it.date }
|
||||
|
||||
examResource.copy(data = sortedExams)
|
||||
}
|
||||
.mapResourceData { exams -> exams.sortedBy { exam -> exam.date } }
|
||||
.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> {
|
||||
when (it) {
|
||||
is Resource.Loading -> {
|
||||
Timber.i("Loading dashboard exams data started")
|
||||
if (forceRefresh) return@onEach
|
||||
updateData(
|
||||
DashboardItem.Exams(it.data.orEmpty(), isLoading = true),
|
||||
DashboardItem.Exams(it.dataOrNull.orEmpty(), isLoading = true),
|
||||
forceRefresh
|
||||
)
|
||||
|
||||
if (!it.data.isNullOrEmpty()) {
|
||||
if (!it.dataOrNull.isNullOrEmpty()) {
|
||||
firstLoadedItemList += DashboardItem.Type.EXAMS
|
||||
}
|
||||
}
|
||||
Status.SUCCESS -> {
|
||||
is Resource.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")
|
||||
errorHandler.dispatch(it.error!!)
|
||||
errorHandler.dispatch(it.error)
|
||||
updateData(DashboardItem.Exams(error = it.error), forceRefresh)
|
||||
}
|
||||
}
|
||||
}.launchWithUniqueRefreshJob("dashboard_exams", forceRefresh)
|
||||
}
|
||||
.launchWithUniqueRefreshJob("dashboard_exams", forceRefresh)
|
||||
}
|
||||
|
||||
private fun loadConferences(student: Student, forceRefresh: Boolean) {
|
||||
flowWithResourceIn {
|
||||
flatResourceFlow {
|
||||
val semester = semesterRepository.getCurrentSemester(student)
|
||||
|
||||
conferenceRepository.getConferences(
|
||||
@ -535,59 +529,62 @@ class DashboardPresenter @Inject constructor(
|
||||
forceRefresh = forceRefresh,
|
||||
startDate = Instant.now(),
|
||||
)
|
||||
}.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> {
|
||||
Timber.i("Loading dashboard conferences data started")
|
||||
if (forceRefresh) return@onEach
|
||||
updateData(
|
||||
DashboardItem.Conferences(it.data ?: emptyList(), isLoading = true),
|
||||
forceRefresh
|
||||
)
|
||||
}
|
||||
.onEach {
|
||||
when (it) {
|
||||
is Resource.Loading -> {
|
||||
Timber.i("Loading dashboard conferences data started")
|
||||
if (forceRefresh) return@onEach
|
||||
updateData(
|
||||
DashboardItem.Conferences(it.dataOrNull.orEmpty(), isLoading = true),
|
||||
forceRefresh
|
||||
)
|
||||
|
||||
if (!it.data.isNullOrEmpty()) {
|
||||
firstLoadedItemList += DashboardItem.Type.CONFERENCES
|
||||
if (!it.dataOrNull.isNullOrEmpty()) {
|
||||
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)
|
||||
}
|
||||
}
|
||||
}.launchWithUniqueRefreshJob("dashboard_conferences", forceRefresh)
|
||||
.launchWithUniqueRefreshJob("dashboard_conferences", forceRefresh)
|
||||
}
|
||||
|
||||
private fun loadAdminMessage(student: Student, forceRefresh: Boolean) {
|
||||
flowWithResourceIn { adminMessageRepository.getAdminMessages(student) }
|
||||
.map {
|
||||
val isDismissed = it.data?.id in preferencesRepository.dismissedAdminMessageIds
|
||||
it.copy(data = it.data.takeUnless { isDismissed })
|
||||
flatResourceFlow { adminMessageRepository.getAdminMessages(student) }
|
||||
.filter {
|
||||
val data = it.dataOrNull ?: return@filter true
|
||||
val isDismissed = data.id in preferencesRepository.dismissedAdminMessageIds
|
||||
!isDismissed
|
||||
}
|
||||
.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> {
|
||||
when (it) {
|
||||
is Resource.Loading -> {
|
||||
Timber.i("Loading dashboard admin message data started")
|
||||
if (forceRefresh) return@onEach
|
||||
updateData(DashboardItem.AdminMessages(), forceRefresh)
|
||||
}
|
||||
Status.SUCCESS -> {
|
||||
is Resource.Success -> {
|
||||
Timber.i("Loading dashboard admin message result: Success")
|
||||
updateData(
|
||||
dashboardItem = DashboardItem.AdminMessages(adminMessage = it.data),
|
||||
forceRefresh = forceRefresh
|
||||
)
|
||||
}
|
||||
Status.ERROR -> {
|
||||
is Resource.Error -> {
|
||||
Timber.i("Loading dashboard admin message result: An exception occurred")
|
||||
errorHandler.dispatch(it.error!!)
|
||||
errorHandler.dispatch(it.error)
|
||||
updateData(
|
||||
dashboardItem = DashboardItem.AdminMessages(
|
||||
adminMessage = it.data,
|
||||
adminMessage = null,
|
||||
error = it.error
|
||||
),
|
||||
forceRefresh = forceRefresh
|
||||
@ -740,7 +737,7 @@ class DashboardPresenter @Inject constructor(
|
||||
|
||||
if (forceRefresh) {
|
||||
onEach {
|
||||
if (it.status == Status.SUCCESS) {
|
||||
if (it is Resource.Success) {
|
||||
cancelJobs(jobName)
|
||||
}
|
||||
}.launch(jobName)
|
||||
|
@ -1,11 +1,11 @@
|
||||
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.StudentRepository
|
||||
import io.github.wulkanowy.data.resourceFlow
|
||||
import io.github.wulkanowy.ui.base.BasePresenter
|
||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||
import io.github.wulkanowy.utils.flowWithResource
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
@ -23,19 +23,21 @@ class LogViewerPresenter @Inject constructor(
|
||||
}
|
||||
|
||||
fun onShareLogsSelected(): Boolean {
|
||||
flowWithResource { loggerRepository.getLogFiles() }.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> Timber.d("Loading logs files started")
|
||||
Status.SUCCESS -> {
|
||||
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")
|
||||
errorHandler.dispatch(it.error!!)
|
||||
resourceFlow { loggerRepository.getLogFiles() }
|
||||
.onEach {
|
||||
when (it) {
|
||||
is Resource.Loading -> Timber.d("Loading logs files started")
|
||||
is Resource.Success -> {
|
||||
Timber.i("Loading logs files result: ${it.data.joinToString { file -> file.name }}")
|
||||
view?.shareLogs(it.data)
|
||||
}
|
||||
is Resource.Error -> {
|
||||
Timber.i("Loading logs files result: An exception occurred")
|
||||
errorHandler.dispatch(it.error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}.launch("share")
|
||||
.launch("share")
|
||||
return true
|
||||
}
|
||||
|
||||
@ -44,18 +46,20 @@ class LogViewerPresenter @Inject constructor(
|
||||
}
|
||||
|
||||
private fun loadLogFile() {
|
||||
flowWithResource { loggerRepository.getLastLogLines() }.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> Timber.d("Loading last log file started")
|
||||
Status.SUCCESS -> {
|
||||
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")
|
||||
errorHandler.dispatch(it.error!!)
|
||||
resourceFlow { loggerRepository.getLastLogLines() }
|
||||
.onEach {
|
||||
when (it) {
|
||||
is Resource.Loading -> Timber.d("Loading last log file started")
|
||||
is Resource.Success -> {
|
||||
Timber.i("Loading last log file result: load ${it.data.size} lines")
|
||||
view?.setLines(it.data)
|
||||
}
|
||||
is Resource.Error -> {
|
||||
Timber.i("Loading last log file result: An exception occurred")
|
||||
errorHandler.dispatch(it.error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}.launch("file")
|
||||
.launch("file")
|
||||
}
|
||||
}
|
||||
|
@ -1,21 +1,13 @@
|
||||
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.repositories.ExamRepository
|
||||
import io.github.wulkanowy.data.repositories.SemesterRepository
|
||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||
import io.github.wulkanowy.ui.base.BasePresenter
|
||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||
import io.github.wulkanowy.utils.AnalyticsHelper
|
||||
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 io.github.wulkanowy.utils.*
|
||||
import kotlinx.coroutines.flow.catch
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
@ -86,61 +78,57 @@ class ExamPresenter @Inject constructor(
|
||||
flow {
|
||||
val student = studentRepository.getCurrentStudent()
|
||||
emit(semesterRepository.getCurrentSemester(student))
|
||||
}.catch {
|
||||
Timber.i("Loading semester result: An exception occurred")
|
||||
}.onEach {
|
||||
baseDate = baseDate.getLastSchoolDayIfHoliday(it.schoolYear)
|
||||
currentDate = baseDate
|
||||
reloadNavigation()
|
||||
}.launch("holidays")
|
||||
}
|
||||
.catch { Timber.i("Loading semester result: An exception occurred") }
|
||||
.onEach {
|
||||
baseDate = baseDate.getLastSchoolDayIfHoliday(it.schoolYear)
|
||||
currentDate = baseDate
|
||||
reloadNavigation()
|
||||
}
|
||||
.launch("holidays")
|
||||
}
|
||||
|
||||
private fun loadData(forceRefresh: Boolean = false) {
|
||||
Timber.i("Loading exam data started")
|
||||
|
||||
flowWithResourceIn {
|
||||
flatResourceFlow {
|
||||
val student = studentRepository.getCurrentStudent()
|
||||
val semester = semesterRepository.getCurrentSemester(student)
|
||||
examRepository.getExams(student, semester, currentDate.monday, currentDate.sunday, forceRefresh)
|
||||
}.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> {
|
||||
if (!it.data.isNullOrEmpty()) {
|
||||
view?.run {
|
||||
enableSwipe(true)
|
||||
showRefresh(true)
|
||||
showProgress(false)
|
||||
showContent(true)
|
||||
updateData(createExamItems(it.data))
|
||||
}
|
||||
}
|
||||
}
|
||||
Status.SUCCESS -> {
|
||||
Timber.i("Loading exam result: Success")
|
||||
view?.apply {
|
||||
updateData(createExamItems(it.data!!))
|
||||
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!!)
|
||||
examRepository.getExams(
|
||||
student = student,
|
||||
semester = semester,
|
||||
start = currentDate.monday,
|
||||
end = currentDate.sunday,
|
||||
forceRefresh = forceRefresh
|
||||
)
|
||||
}
|
||||
.logResourceStatus("load exam data")
|
||||
.mapResourceData { createExamItems(it) }
|
||||
.onResourceData {
|
||||
view?.run {
|
||||
enableSwipe(true)
|
||||
showProgress(false)
|
||||
showErrorView(false)
|
||||
showContent(it.isNotEmpty())
|
||||
showEmpty(it.isEmpty())
|
||||
updateData(it)
|
||||
}
|
||||
}
|
||||
}.afterLoading {
|
||||
view?.run {
|
||||
showRefresh(false)
|
||||
showProgress(false)
|
||||
enableSwipe(true)
|
||||
.onResourceIntermediate { view?.showRefresh(true) }
|
||||
.onResourceSuccess {
|
||||
analytics.logEvent(
|
||||
"load_data",
|
||||
"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) {
|
||||
@ -181,8 +169,10 @@ class ExamPresenter @Inject constructor(
|
||||
view?.apply {
|
||||
showPreButton(!currentDate.minusDays(7).isHolidays)
|
||||
showNextButton(!currentDate.plusDays(7).isHolidays)
|
||||
updateNavigationWeek("${currentDate.monday.toFormattedString("dd.MM")} - " +
|
||||
currentDate.sunday.toFormattedString("dd.MM"))
|
||||
updateNavigationWeek(
|
||||
"${currentDate.monday.toFormattedString("dd.MM")} - " +
|
||||
currentDate.sunday.toFormattedString("dd.MM")
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package io.github.wulkanowy.ui.modules.grade
|
||||
|
||||
import io.github.wulkanowy.data.Resource
|
||||
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.GradeSummary
|
||||
import io.github.wulkanowy.data.db.entities.Semester
|
||||
@ -13,12 +12,10 @@ import io.github.wulkanowy.sdk.Sdk
|
||||
import io.github.wulkanowy.ui.modules.grade.GradeAverageMode.*
|
||||
import io.github.wulkanowy.utils.calcAverage
|
||||
import io.github.wulkanowy.utils.changeModifier
|
||||
import io.github.wulkanowy.utils.flowWithResourceIn
|
||||
import kotlinx.coroutines.FlowPreview
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.map
|
||||
import javax.inject.Inject
|
||||
|
||||
@OptIn(FlowPreview::class)
|
||||
@ -35,7 +32,7 @@ class GradeAverageProvider @Inject constructor(
|
||||
private val isOptionalArithmeticAverage get() = preferencesRepository.isOptionalArithmeticAverage
|
||||
|
||||
fun getGradesDetailsWithAverage(student: Student, semesterId: Int, forceRefresh: Boolean) =
|
||||
flowWithResourceIn {
|
||||
flatResourceFlow {
|
||||
val semesters = semesterRepository.getSemesters(student)
|
||||
|
||||
when (preferencesRepository.gradeAverageMode) {
|
||||
@ -81,17 +78,17 @@ class GradeAverageProvider @Inject constructor(
|
||||
val firstSemesterGradeSubjects = getGradeSubjects(student, firstSemester, forceRefresh)
|
||||
|
||||
return selectedSemesterGradeSubjects.combine(firstSemesterGradeSubjects) { secondSemesterGradeSubject, firstSemesterGradeSubject ->
|
||||
if (firstSemesterGradeSubject.status == Status.ERROR) {
|
||||
if (firstSemesterGradeSubject.errorOrNull != null) {
|
||||
return@combine firstSemesterGradeSubject
|
||||
}
|
||||
|
||||
val isAnyVulcanAverageInFirstSemester =
|
||||
firstSemesterGradeSubject.data.orEmpty().any { it.isVulcanAverage }
|
||||
firstSemesterGradeSubject.dataOrNull.orEmpty().any { it.isVulcanAverage }
|
||||
val isAnyVulcanAverageInSecondSemester =
|
||||
secondSemesterGradeSubject.data.orEmpty().any { it.isVulcanAverage }
|
||||
secondSemesterGradeSubject.dataOrNull.orEmpty().any { it.isVulcanAverage }
|
||||
|
||||
val updatedData = secondSemesterGradeSubject.data?.map { secondSemesterSubject ->
|
||||
val firstSemesterSubject = firstSemesterGradeSubject.data.orEmpty()
|
||||
val updatedData = secondSemesterGradeSubject.dataOrNull?.map { secondSemesterSubject ->
|
||||
val firstSemesterSubject = firstSemesterGradeSubject.dataOrNull.orEmpty()
|
||||
.singleOrNull { it.subject == secondSemesterSubject.subject }
|
||||
|
||||
val updatedAverage = if (averageMode == ALL_YEAR) {
|
||||
@ -113,7 +110,7 @@ class GradeAverageProvider @Inject constructor(
|
||||
}
|
||||
secondSemesterSubject.copy(average = updatedAverage)
|
||||
}
|
||||
secondSemesterGradeSubject.copy(data = updatedData)
|
||||
secondSemesterGradeSubject.mapData { updatedData!! }
|
||||
}
|
||||
}
|
||||
|
||||
@ -166,17 +163,17 @@ class GradeAverageProvider @Inject constructor(
|
||||
val isGradeAverageForceCalc = preferencesRepository.gradeAverageForceCalc
|
||||
|
||||
return gradeRepository.getGrades(student, semester, forceRefresh = forceRefresh)
|
||||
.map { res ->
|
||||
val (details, summaries) = res.data ?: null to null
|
||||
val isAnyAverage = summaries.orEmpty().any { it.average != .0 }
|
||||
val allGrades = details.orEmpty().groupBy { it.subject }
|
||||
.mapResourceData { res ->
|
||||
val (details, summaries) = res
|
||||
val isAnyAverage = summaries.any { it.average != .0 }
|
||||
val allGrades = details.groupBy { it.subject }
|
||||
|
||||
val items = summaries?.emulateEmptySummaries(
|
||||
val items = summaries.emulateEmptySummaries(
|
||||
student = student,
|
||||
semester = semester,
|
||||
grades = allGrades.toList(),
|
||||
calcAverage = isAnyAverage
|
||||
)?.map { summary ->
|
||||
).map { summary ->
|
||||
val grades = allGrades[summary.subject].orEmpty()
|
||||
GradeSubject(
|
||||
subject = summary.subject,
|
||||
@ -190,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
|
||||
|
||||
import io.github.wulkanowy.data.Status
|
||||
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.StudentRepository
|
||||
import io.github.wulkanowy.data.resourceFlow
|
||||
import io.github.wulkanowy.ui.base.BasePresenter
|
||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||
import io.github.wulkanowy.utils.AnalyticsHelper
|
||||
import io.github.wulkanowy.utils.flowWithResource
|
||||
import io.github.wulkanowy.utils.getCurrentOrLast
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
@ -99,32 +99,26 @@ class GradePresenter @Inject constructor(
|
||||
}
|
||||
|
||||
private fun loadData() {
|
||||
flowWithResource {
|
||||
resourceFlow {
|
||||
val student = studentRepository.getCurrentStudent()
|
||||
semesterRepository.getSemesters(student, refreshOnNoCurrent = true)
|
||||
}.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> Timber.i("Loading grade data started")
|
||||
Status.SUCCESS -> {
|
||||
val current = it.data!!.getCurrentOrLast()
|
||||
selectedIndex = if (selectedIndex == 0) current.semesterName else selectedIndex
|
||||
schoolYear = current.schoolYear
|
||||
semesters = it.data.filter { semester -> semester.diaryId == current.diaryId }
|
||||
view?.setCurrentSemesterName(current.semesterName, schoolYear)
|
||||
|
||||
view?.run {
|
||||
Timber.i("Loading grade result: Attempt load index $currentPageIndex")
|
||||
loadChild(currentPageIndex)
|
||||
showErrorView(false)
|
||||
showSemesterSwitch(true)
|
||||
}
|
||||
}
|
||||
Status.ERROR -> {
|
||||
Timber.i("Loading grade result: An exception occurred")
|
||||
errorHandler.dispatch(it.error!!)
|
||||
}
|
||||
.logResourceStatus("load grade data")
|
||||
.onResourceData {
|
||||
val current = it.getCurrentOrLast()
|
||||
selectedIndex = if (selectedIndex == 0) current.semesterName else selectedIndex
|
||||
schoolYear = current.schoolYear
|
||||
semesters = it.filter { semester -> semester.diaryId == current.diaryId }
|
||||
view?.setCurrentSemesterName(current.semesterName, schoolYear)
|
||||
view?.run {
|
||||
Timber.i("Loading grade data: Attempt load index $currentPageIndex")
|
||||
loadChild(currentPageIndex)
|
||||
showErrorView(false)
|
||||
showSemesterSwitch(true)
|
||||
}
|
||||
}
|
||||
}.launch()
|
||||
.onResourceError(errorHandler::dispatch)
|
||||
.launch()
|
||||
}
|
||||
|
||||
private fun showErrorViewOnError(message: String, error: Throwable) {
|
||||
|
@ -12,6 +12,7 @@ import io.github.wulkanowy.data.enums.GradeColorTheme
|
||||
import io.github.wulkanowy.databinding.DialogGradeBinding
|
||||
import io.github.wulkanowy.utils.*
|
||||
|
||||
|
||||
class GradeDetailsDialog : DialogFragment() {
|
||||
|
||||
private var binding: DialogGradeBinding by lifecycleAwareVariable()
|
||||
|
@ -1,6 +1,6 @@
|
||||
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.enums.GradeExpandMode
|
||||
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.GradeSubject
|
||||
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.first
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
@ -71,7 +67,7 @@ class GradeDetailsPresenter @Inject constructor(
|
||||
}
|
||||
|
||||
fun onMarkAsReadSelected(): Boolean {
|
||||
flowWithResource {
|
||||
resourceFlow {
|
||||
val student = studentRepository.getCurrentStudent()
|
||||
val semesters = semesterRepository.getSemesters(student)
|
||||
val semester = semesters.first { item -> item.semesterId == currentSemesterId }
|
||||
@ -79,19 +75,11 @@ class GradeDetailsPresenter @Inject constructor(
|
||||
|
||||
Timber.i("Mark as read ${unreadGrades.size} grades")
|
||||
gradeRepository.updateGrades(unreadGrades.map { it.apply { isRead = true } })
|
||||
}.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> Timber.i("Select mark grades as read")
|
||||
Status.SUCCESS -> {
|
||||
Timber.i("Mark as read result: Success")
|
||||
loadData(currentSemesterId, false)
|
||||
}
|
||||
Status.ERROR -> {
|
||||
Timber.i("Mark as read result: An exception occurred")
|
||||
errorHandler.dispatch(it.error!!)
|
||||
}
|
||||
}
|
||||
}.launch("mark")
|
||||
}
|
||||
.logResourceStatus("mark grades as read")
|
||||
.onResourceSuccess { loadData(currentSemesterId, false) }
|
||||
.onResourceError(errorHandler::dispatch)
|
||||
.launch("mark")
|
||||
return true
|
||||
}
|
||||
|
||||
@ -138,71 +126,49 @@ class GradeDetailsPresenter @Inject constructor(
|
||||
}
|
||||
|
||||
private fun loadData(semesterId: Int, forceRefresh: Boolean) {
|
||||
Timber.i("Loading grade details data started")
|
||||
|
||||
flowWithResourceIn {
|
||||
flatResourceFlow {
|
||||
val student = studentRepository.getCurrentStudent()
|
||||
averageProvider.getGradesDetailsWithAverage(student, semesterId, forceRefresh)
|
||||
}.onEach {
|
||||
Timber.d("Loading grade details status: ${it.status}, data: ${it.data != null}")
|
||||
when (it.status) {
|
||||
Status.LOADING -> {
|
||||
val items = createGradeItems(it.data.orEmpty())
|
||||
if (items.isNotEmpty()) {
|
||||
Timber.i("Loading grade details result: load cached data")
|
||||
view?.run {
|
||||
updateNewGradesAmount(it.data.orEmpty())
|
||||
enableSwipe(true)
|
||||
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!!)
|
||||
}
|
||||
.logResourceStatus("load grade details")
|
||||
.onResourceData {
|
||||
view?.run {
|
||||
enableSwipe(true)
|
||||
showProgress(false)
|
||||
showErrorView(false)
|
||||
showContent(it.isNotEmpty())
|
||||
showEmpty(it.isEmpty())
|
||||
updateNewGradesAmount(it)
|
||||
updateMarkAsDoneButton()
|
||||
val items = createGradeItems(it.data)
|
||||
view?.run {
|
||||
showEmpty(items.isEmpty())
|
||||
showErrorView(false)
|
||||
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
|
||||
updateData(
|
||||
data = createGradeItems(it),
|
||||
expandMode = preferencesRepository.gradeExpandMode,
|
||||
preferencesRepository.gradeColorTheme
|
||||
)
|
||||
}
|
||||
Status.ERROR -> {
|
||||
Timber.i("Loading grade details result: An exception occurred")
|
||||
errorHandler.dispatch(it.error!!)
|
||||
}
|
||||
.onResourceIntermediate { view?.showRefresh(true) }
|
||||
.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 {
|
||||
view?.run {
|
||||
showRefresh(false)
|
||||
showProgress(false)
|
||||
enableSwipe(true)
|
||||
notifyParentDataLoaded(semesterId)
|
||||
.catch {
|
||||
errorHandler.dispatch(it)
|
||||
view?.notifyParentDataLoaded(semesterId)
|
||||
}
|
||||
}.catch {
|
||||
errorHandler.dispatch(it)
|
||||
view?.notifyParentDataLoaded(semesterId)
|
||||
}.launch()
|
||||
.onResourceError(errorHandler::dispatch)
|
||||
.launch()
|
||||
}
|
||||
|
||||
private fun updateNewGradesAmount(grades: List<GradeSubject>) {
|
||||
@ -267,15 +233,9 @@ class GradeDetailsPresenter @Inject constructor(
|
||||
}
|
||||
|
||||
private fun updateGrade(grade: Grade) {
|
||||
flowWithResource { gradeRepository.updateGrade(grade) }.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> Timber.i("Attempt to update grade ${grade.id}")
|
||||
Status.SUCCESS -> Timber.i("Update grade result: Success")
|
||||
Status.ERROR -> {
|
||||
Timber.i("Update grade result: An exception occurred")
|
||||
errorHandler.dispatch(it.error!!)
|
||||
}
|
||||
}
|
||||
}.launch("update")
|
||||
resourceFlow { gradeRepository.updateGrade(grade) }
|
||||
.logResourceStatus("update grade result ${grade.id}")
|
||||
.onResourceError(errorHandler::dispatch)
|
||||
.launch("update")
|
||||
}
|
||||
}
|
||||
|
@ -1,19 +1,12 @@
|
||||
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.pojos.GradeStatisticsItem
|
||||
import io.github.wulkanowy.data.repositories.GradeStatisticsRepository
|
||||
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.data.repositories.*
|
||||
import io.github.wulkanowy.ui.base.BasePresenter
|
||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||
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 javax.inject.Inject
|
||||
|
||||
@ -125,33 +118,26 @@ class GradeStatisticsPresenter @Inject constructor(
|
||||
}
|
||||
|
||||
private fun loadSubjects() {
|
||||
flowWithResourceIn {
|
||||
flatResourceFlow {
|
||||
val student = studentRepository.getCurrentStudent()
|
||||
val semester = semesterRepository.getCurrentSemester(student)
|
||||
subjectRepository.getSubjects(student, semester)
|
||||
}.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> Timber.i("Loading grade stats subjects started")
|
||||
Status.SUCCESS -> {
|
||||
subjects = requireNotNull(it.data)
|
||||
Timber.i("Loading grade stats subjects result: Success")
|
||||
|
||||
view?.run {
|
||||
showSubjects(!preferencesRepository.showAllSubjectsOnStatisticsList)
|
||||
updateSubjects(
|
||||
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!!)
|
||||
}
|
||||
.logResourceStatus("load grade stats subjects")
|
||||
.onResourceData {
|
||||
subjects = it
|
||||
view?.run {
|
||||
showSubjects(!preferencesRepository.showAllSubjectsOnStatisticsList)
|
||||
updateSubjects(
|
||||
data = it.map { subject -> subject.name },
|
||||
selectedIndex = it.indexOfFirst { subject ->
|
||||
subject.name == currentSubjectName
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}.launch("subjects")
|
||||
.onResourceError(errorHandler::dispatch)
|
||||
.launch("subjects")
|
||||
}
|
||||
|
||||
private fun loadDataByType(
|
||||
@ -168,7 +154,7 @@ class GradeStatisticsPresenter @Inject constructor(
|
||||
else -> subjectName
|
||||
}
|
||||
|
||||
flowWithResourceIn {
|
||||
flatResourceFlow {
|
||||
val student = studentRepository.getCurrentStudent()
|
||||
val semesters = semesterRepository.getSemesters(student)
|
||||
val semester = semesters.first { item -> item.semesterId == semesterId }
|
||||
@ -201,58 +187,43 @@ class GradeStatisticsPresenter @Inject constructor(
|
||||
}
|
||||
}
|
||||
}
|
||||
}.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> {
|
||||
val isNoContent = it.data == null || checkIsNoContent(it.data, type)
|
||||
if (!isNoContent) {
|
||||
view?.run {
|
||||
showEmpty(isNoContent)
|
||||
showErrorView(false)
|
||||
enableSwipe(true)
|
||||
showRefresh(true)
|
||||
showProgress(false)
|
||||
updateData(
|
||||
newItems = if (isNoContent) emptyList() else it.data!!,
|
||||
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
|
||||
}
|
||||
.logResourceStatus("load grade stats data")
|
||||
.mapResourceData {
|
||||
val isNoContent = checkIsNoContent(it, type)
|
||||
if (isNoContent) emptyList() else it
|
||||
}
|
||||
.onResourceData {
|
||||
view?.run {
|
||||
enableSwipe(true)
|
||||
showProgress(false)
|
||||
showErrorView(false)
|
||||
showEmpty(it.isEmpty())
|
||||
updateData(
|
||||
newItems = it,
|
||||
newTheme = preferencesRepository.gradeColorTheme,
|
||||
showAllSubjectsOnStatisticsList = preferencesRepository.showAllSubjectsOnStatisticsList
|
||||
)
|
||||
}
|
||||
Status.ERROR -> {
|
||||
Timber.i("Loading grade stats result: An exception occurred")
|
||||
errorHandler.dispatch(it.error!!)
|
||||
}
|
||||
.onResourceIntermediate { view?.showRefresh(true) }
|
||||
.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 {
|
||||
view?.run {
|
||||
showRefresh(false)
|
||||
showProgress(false)
|
||||
enableSwipe(true)
|
||||
notifyParentDataLoaded(semesterId)
|
||||
}
|
||||
}.launch("load")
|
||||
.onResourceError(errorHandler::dispatch)
|
||||
.launch("load")
|
||||
}
|
||||
|
||||
private fun checkIsNoContent(
|
||||
@ -267,7 +238,8 @@ class GradeStatisticsPresenter @Inject constructor(
|
||||
items.firstOrNull()?.partial?.classAmounts.orEmpty().sum() == 0
|
||||
}
|
||||
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
|
||||
|
||||
import io.github.wulkanowy.data.Status
|
||||
import io.github.wulkanowy.data.*
|
||||
import io.github.wulkanowy.data.db.entities.GradeSummary
|
||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||
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.GradeSubject
|
||||
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 javax.inject.Inject
|
||||
|
||||
@ -37,56 +34,40 @@ class GradeSummaryPresenter @Inject constructor(
|
||||
}
|
||||
|
||||
private fun loadData(semesterId: Int, forceRefresh: Boolean) {
|
||||
Timber.i("Loading grade summary started")
|
||||
|
||||
flowWithResourceIn {
|
||||
flatResourceFlow {
|
||||
val student = studentRepository.getCurrentStudent()
|
||||
averageProvider.getGradesDetailsWithAverage(student, semesterId, forceRefresh)
|
||||
}.onEach {
|
||||
Timber.d("Loading grade summary status: ${it.status}, data: ${it.data != null}")
|
||||
when (it.status) {
|
||||
Status.LOADING -> {
|
||||
val items = createGradeSummaryItems(it.data.orEmpty())
|
||||
if (items.isNotEmpty()) {
|
||||
Timber.i("Loading grade summary result: load cached data")
|
||||
view?.run {
|
||||
enableSwipe(true)
|
||||
showRefresh(true)
|
||||
showProgress(false)
|
||||
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!!)
|
||||
}
|
||||
.logResourceStatus("load grade summary", showData = true)
|
||||
.mapResourceData { createGradeSummaryItems(it) }
|
||||
.onResourceData {
|
||||
view?.run {
|
||||
enableSwipe(true)
|
||||
showProgress(false)
|
||||
showErrorView(false)
|
||||
showContent(it.isNotEmpty())
|
||||
showEmpty(it.isEmpty())
|
||||
updateData(it)
|
||||
}
|
||||
}
|
||||
}.afterLoading {
|
||||
view?.run {
|
||||
showRefresh(false)
|
||||
showProgress(false)
|
||||
enableSwipe(true)
|
||||
notifyParentDataLoaded(semesterId)
|
||||
.onResourceIntermediate { view?.showRefresh(true) }
|
||||
.onResourceSuccess {
|
||||
analytics.logEvent(
|
||||
"load_data",
|
||||
"type" to "grade_summary",
|
||||
"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) {
|
||||
@ -153,9 +134,9 @@ class GradeSummaryPresenter @Inject constructor(
|
||||
private fun checkEmpty(gradeSummary: GradeSubject): Boolean {
|
||||
return gradeSummary.run {
|
||||
summary.finalGrade.isBlank()
|
||||
&& summary.predictedGrade.isBlank()
|
||||
&& average == .0
|
||||
&& points.isBlank()
|
||||
&& summary.predictedGrade.isBlank()
|
||||
&& average == .0
|
||||
&& points.isBlank()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,21 +1,13 @@
|
||||
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.repositories.HomeworkRepository
|
||||
import io.github.wulkanowy.data.repositories.SemesterRepository
|
||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||
import io.github.wulkanowy.ui.base.BasePresenter
|
||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||
import io.github.wulkanowy.utils.AnalyticsHelper
|
||||
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 io.github.wulkanowy.utils.*
|
||||
import kotlinx.coroutines.flow.catch
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
@ -89,61 +81,59 @@ class HomeworkPresenter @Inject constructor(
|
||||
flow {
|
||||
val student = studentRepository.getCurrentStudent()
|
||||
emit(semesterRepository.getCurrentSemester(student))
|
||||
}.catch {
|
||||
Timber.i("Loading semester result: An exception occurred")
|
||||
}.onEach {
|
||||
baseDate = baseDate.getLastSchoolDayIfHoliday(it.schoolYear)
|
||||
currentDate = baseDate
|
||||
reloadNavigation()
|
||||
}.launch("holidays")
|
||||
}
|
||||
.catch { Timber.i("Loading semester result: An exception occurred") }
|
||||
.onEach {
|
||||
baseDate = baseDate.getLastSchoolDayIfHoliday(it.schoolYear)
|
||||
currentDate = baseDate
|
||||
reloadNavigation()
|
||||
}
|
||||
.launch("holidays")
|
||||
}
|
||||
|
||||
private fun loadData(forceRefresh: Boolean = false) {
|
||||
Timber.i("Loading homework data started")
|
||||
|
||||
flowWithResourceIn {
|
||||
flatResourceFlow {
|
||||
val student = studentRepository.getCurrentStudent()
|
||||
val semester = semesterRepository.getCurrentSemester(student)
|
||||
homeworkRepository.getHomework(student, semester, currentDate, currentDate, forceRefresh)
|
||||
}.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> {
|
||||
if (!it.data.isNullOrEmpty()) {
|
||||
view?.run {
|
||||
enableSwipe(true)
|
||||
showRefresh(true)
|
||||
showProgress(false)
|
||||
showContent(true)
|
||||
updateData(createHomeworkItem(it.data))
|
||||
}
|
||||
}
|
||||
}
|
||||
Status.SUCCESS -> {
|
||||
Timber.i("Loading homework result: Success")
|
||||
view?.apply {
|
||||
updateData(createHomeworkItem(it.data!!))
|
||||
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!!)
|
||||
homeworkRepository.getHomework(
|
||||
student = student,
|
||||
semester = semester,
|
||||
start = currentDate,
|
||||
end = currentDate,
|
||||
forceRefresh = forceRefresh
|
||||
)
|
||||
}
|
||||
.logResourceStatus("loading homework")
|
||||
.mapResourceData { createHomeworkItem(it) }
|
||||
.onResourceData {
|
||||
view?.run {
|
||||
enableSwipe(true)
|
||||
showProgress(false)
|
||||
showErrorView(false)
|
||||
showContent(it.isNotEmpty())
|
||||
showEmpty(it.isEmpty())
|
||||
updateData(it)
|
||||
}
|
||||
}
|
||||
}.afterLoading {
|
||||
view?.run {
|
||||
showRefresh(false)
|
||||
showProgress(false)
|
||||
enableSwipe(true)
|
||||
.onResourceIntermediate { view?.showRefresh(true) }
|
||||
.onResourceSuccess {
|
||||
analytics.logEvent(
|
||||
"load_data",
|
||||
"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) {
|
||||
@ -159,9 +149,10 @@ class HomeworkPresenter @Inject constructor(
|
||||
|
||||
private fun createHomeworkItem(items: List<Homework>): List<HomeworkItem<*>> {
|
||||
return items.groupBy { it.date }.toSortedMap().map { (date, exams) ->
|
||||
listOf(HomeworkItem(date, HomeworkItem.ViewType.HEADER)) + exams.reversed().map { exam ->
|
||||
HomeworkItem(exam, HomeworkItem.ViewType.ITEM)
|
||||
}
|
||||
listOf(HomeworkItem(date, HomeworkItem.ViewType.HEADER)) + exams.reversed()
|
||||
.map { exam ->
|
||||
HomeworkItem(exam, HomeworkItem.ViewType.ITEM)
|
||||
}
|
||||
}.flatten()
|
||||
}
|
||||
|
||||
@ -184,8 +175,10 @@ class HomeworkPresenter @Inject constructor(
|
||||
view?.apply {
|
||||
showPreButton(!currentDate.minusDays(7).isHolidays)
|
||||
showNextButton(!currentDate.plusDays(7).isHolidays)
|
||||
updateNavigationWeek("${currentDate.monday.toFormattedString("dd.MM")} - " +
|
||||
currentDate.sunday.toFormattedString("dd.MM"))
|
||||
updateNavigationWeek(
|
||||
"${currentDate.monday.toFormattedString("dd.MM")} - " +
|
||||
currentDate.sunday.toFormattedString("dd.MM")
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,16 @@
|
||||
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.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.SemesterRepository
|
||||
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.ErrorHandler
|
||||
import io.github.wulkanowy.utils.flowWithResource
|
||||
import io.github.wulkanowy.utils.toLocalDate
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import timber.log.Timber
|
||||
import java.time.LocalDate
|
||||
import javax.inject.Inject
|
||||
@ -55,7 +56,7 @@ class HomeworkAddPresenter @Inject constructor(
|
||||
}
|
||||
|
||||
private fun saveHomework(subject: String, teacher: String, date: LocalDate, content: String) {
|
||||
flowWithResource {
|
||||
resourceFlow {
|
||||
val student = studentRepository.getCurrentStudent()
|
||||
val semester = semesterRepository.getCurrentSemester(student)
|
||||
val entryDate = LocalDate.now()
|
||||
@ -72,21 +73,15 @@ class HomeworkAddPresenter @Inject constructor(
|
||||
attachments = emptyList(),
|
||||
).apply { isAddedByUser = true }
|
||||
)
|
||||
}.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> Timber.i("Homework insert start")
|
||||
Status.SUCCESS -> {
|
||||
Timber.i("Homework insert: Success")
|
||||
view?.run {
|
||||
showSuccessMessage()
|
||||
closeDialog()
|
||||
}
|
||||
}
|
||||
Status.ERROR -> {
|
||||
Timber.i("Homework insert result: An exception occurred")
|
||||
errorHandler.dispatch(it.error!!)
|
||||
}
|
||||
.logResourceStatus("homework insert")
|
||||
.onResourceSuccess {
|
||||
view?.run {
|
||||
showSuccessMessage()
|
||||
closeDialog()
|
||||
}
|
||||
}
|
||||
}.launch("add_homework")
|
||||
.onResourceError(errorHandler::dispatch)
|
||||
.launch("add_homework")
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,16 @@
|
||||
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.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.PreferencesRepository
|
||||
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.ErrorHandler
|
||||
import io.github.wulkanowy.utils.AnalyticsHelper
|
||||
import io.github.wulkanowy.utils.flowWithResource
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
@ -34,38 +35,26 @@ class HomeworkDetailsPresenter @Inject constructor(
|
||||
}
|
||||
|
||||
fun deleteHomework(homework: Homework) {
|
||||
flowWithResource { homeworkRepository.deleteHomework(homework) }.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> Timber.i("Homework delete start")
|
||||
Status.SUCCESS -> {
|
||||
Timber.i("Homework delete: Success")
|
||||
view?.run {
|
||||
showMessage(homeworkDeleteSuccess)
|
||||
closeDialog()
|
||||
}
|
||||
}
|
||||
Status.ERROR -> {
|
||||
Timber.i("Homework delete result: An exception occurred")
|
||||
errorHandler.dispatch(it.error!!)
|
||||
resourceFlow { homeworkRepository.deleteHomework(homework) }
|
||||
.logResourceStatus("homework delete")
|
||||
.onResourceSuccess {
|
||||
view?.run {
|
||||
showMessage(homeworkDeleteSuccess)
|
||||
closeDialog()
|
||||
}
|
||||
}
|
||||
}.launch("delete")
|
||||
.onResourceError(errorHandler::dispatch)
|
||||
.launch("delete")
|
||||
}
|
||||
|
||||
fun toggleDone(homework: Homework) {
|
||||
flowWithResource { homeworkRepository.toggleDone(homework) }.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> Timber.i("Homework details update start")
|
||||
Status.SUCCESS -> {
|
||||
Timber.i("Homework details update: Success")
|
||||
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!!)
|
||||
}
|
||||
resourceFlow { homeworkRepository.toggleDone(homework) }
|
||||
.logResourceStatus("homework details update")
|
||||
.onResourceSuccess {
|
||||
view?.updateMarkAsDoneLabel(homework.isDone)
|
||||
analytics.logEvent("homework_mark_as_done")
|
||||
}
|
||||
}.launch("toggle")
|
||||
.onResourceError(errorHandler::dispatch)
|
||||
.launch("toggle")
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,16 @@
|
||||
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.logResourceStatus
|
||||
import io.github.wulkanowy.data.onResourceNotLoading
|
||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||
import io.github.wulkanowy.data.resourceFlow
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
import io.github.wulkanowy.ui.base.BasePresenter
|
||||
import io.github.wulkanowy.ui.modules.login.LoginData
|
||||
import io.github.wulkanowy.ui.modules.login.LoginErrorHandler
|
||||
import io.github.wulkanowy.utils.AnalyticsHelper
|
||||
import io.github.wulkanowy.utils.afterLoading
|
||||
import io.github.wulkanowy.utils.flowWithResource
|
||||
import io.github.wulkanowy.utils.ifNullOrBlank
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import timber.log.Timber
|
||||
@ -129,20 +130,20 @@ class LoginAdvancedPresenter @Inject constructor(
|
||||
fun onSignInClick() {
|
||||
if (!validateCredentials()) return
|
||||
|
||||
flowWithResource { getStudentsAppropriatesToLoginType() }.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> view?.run {
|
||||
Timber.i("Login started")
|
||||
hideSoftKeyboard()
|
||||
showProgress(true)
|
||||
showContent(false)
|
||||
}
|
||||
Status.SUCCESS -> {
|
||||
Timber.i("Login result: Success")
|
||||
analytics.logEvent(
|
||||
"registration_form",
|
||||
resourceFlow { getStudentsAppropriatesToLoginType() }
|
||||
.logResourceStatus("login")
|
||||
.onEach {
|
||||
when (it) {
|
||||
is Resource.Loading -> view?.run {
|
||||
hideSoftKeyboard()
|
||||
showProgress(true)
|
||||
showContent(false)
|
||||
}
|
||||
is Resource.Success -> {
|
||||
analytics.logEvent(
|
||||
"registration_form",
|
||||
"success" to true,
|
||||
"students" to it.data!!.size,
|
||||
"students" to it.data.size,
|
||||
"error" to "No error"
|
||||
)
|
||||
val loginData = LoginData(
|
||||
@ -154,23 +155,22 @@ class LoginAdvancedPresenter @Inject constructor(
|
||||
0 -> view?.navigateToSymbol(loginData)
|
||||
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 -> {
|
||||
Timber.i("Login result: An exception occurred")
|
||||
analytics.logEvent(
|
||||
"registration_form",
|
||||
"success" to false, "students" to -1,
|
||||
"error" to it.error!!.message.ifNullOrBlank { "No message" }
|
||||
)
|
||||
loginErrorHandler.dispatch(it.error)
|
||||
}.onResourceNotLoading {
|
||||
view?.apply {
|
||||
showProgress(false)
|
||||
showContent(true)
|
||||
}
|
||||
}
|
||||
}.afterLoading {
|
||||
view?.apply {
|
||||
showProgress(false)
|
||||
showContent(true)
|
||||
}
|
||||
}.launch("login")
|
||||
}.launch("login")
|
||||
}
|
||||
|
||||
private suspend fun getStudentsAppropriatesToLoginType(): List<StudentWithSemesters> {
|
||||
|
@ -1,16 +1,13 @@
|
||||
package io.github.wulkanowy.ui.modules.login.form
|
||||
|
||||
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.ui.base.BasePresenter
|
||||
import io.github.wulkanowy.ui.modules.login.LoginData
|
||||
import io.github.wulkanowy.ui.modules.login.LoginErrorHandler
|
||||
import io.github.wulkanowy.utils.AnalyticsHelper
|
||||
import io.github.wulkanowy.utils.afterLoading
|
||||
import io.github.wulkanowy.utils.flowWithResource
|
||||
import io.github.wulkanowy.utils.ifNullOrBlank
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import timber.log.Timber
|
||||
import java.net.URL
|
||||
import javax.inject.Inject
|
||||
@ -75,7 +72,7 @@ class LoginFormPresenter @Inject constructor(
|
||||
|
||||
val username = view?.formUsernameValue.orEmpty().trim()
|
||||
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("@")
|
||||
|
||||
hosts[usernameHost]?.let {
|
||||
@ -95,54 +92,54 @@ class LoginFormPresenter @Inject constructor(
|
||||
|
||||
if (!validateCredentials(email, password, host)) return
|
||||
|
||||
flowWithResource {
|
||||
resourceFlow {
|
||||
studentRepository.getStudentsScrapper(
|
||||
email = email,
|
||||
password = password,
|
||||
scrapperBaseUrl = host,
|
||||
symbol = symbol
|
||||
)
|
||||
}.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> view?.run {
|
||||
Timber.i("Login started")
|
||||
}
|
||||
.logResourceStatus("login")
|
||||
.onResourceLoading {
|
||||
view?.run {
|
||||
hideSoftKeyboard()
|
||||
showProgress(true)
|
||||
showContent(false)
|
||||
}
|
||||
Status.SUCCESS -> {
|
||||
Timber.i("Login result: Success")
|
||||
analytics.logEvent(
|
||||
"registration_form",
|
||||
"success" to true,
|
||||
"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)
|
||||
}
|
||||
}
|
||||
.onResourceSuccess {
|
||||
when (it.size) {
|
||||
0 -> view?.navigateToSymbol(LoginData(email, password, host))
|
||||
else -> view?.navigateToStudentSelect(it)
|
||||
}
|
||||
Status.ERROR -> {
|
||||
Timber.i("Login result: An exception occurred")
|
||||
analytics.logEvent(
|
||||
"registration_form",
|
||||
"success" to false,
|
||||
"students" to -1,
|
||||
"scrapperBaseUrl" to host,
|
||||
"error" to it.error!!.message.ifNullOrBlank { "No message" })
|
||||
loginErrorHandler.dispatch(it.error)
|
||||
lastError = it.error
|
||||
view?.showContact(true)
|
||||
analytics.logEvent(
|
||||
"registration_form",
|
||||
"success" to true,
|
||||
"students" to it.size,
|
||||
"scrapperBaseUrl" to host,
|
||||
"error" to "No error"
|
||||
)
|
||||
}
|
||||
.onResourceNotLoading {
|
||||
view?.apply {
|
||||
showProgress(false)
|
||||
showContent(true)
|
||||
}
|
||||
}
|
||||
}.afterLoading {
|
||||
view?.apply {
|
||||
showProgress(false)
|
||||
showContent(true)
|
||||
.onResourceError {
|
||||
loginErrorHandler.dispatch(it)
|
||||
lastError = it
|
||||
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() {
|
||||
|
@ -1,12 +1,12 @@
|
||||
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.StudentRepository
|
||||
import io.github.wulkanowy.data.resourceFlow
|
||||
import io.github.wulkanowy.ui.base.BasePresenter
|
||||
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 kotlinx.coroutines.flow.onEach
|
||||
import timber.log.Timber
|
||||
@ -57,24 +57,28 @@ class LoginRecoverPresenter @Inject constructor(
|
||||
|
||||
if (!validateInput(username, host)) return
|
||||
|
||||
flowWithResource { recoverRepository.getReCaptchaSiteKey(host, symbol.ifBlank { "Default" }) }.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> view?.run {
|
||||
resourceFlow {
|
||||
recoverRepository.getReCaptchaSiteKey(
|
||||
host,
|
||||
symbol.ifBlank { "Default" })
|
||||
}.onEach {
|
||||
when (it) {
|
||||
is Resource.Loading -> view?.run {
|
||||
hideSoftKeyboard()
|
||||
showRecoverForm(false)
|
||||
showProgress(true)
|
||||
showErrorView(false)
|
||||
showCaptcha(false)
|
||||
}
|
||||
Status.SUCCESS -> view?.run {
|
||||
loadReCaptcha(url = it.data!!.first, siteKey = it.data.second)
|
||||
is Resource.Success -> view?.run {
|
||||
loadReCaptcha(url = it.data.first, siteKey = it.data.second)
|
||||
showProgress(false)
|
||||
showErrorView(false)
|
||||
showCaptcha(true)
|
||||
}
|
||||
Status.ERROR -> {
|
||||
is Resource.Error -> {
|
||||
Timber.i("Obtain captcha site key result: An exception occurred")
|
||||
errorHandler.dispatch(it.error!!)
|
||||
errorHandler.dispatch(it.error)
|
||||
}
|
||||
}
|
||||
}.launch("captcha")
|
||||
@ -101,26 +105,43 @@ class LoginRecoverPresenter @Inject constructor(
|
||||
val host = view?.recoverHostValue.orEmpty()
|
||||
val symbol = view?.formHostSymbol.ifNullOrBlank { "Default" }
|
||||
|
||||
flowWithResource { recoverRepository.sendRecoverRequest(host, symbol, username, reCaptchaResponse) }.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> view?.run {
|
||||
resourceFlow {
|
||||
recoverRepository.sendRecoverRequest(
|
||||
host,
|
||||
symbol,
|
||||
username,
|
||||
reCaptchaResponse
|
||||
)
|
||||
}.onEach {
|
||||
when (it) {
|
||||
is Resource.Loading -> view?.run {
|
||||
showProgress(true)
|
||||
showRecoverForm(false)
|
||||
showCaptcha(false)
|
||||
}
|
||||
Status.SUCCESS -> view?.run {
|
||||
is Resource.Success -> view?.run {
|
||||
showSuccessView(true)
|
||||
setSuccessTitle(it.data!!.substringBefore(". "))
|
||||
setSuccessTitle(it.data.substringBefore(". "))
|
||||
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")
|
||||
errorHandler.dispatch(it.error!!)
|
||||
analytics.logEvent("account_recover", "register" to host, "symbol" to symbol, "success" to false)
|
||||
errorHandler.dispatch(it.error)
|
||||
analytics.logEvent(
|
||||
"account_recover",
|
||||
"register" to host,
|
||||
"symbol" to symbol,
|
||||
"success" to false
|
||||
)
|
||||
}
|
||||
}
|
||||
}.afterLoading {
|
||||
}.onResourceNotLoading {
|
||||
view?.showProgress(false)
|
||||
}.launch("verified")
|
||||
}
|
||||
|
@ -1,14 +1,15 @@
|
||||
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.StudentWithSemesters
|
||||
import io.github.wulkanowy.data.logResourceStatus
|
||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||
import io.github.wulkanowy.data.resourceFlow
|
||||
import io.github.wulkanowy.services.sync.SyncManager
|
||||
import io.github.wulkanowy.ui.base.BasePresenter
|
||||
import io.github.wulkanowy.ui.modules.login.LoginErrorHandler
|
||||
import io.github.wulkanowy.utils.AnalyticsHelper
|
||||
import io.github.wulkanowy.utils.flowWithResource
|
||||
import io.github.wulkanowy.utils.ifNullOrBlank
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import timber.log.Timber
|
||||
@ -66,16 +67,16 @@ class LoginStudentSelectPresenter @Inject constructor(
|
||||
private fun loadData(studentsWithSemesters: List<StudentWithSemesters>) {
|
||||
resetSelectedState()
|
||||
|
||||
flowWithResource { studentRepository.getSavedStudents(false) }.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> Timber.d("Login student select students load started")
|
||||
Status.SUCCESS -> view?.updateData(studentsWithSemesters.map { studentWithSemesters ->
|
||||
studentWithSemesters to it.data!!.any { item ->
|
||||
resourceFlow { studentRepository.getSavedStudents(false) }.onEach {
|
||||
when (it) {
|
||||
is Resource.Loading -> Timber.d("Login student select students load started")
|
||||
is Resource.Success -> view?.updateData(studentsWithSemesters.map { studentWithSemesters ->
|
||||
studentWithSemesters to it.data.any { item ->
|
||||
compareStudents(studentWithSemesters.student, item.student)
|
||||
}
|
||||
})
|
||||
Status.ERROR -> {
|
||||
errorHandler.dispatch(it.error!!)
|
||||
is Resource.Error -> {
|
||||
errorHandler.dispatch(it.error)
|
||||
lastError = it.error
|
||||
view?.updateData(studentsWithSemesters.map { student -> student to false })
|
||||
}
|
||||
@ -89,29 +90,27 @@ class LoginStudentSelectPresenter @Inject constructor(
|
||||
}
|
||||
|
||||
private fun registerStudents(studentsWithSemesters: List<StudentWithSemesters>) {
|
||||
flowWithResource { studentRepository.saveStudents(studentsWithSemesters) }
|
||||
resourceFlow { studentRepository.saveStudents(studentsWithSemesters) }
|
||||
.logResourceStatus("registration")
|
||||
.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> view?.run {
|
||||
Timber.i("Registration started")
|
||||
when (it) {
|
||||
is Resource.Loading -> view?.run {
|
||||
showProgress(true)
|
||||
showContent(false)
|
||||
}
|
||||
Status.SUCCESS -> {
|
||||
Timber.i("Registration result: Success")
|
||||
is Resource.Success -> {
|
||||
syncManager.startOneTimeSyncWorker(quiet = true)
|
||||
view?.openMainView()
|
||||
logRegisterEvent(studentsWithSemesters)
|
||||
}
|
||||
Status.ERROR -> {
|
||||
Timber.i("Registration result: An exception occurred ")
|
||||
is Resource.Error -> {
|
||||
view?.apply {
|
||||
showProgress(false)
|
||||
showContent(true)
|
||||
showContact(true)
|
||||
}
|
||||
lastError = it.error
|
||||
loginErrorHandler.dispatch(it.error!!)
|
||||
loginErrorHandler.dispatch(it.error)
|
||||
logRegisterEvent(studentsWithSemesters, it.error)
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,13 @@
|
||||
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.resourceFlow
|
||||
import io.github.wulkanowy.ui.base.BasePresenter
|
||||
import io.github.wulkanowy.ui.modules.login.LoginData
|
||||
import io.github.wulkanowy.ui.modules.login.LoginErrorHandler
|
||||
import io.github.wulkanowy.utils.AnalyticsHelper
|
||||
import io.github.wulkanowy.utils.afterLoading
|
||||
import io.github.wulkanowy.utils.flowWithResource
|
||||
import io.github.wulkanowy.utils.ifNullOrBlank
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import timber.log.Timber
|
||||
@ -45,7 +45,7 @@ class LoginSymbolPresenter @Inject constructor(
|
||||
return
|
||||
}
|
||||
|
||||
flowWithResource {
|
||||
resourceFlow {
|
||||
studentRepository.getStudentsScrapper(
|
||||
email = loginData.login,
|
||||
password = loginData.password,
|
||||
@ -53,15 +53,15 @@ class LoginSymbolPresenter @Inject constructor(
|
||||
symbol = symbol,
|
||||
)
|
||||
}.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> view?.run {
|
||||
when (it) {
|
||||
is Resource.Loading -> view?.run {
|
||||
Timber.i("Login with symbol started")
|
||||
hideSoftKeyboard()
|
||||
showProgress(true)
|
||||
showContent(false)
|
||||
}
|
||||
Status.SUCCESS -> {
|
||||
when (it.data?.size) {
|
||||
is Resource.Success -> {
|
||||
when (it.data.size) {
|
||||
0 -> {
|
||||
Timber.i("Login with symbol result: Empty student list")
|
||||
view?.run {
|
||||
@ -77,13 +77,13 @@ class LoginSymbolPresenter @Inject constructor(
|
||||
analytics.logEvent(
|
||||
"registration_symbol",
|
||||
"success" to true,
|
||||
"students" to it.data!!.size,
|
||||
"students" to it.data.size,
|
||||
"scrapperBaseUrl" to loginData.baseUrl,
|
||||
"symbol" to symbol,
|
||||
"error" to "No error"
|
||||
)
|
||||
}
|
||||
Status.ERROR -> {
|
||||
is Resource.Error -> {
|
||||
Timber.i("Login with symbol result: An exception occurred")
|
||||
analytics.logEvent(
|
||||
"registration_symbol",
|
||||
@ -91,14 +91,14 @@ class LoginSymbolPresenter @Inject constructor(
|
||||
"students" to -1,
|
||||
"scrapperBaseUrl" to loginData.baseUrl,
|
||||
"symbol" to symbol,
|
||||
"error" to it.error!!.message.ifNullOrBlank { "No message" }
|
||||
"error" to it.error.message.ifNullOrBlank { "No message" }
|
||||
)
|
||||
loginErrorHandler.dispatch(it.error)
|
||||
lastError = it.error
|
||||
view?.showContact(true)
|
||||
}
|
||||
}
|
||||
}.afterLoading {
|
||||
}.onResourceNotLoading {
|
||||
view?.apply {
|
||||
showProgress(false)
|
||||
showContent(true)
|
||||
|
@ -1,14 +1,11 @@
|
||||
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.StudentRepository
|
||||
import io.github.wulkanowy.ui.base.BasePresenter
|
||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||
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 javax.inject.Inject
|
||||
|
||||
@ -34,47 +31,45 @@ class LuckyNumberPresenter @Inject constructor(
|
||||
}
|
||||
|
||||
private fun loadData(forceRefresh: Boolean = false) {
|
||||
flowWithResourceIn {
|
||||
flatResourceFlow {
|
||||
val student = studentRepository.getCurrentStudent()
|
||||
luckyNumberRepository.getLuckyNumber(student, forceRefresh)
|
||||
}.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> Timber.i("Loading lucky number started")
|
||||
Status.SUCCESS -> {
|
||||
if (it.data != null) {
|
||||
Timber.i("Loading lucky number result: Success")
|
||||
view?.apply {
|
||||
updateData(it.data)
|
||||
showContent(true)
|
||||
showEmpty(false)
|
||||
showErrorView(false)
|
||||
}
|
||||
analytics.logEvent(
|
||||
"load_item",
|
||||
"type" to "lucky_number",
|
||||
"number" to it.data.luckyNumber
|
||||
)
|
||||
} else {
|
||||
Timber.i("Loading lucky number result: No lucky number found")
|
||||
view?.run {
|
||||
showContent(false)
|
||||
showEmpty(true)
|
||||
showErrorView(false)
|
||||
}
|
||||
}
|
||||
.logResourceStatus("load lucky number")
|
||||
.onResourceData {
|
||||
if (it != null) {
|
||||
view?.apply {
|
||||
updateData(it)
|
||||
showContent(true)
|
||||
showEmpty(false)
|
||||
showErrorView(false)
|
||||
}
|
||||
} else {
|
||||
view?.run {
|
||||
showContent(false)
|
||||
showEmpty(true)
|
||||
showErrorView(false)
|
||||
}
|
||||
}
|
||||
Status.ERROR -> {
|
||||
Timber.i("Loading lucky number result: An exception occurred")
|
||||
errorHandler.dispatch(it.error!!)
|
||||
}
|
||||
.onResourceSuccess {
|
||||
if (it != null) {
|
||||
analytics.logEvent(
|
||||
"load_item",
|
||||
"type" to "lucky_number",
|
||||
"number" to it.luckyNumber
|
||||
)
|
||||
}
|
||||
}
|
||||
}.afterLoading {
|
||||
view?.run {
|
||||
hideRefresh()
|
||||
showProgress(false)
|
||||
enableSwipe(true)
|
||||
.onResourceNotLoading {
|
||||
view?.run {
|
||||
hideRefresh()
|
||||
showProgress(false)
|
||||
enableSwipe(true)
|
||||
}
|
||||
}
|
||||
}.launch()
|
||||
.onResourceError(errorHandler::dispatch)
|
||||
.launch()
|
||||
}
|
||||
|
||||
private fun showErrorViewOnError(message: String, error: Throwable) {
|
||||
|
@ -1,24 +1,12 @@
|
||||
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.SemesterRepository
|
||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||
import io.github.wulkanowy.ui.base.BasePresenter
|
||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||
import io.github.wulkanowy.utils.AnalyticsHelper
|
||||
import io.github.wulkanowy.utils.afterLoading
|
||||
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 io.github.wulkanowy.utils.*
|
||||
import kotlinx.coroutines.flow.*
|
||||
import timber.log.Timber
|
||||
import java.time.LocalDate
|
||||
import javax.inject.Inject
|
||||
@ -52,55 +40,51 @@ class LuckyNumberHistoryPresenter @Inject constructor(
|
||||
flow {
|
||||
val student = studentRepository.getCurrentStudent()
|
||||
emit(semesterRepository.getCurrentSemester(student))
|
||||
}.catch {
|
||||
Timber.i("Loading semester result: An exception occurred")
|
||||
}.onEach {
|
||||
currentDate = currentDate.getLastSchoolDayIfHoliday(it.schoolYear)
|
||||
reloadNavigation()
|
||||
}.launch("holidays")
|
||||
}
|
||||
.catch { Timber.i("Loading semester result: An exception occurred") }
|
||||
.onEach {
|
||||
currentDate = currentDate.getLastSchoolDayIfHoliday(it.schoolYear)
|
||||
reloadNavigation()
|
||||
}
|
||||
.launch("holidays")
|
||||
}
|
||||
|
||||
private fun loadData() {
|
||||
flowWithResource {
|
||||
flow {
|
||||
val student = studentRepository.getCurrentStudent()
|
||||
luckyNumberRepository.getLuckyNumberHistory(student, currentDate.monday, currentDate.sunday)
|
||||
}.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> Timber.i("Loading lucky number history started")
|
||||
Status.SUCCESS -> {
|
||||
if (!it.data?.first().isNullOrEmpty()) {
|
||||
Timber.i("Loading lucky number result: Success")
|
||||
view?.apply {
|
||||
updateData(it.data!!.first())
|
||||
showContent(true)
|
||||
showEmpty(false)
|
||||
showErrorView(false)
|
||||
showProgress(false)
|
||||
}
|
||||
analytics.logEvent(
|
||||
"load_items",
|
||||
"type" to "lucky_number_history",
|
||||
"numbers" to it.data
|
||||
)
|
||||
} else {
|
||||
Timber.i("Loading lucky number history result: No lucky numbers found")
|
||||
view?.run {
|
||||
showContent(false)
|
||||
showEmpty(true)
|
||||
showErrorView(false)
|
||||
}
|
||||
emitAll(
|
||||
luckyNumberRepository.getLuckyNumberHistory(
|
||||
student = student,
|
||||
start = currentDate.monday,
|
||||
end = currentDate.sunday
|
||||
)
|
||||
)
|
||||
}
|
||||
.onEach {
|
||||
if (!it.isNullOrEmpty()) {
|
||||
view?.apply {
|
||||
updateData(it)
|
||||
showContent(true)
|
||||
showEmpty(false)
|
||||
showErrorView(false)
|
||||
showProgress(false)
|
||||
}
|
||||
} else {
|
||||
view?.run {
|
||||
showContent(false)
|
||||
showEmpty(true)
|
||||
showErrorView(false)
|
||||
showProgress(false)
|
||||
}
|
||||
}
|
||||
Status.ERROR -> {
|
||||
Timber.i("Loading lucky number history result: An exception occurred")
|
||||
errorHandler.dispatch(it.error!!)
|
||||
}
|
||||
|
||||
analytics.logEvent(
|
||||
"load_items",
|
||||
"type" to "lucky_number_history",
|
||||
)
|
||||
}
|
||||
}.afterLoading {
|
||||
view?.run {
|
||||
showProgress(false)
|
||||
}
|
||||
}.launch()
|
||||
.catch { errorHandler.dispatch(it) }
|
||||
.launchIn(presenterScope)
|
||||
}
|
||||
|
||||
private fun showErrorViewOnError(message: String, error: Throwable) {
|
||||
@ -143,8 +127,10 @@ class LuckyNumberHistoryPresenter @Inject constructor(
|
||||
view?.apply {
|
||||
showPreButton(!currentDate.minusDays(7).isHolidays)
|
||||
showNextButton(!currentDate.plusDays(7).isHolidays)
|
||||
updateNavigationWeek("${currentDate.monday.toFormattedString("dd.MM")} - " +
|
||||
currentDate.sunday.toFormattedString("dd.MM"))
|
||||
updateNavigationWeek(
|
||||
"${currentDate.monday.toFormattedString("dd.MM")} - " +
|
||||
currentDate.sunday.toFormattedString("dd.MM")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,14 +1,14 @@
|
||||
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.entities.Student
|
||||
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.ErrorHandler
|
||||
import io.github.wulkanowy.ui.modules.luckynumberwidget.LuckyNumberWidgetProvider.Companion.getStudentWidgetKey
|
||||
import io.github.wulkanowy.ui.modules.luckynumberwidget.LuckyNumberWidgetProvider.Companion.getThemeWidgetKey
|
||||
import io.github.wulkanowy.utils.flowWithResource
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
@ -47,16 +47,15 @@ class LuckyNumberWidgetConfigurePresenter @Inject constructor(
|
||||
}
|
||||
|
||||
private fun loadData() {
|
||||
flowWithResource { studentRepository.getSavedStudents(false) }.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> Timber.d("Lucky number widget configure students data load")
|
||||
Status.SUCCESS -> {
|
||||
resourceFlow { studentRepository.getSavedStudents(false) }.onEach {
|
||||
when (it) {
|
||||
is Resource.Loading -> Timber.d("Lucky number widget configure students data load")
|
||||
is Resource.Success -> {
|
||||
val selectedStudentId = appWidgetId?.let { id ->
|
||||
sharedPref.getLong(getStudentWidgetKey(id), 0)
|
||||
} ?: -1
|
||||
|
||||
when {
|
||||
it.data!!.isEmpty() -> view?.openLoginView()
|
||||
it.data.isEmpty() -> view?.openLoginView()
|
||||
it.data.size == 1 -> {
|
||||
selectedStudent = it.data.single().student
|
||||
view?.showThemeDialog()
|
||||
@ -64,7 +63,7 @@ class LuckyNumberWidgetConfigurePresenter @Inject constructor(
|
||||
else -> view?.updateData(it.data, selectedStudentId)
|
||||
}
|
||||
}
|
||||
Status.ERROR -> errorHandler.dispatch(it.error!!)
|
||||
is Resource.Error -> errorHandler.dispatch(it.error)
|
||||
}
|
||||
}.launch()
|
||||
}
|
||||
|
@ -13,14 +13,17 @@ import android.view.View.VISIBLE
|
||||
import android.widget.RemoteViews
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
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.entities.LuckyNumber
|
||||
import io.github.wulkanowy.data.exceptions.NoCurrentStudentException
|
||||
import io.github.wulkanowy.data.repositories.LuckyNumberRepository
|
||||
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.splash.SplashActivity
|
||||
import io.github.wulkanowy.utils.PendingIntentCompat
|
||||
import io.github.wulkanowy.utils.toFirstResult
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
@ -66,12 +69,16 @@ class LuckyNumberWidgetProvider : AppWidgetProvider() {
|
||||
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 =
|
||||
RemoteViews(context.packageName, getCorrectLayoutId(appWidgetId, context))
|
||||
.apply {
|
||||
setTextViewText(
|
||||
R.id.luckyNumberWidgetNumber,
|
||||
luckyNumber?.luckyNumber?.toString() ?: "#"
|
||||
luckyNumber.dataOrNull?.toString() ?: "#"
|
||||
)
|
||||
setOnClickPendingIntent(R.id.luckyNumberWidgetContainer, appIntent)
|
||||
}
|
||||
@ -167,14 +174,17 @@ class LuckyNumberWidgetProvider : AppWidgetProvider() {
|
||||
else -> null
|
||||
}
|
||||
|
||||
currentStudent?.let {
|
||||
luckyNumberRepository.getLuckyNumber(it, false).toFirstResult().data
|
||||
if (currentStudent != null) {
|
||||
luckyNumberRepository.getLuckyNumber(currentStudent, forceRefresh = false)
|
||||
.toFirstResult()
|
||||
} else {
|
||||
Resource.Success<LuckyNumber?>(null)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
if (e.cause !is NoCurrentStudentException) {
|
||||
Timber.e(e, "An error has occurred in lucky number provider")
|
||||
}
|
||||
null
|
||||
Resource.Error(e)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,12 @@
|
||||
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.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.StudentRepository
|
||||
import io.github.wulkanowy.data.resourceFlow
|
||||
import io.github.wulkanowy.services.sync.SyncManager
|
||||
import io.github.wulkanowy.ui.base.BasePresenter
|
||||
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.studentinfo.StudentInfoView
|
||||
import io.github.wulkanowy.utils.AnalyticsHelper
|
||||
import io.github.wulkanowy.utils.flowWithResource
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import timber.log.Timber
|
||||
import java.time.Duration
|
||||
import java.time.Instant
|
||||
@ -75,20 +76,14 @@ class MainPresenter @Inject constructor(
|
||||
return
|
||||
}
|
||||
|
||||
flowWithResource { studentRepository.getSavedStudents(false) }
|
||||
.onEach { resource ->
|
||||
when (resource.status) {
|
||||
Status.LOADING -> Timber.i("Loading student avatar data started")
|
||||
Status.SUCCESS -> {
|
||||
studentsWitSemesters = resource.data
|
||||
showCurrentStudentAvatar()
|
||||
}
|
||||
Status.ERROR -> {
|
||||
Timber.i("Loading student avatar result: An exception occurred")
|
||||
errorHandler.dispatch(resource.error!!)
|
||||
}
|
||||
}
|
||||
}.launch("avatar")
|
||||
resourceFlow { studentRepository.getSavedStudents(false) }
|
||||
.logResourceStatus("load student avatar")
|
||||
.onResourceSuccess {
|
||||
studentsWitSemesters = it
|
||||
showCurrentStudentAvatar()
|
||||
}
|
||||
.onResourceError(errorHandler::dispatch)
|
||||
.launch("avatar")
|
||||
}
|
||||
|
||||
fun onViewChange(destinationView: BaseView) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
package io.github.wulkanowy.ui.modules.message.preview
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import io.github.wulkanowy.data.Status
|
||||
import io.github.wulkanowy.data.*
|
||||
import io.github.wulkanowy.data.db.entities.Message
|
||||
import io.github.wulkanowy.data.db.entities.MessageAttachment
|
||||
import io.github.wulkanowy.data.enums.MessageFolder
|
||||
@ -10,11 +10,8 @@ import io.github.wulkanowy.data.repositories.StudentRepository
|
||||
import io.github.wulkanowy.ui.base.BasePresenter
|
||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||
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 io.github.wulkanowy.utils.toFormattedString
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
@ -53,44 +50,43 @@ class MessagePreviewPresenter @Inject constructor(
|
||||
view?.showErrorDetailsDialog(lastError)
|
||||
}
|
||||
|
||||
private fun loadData(message: Message) {
|
||||
flowWithResourceIn {
|
||||
val student = studentRepository.getStudentById(message.studentId)
|
||||
messageRepository.getMessage(student, message, true)
|
||||
}.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> Timber.i("Loading message ${message.messageId} preview started")
|
||||
Status.SUCCESS -> {
|
||||
Timber.i("Loading message ${message.messageId} preview result: Success ")
|
||||
if (it.data != null) {
|
||||
this@MessagePreviewPresenter.message = it.data.message
|
||||
this@MessagePreviewPresenter.attachments = it.data.attachments
|
||||
view?.apply {
|
||||
setMessageWithAttachment(it.data)
|
||||
showContent(true)
|
||||
initOptions()
|
||||
}
|
||||
analytics.logEvent(
|
||||
"load_item",
|
||||
"type" to "message_preview",
|
||||
"length" to it.data.message.content.length
|
||||
)
|
||||
} else {
|
||||
view?.run {
|
||||
showMessage(messageNotExists)
|
||||
popView()
|
||||
}
|
||||
private fun loadData(messageToLoad: Message) {
|
||||
flatResourceFlow {
|
||||
val student = studentRepository.getStudentById(messageToLoad.studentId)
|
||||
messageRepository.getMessage(student, messageToLoad, true)
|
||||
}
|
||||
.logResourceStatus("message ${messageToLoad.messageId} preview")
|
||||
.onResourceData {
|
||||
if (it != null) {
|
||||
message = it.message
|
||||
attachments = it.attachments
|
||||
view?.apply {
|
||||
setMessageWithAttachment(it)
|
||||
showContent(true)
|
||||
initOptions()
|
||||
}
|
||||
} else {
|
||||
view?.run {
|
||||
showMessage(messageNotExists)
|
||||
popView()
|
||||
}
|
||||
}
|
||||
Status.ERROR -> {
|
||||
Timber.i("Loading message ${message.messageId} preview result: An exception occurred ")
|
||||
retryCallback = { onMessageLoadRetry(message) }
|
||||
errorHandler.dispatch(it.error!!)
|
||||
}
|
||||
.onResourceSuccess {
|
||||
if (it != null) {
|
||||
analytics.logEvent(
|
||||
"load_item",
|
||||
"type" to "message_preview",
|
||||
"length" to it.message.content.length
|
||||
)
|
||||
}
|
||||
}
|
||||
}.afterLoading {
|
||||
view?.showProgress(false)
|
||||
}.launch()
|
||||
.onResourceNotLoading { view?.showProgress(false) }
|
||||
.onResourceError {
|
||||
retryCallback = { onMessageLoadRetry(messageToLoad) }
|
||||
errorHandler.dispatch(it)
|
||||
}
|
||||
.launch()
|
||||
}
|
||||
|
||||
fun onReply(): Boolean {
|
||||
@ -176,28 +172,26 @@ class MessagePreviewPresenter @Inject constructor(
|
||||
showErrorView(false)
|
||||
}
|
||||
|
||||
flowWithResource {
|
||||
val student = studentRepository.getCurrentStudent()
|
||||
messageRepository.deleteMessage(student, message!!)
|
||||
}.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> Timber.d("Message ${message?.id} delete started")
|
||||
Status.SUCCESS -> {
|
||||
Timber.d("Message ${message?.id} delete success")
|
||||
Timber.i("Delete message ${message?.id}")
|
||||
|
||||
presenterScope.launch {
|
||||
runCatching {
|
||||
val student = studentRepository.getCurrentStudent()
|
||||
messageRepository.deleteMessage(student, message!!)
|
||||
}
|
||||
.onFailure {
|
||||
retryCallback = { onMessageDelete() }
|
||||
errorHandler.dispatch(it)
|
||||
}
|
||||
.onSuccess {
|
||||
view?.run {
|
||||
showMessage(deleteMessageSuccessString)
|
||||
popView()
|
||||
}
|
||||
}
|
||||
Status.ERROR -> {
|
||||
Timber.d("Message ${message?.id} delete failed")
|
||||
retryCallback = { onMessageDelete() }
|
||||
errorHandler.dispatch(it.error!!)
|
||||
}
|
||||
}
|
||||
}.afterLoading {
|
||||
|
||||
view?.showProgress(false)
|
||||
}.launch("delete")
|
||||
}
|
||||
}
|
||||
|
||||
private fun showErrorViewOnError(message: String, error: Throwable) {
|
||||
|
@ -1,25 +1,20 @@
|
||||
package io.github.wulkanowy.ui.modules.message.send
|
||||
|
||||
import io.github.wulkanowy.data.Status
|
||||
import io.github.wulkanowy.data.Resource
|
||||
import io.github.wulkanowy.data.db.entities.Message
|
||||
import io.github.wulkanowy.data.db.entities.Recipient
|
||||
import io.github.wulkanowy.data.logResourceStatus
|
||||
import io.github.wulkanowy.data.onResourceNotLoading
|
||||
import io.github.wulkanowy.data.pojos.MessageDraft
|
||||
import io.github.wulkanowy.data.repositories.MessageRepository
|
||||
import io.github.wulkanowy.data.repositories.PreferencesRepository
|
||||
import io.github.wulkanowy.data.repositories.RecipientRepository
|
||||
import io.github.wulkanowy.data.repositories.ReportingUnitRepository
|
||||
import io.github.wulkanowy.data.repositories.SemesterRepository
|
||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||
import io.github.wulkanowy.data.repositories.*
|
||||
import io.github.wulkanowy.data.resourceFlow
|
||||
import io.github.wulkanowy.ui.base.BasePresenter
|
||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||
import io.github.wulkanowy.utils.AnalyticsHelper
|
||||
import io.github.wulkanowy.utils.afterLoading
|
||||
import io.github.wulkanowy.utils.flowWithResource
|
||||
import io.github.wulkanowy.utils.toFormattedString
|
||||
import kotlinx.coroutines.FlowPreview
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.flow.catch
|
||||
import kotlinx.coroutines.flow.collect
|
||||
import kotlinx.coroutines.flow.consumeAsFlow
|
||||
import kotlinx.coroutines.flow.debounce
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
@ -55,10 +50,12 @@ class SendMessagePresenter @Inject constructor(
|
||||
setContent(it)
|
||||
}
|
||||
message?.let {
|
||||
setSubject(when (reply) {
|
||||
true -> "Re: "
|
||||
else -> "FW: "
|
||||
} + message.subject)
|
||||
setSubject(
|
||||
when (reply) {
|
||||
true -> "Re: "
|
||||
else -> "FW: "
|
||||
} + message.subject
|
||||
)
|
||||
if (preferencesRepository.fillMessageContent || reply != true) {
|
||||
setContent(
|
||||
when (reply) {
|
||||
@ -67,7 +64,8 @@ class SendMessagePresenter @Inject constructor(
|
||||
} + when (message.sender.isNotEmpty()) {
|
||||
true -> "Od: ${message.sender}\n"
|
||||
false -> "Do: ${message.recipient}\n"
|
||||
} + "Data: ${message.date.toFormattedString("yyyy-MM-dd HH:mm:ss")}\n\n${message.content}")
|
||||
} + "Data: ${message.date.toFormattedString("yyyy-MM-dd HH:mm:ss")}\n\n${message.content}"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -111,7 +109,7 @@ class SendMessagePresenter @Inject constructor(
|
||||
}
|
||||
|
||||
private fun loadData(message: Message?, reply: Boolean?) {
|
||||
flowWithResource {
|
||||
resourceFlow {
|
||||
val student = studentRepository.getCurrentStudent()
|
||||
val semester = semesterRepository.getCurrentSemester(student)
|
||||
val unit = reportingUnitRepository.getReportingUnit(student, semester.unitId)
|
||||
@ -125,58 +123,64 @@ class SendMessagePresenter @Inject constructor(
|
||||
|
||||
Timber.i("Loading message recipients started")
|
||||
val messageRecipients = when {
|
||||
message != null && reply == true -> recipientRepository.getMessageRecipients(student, message)
|
||||
message != null && reply == true -> recipientRepository.getMessageRecipients(
|
||||
student,
|
||||
message
|
||||
)
|
||||
else -> emptyList()
|
||||
}.let { createChips(it) }
|
||||
Timber.i("Loaded message recipients to reply result: Success, fetched %d recipients", messageRecipients.size)
|
||||
Timber.i(
|
||||
"Loaded message recipients to reply result: Success, fetched %d recipients",
|
||||
messageRecipients.size
|
||||
)
|
||||
|
||||
Triple(unit, recipients, messageRecipients)
|
||||
}.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> view?.run {
|
||||
Timber.i("Loading recipients started")
|
||||
showProgress(true)
|
||||
showContent(false)
|
||||
}
|
||||
Status.SUCCESS -> it.data!!.let { (reportingUnit, recipientChips, selectedRecipientChips) ->
|
||||
view?.run {
|
||||
if (reportingUnit != null) {
|
||||
setReportingUnit(reportingUnit)
|
||||
setRecipients(recipientChips)
|
||||
if (selectedRecipientChips.isNotEmpty()) setSelectedRecipients(selectedRecipientChips)
|
||||
showContent(true)
|
||||
} else {
|
||||
Timber.i("Loading recipients result: Can't find the reporting unit")
|
||||
view?.showEmpty(true)
|
||||
}
|
||||
.logResourceStatus("load recipients")
|
||||
.onEach {
|
||||
when (it) {
|
||||
is Resource.Loading -> view?.run {
|
||||
showProgress(true)
|
||||
showContent(false)
|
||||
}
|
||||
is Resource.Success -> it.data.let { (reportingUnit, recipientChips, selectedRecipientChips) ->
|
||||
view?.run {
|
||||
if (reportingUnit != null) {
|
||||
setReportingUnit(reportingUnit)
|
||||
setRecipients(recipientChips)
|
||||
if (selectedRecipientChips.isNotEmpty()) setSelectedRecipients(
|
||||
selectedRecipientChips
|
||||
)
|
||||
showContent(true)
|
||||
} else {
|
||||
Timber.i("Loading recipients result: Can't find the reporting unit")
|
||||
view?.showEmpty(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
is Resource.Error -> {
|
||||
view?.showContent(true)
|
||||
errorHandler.dispatch(it.error)
|
||||
}
|
||||
}
|
||||
Status.ERROR -> {
|
||||
Timber.i("Loading recipients result: An exception occurred")
|
||||
view?.showContent(true)
|
||||
errorHandler.dispatch(it.error!!)
|
||||
}
|
||||
}
|
||||
}.afterLoading {
|
||||
view?.run { showProgress(false) }
|
||||
}.launch()
|
||||
}.onResourceNotLoading {
|
||||
view?.run { showProgress(false) }
|
||||
}.launch()
|
||||
}
|
||||
|
||||
private fun sendMessage(subject: String, content: String, recipients: List<Recipient>) {
|
||||
flowWithResource {
|
||||
resourceFlow {
|
||||
val student = studentRepository.getCurrentStudent()
|
||||
messageRepository.sendMessage(student, subject, content, recipients)
|
||||
}.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> view?.run {
|
||||
Timber.i("Sending message started")
|
||||
}.logResourceStatus("sending message").onEach {
|
||||
when (it) {
|
||||
is Resource.Loading -> view?.run {
|
||||
showSoftInput(false)
|
||||
showContent(false)
|
||||
showProgress(true)
|
||||
showActionBar(false)
|
||||
}
|
||||
Status.SUCCESS -> {
|
||||
Timber.i("Sending message result: Success")
|
||||
is Resource.Success -> {
|
||||
view?.clearDraft()
|
||||
view?.run {
|
||||
showMessage(messageSuccess)
|
||||
@ -184,14 +188,13 @@ class SendMessagePresenter @Inject constructor(
|
||||
}
|
||||
analytics.logEvent("send_message", "recipients" to recipients.size)
|
||||
}
|
||||
Status.ERROR -> {
|
||||
Timber.i("Sending message result: An exception occurred")
|
||||
is Resource.Error -> {
|
||||
view?.run {
|
||||
showContent(true)
|
||||
showProgress(false)
|
||||
showActionBar(true)
|
||||
}
|
||||
errorHandler.dispatch(it.error!!)
|
||||
errorHandler.dispatch(it.error)
|
||||
}
|
||||
}
|
||||
}.launch("send")
|
||||
@ -259,7 +262,8 @@ class SendMessagePresenter @Inject constructor(
|
||||
}
|
||||
|
||||
fun getRecipientsNames(): String {
|
||||
return messageRepository.draftMessage?.recipients.orEmpty().joinToString { it.recipient.name }
|
||||
return messageRepository.draftMessage?.recipients.orEmpty()
|
||||
.joinToString { it.recipient.name }
|
||||
}
|
||||
|
||||
fun clearDraft() {
|
||||
@ -267,6 +271,7 @@ class SendMessagePresenter @Inject constructor(
|
||||
Timber.i("Draft cleared!")
|
||||
}
|
||||
|
||||
fun getMessageBackupContent(recipients: String) = if (recipients.isEmpty()) view?.getMessageBackupDialogString()
|
||||
fun getMessageBackupContent(recipients: String) =
|
||||
if (recipients.isEmpty()) view?.getMessageBackupDialogString()
|
||||
else view?.getMessageBackupDialogStringWithRecipients(recipients)
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
package io.github.wulkanowy.ui.modules.message.tab
|
||||
|
||||
import io.github.wulkanowy.data.Status
|
||||
import io.github.wulkanowy.data.*
|
||||
import io.github.wulkanowy.data.db.entities.Message
|
||||
import io.github.wulkanowy.data.enums.MessageFolder
|
||||
import io.github.wulkanowy.data.repositories.MessageRepository
|
||||
@ -9,17 +9,10 @@ import io.github.wulkanowy.data.repositories.StudentRepository
|
||||
import io.github.wulkanowy.ui.base.BasePresenter
|
||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||
import io.github.wulkanowy.utils.AnalyticsHelper
|
||||
import io.github.wulkanowy.utils.afterLoading
|
||||
import io.github.wulkanowy.utils.flowWithResourceIn
|
||||
import io.github.wulkanowy.utils.toFormattedString
|
||||
import kotlinx.coroutines.FlowPreview
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.flow.catch
|
||||
import kotlinx.coroutines.flow.collect
|
||||
import kotlinx.coroutines.flow.consumeAsFlow
|
||||
import kotlinx.coroutines.flow.debounce
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.launch
|
||||
import me.xdrop.fuzzywuzzy.FuzzySearch
|
||||
import timber.log.Timber
|
||||
@ -107,64 +100,75 @@ class MessageTabPresenter @Inject constructor(
|
||||
) {
|
||||
Timber.i("Loading $folder message data started")
|
||||
|
||||
flowWithResourceIn {
|
||||
flatResourceFlow {
|
||||
val student = studentRepository.getCurrentStudent()
|
||||
val semester = semesterRepository.getCurrentSemester(student)
|
||||
messageRepository.getMessages(student, semester, folder, forceRefresh)
|
||||
}.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> {
|
||||
if (!it.data.isNullOrEmpty()) {
|
||||
view?.run {
|
||||
enableSwipe(true)
|
||||
showErrorView(false)
|
||||
showRefresh(true)
|
||||
showProgress(false)
|
||||
showContent(true)
|
||||
messages = it.data
|
||||
val filteredData = getFilteredData(
|
||||
}
|
||||
.logResourceStatus("load $folder message")
|
||||
.onEach {
|
||||
when (it) {
|
||||
is Resource.Intermediate -> {
|
||||
if (it.data.isNotEmpty()) {
|
||||
view?.run {
|
||||
enableSwipe(true)
|
||||
showErrorView(false)
|
||||
showRefresh(true)
|
||||
showProgress(false)
|
||||
showContent(true)
|
||||
messages = it.data
|
||||
val filteredData = getFilteredData(
|
||||
lastSearchQuery,
|
||||
onlyUnread,
|
||||
onlyWithAttachments
|
||||
)
|
||||
val messageItems = filteredData.map { message ->
|
||||
MessageTabDataItem.MessageItem(message)
|
||||
}
|
||||
val messageItemsWithHeader =
|
||||
listOf(MessageTabDataItem.Header) + messageItems
|
||||
|
||||
updateData(
|
||||
messageItemsWithHeader,
|
||||
folder.id == MessageFolder.SENT.id
|
||||
)
|
||||
notifyParentDataLoaded()
|
||||
}
|
||||
}
|
||||
}
|
||||
is Resource.Success -> {
|
||||
messages = it.data
|
||||
updateData(
|
||||
getFilteredData(
|
||||
lastSearchQuery,
|
||||
onlyUnread,
|
||||
onlyWithAttachments
|
||||
)
|
||||
val messageItems = filteredData.map { message ->
|
||||
MessageTabDataItem.MessageItem(message)
|
||||
}
|
||||
val messageItemsWithHeader =
|
||||
listOf(MessageTabDataItem.Header) + messageItems
|
||||
|
||||
updateData(messageItemsWithHeader, folder.id == MessageFolder.SENT.id)
|
||||
notifyParentDataLoaded()
|
||||
}
|
||||
)
|
||||
analytics.logEvent(
|
||||
"load_data",
|
||||
"type" to "messages",
|
||||
"items" to it.data.size,
|
||||
"folder" to folder.name
|
||||
)
|
||||
}
|
||||
}
|
||||
Status.SUCCESS -> {
|
||||
Timber.i("Loading $folder message result: Success")
|
||||
messages = it.data!!
|
||||
updateData(getFilteredData(lastSearchQuery, onlyUnread, onlyWithAttachments))
|
||||
analytics.logEvent(
|
||||
"load_data",
|
||||
"type" to "messages",
|
||||
"items" to it.data.size,
|
||||
"folder" to folder.name
|
||||
)
|
||||
}
|
||||
Status.ERROR -> {
|
||||
Timber.i("Loading $folder message result: An exception occurred")
|
||||
errorHandler.dispatch(it.error!!)
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
}.afterLoading {
|
||||
view?.run {
|
||||
showRefresh(false)
|
||||
showProgress(false)
|
||||
enableSwipe(true)
|
||||
notifyParentDataLoaded()
|
||||
.onResourceNotLoading {
|
||||
view?.run {
|
||||
showRefresh(false)
|
||||
showProgress(false)
|
||||
enableSwipe(true)
|
||||
notifyParentDataLoaded()
|
||||
}
|
||||
}
|
||||
}.catch {
|
||||
errorHandler.dispatch(it)
|
||||
view?.notifyParentDataLoaded()
|
||||
}.launch()
|
||||
.onResourceError(errorHandler::dispatch)
|
||||
.catch {
|
||||
errorHandler.dispatch(it)
|
||||
view?.notifyParentDataLoaded()
|
||||
}
|
||||
.launch()
|
||||
}
|
||||
|
||||
private fun showErrorViewOnError(message: String, error: Throwable) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
package io.github.wulkanowy.ui.modules.mobiledevice
|
||||
|
||||
import io.github.wulkanowy.data.Status
|
||||
import io.github.wulkanowy.data.*
|
||||
import io.github.wulkanowy.data.db.entities.MobileDevice
|
||||
import io.github.wulkanowy.data.repositories.MobileDeviceRepository
|
||||
import io.github.wulkanowy.data.repositories.SemesterRepository
|
||||
@ -8,10 +8,6 @@ import io.github.wulkanowy.data.repositories.StudentRepository
|
||||
import io.github.wulkanowy.ui.base.BasePresenter
|
||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||
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.onEach
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
@ -52,49 +48,39 @@ class MobileDevicePresenter @Inject constructor(
|
||||
private fun loadData(forceRefresh: Boolean = false) {
|
||||
Timber.i("Loading mobile devices data started")
|
||||
|
||||
flowWithResourceIn {
|
||||
flatResourceFlow {
|
||||
val student = studentRepository.getCurrentStudent()
|
||||
val semester = semesterRepository.getCurrentSemester(student)
|
||||
mobileDeviceRepository.getDevices(student, semester, forceRefresh)
|
||||
}.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> {
|
||||
if (!it.data.isNullOrEmpty()) {
|
||||
view?.run {
|
||||
enableSwipe(true)
|
||||
showRefresh(true)
|
||||
showProgress(false)
|
||||
showContent(true)
|
||||
updateData(it.data)
|
||||
}
|
||||
}
|
||||
}
|
||||
Status.SUCCESS -> {
|
||||
Timber.i("Loading mobile devices result: Success")
|
||||
view?.run {
|
||||
updateData(it.data!!)
|
||||
showContent(it.data.isNotEmpty())
|
||||
showEmpty(it.data.isEmpty())
|
||||
showErrorView(false)
|
||||
}
|
||||
analytics.logEvent(
|
||||
"load_data",
|
||||
"type" to "devices",
|
||||
"items" to it.data!!.size
|
||||
)
|
||||
}
|
||||
Status.ERROR -> {
|
||||
Timber.i("Loading mobile devices result: An exception occurred")
|
||||
errorHandler.dispatch(it.error!!)
|
||||
}
|
||||
.logResourceStatus("load mobile devices data")
|
||||
.onResourceData {
|
||||
view?.run {
|
||||
enableSwipe(true)
|
||||
showProgress(false)
|
||||
showErrorView(false)
|
||||
showContent(it.isNotEmpty())
|
||||
showEmpty(it.isEmpty())
|
||||
updateData(it)
|
||||
}
|
||||
}
|
||||
}.afterLoading {
|
||||
view?.run {
|
||||
showRefresh(false)
|
||||
showProgress(false)
|
||||
enableSwipe(true)
|
||||
.onResourceIntermediate { view?.showRefresh(true) }
|
||||
.onResourceSuccess {
|
||||
analytics.logEvent(
|
||||
"load_data",
|
||||
"type" to "devices",
|
||||
"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) {
|
||||
@ -128,25 +114,19 @@ class MobileDevicePresenter @Inject constructor(
|
||||
}
|
||||
|
||||
fun onUnregisterConfirmed(device: MobileDevice) {
|
||||
flowWithResource {
|
||||
resourceFlow {
|
||||
val student = studentRepository.getCurrentStudent()
|
||||
val semester = semesterRepository.getCurrentSemester(student)
|
||||
mobileDeviceRepository.unregisterDevice(student, semester, device)
|
||||
}.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> Timber.i("Unregister device started")
|
||||
Status.SUCCESS -> {
|
||||
Timber.i("Unregister device result: Success")
|
||||
view?.run {
|
||||
showProgress(false)
|
||||
enableSwipe(true)
|
||||
}
|
||||
}
|
||||
Status.ERROR -> {
|
||||
Timber.i("Unregister device result: An exception occurred")
|
||||
errorHandler.dispatch(it.error!!)
|
||||
}
|
||||
.logResourceStatus("unregister device")
|
||||
.onResourceSuccess {
|
||||
view?.run {
|
||||
showProgress(false)
|
||||
enableSwipe(true)
|
||||
}
|
||||
}
|
||||
}.launch("unregister")
|
||||
.onResourceError(errorHandler::dispatch)
|
||||
.launch("unregister")
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,12 @@
|
||||
package io.github.wulkanowy.ui.modules.mobiledevice.token
|
||||
|
||||
import io.github.wulkanowy.data.Status
|
||||
import io.github.wulkanowy.data.*
|
||||
import io.github.wulkanowy.data.repositories.MobileDeviceRepository
|
||||
import io.github.wulkanowy.data.repositories.SemesterRepository
|
||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||
import io.github.wulkanowy.ui.base.BasePresenter
|
||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||
import io.github.wulkanowy.utils.AnalyticsHelper
|
||||
import io.github.wulkanowy.utils.afterLoading
|
||||
import io.github.wulkanowy.utils.flowWithResource
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
@ -29,29 +26,29 @@ class MobileDeviceTokenPresenter @Inject constructor(
|
||||
}
|
||||
|
||||
private fun loadData() {
|
||||
flowWithResource {
|
||||
resourceFlow {
|
||||
val student = studentRepository.getCurrentStudent()
|
||||
val semester = semesterRepository.getCurrentSemester(student)
|
||||
mobileDeviceRepository.getToken(student, semester)
|
||||
}.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> Timber.i("Mobile device registration data started")
|
||||
Status.SUCCESS -> {
|
||||
Timber.i("Mobile device registration result: Success")
|
||||
view?.run {
|
||||
updateData(it.data!!)
|
||||
showContent()
|
||||
}
|
||||
analytics.logEvent("device_register", "symbol" to it.data!!.token.substring(0, 3))
|
||||
}
|
||||
Status.ERROR -> {
|
||||
Timber.i("Mobile device registration result: An exception occurred")
|
||||
view?.closeDialog()
|
||||
errorHandler.dispatch(it.error!!)
|
||||
}
|
||||
.logResourceStatus("load mobile device registration")
|
||||
.onResourceData {
|
||||
view?.run {
|
||||
updateData(it)
|
||||
showContent()
|
||||
}
|
||||
}
|
||||
}.afterLoading {
|
||||
view?.hideLoading()
|
||||
}.launch()
|
||||
.onResourceSuccess {
|
||||
analytics.logEvent(
|
||||
"device_register",
|
||||
"symbol" to it.token.substring(0, 3)
|
||||
)
|
||||
}
|
||||
.onResourceNotLoading { view?.hideLoading() }
|
||||
.onResourceError {
|
||||
view?.closeDialog()
|
||||
errorHandler.dispatch(it)
|
||||
}
|
||||
.launch()
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
package io.github.wulkanowy.ui.modules.note
|
||||
|
||||
import io.github.wulkanowy.data.Status
|
||||
import io.github.wulkanowy.data.*
|
||||
import io.github.wulkanowy.data.db.entities.Note
|
||||
import io.github.wulkanowy.data.repositories.NoteRepository
|
||||
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.ErrorHandler
|
||||
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.onEach
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
@ -51,51 +48,40 @@ class NotePresenter @Inject constructor(
|
||||
}
|
||||
|
||||
private fun loadData(forceRefresh: Boolean = false) {
|
||||
Timber.i("Loading note data started")
|
||||
|
||||
flowWithResourceIn {
|
||||
flatResourceFlow {
|
||||
val student = studentRepository.getCurrentStudent()
|
||||
val semester = semesterRepository.getCurrentSemester(student)
|
||||
noteRepository.getNotes(student, semester, forceRefresh)
|
||||
}.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> {
|
||||
if (!it.data.isNullOrEmpty()) {
|
||||
view?.run {
|
||||
enableSwipe(true)
|
||||
showRefresh(true)
|
||||
showProgress(false)
|
||||
showContent(true)
|
||||
updateData(it.data.sortedByDescending { item -> item.date })
|
||||
}
|
||||
}
|
||||
}
|
||||
Status.SUCCESS -> {
|
||||
Timber.i("Loading note result: Success")
|
||||
view?.apply {
|
||||
updateData(it.data!!.sortedByDescending { item -> item.date })
|
||||
showEmpty(it.data.isEmpty())
|
||||
showErrorView(false)
|
||||
showContent(it.data.isNotEmpty())
|
||||
}
|
||||
analytics.logEvent(
|
||||
"load_data",
|
||||
"type" to "note",
|
||||
"items" to it.data!!.size
|
||||
)
|
||||
}
|
||||
Status.ERROR -> {
|
||||
Timber.i("Loading note result: An exception occurred")
|
||||
errorHandler.dispatch(it.error!!)
|
||||
}
|
||||
.logResourceStatus("load note data")
|
||||
.mapResourceData { it.sortedByDescending { note -> note.date } }
|
||||
.onResourceData {
|
||||
view?.run {
|
||||
enableSwipe(true)
|
||||
showProgress(false)
|
||||
showErrorView(false)
|
||||
showContent(it.isNotEmpty())
|
||||
showEmpty(it.isEmpty())
|
||||
updateData(it)
|
||||
}
|
||||
}
|
||||
}.afterLoading {
|
||||
view?.run {
|
||||
showRefresh(false)
|
||||
showProgress(false)
|
||||
enableSwipe(true)
|
||||
.onResourceIntermediate { view?.showRefresh(true) }
|
||||
.onResourceSuccess {
|
||||
analytics.logEvent(
|
||||
"load_data",
|
||||
"type" to "note",
|
||||
"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) {
|
||||
@ -122,14 +108,14 @@ class NotePresenter @Inject constructor(
|
||||
}
|
||||
|
||||
private fun updateNote(note: Note) {
|
||||
flowWithResource { noteRepository.updateNote(note) }
|
||||
resourceFlow { noteRepository.updateNote(note) }
|
||||
.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> Timber.i("Attempt to update note ${note.id}")
|
||||
Status.SUCCESS -> Timber.i("Update note result: Success")
|
||||
Status.ERROR -> {
|
||||
when (it) {
|
||||
is Resource.Loading -> Timber.i("Attempt to update note ${note.id}")
|
||||
is Resource.Success -> Timber.i("Update note result: Success")
|
||||
is Resource.Error -> {
|
||||
Timber.i("Update note result: An exception occurred")
|
||||
errorHandler.dispatch(it.error!!)
|
||||
errorHandler.dispatch(it.error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,13 @@
|
||||
package io.github.wulkanowy.ui.modules.schoolandteachers.school
|
||||
|
||||
import io.github.wulkanowy.data.Status
|
||||
import io.github.wulkanowy.data.*
|
||||
import io.github.wulkanowy.data.repositories.SchoolRepository
|
||||
import io.github.wulkanowy.data.repositories.SemesterRepository
|
||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||
import io.github.wulkanowy.ui.base.BasePresenter
|
||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||
import io.github.wulkanowy.utils.AnalyticsHelper
|
||||
import io.github.wulkanowy.utils.afterLoading
|
||||
import io.github.wulkanowy.utils.flowWithResourceIn
|
||||
import kotlinx.coroutines.flow.catch
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
@ -65,46 +62,48 @@ class SchoolPresenter @Inject constructor(
|
||||
}
|
||||
|
||||
private fun loadData(forceRefresh: Boolean = false) {
|
||||
flowWithResourceIn {
|
||||
flatResourceFlow {
|
||||
val student = studentRepository.getCurrentStudent()
|
||||
val semester = semesterRepository.getCurrentSemester(student)
|
||||
schoolRepository.getSchoolInfo(student, semester, forceRefresh)
|
||||
}.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> Timber.i("Loading school info started")
|
||||
Status.SUCCESS -> if (it.data != null) {
|
||||
Timber.i("Loading teachers result: Success")
|
||||
}
|
||||
.logResourceStatus("load school info")
|
||||
.onResourceData {
|
||||
if (it != null) {
|
||||
view?.run {
|
||||
address = it.data.address.ifBlank { null }
|
||||
contact = it.data.contact.ifBlank { null }
|
||||
updateData(it.data)
|
||||
address = it.address.ifBlank { null }
|
||||
contact = it.contact.ifBlank { null }
|
||||
updateData(it)
|
||||
showContent(true)
|
||||
showEmpty(false)
|
||||
showErrorView(false)
|
||||
}
|
||||
analytics.logEvent("load_item", "type" to "school")
|
||||
} else view?.run {
|
||||
Timber.i("Loading school result: No school info found")
|
||||
showContent(!isViewEmpty)
|
||||
showEmpty(isViewEmpty)
|
||||
showErrorView(false)
|
||||
}
|
||||
Status.ERROR -> {
|
||||
Timber.i("Loading school result: An exception occurred")
|
||||
errorHandler.dispatch(it.error!!)
|
||||
}
|
||||
.onResourceSuccess {
|
||||
if (it != null) {
|
||||
analytics.logEvent("load_item", "type" to "school")
|
||||
}
|
||||
}
|
||||
}.afterLoading {
|
||||
view?.run {
|
||||
hideRefresh()
|
||||
showProgress(false)
|
||||
enableSwipe(true)
|
||||
notifyParentDataLoaded()
|
||||
.onResourceNotLoading {
|
||||
view?.run {
|
||||
hideRefresh()
|
||||
showProgress(false)
|
||||
enableSwipe(true)
|
||||
notifyParentDataLoaded()
|
||||
}
|
||||
}
|
||||
}.catch {
|
||||
errorHandler.dispatch(it)
|
||||
view?.notifyParentDataLoaded()
|
||||
}.launch()
|
||||
.onResourceError(errorHandler::dispatch)
|
||||
.catch {
|
||||
errorHandler.dispatch(it)
|
||||
view?.notifyParentDataLoaded()
|
||||
}
|
||||
.launch()
|
||||
}
|
||||
|
||||
private fun showErrorViewOnError(message: String, error: Throwable) {
|
||||
|
@ -1,16 +1,13 @@
|
||||
package io.github.wulkanowy.ui.modules.schoolandteachers.teacher
|
||||
|
||||
import io.github.wulkanowy.data.Status
|
||||
import io.github.wulkanowy.data.*
|
||||
import io.github.wulkanowy.data.repositories.SemesterRepository
|
||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||
import io.github.wulkanowy.data.repositories.TeacherRepository
|
||||
import io.github.wulkanowy.ui.base.BasePresenter
|
||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||
import io.github.wulkanowy.utils.AnalyticsHelper
|
||||
import io.github.wulkanowy.utils.afterLoading
|
||||
import io.github.wulkanowy.utils.flowWithResourceIn
|
||||
import kotlinx.coroutines.flow.catch
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
@ -53,43 +50,41 @@ class TeacherPresenter @Inject constructor(
|
||||
}
|
||||
|
||||
private fun loadData(forceRefresh: Boolean = false) {
|
||||
flowWithResourceIn {
|
||||
flatResourceFlow {
|
||||
val student = studentRepository.getCurrentStudent()
|
||||
val semester = semesterRepository.getCurrentSemester(student)
|
||||
teacherRepository.getTeachers(student, semester, forceRefresh)
|
||||
}.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> Timber.i("Loading teachers data started")
|
||||
Status.SUCCESS -> {
|
||||
Timber.i("Loading teachers result: Success")
|
||||
view?.run {
|
||||
updateData(it.data!!.filter { item -> item.name.isNotBlank() })
|
||||
showContent(it.data.isNotEmpty())
|
||||
showEmpty(it.data.isEmpty())
|
||||
showErrorView(false)
|
||||
}
|
||||
analytics.logEvent(
|
||||
"load_data",
|
||||
"type" to "teachers",
|
||||
"items" to it.data!!.size
|
||||
)
|
||||
}
|
||||
Status.ERROR -> {
|
||||
Timber.i("Loading teachers result: An exception occurred")
|
||||
errorHandler.dispatch(it.error!!)
|
||||
}
|
||||
.logResourceStatus("load teachers data")
|
||||
.onResourceData {
|
||||
view?.run {
|
||||
updateData(it.filter { item -> item.name.isNotBlank() })
|
||||
showContent(it.isNotEmpty())
|
||||
showEmpty(it.isEmpty())
|
||||
showErrorView(false)
|
||||
}
|
||||
}
|
||||
}.afterLoading {
|
||||
view?.run {
|
||||
hideRefresh()
|
||||
showProgress(false)
|
||||
enableSwipe(true)
|
||||
notifyParentDataLoaded()
|
||||
.onResourceSuccess {
|
||||
analytics.logEvent(
|
||||
"load_data",
|
||||
"type" to "teachers",
|
||||
"items" to it.size
|
||||
)
|
||||
}
|
||||
}.catch {
|
||||
errorHandler.dispatch(it)
|
||||
view?.notifyParentDataLoaded()
|
||||
}.launch()
|
||||
.onResourceNotLoading {
|
||||
view?.run {
|
||||
hideRefresh()
|
||||
showProgress(false)
|
||||
enableSwipe(true)
|
||||
notifyParentDataLoaded()
|
||||
}
|
||||
}
|
||||
.onResourceError(errorHandler::dispatch)
|
||||
.catch {
|
||||
errorHandler.dispatch(it)
|
||||
view?.notifyParentDataLoaded()
|
||||
}
|
||||
.launch()
|
||||
}
|
||||
|
||||
private fun showErrorViewOnError(message: String, error: Throwable) {
|
||||
|
@ -1,15 +1,12 @@
|
||||
package io.github.wulkanowy.ui.modules.schoolannouncement
|
||||
|
||||
import io.github.wulkanowy.data.Status
|
||||
import io.github.wulkanowy.data.*
|
||||
import io.github.wulkanowy.data.db.entities.SchoolAnnouncement
|
||||
import io.github.wulkanowy.data.repositories.SchoolAnnouncementRepository
|
||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||
import io.github.wulkanowy.ui.base.BasePresenter
|
||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||
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 javax.inject.Inject
|
||||
|
||||
@ -52,50 +49,37 @@ class SchoolAnnouncementPresenter @Inject constructor(
|
||||
}
|
||||
|
||||
private fun loadData(forceRefresh: Boolean = false) {
|
||||
Timber.i("Loading School announcement data started")
|
||||
|
||||
flowWithResourceIn {
|
||||
flatResourceFlow {
|
||||
val student = studentRepository.getCurrentStudent()
|
||||
schoolAnnouncementRepository.getSchoolAnnouncements(student, forceRefresh)
|
||||
}.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> {
|
||||
if (!it.data.isNullOrEmpty()) {
|
||||
view?.run {
|
||||
enableSwipe(true)
|
||||
showRefresh(true)
|
||||
showErrorView(false)
|
||||
showProgress(false)
|
||||
showContent(true)
|
||||
updateData(it.data)
|
||||
}
|
||||
}
|
||||
}
|
||||
Status.SUCCESS -> {
|
||||
Timber.i("Loading School announcement result: Success")
|
||||
view?.apply {
|
||||
updateData(it.data!!)
|
||||
showEmpty(it.data.isEmpty())
|
||||
showErrorView(false)
|
||||
showContent(it.data.isNotEmpty())
|
||||
}
|
||||
analytics.logEvent(
|
||||
"load_school_announcement",
|
||||
"items" to it.data!!.size
|
||||
)
|
||||
}
|
||||
Status.ERROR -> {
|
||||
Timber.i("Loading School announcement result: An exception occurred")
|
||||
errorHandler.dispatch(it.error!!)
|
||||
}
|
||||
.logResourceStatus("load school announcement")
|
||||
.onResourceData {
|
||||
view?.run {
|
||||
enableSwipe(true)
|
||||
showProgress(false)
|
||||
showErrorView(false)
|
||||
showContent(it.isNotEmpty())
|
||||
showEmpty(it.isEmpty())
|
||||
updateData(it)
|
||||
}
|
||||
}
|
||||
}.afterLoading {
|
||||
view?.run {
|
||||
showRefresh(false)
|
||||
showProgress(false)
|
||||
enableSwipe(true)
|
||||
.onResourceSuccess {
|
||||
analytics.logEvent(
|
||||
"load_school_announcement",
|
||||
"items" to it.size
|
||||
)
|
||||
}
|
||||
}.launch()
|
||||
.onResourceIntermediate { view?.showRefresh(true) }
|
||||
.onResourceNotLoading {
|
||||
view?.run {
|
||||
enableSwipe(true)
|
||||
showProgress(false)
|
||||
showRefresh(false)
|
||||
}
|
||||
}
|
||||
.onResourceError(errorHandler::dispatch)
|
||||
.launch("load_data")
|
||||
}
|
||||
|
||||
private fun showErrorViewOnError(message: String, error: Throwable) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
package io.github.wulkanowy.ui.modules.studentinfo
|
||||
|
||||
import io.github.wulkanowy.data.Status
|
||||
import io.github.wulkanowy.data.*
|
||||
import io.github.wulkanowy.data.db.entities.StudentInfo
|
||||
import io.github.wulkanowy.data.db.entities.StudentWithSemesters
|
||||
import io.github.wulkanowy.data.repositories.StudentInfoRepository
|
||||
@ -8,10 +8,7 @@ import io.github.wulkanowy.data.repositories.StudentRepository
|
||||
import io.github.wulkanowy.ui.base.BasePresenter
|
||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||
import io.github.wulkanowy.utils.AnalyticsHelper
|
||||
import io.github.wulkanowy.utils.afterLoading
|
||||
import io.github.wulkanowy.utils.flowWithResourceIn
|
||||
import io.github.wulkanowy.utils.getCurrentOrLast
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
@ -72,51 +69,50 @@ class StudentInfoPresenter @Inject constructor(
|
||||
}
|
||||
|
||||
private fun loadData(forceRefresh: Boolean = false) {
|
||||
flowWithResourceIn {
|
||||
flatResourceFlow {
|
||||
val semester = studentWithSemesters.semesters.getCurrentOrLast()
|
||||
studentInfoRepository.getStudentInfo(
|
||||
student = studentWithSemesters.student,
|
||||
semester = semester,
|
||||
forceRefresh = forceRefresh
|
||||
)
|
||||
}.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> Timber.i("Loading student info $infoType started")
|
||||
Status.SUCCESS -> {
|
||||
val isFamily = infoType == StudentInfoView.Type.FAMILY
|
||||
val isFirstGuardianEmpty = it.data?.firstGuardian == null
|
||||
val isSecondGuardianEmpty = it.data?.secondGuardian == null
|
||||
|
||||
if (it.data != null && !(isFamily && isFirstGuardianEmpty && isSecondGuardianEmpty)) {
|
||||
Timber.i("Loading student info $infoType result: Success")
|
||||
showCorrectData(it.data)
|
||||
view?.run {
|
||||
showContent(true)
|
||||
showEmpty(false)
|
||||
showErrorView(false)
|
||||
}
|
||||
analytics.logEvent("load_item", "type" to "student_info")
|
||||
} else {
|
||||
Timber.i("Loading student info $infoType result: No student or family info found")
|
||||
view?.run {
|
||||
showContent(!isViewEmpty)
|
||||
showEmpty(isViewEmpty)
|
||||
showErrorView(false)
|
||||
}
|
||||
}
|
||||
.logResourceStatus("load student info $infoType")
|
||||
.onResourceData {
|
||||
val isFamily = infoType == StudentInfoView.Type.FAMILY
|
||||
val isFirstGuardianEmpty = it?.firstGuardian == null
|
||||
val isSecondGuardianEmpty = it?.secondGuardian == null
|
||||
if (it != null && !(isFamily && isFirstGuardianEmpty && isSecondGuardianEmpty)) {
|
||||
Timber.i("Loading student info $infoType result: Success")
|
||||
showCorrectData(it)
|
||||
view?.run {
|
||||
showContent(true)
|
||||
showEmpty(false)
|
||||
showErrorView(false)
|
||||
}
|
||||
} else {
|
||||
Timber.i("Loading student info $infoType result: No student or family info found")
|
||||
view?.run {
|
||||
showContent(!isViewEmpty)
|
||||
showEmpty(isViewEmpty)
|
||||
showErrorView(false)
|
||||
}
|
||||
}
|
||||
Status.ERROR -> {
|
||||
Timber.i("Loading student info $infoType result: An exception occurred")
|
||||
errorHandler.dispatch(it.error!!)
|
||||
}
|
||||
.onResourceSuccess {
|
||||
if (it != null) {
|
||||
analytics.logEvent("load_item", "type" to "student_info")
|
||||
}
|
||||
}
|
||||
}.afterLoading {
|
||||
view?.run {
|
||||
hideRefresh()
|
||||
showProgress(false)
|
||||
enableSwipe(true)
|
||||
.onResourceNotLoading {
|
||||
view?.run {
|
||||
hideRefresh()
|
||||
showProgress(false)
|
||||
enableSwipe(true)
|
||||
}
|
||||
}
|
||||
}.launch()
|
||||
.onResourceError(errorHandler::dispatch)
|
||||
.launch()
|
||||
}
|
||||
|
||||
private fun showCorrectData(studentInfo: StudentInfo) {
|
||||
|
@ -1,6 +1,6 @@
|
||||
package io.github.wulkanowy.ui.modules.timetable
|
||||
|
||||
import io.github.wulkanowy.data.Status
|
||||
import io.github.wulkanowy.data.*
|
||||
import io.github.wulkanowy.data.db.entities.Timetable
|
||||
import io.github.wulkanowy.data.enums.TimetableMode
|
||||
import io.github.wulkanowy.data.repositories.PreferencesRepository
|
||||
@ -123,57 +123,47 @@ class TimetablePresenter @Inject constructor(
|
||||
}
|
||||
|
||||
private fun loadData(forceRefresh: Boolean = false) {
|
||||
Timber.i("Loading timetable data started")
|
||||
|
||||
flowWithResourceIn {
|
||||
flatResourceFlow {
|
||||
val student = studentRepository.getCurrentStudent()
|
||||
val semester = semesterRepository.getCurrentSemester(student)
|
||||
timetableRepository.getTimetable(
|
||||
student, semester, currentDate, currentDate, forceRefresh
|
||||
student = student,
|
||||
semester = semester,
|
||||
start = currentDate,
|
||||
end = currentDate,
|
||||
forceRefresh = forceRefresh,
|
||||
timetableType = TimetableRepository.TimetableType.NORMAL
|
||||
)
|
||||
}.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> {
|
||||
if (!it.data?.lessons.isNullOrEmpty()) {
|
||||
view?.run {
|
||||
updateData(it.data!!.lessons)
|
||||
enableSwipe(true)
|
||||
showRefresh(true)
|
||||
showErrorView(false)
|
||||
showProgress(false)
|
||||
showContent(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
Status.SUCCESS -> {
|
||||
Timber.i("Loading timetable result: Success")
|
||||
view?.apply {
|
||||
updateData(it.data!!.lessons)
|
||||
showEmpty(it.data.lessons.isEmpty())
|
||||
setDayHeaderMessage(it.data.headers.singleOrNull { header ->
|
||||
header.date == currentDate
|
||||
}?.content)
|
||||
showErrorView(false)
|
||||
showContent(it.data.lessons.isNotEmpty())
|
||||
}
|
||||
analytics.logEvent(
|
||||
"load_data",
|
||||
"type" to "timetable",
|
||||
"items" to it.data!!.lessons.size
|
||||
)
|
||||
}
|
||||
Status.ERROR -> {
|
||||
Timber.i("Loading timetable result: An exception occurred")
|
||||
errorHandler.dispatch(it.error!!)
|
||||
}
|
||||
.logResourceStatus("load timetable data")
|
||||
.onResourceData {
|
||||
view?.run {
|
||||
enableSwipe(true)
|
||||
showProgress(false)
|
||||
showErrorView(false)
|
||||
showContent(it.lessons.isNotEmpty())
|
||||
showEmpty(it.lessons.isEmpty())
|
||||
updateData(it.lessons)
|
||||
setDayHeaderMessage(it.headers.singleOrNull { header -> header.date == currentDate }?.content)
|
||||
}
|
||||
}
|
||||
}.afterLoading {
|
||||
view?.run {
|
||||
showRefresh(false)
|
||||
showProgress(false)
|
||||
enableSwipe(true)
|
||||
.onResourceIntermediate { view?.showRefresh(true) }
|
||||
.onResourceSuccess {
|
||||
analytics.logEvent(
|
||||
"load_data",
|
||||
"type" to "timetable",
|
||||
"items" to it.lessons.size
|
||||
)
|
||||
}
|
||||
}.launch()
|
||||
.onResourceNotLoading {
|
||||
view?.run {
|
||||
enableSwipe(true)
|
||||
showProgress(false)
|
||||
showRefresh(false)
|
||||
}
|
||||
}
|
||||
.onResourceError(errorHandler::dispatch)
|
||||
.launch()
|
||||
}
|
||||
|
||||
private fun updateData(lessons: List<Timetable>) {
|
||||
|
@ -1,23 +1,14 @@
|
||||
package io.github.wulkanowy.ui.modules.timetable.additional
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import io.github.wulkanowy.data.Status
|
||||
import io.github.wulkanowy.data.*
|
||||
import io.github.wulkanowy.data.db.entities.TimetableAdditional
|
||||
import io.github.wulkanowy.data.repositories.SemesterRepository
|
||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||
import io.github.wulkanowy.data.repositories.TimetableRepository
|
||||
import io.github.wulkanowy.ui.base.BasePresenter
|
||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||
import io.github.wulkanowy.utils.AnalyticsHelper
|
||||
import io.github.wulkanowy.utils.afterLoading
|
||||
import io.github.wulkanowy.utils.capitalise
|
||||
import io.github.wulkanowy.utils.flowWithResourceIn
|
||||
import io.github.wulkanowy.utils.getLastSchoolDayIfHoliday
|
||||
import io.github.wulkanowy.utils.isHolidays
|
||||
import io.github.wulkanowy.utils.nextOrSameSchoolDay
|
||||
import io.github.wulkanowy.utils.nextSchoolDay
|
||||
import io.github.wulkanowy.utils.previousSchoolDay
|
||||
import io.github.wulkanowy.utils.toFormattedString
|
||||
import io.github.wulkanowy.utils.*
|
||||
import kotlinx.coroutines.flow.catch
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
@ -137,39 +128,44 @@ class AdditionalLessonsPresenter @Inject constructor(
|
||||
private fun loadData(date: LocalDate, forceRefresh: Boolean = false) {
|
||||
currentDate = date
|
||||
|
||||
flowWithResourceIn {
|
||||
flatResourceFlow {
|
||||
val student = studentRepository.getCurrentStudent()
|
||||
val semester = semesterRepository.getCurrentSemester(student)
|
||||
timetableRepository.getTimetable(student, semester, date, date, forceRefresh, true)
|
||||
}.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> Timber.i("Loading additional lessons data started")
|
||||
Status.SUCCESS -> {
|
||||
Timber.i("Loading additional lessons lessons result: Success")
|
||||
view?.apply {
|
||||
updateData(it.data!!.additional.sortedBy { item -> item.start })
|
||||
showEmpty(it.data.additional.isEmpty())
|
||||
showErrorView(false)
|
||||
showContent(it.data.additional.isNotEmpty())
|
||||
}
|
||||
analytics.logEvent(
|
||||
"load_data",
|
||||
"type" to "additional_lessons",
|
||||
"items" to it.data!!.additional.size
|
||||
)
|
||||
}
|
||||
Status.ERROR -> {
|
||||
Timber.i("Loading additional lessons result: An exception occurred")
|
||||
errorHandler.dispatch(it.error!!)
|
||||
timetableRepository.getTimetable(
|
||||
student = student,
|
||||
semester = semester,
|
||||
start = date,
|
||||
end = date,
|
||||
forceRefresh = forceRefresh,
|
||||
refreshAdditional = true,
|
||||
timetableType = TimetableRepository.TimetableType.ADDITIONAL
|
||||
)
|
||||
}
|
||||
.logResourceStatus("load additional lessons")
|
||||
.onResourceData {
|
||||
view?.apply {
|
||||
updateData(it.additional.sortedBy { item -> item.start })
|
||||
showEmpty(it.additional.isEmpty())
|
||||
showErrorView(false)
|
||||
showContent(it.additional.isNotEmpty())
|
||||
}
|
||||
}
|
||||
}.afterLoading {
|
||||
view?.run {
|
||||
hideRefresh()
|
||||
showProgress(false)
|
||||
enableSwipe(true)
|
||||
.onResourceSuccess {
|
||||
analytics.logEvent(
|
||||
"load_data",
|
||||
"type" to "additional_lessons",
|
||||
"items" to it.additional.size
|
||||
)
|
||||
}
|
||||
}.launch()
|
||||
.onResourceNotLoading {
|
||||
view?.run {
|
||||
hideRefresh()
|
||||
showProgress(false)
|
||||
enableSwipe(true)
|
||||
}
|
||||
}
|
||||
.onResourceError(errorHandler::dispatch)
|
||||
.launch()
|
||||
}
|
||||
|
||||
private fun showErrorViewOnError(message: String, error: Throwable) {
|
||||
|
@ -1,22 +1,13 @@
|
||||
package io.github.wulkanowy.ui.modules.timetable.completed
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import io.github.wulkanowy.data.Status
|
||||
import io.github.wulkanowy.data.*
|
||||
import io.github.wulkanowy.data.db.entities.CompletedLesson
|
||||
import io.github.wulkanowy.data.repositories.CompletedLessonsRepository
|
||||
import io.github.wulkanowy.data.repositories.SemesterRepository
|
||||
import io.github.wulkanowy.data.repositories.StudentRepository
|
||||
import io.github.wulkanowy.ui.base.BasePresenter
|
||||
import io.github.wulkanowy.utils.AnalyticsHelper
|
||||
import io.github.wulkanowy.utils.afterLoading
|
||||
import io.github.wulkanowy.utils.capitalise
|
||||
import io.github.wulkanowy.utils.flowWithResourceIn
|
||||
import io.github.wulkanowy.utils.getLastSchoolDayIfHoliday
|
||||
import io.github.wulkanowy.utils.isHolidays
|
||||
import io.github.wulkanowy.utils.nextOrSameSchoolDay
|
||||
import io.github.wulkanowy.utils.nextSchoolDay
|
||||
import io.github.wulkanowy.utils.previousSchoolDay
|
||||
import io.github.wulkanowy.utils.toFormattedString
|
||||
import io.github.wulkanowy.utils.*
|
||||
import kotlinx.coroutines.flow.catch
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
@ -111,51 +102,46 @@ class CompletedLessonsPresenter @Inject constructor(
|
||||
}
|
||||
|
||||
private fun loadData(forceRefresh: Boolean = false) {
|
||||
Timber.i("Loading completed lessons data started")
|
||||
|
||||
flowWithResourceIn {
|
||||
flatResourceFlow {
|
||||
val student = studentRepository.getCurrentStudent()
|
||||
val semester = semesterRepository.getCurrentSemester(student)
|
||||
completedLessonsRepository.getCompletedLessons(student, semester, currentDate, currentDate, forceRefresh)
|
||||
}.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> {
|
||||
if (!it.data.isNullOrEmpty()) {
|
||||
view?.run {
|
||||
enableSwipe(true)
|
||||
showRefresh(true)
|
||||
showProgress(false)
|
||||
showContent(true)
|
||||
updateData(it.data.sortedBy { item -> item.number })
|
||||
}
|
||||
}
|
||||
}
|
||||
Status.SUCCESS -> {
|
||||
Timber.i("Loading completed lessons lessons result: Success")
|
||||
view?.apply {
|
||||
updateData(it.data!!.sortedBy { item -> item.number })
|
||||
showEmpty(it.data.isEmpty())
|
||||
showErrorView(false)
|
||||
showContent(it.data.isNotEmpty())
|
||||
}
|
||||
analytics.logEvent(
|
||||
"load_data",
|
||||
"type" to "completed_lessons",
|
||||
"items" to it.data!!.size
|
||||
)
|
||||
}
|
||||
Status.ERROR -> {
|
||||
Timber.i("Loading completed lessons result: An exception occurred")
|
||||
completedLessonsErrorHandler.dispatch(it.error!!)
|
||||
completedLessonsRepository.getCompletedLessons(
|
||||
student = student,
|
||||
semester = semester,
|
||||
start = currentDate,
|
||||
end = currentDate,
|
||||
forceRefresh = forceRefresh
|
||||
)
|
||||
}
|
||||
.logResourceStatus("load completed lessons")
|
||||
.mapResourceData { it.sortedBy { lesson -> lesson.number } }
|
||||
.onResourceData {
|
||||
view?.run {
|
||||
enableSwipe(true)
|
||||
showProgress(false)
|
||||
showErrorView(false)
|
||||
showContent(it.isNotEmpty())
|
||||
showEmpty(it.isEmpty())
|
||||
updateData(it)
|
||||
}
|
||||
}
|
||||
}.afterLoading {
|
||||
view?.run {
|
||||
showRefresh(false)
|
||||
showProgress(false)
|
||||
enableSwipe(true)
|
||||
.onResourceIntermediate { view?.showRefresh(true) }
|
||||
.onResourceSuccess {
|
||||
analytics.logEvent(
|
||||
"load_data",
|
||||
"type" to "completed_lessons",
|
||||
"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) {
|
||||
|
@ -1,14 +1,14 @@
|
||||
package io.github.wulkanowy.ui.modules.timetablewidget
|
||||
|
||||
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.entities.Student
|
||||
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.ErrorHandler
|
||||
import io.github.wulkanowy.ui.modules.timetablewidget.TimetableWidgetProvider.Companion.getStudentWidgetKey
|
||||
import io.github.wulkanowy.ui.modules.timetablewidget.TimetableWidgetProvider.Companion.getThemeWidgetKey
|
||||
import io.github.wulkanowy.utils.flowWithResource
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
@ -56,16 +56,15 @@ class TimetableWidgetConfigurePresenter @Inject constructor(
|
||||
}
|
||||
|
||||
private fun loadData() {
|
||||
flowWithResource { studentRepository.getSavedStudents(false) }.onEach {
|
||||
when (it.status) {
|
||||
Status.LOADING -> Timber.d("Timetable widget configure students data load")
|
||||
Status.SUCCESS -> {
|
||||
resourceFlow { studentRepository.getSavedStudents(false) }.onEach {
|
||||
when (it) {
|
||||
is Resource.Loading -> Timber.d("Timetable widget configure students data load")
|
||||
is Resource.Success -> {
|
||||
val selectedStudentId = appWidgetId?.let { id ->
|
||||
sharedPref.getLong(getStudentWidgetKey(id), 0)
|
||||
} ?: -1
|
||||
|
||||
when {
|
||||
it.data!!.isEmpty() -> view?.openLoginView()
|
||||
it.data.isEmpty() -> view?.openLoginView()
|
||||
it.data.size == 1 && !isFromProvider -> {
|
||||
selectedStudent = it.data.single().student
|
||||
view?.showThemeDialog()
|
||||
@ -73,7 +72,7 @@ class TimetableWidgetConfigurePresenter @Inject constructor(
|
||||
else -> view?.updateData(it.data, selectedStudentId)
|
||||
}
|
||||
}
|
||||
Status.ERROR -> errorHandler.dispatch(it.error!!)
|
||||
is Resource.Error -> errorHandler.dispatch(it.error)
|
||||
}
|
||||
}.launch()
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import android.widget.AdapterView.INVALID_POSITION
|
||||
import android.widget.RemoteViews
|
||||
import android.widget.RemoteViewsService
|
||||
import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.data.dataOrNull
|
||||
import io.github.wulkanowy.data.db.SharedPrefProvider
|
||||
import io.github.wulkanowy.data.db.entities.Timetable
|
||||
import io.github.wulkanowy.data.enums.TimetableMode
|
||||
@ -19,12 +20,12 @@ 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.TimetableRepository
|
||||
import io.github.wulkanowy.data.toFirstResult
|
||||
import io.github.wulkanowy.ui.modules.timetablewidget.TimetableWidgetProvider.Companion.getCurrentThemeWidgetKey
|
||||
import io.github.wulkanowy.ui.modules.timetablewidget.TimetableWidgetProvider.Companion.getDateWidgetKey
|
||||
import io.github.wulkanowy.ui.modules.timetablewidget.TimetableWidgetProvider.Companion.getStudentWidgetKey
|
||||
import io.github.wulkanowy.ui.modules.timetablewidget.TimetableWidgetProvider.Companion.getTodayLastLessonEndDateTimeWidgetKey
|
||||
import io.github.wulkanowy.utils.getCompatColor
|
||||
import io.github.wulkanowy.utils.toFirstResult
|
||||
import io.github.wulkanowy.utils.toFormattedString
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import timber.log.Timber
|
||||
@ -118,7 +119,7 @@ class TimetableWidgetFactory(
|
||||
|
||||
val semester = semesterRepository.getCurrentSemester(student)
|
||||
timetableRepository.getTimetable(student, semester, date, date, false)
|
||||
.toFirstResult().data?.lessons.orEmpty()
|
||||
.toFirstResult().dataOrNull?.lessons.orEmpty()
|
||||
.sortedWith(compareBy({ it.number }, { !it.isStudentPlan }))
|
||||
.filter {
|
||||
if (prefRepository.showWholeClassPlan == TimetableMode.ONLY_CURRENT_GROUP) {
|
||||
|
@ -1,96 +0,0 @@
|
||||
package io.github.wulkanowy.utils
|
||||
|
||||
import io.github.wulkanowy.data.Resource
|
||||
import io.github.wulkanowy.data.Status
|
||||
import kotlinx.coroutines.FlowPreview
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.catch
|
||||
import kotlinx.coroutines.flow.collect
|
||||
import kotlinx.coroutines.flow.emitAll
|
||||
import kotlinx.coroutines.flow.filter
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.takeWhile
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
import kotlinx.coroutines.sync.withLock
|
||||
|
||||
inline fun <ResultType, RequestType> networkBoundResource(
|
||||
mutex: Mutex = Mutex(),
|
||||
showSavedOnLoading: Boolean = true,
|
||||
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)) {
|
||||
if (showSavedOnLoading) emit(Resource.loading(filterResult(data)))
|
||||
|
||||
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, filterResult(it)) }
|
||||
}
|
||||
} else {
|
||||
query().map { Resource.success(filterResult(it)) }
|
||||
})
|
||||
}
|
||||
|
||||
@JvmName("networkBoundResourceWithMap")
|
||||
inline fun <ResultType, RequestType, T> networkBoundResource(
|
||||
mutex: Mutex = Mutex(),
|
||||
showSavedOnLoading: Boolean = true,
|
||||
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)) {
|
||||
if (showSavedOnLoading) emit(Resource.loading(mapResult(data)))
|
||||
|
||||
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, mapResult(it)) }
|
||||
}
|
||||
} else {
|
||||
query().map { Resource.success(mapResult(it)) }
|
||||
})
|
||||
}
|
||||
|
||||
fun <T> flowWithResource(block: suspend () -> T) = flow {
|
||||
emit(Resource.loading())
|
||||
emit(Resource.success(block()))
|
||||
}.catch { emit(Resource.error(it)) }
|
||||
|
||||
@OptIn(FlowPreview::class)
|
||||
fun <T> flowWithResourceIn(block: suspend () -> Flow<Resource<T>>) = flow {
|
||||
emit(Resource.loading())
|
||||
emitAll(block().filter { it.status != Status.LOADING || (it.status == Status.LOADING && it.data != null) })
|
||||
}.catch { emit(Resource.error(it)) }
|
||||
|
||||
fun <T> Flow<Resource<T>>.afterLoading(callback: () -> Unit) = onEach {
|
||||
if (it.status != Status.LOADING) callback()
|
||||
}
|
||||
|
||||
suspend fun <T> Flow<Resource<T>>.toFirstResult() = filter { it.status != Status.LOADING }.first()
|
||||
|
||||
suspend fun <T> Flow<Resource<T>>.waitForResult() =
|
||||
takeWhile { it.status == Status.LOADING }.collect()
|
@ -1,4 +1,4 @@
|
||||
package io.github.wulkanowy.utils
|
||||
package io.github.wulkanowy.data
|
||||
|
||||
import io.mockk.*
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
@ -13,7 +13,7 @@ import org.junit.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
class FlowUtilsKtTest {
|
||||
class ResourceTest {
|
||||
|
||||
private val testScope = TestScope(UnconfinedTestDispatcher())
|
||||
|
||||
@ -41,6 +41,7 @@ class FlowUtilsKtTest {
|
||||
|
||||
// first
|
||||
networkBoundResource(
|
||||
isResultEmpty = { false },
|
||||
showSavedOnLoading = false,
|
||||
query = { repo.query() },
|
||||
fetch = {
|
||||
@ -55,6 +56,7 @@ class FlowUtilsKtTest {
|
||||
|
||||
// second
|
||||
networkBoundResource(
|
||||
isResultEmpty = { false },
|
||||
showSavedOnLoading = false,
|
||||
query = { repo.query() },
|
||||
fetch = {
|
||||
@ -120,6 +122,7 @@ class FlowUtilsKtTest {
|
||||
|
||||
// first
|
||||
networkBoundResource(
|
||||
isResultEmpty = { false },
|
||||
mutex = saveResultMutex,
|
||||
showSavedOnLoading = false,
|
||||
query = { repo.query() },
|
||||
@ -138,6 +141,7 @@ class FlowUtilsKtTest {
|
||||
|
||||
// second
|
||||
networkBoundResource(
|
||||
isResultEmpty = { false },
|
||||
mutex = saveResultMutex,
|
||||
showSavedOnLoading = false,
|
||||
query = { repo.query() },
|
@ -1,20 +1,17 @@
|
||||
package io.github.wulkanowy.data.repositories
|
||||
|
||||
import io.github.wulkanowy.data.dataOrNull
|
||||
import io.github.wulkanowy.data.db.dao.AttendanceDao
|
||||
import io.github.wulkanowy.data.errorOrNull
|
||||
import io.github.wulkanowy.data.mappers.mapToEntities
|
||||
import io.github.wulkanowy.data.toFirstResult
|
||||
import io.github.wulkanowy.getSemesterEntity
|
||||
import io.github.wulkanowy.getStudentEntity
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
import io.github.wulkanowy.utils.AutoRefreshHelper
|
||||
import io.github.wulkanowy.utils.toFirstResult
|
||||
import io.mockk.MockKAnnotations
|
||||
import io.mockk.Runs
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.coVerify
|
||||
import io.mockk.every
|
||||
import io.mockk.*
|
||||
import io.mockk.impl.annotations.MockK
|
||||
import io.mockk.impl.annotations.SpyK
|
||||
import io.mockk.just
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Assert.assertEquals
|
||||
@ -73,8 +70,8 @@ class AttendanceRepositoryTest {
|
||||
val res = runBlocking { attendanceRepository.getAttendance(student, semester, startDate, endDate, true).toFirstResult() }
|
||||
|
||||
// verify
|
||||
assertEquals(null, res.error)
|
||||
assertEquals(2, res.data?.size)
|
||||
assertEquals(null, res.errorOrNull)
|
||||
assertEquals(2, res.dataOrNull?.size)
|
||||
coVerify { sdk.getAttendance(startDate, endDate, 1) }
|
||||
coVerify { attendanceDb.loadAll(1, 1, startDate, endDate) }
|
||||
coVerify { attendanceDb.insertAll(match { it.isEmpty() }) }
|
||||
@ -97,8 +94,8 @@ class AttendanceRepositoryTest {
|
||||
val res = runBlocking { attendanceRepository.getAttendance(student, semester, startDate, endDate, true).toFirstResult() }
|
||||
|
||||
// verify
|
||||
assertEquals(null, res.error)
|
||||
assertEquals(2, res.data?.size)
|
||||
assertEquals(null, res.errorOrNull)
|
||||
assertEquals(2, res.dataOrNull?.size)
|
||||
coVerify { sdk.getAttendance(startDate, endDate, 1) }
|
||||
coVerify { attendanceDb.loadAll(1, 1, startDate, endDate) }
|
||||
coVerify {
|
||||
@ -125,8 +122,8 @@ class AttendanceRepositoryTest {
|
||||
val res = runBlocking { attendanceRepository.getAttendance(student, semester, startDate, endDate, true).toFirstResult() }
|
||||
|
||||
// verify
|
||||
assertEquals(null, res.error)
|
||||
assertEquals(1, res.data?.size)
|
||||
assertEquals(null, res.errorOrNull)
|
||||
assertEquals(1, res.dataOrNull?.size)
|
||||
coVerify { sdk.getAttendance(startDate, endDate, 1) }
|
||||
coVerify { attendanceDb.loadAll(1, 1, startDate, endDate) }
|
||||
coVerify { attendanceDb.insertAll(match { it.isEmpty() }) }
|
||||
|
@ -1,20 +1,17 @@
|
||||
package io.github.wulkanowy.data.repositories
|
||||
|
||||
import io.github.wulkanowy.data.dataOrNull
|
||||
import io.github.wulkanowy.data.db.dao.CompletedLessonsDao
|
||||
import io.github.wulkanowy.data.errorOrNull
|
||||
import io.github.wulkanowy.data.mappers.mapToEntities
|
||||
import io.github.wulkanowy.data.toFirstResult
|
||||
import io.github.wulkanowy.getSemesterEntity
|
||||
import io.github.wulkanowy.getStudentEntity
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
import io.github.wulkanowy.utils.AutoRefreshHelper
|
||||
import io.github.wulkanowy.utils.toFirstResult
|
||||
import io.mockk.MockKAnnotations
|
||||
import io.mockk.Runs
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.coVerify
|
||||
import io.mockk.every
|
||||
import io.mockk.*
|
||||
import io.mockk.impl.annotations.MockK
|
||||
import io.mockk.impl.annotations.SpyK
|
||||
import io.mockk.just
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Assert.assertEquals
|
||||
@ -73,8 +70,8 @@ class CompletedLessonsRepositoryTest {
|
||||
val res = runBlocking { completedLessonRepository.getCompletedLessons(student, semester, startDate, endDate, true).toFirstResult() }
|
||||
|
||||
// verify
|
||||
assertEquals(null, res.error)
|
||||
assertEquals(2, res.data?.size)
|
||||
assertEquals(null, res.errorOrNull)
|
||||
assertEquals(2, res.dataOrNull?.size)
|
||||
coVerify { sdk.getCompletedLessons(startDate, endDate) }
|
||||
coVerify { completedLessonDb.loadAll(1, 1, startDate, endDate) }
|
||||
coVerify { completedLessonDb.insertAll(match { it.isEmpty() }) }
|
||||
@ -97,8 +94,8 @@ class CompletedLessonsRepositoryTest {
|
||||
val res = runBlocking { completedLessonRepository.getCompletedLessons(student, semester, startDate, endDate, true).toFirstResult() }
|
||||
|
||||
// verify
|
||||
assertEquals(null, res.error)
|
||||
assertEquals(2, res.data?.size)
|
||||
assertEquals(null, res.errorOrNull)
|
||||
assertEquals(2, res.dataOrNull?.size)
|
||||
coVerify { sdk.getCompletedLessons(startDate, endDate) }
|
||||
coVerify { completedLessonDb.loadAll(1, 1, startDate, endDate) }
|
||||
coVerify {
|
||||
@ -125,8 +122,8 @@ class CompletedLessonsRepositoryTest {
|
||||
val res = runBlocking { completedLessonRepository.getCompletedLessons(student, semester, startDate, endDate, true).toFirstResult() }
|
||||
|
||||
// verify
|
||||
assertEquals(null, res.error)
|
||||
assertEquals(1, res.data?.size)
|
||||
assertEquals(null, res.errorOrNull)
|
||||
assertEquals(1, res.dataOrNull?.size)
|
||||
coVerify { sdk.getCompletedLessons(startDate, endDate) }
|
||||
coVerify { completedLessonDb.loadAll(1, 1, startDate, endDate) }
|
||||
coVerify { completedLessonDb.insertAll(match { it.isEmpty() }) }
|
||||
|
@ -1,20 +1,17 @@
|
||||
package io.github.wulkanowy.data.repositories
|
||||
|
||||
import io.github.wulkanowy.data.dataOrNull
|
||||
import io.github.wulkanowy.data.db.dao.ExamDao
|
||||
import io.github.wulkanowy.data.errorOrNull
|
||||
import io.github.wulkanowy.data.mappers.mapToEntities
|
||||
import io.github.wulkanowy.data.toFirstResult
|
||||
import io.github.wulkanowy.getSemesterEntity
|
||||
import io.github.wulkanowy.getStudentEntity
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
import io.github.wulkanowy.utils.AutoRefreshHelper
|
||||
import io.github.wulkanowy.utils.toFirstResult
|
||||
import io.mockk.MockKAnnotations
|
||||
import io.mockk.Runs
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.coVerify
|
||||
import io.mockk.every
|
||||
import io.mockk.*
|
||||
import io.mockk.impl.annotations.MockK
|
||||
import io.mockk.impl.annotations.SpyK
|
||||
import io.mockk.just
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Assert.assertEquals
|
||||
@ -74,8 +71,8 @@ class ExamRemoteTest {
|
||||
val res = runBlocking { examRepository.getExams(student, semester, startDate, endDate, true).toFirstResult() }
|
||||
|
||||
// verify
|
||||
assertEquals(null, res.error)
|
||||
assertEquals(2, res.data?.size)
|
||||
assertEquals(null, res.errorOrNull)
|
||||
assertEquals(2, res.dataOrNull?.size)
|
||||
coVerify { sdk.getExams(startDate, realEndDate, 1) }
|
||||
coVerify { examDb.loadAll(1, 1, startDate, realEndDate) }
|
||||
coVerify { examDb.insertAll(match { it.isEmpty() }) }
|
||||
@ -98,8 +95,8 @@ class ExamRemoteTest {
|
||||
val res = runBlocking { examRepository.getExams(student, semester, startDate, endDate, true).toFirstResult() }
|
||||
|
||||
// verify
|
||||
assertEquals(null, res.error)
|
||||
assertEquals(2, res.data?.size)
|
||||
assertEquals(null, res.errorOrNull)
|
||||
assertEquals(2, res.dataOrNull?.size)
|
||||
coVerify { sdk.getExams(startDate, realEndDate, 1) }
|
||||
coVerify { examDb.loadAll(1, 1, startDate, realEndDate) }
|
||||
coVerify {
|
||||
@ -126,8 +123,8 @@ class ExamRemoteTest {
|
||||
val res = runBlocking { examRepository.getExams(student, semester, startDate, endDate, true).toFirstResult() }
|
||||
|
||||
// verify
|
||||
assertEquals(null, res.error)
|
||||
assertEquals(1, res.data?.size)
|
||||
assertEquals(null, res.errorOrNull)
|
||||
assertEquals(1, res.dataOrNull?.size)
|
||||
coVerify { sdk.getExams(startDate, realEndDate, 1) }
|
||||
coVerify { examDb.loadAll(1, 1, startDate, realEndDate) }
|
||||
coVerify { examDb.insertAll(match { it.isEmpty() }) }
|
||||
|
@ -1,13 +1,15 @@
|
||||
package io.github.wulkanowy.data.repositories
|
||||
|
||||
import io.github.wulkanowy.data.dataOrNull
|
||||
import io.github.wulkanowy.data.db.dao.GradeDao
|
||||
import io.github.wulkanowy.data.db.dao.GradeSummaryDao
|
||||
import io.github.wulkanowy.data.errorOrNull
|
||||
import io.github.wulkanowy.data.mappers.mapToEntities
|
||||
import io.github.wulkanowy.data.toFirstResult
|
||||
import io.github.wulkanowy.getSemesterEntity
|
||||
import io.github.wulkanowy.getStudentEntity
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
import io.github.wulkanowy.utils.AutoRefreshHelper
|
||||
import io.github.wulkanowy.utils.toFirstResult
|
||||
import io.mockk.*
|
||||
import io.mockk.impl.annotations.MockK
|
||||
import io.mockk.impl.annotations.SpyK
|
||||
@ -88,8 +90,8 @@ class GradeRepositoryTest {
|
||||
}
|
||||
|
||||
// verify
|
||||
assertEquals(null, res.error)
|
||||
assertEquals(4, res.data?.first?.size)
|
||||
assertEquals(null, res.errorOrNull)
|
||||
assertEquals(4, res.dataOrNull?.first?.size)
|
||||
coVerify {
|
||||
gradeDb.insertAll(withArg {
|
||||
assertEquals(4, it.size)
|
||||
@ -142,8 +144,8 @@ class GradeRepositoryTest {
|
||||
val res = runBlocking { gradeRepository.getGrades(student, semester, true).toFirstResult() }
|
||||
|
||||
// verify
|
||||
assertEquals(null, res.error)
|
||||
assertEquals(4, res.data?.first?.size)
|
||||
assertEquals(null, res.errorOrNull)
|
||||
assertEquals(4, res.dataOrNull?.first?.size)
|
||||
coVerify {
|
||||
gradeDb.insertAll(withArg {
|
||||
assertEquals(3, it.size)
|
||||
@ -184,8 +186,8 @@ class GradeRepositoryTest {
|
||||
val res = runBlocking { gradeRepository.getGrades(student, semester, true).toFirstResult() }
|
||||
|
||||
// verify
|
||||
assertEquals(null, res.error)
|
||||
assertEquals(2, res.data?.first?.size)
|
||||
assertEquals(null, res.errorOrNull)
|
||||
assertEquals(2, res.dataOrNull?.first?.size)
|
||||
coVerify { gradeDb.insertAll(match { it.isEmpty() }) }
|
||||
coVerify { gradeDb.deleteAll(match { it.size == 1 }) } // ... here
|
||||
}
|
||||
@ -214,8 +216,8 @@ class GradeRepositoryTest {
|
||||
val res = runBlocking { gradeRepository.getGrades(student, semester, true).toFirstResult() }
|
||||
|
||||
// verify
|
||||
assertEquals(null, res.error)
|
||||
assertEquals(3, res.data?.first?.size)
|
||||
assertEquals(null, res.errorOrNull)
|
||||
assertEquals(3, res.dataOrNull?.first?.size)
|
||||
coVerify { gradeDb.insertAll(match { it.size == 1 }) } // ... here
|
||||
coVerify { gradeDb.deleteAll(match { it.isEmpty() }) }
|
||||
}
|
||||
@ -240,8 +242,8 @@ class GradeRepositoryTest {
|
||||
val res = runBlocking { gradeRepository.getGrades(student, semester, true).toFirstResult() }
|
||||
|
||||
// verify
|
||||
assertEquals(null, res.error)
|
||||
assertEquals(3, res.data?.first?.size)
|
||||
assertEquals(null, res.errorOrNull)
|
||||
assertEquals(3, res.dataOrNull?.first?.size)
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -263,8 +265,8 @@ class GradeRepositoryTest {
|
||||
val res = runBlocking { gradeRepository.getGrades(student, semester, true).toFirstResult() }
|
||||
|
||||
// verify
|
||||
assertEquals(null, res.error)
|
||||
assertEquals(0, res.data?.first?.size)
|
||||
assertEquals(null, res.errorOrNull)
|
||||
assertEquals(0, res.dataOrNull?.first?.size)
|
||||
}
|
||||
|
||||
private fun createGradeApi(value: Int, weight: Double, date: LocalDate, desc: String) =
|
||||
|
@ -1,16 +1,18 @@
|
||||
package io.github.wulkanowy.data.repositories
|
||||
|
||||
import io.github.wulkanowy.data.dataOrNull
|
||||
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.errorOrNull
|
||||
import io.github.wulkanowy.data.mappers.mapToEntities
|
||||
import io.github.wulkanowy.data.toFirstResult
|
||||
import io.github.wulkanowy.getSemesterEntity
|
||||
import io.github.wulkanowy.getStudentEntity
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
import io.github.wulkanowy.sdk.pojo.GradeStatisticsItem
|
||||
import io.github.wulkanowy.sdk.pojo.GradeStatisticsSubject
|
||||
import io.github.wulkanowy.utils.AutoRefreshHelper
|
||||
import io.github.wulkanowy.utils.toFirstResult
|
||||
import io.mockk.*
|
||||
import io.mockk.impl.annotations.MockK
|
||||
import io.mockk.impl.annotations.SpyK
|
||||
@ -81,11 +83,11 @@ class GradeStatisticsRepositoryTest {
|
||||
forceRefresh = true,
|
||||
).toFirstResult()
|
||||
}
|
||||
val items = res.data.orEmpty()
|
||||
val items = res.dataOrNull.orEmpty()
|
||||
|
||||
// verify
|
||||
assertEquals(null, res.error)
|
||||
assertEquals(2 + 1, res.data?.size)
|
||||
assertEquals(null, res.errorOrNull)
|
||||
assertEquals(2 + 1, res.dataOrNull?.size)
|
||||
assertEquals("", items[0].partial?.studentAverage)
|
||||
assertEquals("", items[1].partial?.studentAverage)
|
||||
assertEquals("", items[2].partial?.studentAverage)
|
||||
@ -119,11 +121,11 @@ class GradeStatisticsRepositoryTest {
|
||||
forceRefresh = true,
|
||||
).toFirstResult()
|
||||
}
|
||||
val items = res.data.orEmpty()
|
||||
val items = res.dataOrNull.orEmpty()
|
||||
|
||||
// verify
|
||||
assertEquals(null, res.error)
|
||||
assertEquals(2 + 1, res.data?.size)
|
||||
assertEquals(null, res.errorOrNull)
|
||||
assertEquals(2 + 1, res.dataOrNull?.size)
|
||||
assertEquals("3,00", items[0].partial?.studentAverage)
|
||||
assertEquals("1.0", items[1].partial?.studentAverage)
|
||||
assertEquals("5.0", items[2].partial?.studentAverage)
|
||||
|
@ -1,17 +1,15 @@
|
||||
package io.github.wulkanowy.data.repositories
|
||||
|
||||
import io.github.wulkanowy.data.dataOrNull
|
||||
import io.github.wulkanowy.data.db.dao.LuckyNumberDao
|
||||
import io.github.wulkanowy.data.errorOrNull
|
||||
import io.github.wulkanowy.data.mappers.mapToEntity
|
||||
import io.github.wulkanowy.data.toFirstResult
|
||||
import io.github.wulkanowy.getStudentEntity
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
import io.github.wulkanowy.utils.toFirstResult
|
||||
import io.mockk.MockKAnnotations
|
||||
import io.mockk.Runs
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.coVerify
|
||||
import io.mockk.*
|
||||
import io.mockk.impl.annotations.MockK
|
||||
import io.mockk.impl.annotations.SpyK
|
||||
import io.mockk.just
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Assert.assertEquals
|
||||
@ -58,8 +56,8 @@ class LuckyNumberRemoteTest {
|
||||
val res = runBlocking { luckyNumberRepository.getLuckyNumber(student, true).toFirstResult() }
|
||||
|
||||
// verify
|
||||
assertEquals(null, res.error)
|
||||
assertEquals(luckyNumber.number, res.data?.luckyNumber)
|
||||
assertEquals(null, res.errorOrNull)
|
||||
assertEquals(luckyNumber.number, res.dataOrNull?.luckyNumber)
|
||||
coVerify { sdk.getLuckyNumber(student.schoolShortName) }
|
||||
coVerify { luckyNumberDb.load(1, date) }
|
||||
coVerify(exactly = 0) { luckyNumberDb.insertAll(any()) }
|
||||
@ -82,8 +80,8 @@ class LuckyNumberRemoteTest {
|
||||
val res = runBlocking { luckyNumberRepository.getLuckyNumber(student, true).toFirstResult() }
|
||||
|
||||
// verify
|
||||
assertEquals(null, res.error)
|
||||
assertEquals(luckyNumber.number, res.data?.luckyNumber)
|
||||
assertEquals(null, res.errorOrNull)
|
||||
assertEquals(luckyNumber.number, res.dataOrNull?.luckyNumber)
|
||||
coVerify { sdk.getLuckyNumber(student.schoolShortName) }
|
||||
coVerify { luckyNumberDb.load(1, date) }
|
||||
coVerify {
|
||||
@ -112,8 +110,8 @@ class LuckyNumberRemoteTest {
|
||||
val res = runBlocking { luckyNumberRepository.getLuckyNumber(student, true).toFirstResult() }
|
||||
|
||||
// verify
|
||||
assertEquals(null, res.error)
|
||||
assertEquals(luckyNumber.number, res.data?.luckyNumber)
|
||||
assertEquals(null, res.errorOrNull)
|
||||
assertEquals(luckyNumber.number, res.dataOrNull?.luckyNumber)
|
||||
coVerify { sdk.getLuckyNumber(student.schoolShortName) }
|
||||
coVerify { luckyNumberDb.load(1, date) }
|
||||
coVerify {
|
||||
|
@ -1,13 +1,15 @@
|
||||
package io.github.wulkanowy.data.repositories
|
||||
|
||||
import android.content.Context
|
||||
import io.github.wulkanowy.data.Status
|
||||
import io.github.wulkanowy.data.dataOrNull
|
||||
import io.github.wulkanowy.data.db.SharedPrefProvider
|
||||
import io.github.wulkanowy.data.db.dao.MessageAttachmentDao
|
||||
import io.github.wulkanowy.data.db.dao.MessagesDao
|
||||
import io.github.wulkanowy.data.db.entities.Message
|
||||
import io.github.wulkanowy.data.db.entities.MessageWithAttachment
|
||||
import io.github.wulkanowy.data.enums.MessageFolder
|
||||
import io.github.wulkanowy.data.errorOrNull
|
||||
import io.github.wulkanowy.data.toFirstResult
|
||||
import io.github.wulkanowy.getSemesterEntity
|
||||
import io.github.wulkanowy.getStudentEntity
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
@ -15,7 +17,8 @@ import io.github.wulkanowy.sdk.pojo.Folder
|
||||
import io.github.wulkanowy.sdk.pojo.MessageDetails
|
||||
import io.github.wulkanowy.sdk.pojo.Sender
|
||||
import io.github.wulkanowy.utils.AutoRefreshHelper
|
||||
import io.github.wulkanowy.utils.toFirstResult
|
||||
import io.github.wulkanowy.utils.Status
|
||||
import io.github.wulkanowy.utils.status
|
||||
import io.mockk.*
|
||||
import io.mockk.impl.annotations.MockK
|
||||
import io.mockk.impl.annotations.SpyK
|
||||
@ -102,7 +105,7 @@ class MessageRepositoryTest {
|
||||
folder = MessageFolder.RECEIVED,
|
||||
forceRefresh = true,
|
||||
notify = true, // all new messages will be marked as not notified
|
||||
).toFirstResult().data.orEmpty()
|
||||
).toFirstResult().dataOrNull.orEmpty()
|
||||
|
||||
coVerify(exactly = 1) { messageDb.deleteAll(emptyList()) }
|
||||
coVerify(exactly = 1) { messageDb.insertAll(emptyList()) }
|
||||
@ -133,7 +136,7 @@ class MessageRepositoryTest {
|
||||
folder = MessageFolder.RECEIVED,
|
||||
forceRefresh = true,
|
||||
notify = false,
|
||||
).toFirstResult().data.orEmpty()
|
||||
).toFirstResult().dataOrNull.orEmpty()
|
||||
|
||||
coVerify(exactly = 1) { messageDb.deleteAll(withArg { checkEquals(emptyList<Message>()) }) }
|
||||
coVerify {
|
||||
@ -165,9 +168,9 @@ class MessageRepositoryTest {
|
||||
|
||||
val res = runBlocking { repository.getMessage(student, testMessage).toFirstResult() }
|
||||
|
||||
assertEquals(null, res.error)
|
||||
assertEquals(null, res.errorOrNull)
|
||||
assertEquals(Status.SUCCESS, res.status)
|
||||
assertEquals("Test", res.data!!.message.content)
|
||||
assertEquals("Test", res.dataOrNull!!.message.content)
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -197,9 +200,9 @@ class MessageRepositoryTest {
|
||||
|
||||
val res = runBlocking { repository.getMessage(student, testMessage).toFirstResult() }
|
||||
|
||||
assertEquals(null, res.error)
|
||||
assertEquals(null, res.errorOrNull)
|
||||
assertEquals(Status.SUCCESS, res.status)
|
||||
assertEquals("Test", res.data!!.message.content)
|
||||
assertEquals("Test", res.dataOrNull!!.message.content)
|
||||
coVerify { messageDb.updateAll(listOf(testMessageWithContent)) }
|
||||
}
|
||||
|
||||
|
@ -1,21 +1,18 @@
|
||||
package io.github.wulkanowy.data.repositories
|
||||
|
||||
import io.github.wulkanowy.data.dataOrNull
|
||||
import io.github.wulkanowy.data.db.dao.MobileDeviceDao
|
||||
import io.github.wulkanowy.data.errorOrNull
|
||||
import io.github.wulkanowy.data.mappers.mapToEntities
|
||||
import io.github.wulkanowy.data.toFirstResult
|
||||
import io.github.wulkanowy.getSemesterEntity
|
||||
import io.github.wulkanowy.getStudentEntity
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
import io.github.wulkanowy.sdk.pojo.Device
|
||||
import io.github.wulkanowy.utils.AutoRefreshHelper
|
||||
import io.github.wulkanowy.utils.toFirstResult
|
||||
import io.mockk.MockKAnnotations
|
||||
import io.mockk.Runs
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.coVerify
|
||||
import io.mockk.every
|
||||
import io.mockk.*
|
||||
import io.mockk.impl.annotations.MockK
|
||||
import io.mockk.impl.annotations.SpyK
|
||||
import io.mockk.just
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Assert
|
||||
@ -69,8 +66,8 @@ class MobileDeviceRepositoryTest {
|
||||
val res = runBlocking { mobileDeviceRepository.getDevices(student, semester, true).toFirstResult() }
|
||||
|
||||
// verify
|
||||
Assert.assertEquals(null, res.error)
|
||||
Assert.assertEquals(2, res.data?.size)
|
||||
Assert.assertEquals(null, res.errorOrNull)
|
||||
Assert.assertEquals(2, res.dataOrNull?.size)
|
||||
coVerify { sdk.getRegisteredDevices() }
|
||||
coVerify { mobileDeviceDb.loadAll(1) }
|
||||
coVerify { mobileDeviceDb.insertAll(match { it.isEmpty() }) }
|
||||
@ -93,8 +90,8 @@ class MobileDeviceRepositoryTest {
|
||||
val res = runBlocking { mobileDeviceRepository.getDevices(student, semester, true).toFirstResult() }
|
||||
|
||||
// verify
|
||||
Assert.assertEquals(null, res.error)
|
||||
Assert.assertEquals(2, res.data?.size)
|
||||
Assert.assertEquals(null, res.errorOrNull)
|
||||
Assert.assertEquals(2, res.dataOrNull?.size)
|
||||
coVerify { sdk.getRegisteredDevices() }
|
||||
coVerify { mobileDeviceDb.loadAll(1) }
|
||||
coVerify {
|
||||
@ -121,8 +118,8 @@ class MobileDeviceRepositoryTest {
|
||||
val res = runBlocking { mobileDeviceRepository.getDevices(student, semester, true).toFirstResult() }
|
||||
|
||||
// verify
|
||||
Assert.assertEquals(null, res.error)
|
||||
Assert.assertEquals(1, res.data?.size)
|
||||
Assert.assertEquals(null, res.errorOrNull)
|
||||
Assert.assertEquals(1, res.dataOrNull?.size)
|
||||
coVerify { sdk.getRegisteredDevices() }
|
||||
coVerify { mobileDeviceDb.loadAll(1) }
|
||||
coVerify { mobileDeviceDb.insertAll(match { it.isEmpty() }) }
|
||||
|
@ -1,24 +1,21 @@
|
||||
package io.github.wulkanowy.data.repositories
|
||||
|
||||
import io.github.wulkanowy.data.dataOrNull
|
||||
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.errorOrNull
|
||||
import io.github.wulkanowy.data.mappers.mapToEntities
|
||||
import io.github.wulkanowy.data.toFirstResult
|
||||
import io.github.wulkanowy.getSemesterEntity
|
||||
import io.github.wulkanowy.getStudentEntity
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
import io.github.wulkanowy.sdk.pojo.TimetableFull
|
||||
import io.github.wulkanowy.services.alarm.TimetableNotificationSchedulerHelper
|
||||
import io.github.wulkanowy.utils.AutoRefreshHelper
|
||||
import io.github.wulkanowy.utils.toFirstResult
|
||||
import io.mockk.MockKAnnotations
|
||||
import io.mockk.Runs
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.coVerify
|
||||
import io.mockk.every
|
||||
import io.mockk.*
|
||||
import io.mockk.impl.annotations.MockK
|
||||
import io.mockk.impl.annotations.SpyK
|
||||
import io.mockk.just
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.junit.Assert.assertEquals
|
||||
@ -96,8 +93,8 @@ class TimetableRepositoryTest {
|
||||
val res = runBlocking { timetableRepository.getTimetable(student, semester, startDate, endDate, true).toFirstResult() }
|
||||
|
||||
// verify
|
||||
assertEquals(null, res.error)
|
||||
assertEquals(2, res.data?.lessons?.size)
|
||||
assertEquals(null, res.errorOrNull)
|
||||
assertEquals(2, res.dataOrNull!!.lessons.size)
|
||||
coVerify { sdk.getTimetableFull(startDate, endDate) }
|
||||
coVerify { timetableDb.loadAll(1, 1, startDate, endDate) }
|
||||
coVerify { timetableDb.insertAll(match { it.isEmpty() }) }
|
||||
|
@ -1,16 +1,18 @@
|
||||
package io.github.wulkanowy.ui.modules.grade
|
||||
|
||||
import io.github.wulkanowy.data.Resource
|
||||
import io.github.wulkanowy.data.Status
|
||||
import io.github.wulkanowy.data.dataOrNull
|
||||
import io.github.wulkanowy.data.db.entities.Grade
|
||||
import io.github.wulkanowy.data.db.entities.GradeSummary
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
import io.github.wulkanowy.data.repositories.GradeRepository
|
||||
import io.github.wulkanowy.data.repositories.PreferencesRepository
|
||||
import io.github.wulkanowy.data.repositories.SemesterRepository
|
||||
import io.github.wulkanowy.data.resourceFlow
|
||||
import io.github.wulkanowy.getSemesterEntity
|
||||
import io.github.wulkanowy.sdk.Sdk
|
||||
import io.github.wulkanowy.utils.flowWithResource
|
||||
import io.github.wulkanowy.utils.Status
|
||||
import io.github.wulkanowy.utils.status
|
||||
import io.mockk.MockKAnnotations
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.every
|
||||
@ -29,7 +31,7 @@ import java.time.LocalDate.of
|
||||
|
||||
class GradeAverageProviderTest {
|
||||
|
||||
private suspend fun <T> Flow<Resource<T>>.getResult() = toList()[1].data!!
|
||||
private suspend fun <T> Flow<Resource<T>>.getResult() = toList()[1].dataOrNull!!
|
||||
|
||||
@MockK
|
||||
lateinit var preferencesRepository: PreferencesRepository
|
||||
@ -144,7 +146,13 @@ class GradeAverageProviderTest {
|
||||
every { preferencesRepository.gradeAverageForceCalc } returns false
|
||||
every { preferencesRepository.isOptionalArithmeticAverage } returns false
|
||||
every { preferencesRepository.gradeAverageMode } returns GradeAverageMode.ONE_SEMESTER
|
||||
coEvery { gradeRepository.getGrades(student, semesters[2], true) } returns flowWithResource { noWeightGrades to noWeightGradesSummary }
|
||||
coEvery {
|
||||
gradeRepository.getGrades(
|
||||
student,
|
||||
semesters[2],
|
||||
true
|
||||
)
|
||||
} returns resourceFlow { noWeightGrades to noWeightGradesSummary }
|
||||
|
||||
val items = runBlocking { gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId, true).getResult() }
|
||||
|
||||
@ -156,7 +164,13 @@ class GradeAverageProviderTest {
|
||||
every { preferencesRepository.gradeAverageForceCalc } returns false
|
||||
every { preferencesRepository.isOptionalArithmeticAverage } returns true
|
||||
every { preferencesRepository.gradeAverageMode } returns GradeAverageMode.ONE_SEMESTER
|
||||
coEvery { gradeRepository.getGrades(student, semesters[2], true) } returns flowWithResource { noWeightGrades to noWeightGradesArithmeticSummary }
|
||||
coEvery {
|
||||
gradeRepository.getGrades(
|
||||
student,
|
||||
semesters[2],
|
||||
true
|
||||
)
|
||||
} returns resourceFlow { noWeightGrades to noWeightGradesArithmeticSummary }
|
||||
|
||||
val items = runBlocking { gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId, true).getResult() }
|
||||
|
||||
@ -170,27 +184,27 @@ class GradeAverageProviderTest {
|
||||
every { preferencesRepository.gradeAverageMode } returns GradeAverageMode.ONE_SEMESTER
|
||||
coEvery { semesterRepository.getSemesters(student) } returns semesters
|
||||
coEvery { gradeRepository.getGrades(student, semesters[2], true) } returns flow {
|
||||
emit(Resource.loading())
|
||||
emit(Resource.loading(secondGradeWithModifier to secondSummariesWithModifier))
|
||||
emit(Resource.success(secondGradeWithModifier to secondSummariesWithModifier))
|
||||
emit(Resource.Loading())
|
||||
emit(Resource.Intermediate(secondGradeWithModifier to secondSummariesWithModifier))
|
||||
emit(Resource.Success(secondGradeWithModifier to secondSummariesWithModifier))
|
||||
}
|
||||
|
||||
val items = runBlocking { gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId, true).toList() }
|
||||
|
||||
with(items[0]) {
|
||||
assertEquals(Status.LOADING, status)
|
||||
assertEquals(null, data)
|
||||
assertEquals(null, dataOrNull)
|
||||
}
|
||||
with(items[1]) {
|
||||
assertEquals(Status.LOADING, status)
|
||||
assertEquals(1, data!!.size)
|
||||
assertEquals(1, dataOrNull?.size)
|
||||
}
|
||||
with(items[2]) {
|
||||
assertEquals(Status.SUCCESS, status)
|
||||
assertEquals(1, data!!.size)
|
||||
assertEquals(1, dataOrNull?.size)
|
||||
}
|
||||
|
||||
assertEquals(3.5, items[1].data?.single { it.subject == "Język polski" }!!.average, .0) // from details and after set custom plus/minus
|
||||
assertEquals(3.5, items[1].dataOrNull?.single { it.subject == "Język polski" }?.average ?: 0.0, .0) // from details and after set custom plus/minus
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -201,27 +215,27 @@ class GradeAverageProviderTest {
|
||||
|
||||
coEvery { semesterRepository.getSemesters(student) } returns semesters
|
||||
coEvery { gradeRepository.getGrades(student, semesters[2], false) } returns flow {
|
||||
emit(Resource.loading())
|
||||
emit(Resource.Loading())
|
||||
delay(1000)
|
||||
emit(Resource.success(secondGradeWithModifier to secondSummariesWithModifier))
|
||||
emit(Resource.Success(secondGradeWithModifier to secondSummariesWithModifier))
|
||||
}
|
||||
coEvery { gradeRepository.getGrades(student, semesters[1], false) } returns flow {
|
||||
emit(Resource.loading())
|
||||
emit(Resource.success(secondGradeWithModifier to secondSummariesWithModifier))
|
||||
emit(Resource.Loading())
|
||||
emit(Resource.Success(secondGradeWithModifier to secondSummariesWithModifier))
|
||||
}
|
||||
|
||||
val items = runBlocking { gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId, false).toList() }
|
||||
|
||||
with(items[0]) {
|
||||
assertEquals(Status.LOADING, status)
|
||||
assertEquals(null, data)
|
||||
assertEquals(null, dataOrNull)
|
||||
}
|
||||
with(items[1]) {
|
||||
assertEquals(Status.SUCCESS, status)
|
||||
assertEquals(1, data!!.size)
|
||||
assertEquals(1, dataOrNull?.size)
|
||||
}
|
||||
|
||||
assertEquals(3.5, items[1].data?.single { it.subject == "Język polski" }!!.average, .0) // from details and after set custom plus/minus
|
||||
assertEquals(3.5, items[1].dataOrNull?.single { it.subject == "Język polski" }?.average ?: 0.0, .0) // from details and after set custom plus/minus
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -230,12 +244,26 @@ class GradeAverageProviderTest {
|
||||
every { preferencesRepository.isOptionalArithmeticAverage } returns false
|
||||
every { preferencesRepository.gradeAverageMode } returns GradeAverageMode.BOTH_SEMESTERS
|
||||
|
||||
coEvery { gradeRepository.getGrades(student, semesters[1], false) } returns flowWithResource { secondGradeWithModifier to secondSummariesWithModifier }
|
||||
coEvery { gradeRepository.getGrades(student, semesters[2], false) } returns flowWithResource {
|
||||
listOf(getGrade(semesters[2].semesterId, "Język polski", .0, .0, .0)) to listOf(getSummary(semesters[2].semesterId, "Język polski", 2.5))
|
||||
coEvery {
|
||||
gradeRepository.getGrades(
|
||||
student,
|
||||
semesters[1],
|
||||
false
|
||||
)
|
||||
} returns resourceFlow { secondGradeWithModifier to secondSummariesWithModifier }
|
||||
coEvery { gradeRepository.getGrades(student, semesters[2], false) } returns resourceFlow {
|
||||
listOf(getGrade(semesters[2].semesterId, "Język polski", .0, .0, .0)) to listOf(
|
||||
getSummary(semesters[2].semesterId, "Język polski", 2.5)
|
||||
)
|
||||
}
|
||||
|
||||
val items = runBlocking { gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId, false).getResult() }
|
||||
val items = runBlocking {
|
||||
gradeAverageProvider.getGradesDetailsWithAverage(
|
||||
student,
|
||||
semesters[2].semesterId,
|
||||
false
|
||||
).getResult()
|
||||
}
|
||||
|
||||
assertEquals(3.5, items.single { it.subject == "Język polski" }.average, .0)
|
||||
}
|
||||
@ -246,10 +274,28 @@ class GradeAverageProviderTest {
|
||||
every { preferencesRepository.isOptionalArithmeticAverage } returns false
|
||||
every { preferencesRepository.gradeAverageMode } returns GradeAverageMode.BOTH_SEMESTERS
|
||||
|
||||
coEvery { gradeRepository.getGrades(student, semesters[1], false) } returns flowWithResource { secondGradeWithModifier to secondSummariesWithModifier }
|
||||
coEvery { gradeRepository.getGrades(student, semesters[2], false) } returns flowWithResource { emptyList<Grade>() to listOf(getSummary(24, "Język polski", .0))}
|
||||
coEvery {
|
||||
gradeRepository.getGrades(
|
||||
student,
|
||||
semesters[1],
|
||||
false
|
||||
)
|
||||
} returns resourceFlow { secondGradeWithModifier to secondSummariesWithModifier }
|
||||
coEvery {
|
||||
gradeRepository.getGrades(
|
||||
student,
|
||||
semesters[2],
|
||||
false
|
||||
)
|
||||
} returns resourceFlow { emptyList<Grade>() to listOf(getSummary(24, "Język polski", .0)) }
|
||||
|
||||
val items = runBlocking { gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId, false).getResult() }
|
||||
val items = runBlocking {
|
||||
gradeAverageProvider.getGradesDetailsWithAverage(
|
||||
student,
|
||||
semesters[2].semesterId,
|
||||
false
|
||||
).getResult()
|
||||
}
|
||||
|
||||
assertEquals(3.49, items.single { it.subject == "Język polski" }.average, .0)
|
||||
}
|
||||
@ -260,10 +306,28 @@ class GradeAverageProviderTest {
|
||||
every { preferencesRepository.isOptionalArithmeticAverage } returns false
|
||||
every { preferencesRepository.gradeAverageMode } returns GradeAverageMode.BOTH_SEMESTERS
|
||||
|
||||
coEvery { gradeRepository.getGrades(student, semesters[1], true) } returns flowWithResource { emptyList<Grade>() to emptyList() }
|
||||
coEvery { gradeRepository.getGrades(student, semesters[2], true) } returns flowWithResource { emptyList<Grade>() to emptyList() }
|
||||
coEvery {
|
||||
gradeRepository.getGrades(
|
||||
student,
|
||||
semesters[1],
|
||||
true
|
||||
)
|
||||
} returns resourceFlow { emptyList<Grade>() to emptyList() }
|
||||
coEvery {
|
||||
gradeRepository.getGrades(
|
||||
student,
|
||||
semesters[2],
|
||||
true
|
||||
)
|
||||
} returns resourceFlow { emptyList<Grade>() to emptyList() }
|
||||
|
||||
val items = runBlocking { gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId, true).getResult() }
|
||||
val items = runBlocking {
|
||||
gradeAverageProvider.getGradesDetailsWithAverage(
|
||||
student,
|
||||
semesters[2].semesterId,
|
||||
true
|
||||
).getResult()
|
||||
}
|
||||
|
||||
assertEquals(0, items.size)
|
||||
}
|
||||
@ -274,7 +338,13 @@ class GradeAverageProviderTest {
|
||||
every { preferencesRepository.isOptionalArithmeticAverage } returns false
|
||||
every { preferencesRepository.gradeAverageMode } returns GradeAverageMode.ONE_SEMESTER
|
||||
coEvery { semesterRepository.getSemesters(student) } returns semesters
|
||||
coEvery { gradeRepository.getGrades(student, semesters[2], true) } returns flowWithResource { secondGradeWithModifier to secondSummariesWithModifier }
|
||||
coEvery {
|
||||
gradeRepository.getGrades(
|
||||
student,
|
||||
semesters[2],
|
||||
true
|
||||
)
|
||||
} returns resourceFlow { secondGradeWithModifier to secondSummariesWithModifier }
|
||||
|
||||
val items = runBlocking { gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId, true).getResult() }
|
||||
|
||||
@ -292,7 +362,13 @@ class GradeAverageProviderTest {
|
||||
|
||||
every { preferencesRepository.gradeAverageMode } returns GradeAverageMode.ONE_SEMESTER
|
||||
coEvery { semesterRepository.getSemesters(student) } returns semesters
|
||||
coEvery { gradeRepository.getGrades(student, semesters[2], true) } returns flowWithResource { secondGradeWithModifier to secondSummariesWithModifier }
|
||||
coEvery {
|
||||
gradeRepository.getGrades(
|
||||
student,
|
||||
semesters[2],
|
||||
true
|
||||
)
|
||||
} returns resourceFlow { secondGradeWithModifier to secondSummariesWithModifier }
|
||||
|
||||
val items = runBlocking { gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId, true).getResult() }
|
||||
|
||||
@ -310,7 +386,13 @@ class GradeAverageProviderTest {
|
||||
|
||||
every { preferencesRepository.gradeAverageMode } returns GradeAverageMode.ONE_SEMESTER
|
||||
coEvery { semesterRepository.getSemesters(student) } returns semesters
|
||||
coEvery { gradeRepository.getGrades(student, semesters[2], true) } returns flowWithResource { secondGradeWithModifier to secondSummariesWithModifier }
|
||||
coEvery {
|
||||
gradeRepository.getGrades(
|
||||
student,
|
||||
semesters[2],
|
||||
true
|
||||
)
|
||||
} returns resourceFlow { secondGradeWithModifier to secondSummariesWithModifier }
|
||||
|
||||
val items = runBlocking { gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId, true).getResult() }
|
||||
|
||||
@ -328,7 +410,13 @@ class GradeAverageProviderTest {
|
||||
|
||||
every { preferencesRepository.gradeAverageMode } returns GradeAverageMode.ONE_SEMESTER
|
||||
coEvery { semesterRepository.getSemesters(student) } returns semesters
|
||||
coEvery { gradeRepository.getGrades(student, semesters[2], true) } returns flowWithResource { secondGradeWithModifier to secondSummariesWithModifier }
|
||||
coEvery {
|
||||
gradeRepository.getGrades(
|
||||
student,
|
||||
semesters[2],
|
||||
true
|
||||
)
|
||||
} returns resourceFlow { secondGradeWithModifier to secondSummariesWithModifier }
|
||||
|
||||
val items = runBlocking { gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId, true).getResult() }
|
||||
|
||||
@ -340,7 +428,13 @@ class GradeAverageProviderTest {
|
||||
every { preferencesRepository.gradeAverageForceCalc } returns false
|
||||
every { preferencesRepository.isOptionalArithmeticAverage } returns false
|
||||
every { preferencesRepository.gradeAverageMode } returns GradeAverageMode.ONE_SEMESTER
|
||||
coEvery { gradeRepository.getGrades(student, semesters[2], true) } returns flowWithResource { secondGrades to secondSummaries }
|
||||
coEvery {
|
||||
gradeRepository.getGrades(
|
||||
student,
|
||||
semesters[2],
|
||||
true
|
||||
)
|
||||
} returns resourceFlow { secondGrades to secondSummaries }
|
||||
|
||||
val items = runBlocking { gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId, true).getResult() }
|
||||
|
||||
@ -354,7 +448,13 @@ class GradeAverageProviderTest {
|
||||
every { preferencesRepository.gradeAverageForceCalc } returns true
|
||||
every { preferencesRepository.isOptionalArithmeticAverage } returns false
|
||||
every { preferencesRepository.gradeAverageMode } returns GradeAverageMode.ONE_SEMESTER
|
||||
coEvery { gradeRepository.getGrades(student, semesters[2], true) } returns flowWithResource { secondGrades to secondSummaries }
|
||||
coEvery {
|
||||
gradeRepository.getGrades(
|
||||
student,
|
||||
semesters[2],
|
||||
true
|
||||
)
|
||||
} returns resourceFlow { secondGrades to secondSummaries }
|
||||
|
||||
val items = runBlocking { gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId, true).getResult() }
|
||||
|
||||
@ -368,7 +468,13 @@ class GradeAverageProviderTest {
|
||||
every { preferencesRepository.gradeAverageForceCalc } returns true
|
||||
every { preferencesRepository.isOptionalArithmeticAverage } returns false
|
||||
every { preferencesRepository.gradeAverageMode } returns GradeAverageMode.ALL_YEAR
|
||||
coEvery { gradeRepository.getGrades(student, semesters[1], true) } returns flowWithResource { firstGrades to firstSummaries }
|
||||
coEvery {
|
||||
gradeRepository.getGrades(
|
||||
student,
|
||||
semesters[1],
|
||||
true
|
||||
)
|
||||
} returns resourceFlow { firstGrades to firstSummaries }
|
||||
|
||||
val items = runBlocking { gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[1].semesterId, true).getResult() }
|
||||
|
||||
@ -384,29 +490,29 @@ class GradeAverageProviderTest {
|
||||
every { preferencesRepository.gradeAverageMode } returns GradeAverageMode.ALL_YEAR
|
||||
coEvery { semesterRepository.getSemesters(student) } returns semesters
|
||||
coEvery { gradeRepository.getGrades(student, semesters[1], true) } returns flow {
|
||||
emit(Resource.loading())
|
||||
emit(Resource.loading(firstGrades to firstSummaries))
|
||||
emit(Resource.success(firstGrades to firstSummaries))
|
||||
emit(Resource.Loading())
|
||||
emit(Resource.Intermediate(firstGrades to firstSummaries))
|
||||
emit(Resource.Success(firstGrades to firstSummaries))
|
||||
}
|
||||
|
||||
val items = runBlocking { gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[1].semesterId, true).toList() }
|
||||
|
||||
with(items[0]) {
|
||||
assertEquals(Status.LOADING, status)
|
||||
assertEquals(null, data)
|
||||
assertEquals(null, dataOrNull)
|
||||
}
|
||||
with(items[1]) {
|
||||
assertEquals(Status.LOADING, status)
|
||||
assertEquals(2, data!!.size)
|
||||
assertEquals(2, dataOrNull?.size)
|
||||
}
|
||||
with(items[2]) {
|
||||
assertEquals(Status.SUCCESS, status)
|
||||
assertEquals(2, data!!.size)
|
||||
assertEquals(2, dataOrNull?.size)
|
||||
}
|
||||
|
||||
assertEquals(2, items[2].data!!.size)
|
||||
assertEquals(3.5, items[2].data!!.single { it.subject == "Matematyka" }.average, .0) // (from summary): 3,5
|
||||
assertEquals(3.5, items[2].data!!.single { it.subject == "Fizyka" }.average, .0) // (from summary): 3,5
|
||||
assertEquals(2, items[2].dataOrNull?.size)
|
||||
assertEquals(3.5, items[2].dataOrNull?.single { it.subject == "Matematyka" }?.average ?: 0.0, .0) // (from summary): 3,5
|
||||
assertEquals(3.5, items[2].dataOrNull?.single { it.subject == "Fizyka" }?.average ?: 0.0, .0) // (from summary): 3,5
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -414,13 +520,13 @@ class GradeAverageProviderTest {
|
||||
every { preferencesRepository.gradeAverageMode } returns GradeAverageMode.BOTH_SEMESTERS
|
||||
every { preferencesRepository.gradeAverageForceCalc } returns false
|
||||
every { preferencesRepository.isOptionalArithmeticAverage } returns false
|
||||
coEvery { gradeRepository.getGrades(student, semesters[1], true) } returns flowWithResource {
|
||||
coEvery { gradeRepository.getGrades(student, semesters[1], true) } returns resourceFlow {
|
||||
firstGrades to listOf(
|
||||
getSummary(22, "Matematyka", 3.0),
|
||||
getSummary(22, "Fizyka", 3.5)
|
||||
)
|
||||
}
|
||||
coEvery { gradeRepository.getGrades(student, semesters[2], true) } returns flowWithResource {
|
||||
coEvery { gradeRepository.getGrades(student, semesters[2], true) } returns resourceFlow {
|
||||
secondGrades to listOf(
|
||||
getSummary(22, "Matematyka", 3.5),
|
||||
getSummary(22, "Fizyka", 4.0)
|
||||
@ -440,46 +546,62 @@ class GradeAverageProviderTest {
|
||||
every { preferencesRepository.isOptionalArithmeticAverage } returns false
|
||||
every { preferencesRepository.gradeAverageForceCalc } returns false
|
||||
coEvery { gradeRepository.getGrades(student, semesters[1], true) } returns flow {
|
||||
emit(Resource.loading())
|
||||
emit(Resource.loading(firstGrades to listOf(
|
||||
getSummary(22, "Matematyka", 3.0),
|
||||
getSummary(22, "Fizyka", 3.5)
|
||||
)))
|
||||
emit(Resource.success(firstGrades to listOf(
|
||||
getSummary(22, "Matematyka", 3.0),
|
||||
getSummary(22, "Fizyka", 3.5)
|
||||
)))
|
||||
emit(Resource.Loading())
|
||||
emit(
|
||||
Resource.Intermediate(
|
||||
firstGrades to listOf(
|
||||
getSummary(22, "Matematyka", 3.0),
|
||||
getSummary(22, "Fizyka", 3.5)
|
||||
)
|
||||
)
|
||||
)
|
||||
emit(
|
||||
Resource.Success(
|
||||
firstGrades to listOf(
|
||||
getSummary(22, "Matematyka", 3.0),
|
||||
getSummary(22, "Fizyka", 3.5)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
coEvery { gradeRepository.getGrades(student, semesters[2], true) } returns flow {
|
||||
emit(Resource.loading())
|
||||
emit(Resource.loading(secondGrades to listOf(
|
||||
getSummary(22, "Matematyka", 3.5),
|
||||
getSummary(22, "Fizyka", 4.0)
|
||||
)))
|
||||
emit(Resource.success(secondGrades to listOf(
|
||||
getSummary(22, "Matematyka", 3.5),
|
||||
getSummary(22, "Fizyka", 4.0)
|
||||
)))
|
||||
emit(Resource.Loading())
|
||||
emit(
|
||||
Resource.Intermediate(
|
||||
secondGrades to listOf(
|
||||
getSummary(22, "Matematyka", 3.5),
|
||||
getSummary(22, "Fizyka", 4.0)
|
||||
)
|
||||
)
|
||||
)
|
||||
emit(
|
||||
Resource.Success(
|
||||
secondGrades to listOf(
|
||||
getSummary(22, "Matematyka", 3.5),
|
||||
getSummary(22, "Fizyka", 4.0)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
val items = runBlocking { gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId, true).toList() }
|
||||
|
||||
with(items[0]) {
|
||||
assertEquals(Status.LOADING, status)
|
||||
assertEquals(null, data)
|
||||
assertEquals(null, dataOrNull)
|
||||
}
|
||||
with(items[1]) {
|
||||
assertEquals(Status.LOADING, status)
|
||||
assertEquals(2, data!!.size)
|
||||
assertEquals(2, dataOrNull?.size)
|
||||
}
|
||||
with(items[2]) {
|
||||
assertEquals(Status.SUCCESS, status)
|
||||
assertEquals(2, data!!.size)
|
||||
assertEquals(2, dataOrNull?.size)
|
||||
}
|
||||
|
||||
assertEquals(2, items[2].data!!.size)
|
||||
assertEquals(3.25, items[2].data!!.single { it.subject == "Matematyka" }.average, .0) // (from summaries ↑): 3,0 + 3,5 → 3,25
|
||||
assertEquals(3.75, items[2].data!!.single { it.subject == "Fizyka" }.average, .0) // (from summaries ↑): 3,5 + 4,0 → 3,75
|
||||
assertEquals(2, items[2].dataOrNull?.size)
|
||||
assertEquals(3.25, items[2].dataOrNull?.single { it.subject == "Matematyka" }?.average ?: 0.0, .0) // (from summaries ↑): 3,0 + 3,5 → 3,25
|
||||
assertEquals(3.75, items[2].dataOrNull?.single { it.subject == "Fizyka" }?.average ?: 0.0, .0) // (from summaries ↑): 3,5 + 4,0 → 3,75
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -487,8 +609,14 @@ class GradeAverageProviderTest {
|
||||
every { preferencesRepository.gradeAverageForceCalc } returns true
|
||||
every { preferencesRepository.isOptionalArithmeticAverage } returns false
|
||||
every { preferencesRepository.gradeAverageMode } returns GradeAverageMode.ALL_YEAR
|
||||
coEvery { gradeRepository.getGrades(student, semesters[1], true) } returns flowWithResource { firstGrades to firstSummaries }
|
||||
coEvery { gradeRepository.getGrades(student, semesters[2], true) } returns flowWithResource {
|
||||
coEvery {
|
||||
gradeRepository.getGrades(
|
||||
student,
|
||||
semesters[1],
|
||||
true
|
||||
)
|
||||
} returns resourceFlow { firstGrades to firstSummaries }
|
||||
coEvery { gradeRepository.getGrades(student, semesters[2], true) } returns resourceFlow {
|
||||
secondGrades to listOf(
|
||||
getSummary(22, "Matematyka", 1.1),
|
||||
getSummary(22, "Fizyka", 7.26)
|
||||
@ -527,7 +655,7 @@ class GradeAverageProviderTest {
|
||||
semesters[1],
|
||||
true
|
||||
)
|
||||
} returns flowWithResource {
|
||||
} returns resourceFlow {
|
||||
firstGrades to listOf(
|
||||
getSummary(22, "Matematyka", .0),
|
||||
getSummary(22, "Fizyka", .0)
|
||||
@ -539,7 +667,7 @@ class GradeAverageProviderTest {
|
||||
semesters[2],
|
||||
true
|
||||
)
|
||||
} returns flowWithResource {
|
||||
} returns resourceFlow {
|
||||
secondGrades to listOf(
|
||||
getSummary(22, "Matematyka", .0),
|
||||
getSummary(22, "Fizyka", .0)
|
||||
@ -566,40 +694,48 @@ class GradeAverageProviderTest {
|
||||
every { preferencesRepository.gradeAverageMode } returns GradeAverageMode.ALL_YEAR
|
||||
coEvery { semesterRepository.getSemesters(student) } returns semesters
|
||||
coEvery { gradeRepository.getGrades(student, semesters[1], true) } returns flow {
|
||||
emit(Resource.loading())
|
||||
emit(Resource.loading(firstGrades to firstSummaries))
|
||||
emit(Resource.success(firstGrades to firstSummaries))
|
||||
emit(Resource.Loading())
|
||||
emit(Resource.Intermediate(firstGrades to firstSummaries))
|
||||
emit(Resource.Success(firstGrades to firstSummaries))
|
||||
}
|
||||
coEvery { gradeRepository.getGrades(student, semesters[2], true) } returns flow {
|
||||
emit(Resource.loading())
|
||||
emit(Resource.loading(secondGrades to listOf(
|
||||
getSummary(22, "Matematyka", 1.1),
|
||||
getSummary(22, "Fizyka", 7.26)
|
||||
)))
|
||||
emit(Resource.success(secondGrades to listOf(
|
||||
getSummary(22, "Matematyka", 1.1),
|
||||
getSummary(22, "Fizyka", 7.26)
|
||||
)))
|
||||
emit(Resource.Loading())
|
||||
emit(
|
||||
Resource.Intermediate(
|
||||
secondGrades to listOf(
|
||||
getSummary(22, "Matematyka", 1.1),
|
||||
getSummary(22, "Fizyka", 7.26)
|
||||
)
|
||||
)
|
||||
)
|
||||
emit(
|
||||
Resource.Success(
|
||||
secondGrades to listOf(
|
||||
getSummary(22, "Matematyka", 1.1),
|
||||
getSummary(22, "Fizyka", 7.26)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
val items = runBlocking { gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId, true).toList() }
|
||||
|
||||
with(items[0]) {
|
||||
assertEquals(Status.LOADING, status)
|
||||
assertEquals(null, data)
|
||||
assertEquals(null, dataOrNull)
|
||||
}
|
||||
with(items[1]) {
|
||||
assertEquals(Status.LOADING, status)
|
||||
assertEquals(2, data!!.size)
|
||||
assertEquals(2, dataOrNull?.size)
|
||||
}
|
||||
with(items[2]) {
|
||||
assertEquals(Status.SUCCESS, status)
|
||||
assertEquals(2, data!!.size)
|
||||
assertEquals(2, dataOrNull?.size)
|
||||
}
|
||||
|
||||
assertEquals(2, items[2].data!!.size)
|
||||
assertEquals(3.0, items[2].data!!.single { it.subject == "Matematyka" }.average, .0) // (from details): 3,5 + 2,5 → 3,0
|
||||
assertEquals(3.25, items[2].data!!.single { it.subject == "Fizyka" }.average, .0) // (from details): 3,5 + 3,0 → 3,25
|
||||
assertEquals(2, items[2].dataOrNull?.size)
|
||||
assertEquals(3.0, items[2].dataOrNull?.single { it.subject == "Matematyka" }?.average ?: 0.0, .0) // (from details): 3,5 + 2,5 → 3,0
|
||||
assertEquals(3.25, items[2].dataOrNull?.single { it.subject == "Fizyka" }?.average ?: 0.0, .0) // (from details): 3,5 + 3,0 → 3,25
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -614,14 +750,14 @@ class GradeAverageProviderTest {
|
||||
semesters[1],
|
||||
true
|
||||
)
|
||||
} returns flowWithResource { firstGrades to emptyList() }
|
||||
} returns resourceFlow { firstGrades to emptyList() }
|
||||
coEvery {
|
||||
gradeRepository.getGrades(
|
||||
student,
|
||||
semesters[2],
|
||||
true
|
||||
)
|
||||
} returns flowWithResource { secondGrades to emptyList() }
|
||||
} returns resourceFlow { secondGrades to emptyList() }
|
||||
|
||||
val items = runBlocking {
|
||||
gradeAverageProvider.getGradesDetailsWithAverage(
|
||||
@ -646,14 +782,40 @@ class GradeAverageProviderTest {
|
||||
every { preferencesRepository.isOptionalArithmeticAverage } returns false
|
||||
every { preferencesRepository.gradeAverageMode } returns GradeAverageMode.ALL_YEAR
|
||||
|
||||
coEvery { gradeRepository.getGrades(student, semesters[1], true) } returns flowWithResource { firstGrades to emptyList() }
|
||||
coEvery { gradeRepository.getGrades(student, semesters[2], true) } returns flowWithResource { secondGrades to emptyList() }
|
||||
coEvery {
|
||||
gradeRepository.getGrades(
|
||||
student,
|
||||
semesters[1],
|
||||
true
|
||||
)
|
||||
} returns resourceFlow { firstGrades to emptyList() }
|
||||
coEvery {
|
||||
gradeRepository.getGrades(
|
||||
student,
|
||||
semesters[2],
|
||||
true
|
||||
)
|
||||
} returns resourceFlow { secondGrades to emptyList() }
|
||||
|
||||
val items = runBlocking { gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId, true).getResult() }
|
||||
val items = runBlocking {
|
||||
gradeAverageProvider.getGradesDetailsWithAverage(
|
||||
student,
|
||||
semesters[2].semesterId,
|
||||
true
|
||||
).getResult()
|
||||
}
|
||||
|
||||
assertEquals(2, items.size)
|
||||
assertEquals(3.0, items.single { it.subject == "Matematyka" }.average, .0) // (from details): 3,5 + 2,5 → 3,0
|
||||
assertEquals(3.25, items.single { it.subject == "Fizyka" }.average, .0) // (from details): 3,5 + 3,0 → 3,25
|
||||
assertEquals(
|
||||
3.0,
|
||||
items.single { it.subject == "Matematyka" }.average,
|
||||
.0
|
||||
) // (from details): 3,5 + 2,5 → 3,0
|
||||
assertEquals(
|
||||
3.25,
|
||||
items.single { it.subject == "Fizyka" }.average,
|
||||
.0
|
||||
) // (from details): 3,5 + 3,0 → 3,25
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -662,12 +824,12 @@ class GradeAverageProviderTest {
|
||||
every { preferencesRepository.isOptionalArithmeticAverage } returns false
|
||||
every { preferencesRepository.gradeAverageMode } returns GradeAverageMode.BOTH_SEMESTERS
|
||||
|
||||
coEvery { gradeRepository.getGrades(student, semesters[1], true) } returns flowWithResource {
|
||||
coEvery { gradeRepository.getGrades(student, semesters[1], true) } returns resourceFlow {
|
||||
firstGrades to listOf(
|
||||
getSummary(22, "Matematyka", 4.0)
|
||||
)
|
||||
}
|
||||
coEvery { gradeRepository.getGrades(student, semesters[2], true) } returns flowWithResource {
|
||||
coEvery { gradeRepository.getGrades(student, semesters[2], true) } returns resourceFlow {
|
||||
secondGrades to listOf(
|
||||
getSummary(23, "Matematyka", 3.0)
|
||||
)
|
||||
@ -686,14 +848,40 @@ class GradeAverageProviderTest {
|
||||
every { preferencesRepository.isOptionalArithmeticAverage } returns false
|
||||
every { preferencesRepository.gradeAverageMode } returns GradeAverageMode.BOTH_SEMESTERS
|
||||
|
||||
coEvery { gradeRepository.getGrades(student, semesters[1], true) } returns flowWithResource { firstGrades to firstSummaries }
|
||||
coEvery { gradeRepository.getGrades(student, semesters[2], true) } returns flowWithResource { secondGrades to secondSummaries.dropLast(1) }
|
||||
coEvery {
|
||||
gradeRepository.getGrades(
|
||||
student,
|
||||
semesters[1],
|
||||
true
|
||||
)
|
||||
} returns resourceFlow { firstGrades to firstSummaries }
|
||||
coEvery {
|
||||
gradeRepository.getGrades(
|
||||
student,
|
||||
semesters[2],
|
||||
true
|
||||
)
|
||||
} returns resourceFlow { secondGrades to secondSummaries.dropLast(1) }
|
||||
|
||||
val items = runBlocking { gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId, true).getResult() }
|
||||
val items = runBlocking {
|
||||
gradeAverageProvider.getGradesDetailsWithAverage(
|
||||
student,
|
||||
semesters[2].semesterId,
|
||||
true
|
||||
).getResult()
|
||||
}
|
||||
|
||||
assertEquals(2, items.size)
|
||||
assertEquals(3.4, items.single { it.subject == "Matematyka" }.average, .0) // (from summaries): 3,9 + 2,9 → 3,4
|
||||
assertEquals(3.05, items.single { it.subject == "Fizyka" }.average, .0) // 3,1 (from summary) + 3,0 (from details) → 3,05
|
||||
assertEquals(
|
||||
3.4,
|
||||
items.single { it.subject == "Matematyka" }.average,
|
||||
.0
|
||||
) // (from summaries): 3,9 + 2,9 → 3,4
|
||||
assertEquals(
|
||||
3.05,
|
||||
items.single { it.subject == "Fizyka" }.average,
|
||||
.0
|
||||
) // 3,1 (from summary) + 3,0 (from details) → 3,05
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -702,14 +890,40 @@ class GradeAverageProviderTest {
|
||||
every { preferencesRepository.isOptionalArithmeticAverage } returns false
|
||||
every { preferencesRepository.gradeAverageMode } returns GradeAverageMode.BOTH_SEMESTERS
|
||||
|
||||
coEvery { gradeRepository.getGrades(student, semesters[1], true) } returns flowWithResource { firstGrades to firstSummaries.dropLast(1) }
|
||||
coEvery { gradeRepository.getGrades(student, semesters[2], true) } returns flowWithResource { secondGrades to secondSummaries }
|
||||
coEvery {
|
||||
gradeRepository.getGrades(
|
||||
student,
|
||||
semesters[1],
|
||||
true
|
||||
)
|
||||
} returns resourceFlow { firstGrades to firstSummaries.dropLast(1) }
|
||||
coEvery {
|
||||
gradeRepository.getGrades(
|
||||
student,
|
||||
semesters[2],
|
||||
true
|
||||
)
|
||||
} returns resourceFlow { secondGrades to secondSummaries }
|
||||
|
||||
val items = runBlocking { gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId, true).getResult() }
|
||||
val items = runBlocking {
|
||||
gradeAverageProvider.getGradesDetailsWithAverage(
|
||||
student,
|
||||
semesters[2].semesterId,
|
||||
true
|
||||
).getResult()
|
||||
}
|
||||
|
||||
assertEquals(2, items.size)
|
||||
assertEquals(3.4, items.single { it.subject == "Matematyka" }.average, .0) // (from summaries): 3,9 + 2,9 → 3,4
|
||||
assertEquals(3.45, items.single { it.subject == "Fizyka" }.average, .0) // 3,5 (from details) + 3,4 (from summary) → 3,45
|
||||
assertEquals(
|
||||
3.4,
|
||||
items.single { it.subject == "Matematyka" }.average,
|
||||
.0
|
||||
) // (from summaries): 3,9 + 2,9 → 3,4
|
||||
assertEquals(
|
||||
3.45,
|
||||
items.single { it.subject == "Fizyka" }.average,
|
||||
.0
|
||||
) // 3,5 (from details) + 3,4 (from summary) → 3,45
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -718,14 +932,40 @@ class GradeAverageProviderTest {
|
||||
every { preferencesRepository.isOptionalArithmeticAverage } returns false
|
||||
every { preferencesRepository.gradeAverageMode } returns GradeAverageMode.ALL_YEAR
|
||||
|
||||
coEvery { gradeRepository.getGrades(student, semesters[1], true) } returns flowWithResource { firstGrades to firstSummaries.dropLast(1) }
|
||||
coEvery { gradeRepository.getGrades(student, semesters[2], true) } returns flowWithResource { secondGrades to secondSummaries }
|
||||
coEvery {
|
||||
gradeRepository.getGrades(
|
||||
student,
|
||||
semesters[1],
|
||||
true
|
||||
)
|
||||
} returns resourceFlow { firstGrades to firstSummaries.dropLast(1) }
|
||||
coEvery {
|
||||
gradeRepository.getGrades(
|
||||
student,
|
||||
semesters[2],
|
||||
true
|
||||
)
|
||||
} returns resourceFlow { secondGrades to secondSummaries }
|
||||
|
||||
val items = runBlocking { gradeAverageProvider.getGradesDetailsWithAverage(student, semesters[2].semesterId, true).getResult() }
|
||||
val items = runBlocking {
|
||||
gradeAverageProvider.getGradesDetailsWithAverage(
|
||||
student,
|
||||
semesters[2].semesterId,
|
||||
true
|
||||
).getResult()
|
||||
}
|
||||
|
||||
assertEquals(2, items.size)
|
||||
assertEquals(3.0, items.single { it.subject == "Matematyka" }.average, .0) // (from details): 3,5 + 2,5 → 3,0
|
||||
assertEquals(3.25, items.single { it.subject == "Fizyka" }.average, .0) // (from details): 3,5 + 3,0 → 3,25
|
||||
assertEquals(
|
||||
3.0,
|
||||
items.single { it.subject == "Matematyka" }.average,
|
||||
.0
|
||||
) // (from details): 3,5 + 2,5 → 3,0
|
||||
assertEquals(
|
||||
3.25,
|
||||
items.single { it.subject == "Fizyka" }.average,
|
||||
.0
|
||||
) // (from details): 3,5 + 3,0 → 3,25
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -734,7 +974,7 @@ class GradeAverageProviderTest {
|
||||
every { preferencesRepository.gradeAverageMode } returns GradeAverageMode.BOTH_SEMESTERS
|
||||
every { preferencesRepository.isOptionalArithmeticAverage } returns false
|
||||
|
||||
coEvery { gradeRepository.getGrades(student, semesters[1], true) } returns flowWithResource {
|
||||
coEvery { gradeRepository.getGrades(student, semesters[1], true) } returns resourceFlow {
|
||||
listOf(
|
||||
getGrade(22, "Fizyka", 5.0, weight = 2.0),
|
||||
getGrade(22, "Fizyka", 6.0, weight = 2.0),
|
||||
@ -746,7 +986,7 @@ class GradeAverageProviderTest {
|
||||
getGrade(22, "Fizyka", 6.0, weight = 2.0)
|
||||
) to listOf(getSummary(semesterId = 22, subject = "Fizyka", average = .0))
|
||||
}
|
||||
coEvery { gradeRepository.getGrades(student, semesters[2], true) } returns flowWithResource {
|
||||
coEvery { gradeRepository.getGrades(student, semesters[2], true) } returns resourceFlow {
|
||||
listOf(
|
||||
getGrade(23, "Fizyka", 5.0, weight = 1.0),
|
||||
getGrade(23, "Fizyka", 5.0, weight = 2.0),
|
||||
@ -765,7 +1005,7 @@ class GradeAverageProviderTest {
|
||||
every { preferencesRepository.isOptionalArithmeticAverage } returns false
|
||||
every { preferencesRepository.gradeAverageMode } returns GradeAverageMode.ALL_YEAR
|
||||
|
||||
coEvery { gradeRepository.getGrades(student, semesters[1], true) } returns flowWithResource {
|
||||
coEvery { gradeRepository.getGrades(student, semesters[1], true) } returns resourceFlow {
|
||||
listOf(
|
||||
getGrade(22, "Fizyka", 5.0, weight = 2.0),
|
||||
getGrade(22, "Fizyka", 6.0, weight = 2.0),
|
||||
@ -777,7 +1017,7 @@ class GradeAverageProviderTest {
|
||||
getGrade(22, "Fizyka", 6.0, weight = 2.0)
|
||||
) to listOf(getSummary(semesterId = 22, subject = "Fizyka", average = .0))
|
||||
}
|
||||
coEvery { gradeRepository.getGrades(student, semesters[2], true) } returns flowWithResource {
|
||||
coEvery { gradeRepository.getGrades(student, semesters[2], true) } returns resourceFlow {
|
||||
listOf(
|
||||
getGrade(23, "Fizyka", 5.0, weight = 1.0),
|
||||
getGrade(23, "Fizyka", 5.0, weight = 2.0),
|
||||
@ -802,7 +1042,7 @@ class GradeAverageProviderTest {
|
||||
every { preferencesRepository.gradeAverageMode } returns GradeAverageMode.BOTH_SEMESTERS
|
||||
coEvery { semesterRepository.getSemesters(student) } returns semesters
|
||||
|
||||
coEvery { gradeRepository.getGrades(student, semesters[1], true) } returns flowWithResource {
|
||||
coEvery { gradeRepository.getGrades(student, semesters[1], true) } returns resourceFlow {
|
||||
listOf(
|
||||
getGrade(22, "Fizyka", 5.0, weight = 2.0),
|
||||
getGrade(22, "Fizyka", 6.0, weight = 2.0),
|
||||
@ -814,7 +1054,7 @@ class GradeAverageProviderTest {
|
||||
getGrade(22, "Fizyka", 6.0, weight = 2.0)
|
||||
) to listOf(getSummary(semesterId = 22, subject = "Fizyka", average = .0))
|
||||
}
|
||||
coEvery { gradeRepository.getGrades(student, semesters[2], true) } returns flowWithResource {
|
||||
coEvery { gradeRepository.getGrades(student, semesters[2], true) } returns resourceFlow {
|
||||
listOf(
|
||||
getGrade(23, "Fizyka", 5.0, weight = 1.0),
|
||||
getGrade(23, "Fizyka", 5.0, weight = 2.0),
|
||||
@ -839,7 +1079,7 @@ class GradeAverageProviderTest {
|
||||
every { preferencesRepository.gradeAverageMode } returns GradeAverageMode.ALL_YEAR
|
||||
coEvery { semesterRepository.getSemesters(student) } returns semesters
|
||||
|
||||
coEvery { gradeRepository.getGrades(student, semesters[1], true) } returns flowWithResource {
|
||||
coEvery { gradeRepository.getGrades(student, semesters[1], true) } returns resourceFlow {
|
||||
listOf(
|
||||
getGrade(22, "Fizyka", 5.0, weight = 2.0),
|
||||
getGrade(22, "Fizyka", 6.0, weight = 2.0),
|
||||
@ -851,7 +1091,7 @@ class GradeAverageProviderTest {
|
||||
getGrade(22, "Fizyka", 6.0, weight = 2.0)
|
||||
) to listOf(getSummary(semesterId = 22, subject = "Fizyka", average = .0))
|
||||
}
|
||||
coEvery { gradeRepository.getGrades(student, semesters[2], true) } returns flowWithResource {
|
||||
coEvery { gradeRepository.getGrades(student, semesters[2], true) } returns resourceFlow {
|
||||
listOf(
|
||||
getGrade(23, "Fizyka", 5.0, weight = 1.0),
|
||||
getGrade(23, "Fizyka", 5.0, weight = 2.0),
|
||||
@ -881,9 +1121,9 @@ class GradeAverageProviderTest {
|
||||
every { preferencesRepository.isOptionalArithmeticAverage } returns false
|
||||
|
||||
coEvery { gradeRepository.getGrades(student, semesters[1], true) } returns
|
||||
flowWithResource { firstGrades to firstSummaries }
|
||||
resourceFlow { firstGrades to firstSummaries }
|
||||
coEvery { gradeRepository.getGrades(student, semesters[2], true) } returns
|
||||
flowWithResource { listOf<Grade>() to firstSummaries }
|
||||
resourceFlow { listOf<Grade>() to firstSummaries }
|
||||
|
||||
val items = runBlocking {
|
||||
gradeAverageProvider.getGradesDetailsWithAverage(
|
||||
|
14
app/src/test/java/io/github/wulkanowy/utils/ResourceUtils.kt
Normal file
14
app/src/test/java/io/github/wulkanowy/utils/ResourceUtils.kt
Normal file
@ -0,0 +1,14 @@
|
||||
package io.github.wulkanowy.utils
|
||||
|
||||
import io.github.wulkanowy.data.Resource
|
||||
|
||||
enum class Status {
|
||||
LOADING, SUCCESS, ERROR
|
||||
}
|
||||
|
||||
val <T> Resource<T>.status
|
||||
get() = when (this) {
|
||||
is Resource.Error -> Status.ERROR
|
||||
is Resource.Loading -> Status.LOADING
|
||||
is Resource.Success -> Status.SUCCESS
|
||||
}
|
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