forked from github/wulkanowy-mirror
Automatically switch semesters without sync (#681)
This commit is contained in:
@ -27,9 +27,6 @@ data class Semester(
|
||||
@ColumnInfo(name = "semester_name")
|
||||
val semesterName: Int,
|
||||
|
||||
@ColumnInfo(name = "is_current")
|
||||
val isCurrent: Boolean,
|
||||
|
||||
val start: LocalDate,
|
||||
|
||||
val end: LocalDate,
|
||||
@ -43,4 +40,8 @@ data class Semester(
|
||||
|
||||
@PrimaryKey(autoGenerate = true)
|
||||
var id: Long = 0
|
||||
|
||||
|
||||
@ColumnInfo(name = "is_current")
|
||||
var current: Boolean = false
|
||||
}
|
||||
|
@ -19,6 +19,6 @@ class SemesterLocal @Inject constructor(private val semesterDb: SemesterDao) {
|
||||
}
|
||||
|
||||
fun getSemesters(student: Student): Maybe<List<Semester>> {
|
||||
return semesterDb.loadAll(student.studentId, student.classId).filter { !it.isEmpty() }
|
||||
return semesterDb.loadAll(student.studentId, student.classId).filter { it.isNotEmpty() }
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,6 @@ class SemesterRemote @Inject constructor(private val sdk: Sdk) {
|
||||
schoolYear = it.schoolYear,
|
||||
semesterId = it.semesterId,
|
||||
semesterName = it.semesterNumber,
|
||||
isCurrent = it.current,
|
||||
start = it.start,
|
||||
end = it.end,
|
||||
classId = it.classId,
|
||||
|
@ -5,10 +5,11 @@ import com.github.pwittchen.reactivenetwork.library.rx2.internet.observing.Inter
|
||||
import io.github.wulkanowy.data.SdkHelper
|
||||
import io.github.wulkanowy.data.db.entities.Semester
|
||||
import io.github.wulkanowy.data.db.entities.Student
|
||||
import io.github.wulkanowy.utils.getCurrentOrLast
|
||||
import io.github.wulkanowy.utils.isCurrent
|
||||
import io.github.wulkanowy.utils.uniqueSubtract
|
||||
import io.reactivex.Maybe
|
||||
import io.reactivex.Single
|
||||
import timber.log.Timber
|
||||
import java.net.UnknownHostException
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
@ -21,28 +22,30 @@ class SemesterRepository @Inject constructor(
|
||||
private val sdkHelper: SdkHelper
|
||||
) {
|
||||
|
||||
fun getSemesters(student: Student, forceRefresh: Boolean = false): Single<List<Semester>> {
|
||||
fun getSemesters(student: Student, forceRefresh: Boolean = false, refreshOnNoCurrent: Boolean = false): Single<List<Semester>> {
|
||||
return Maybe.just(sdkHelper.init(student))
|
||||
.flatMap { local.getSemesters(student).filter { !forceRefresh } }
|
||||
.flatMap {
|
||||
local.getSemesters(student).filter { !forceRefresh }.filter {
|
||||
if (refreshOnNoCurrent) {
|
||||
it.any { semester -> semester.isCurrent }
|
||||
} else true
|
||||
}
|
||||
}
|
||||
.switchIfEmpty(ReactiveNetwork.checkInternetConnectivity(settings)
|
||||
.flatMap {
|
||||
if (it) remote.getSemesters(student) else Single.error(UnknownHostException())
|
||||
if (it) remote.getSemesters(student)
|
||||
else Single.error(UnknownHostException())
|
||||
}.flatMap { new ->
|
||||
val currentSemesters = new.filter { it.isCurrent }
|
||||
if (currentSemesters.size == 1) {
|
||||
local.getSemesters(student).toSingle(emptyList())
|
||||
.doOnSuccess { old ->
|
||||
local.deleteSemesters(old.uniqueSubtract(new))
|
||||
local.saveSemesters(new.uniqueSubtract(old))
|
||||
}
|
||||
} else {
|
||||
Timber.i("Current semesters list:\n${new.joinToString(separator = "\n")}")
|
||||
throw IllegalArgumentException("Current semester can be only one.")
|
||||
if (new.isEmpty()) throw IllegalArgumentException("Empty semester list!")
|
||||
|
||||
local.getSemesters(student).toSingle(emptyList()).doOnSuccess { old ->
|
||||
local.deleteSemesters(old.uniqueSubtract(new))
|
||||
local.saveSemesters(new.uniqueSubtract(old))
|
||||
}
|
||||
}.flatMap { local.getSemesters(student).toSingle(emptyList()) })
|
||||
}
|
||||
|
||||
fun getCurrentSemester(student: Student, forceRefresh: Boolean = false): Single<Semester> {
|
||||
return getSemesters(student, forceRefresh).map { item -> item.single { it.isCurrent } }
|
||||
return getSemesters(student, forceRefresh).map { it.getCurrentOrLast() }
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,9 @@ import io.github.wulkanowy.ui.base.BasePresenter
|
||||
import io.github.wulkanowy.ui.base.ErrorHandler
|
||||
import io.github.wulkanowy.utils.FirebaseAnalyticsHelper
|
||||
import io.github.wulkanowy.utils.SchedulersProvider
|
||||
import io.github.wulkanowy.utils.getCurrentOrLast
|
||||
import timber.log.Timber
|
||||
import java.util.concurrent.TimeUnit.MILLISECONDS
|
||||
import javax.inject.Inject
|
||||
|
||||
class GradePresenter @Inject constructor(
|
||||
@ -98,17 +100,16 @@ class GradePresenter @Inject constructor(
|
||||
private fun loadData() {
|
||||
Timber.i("Loading grade data started")
|
||||
disposable.add(studentRepository.getCurrentStudent()
|
||||
.flatMap { semesterRepository.getSemesters(it) }
|
||||
.flatMap { semesterRepository.getSemesters(it, refreshOnNoCurrent = true) }
|
||||
.delay(200, MILLISECONDS)
|
||||
.subscribeOn(schedulers.backgroundThread)
|
||||
.observeOn(schedulers.mainThread)
|
||||
.doFinally { view?.showProgress(false) }
|
||||
.subscribe({
|
||||
it.first { item -> item.isCurrent }.also { current ->
|
||||
selectedIndex = if (selectedIndex == 0) current.semesterName else selectedIndex
|
||||
schoolYear = current.schoolYear
|
||||
semesters = it.filter { semester -> semester.diaryId == current.diaryId }
|
||||
view?.setCurrentSemesterName(current.semesterName, schoolYear)
|
||||
}
|
||||
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 result: Attempt load index $currentPageIndex")
|
||||
@ -125,6 +126,7 @@ class GradePresenter @Inject constructor(
|
||||
private fun showErrorViewOnError(message: String, error: Throwable) {
|
||||
lastError = error
|
||||
view?.run {
|
||||
showProgress(false)
|
||||
showErrorView(true)
|
||||
setErrorDetails(message)
|
||||
}
|
||||
|
@ -0,0 +1,19 @@
|
||||
package io.github.wulkanowy.utils
|
||||
|
||||
import io.github.wulkanowy.data.db.entities.Semester
|
||||
import org.threeten.bp.LocalDate.now
|
||||
|
||||
inline val Semester.isCurrent: Boolean
|
||||
get() = now() in start..end
|
||||
|
||||
fun List<Semester>.getCurrentOrLast(): Semester {
|
||||
if (isEmpty()) throw RuntimeException("Empty semester list")
|
||||
|
||||
// when there is only one current semester
|
||||
singleOrNull { it.isCurrent }?.let { return it }
|
||||
|
||||
// when there is more than one current semester - find one with higher id
|
||||
singleOrNull { semester -> semester.semesterId == maxBy { it.semesterId }?.semesterId }?.let { return it }
|
||||
|
||||
throw IllegalArgumentException("Duplicated last semester! Semesters: ${joinToString(separator = "\n")}")
|
||||
}
|
@ -1,42 +1,30 @@
|
||||
package io.github.wulkanowy.utils
|
||||
|
||||
import org.threeten.bp.DateTimeUtils
|
||||
import org.threeten.bp.DayOfWeek.FRIDAY
|
||||
import org.threeten.bp.DayOfWeek.MONDAY
|
||||
import org.threeten.bp.DayOfWeek.SATURDAY
|
||||
import org.threeten.bp.DayOfWeek.SUNDAY
|
||||
import org.threeten.bp.Instant
|
||||
import org.threeten.bp.Instant.ofEpochMilli
|
||||
import org.threeten.bp.LocalDate
|
||||
import org.threeten.bp.LocalDateTime
|
||||
import org.threeten.bp.Month
|
||||
import org.threeten.bp.ZoneId
|
||||
import org.threeten.bp.format.DateTimeFormatter.ofPattern
|
||||
import org.threeten.bp.format.TextStyle.FULL_STANDALONE
|
||||
import org.threeten.bp.temporal.TemporalAdjusters.firstInMonth
|
||||
import org.threeten.bp.temporal.TemporalAdjusters.next
|
||||
import org.threeten.bp.temporal.TemporalAdjusters.previous
|
||||
import java.util.Date
|
||||
import java.util.Locale
|
||||
|
||||
private const val DATE_PATTERN = "dd.MM.yyyy"
|
||||
|
||||
fun Date.toLocalDate(): LocalDate = Instant.ofEpochMilli(time).atZone(ZoneId.systemDefault()).toLocalDate()
|
||||
|
||||
fun Date.toLocalDateTime(): LocalDateTime = ofEpochMilli(time).atZone(ZoneId.systemDefault()).toLocalDateTime()
|
||||
|
||||
fun String.toLocalDate(format: String = DATE_PATTERN): LocalDate = LocalDate.parse(this, ofPattern(format))
|
||||
|
||||
fun LocalDate.toFormattedString(format: String = DATE_PATTERN): String = format(ofPattern(format))
|
||||
|
||||
fun LocalDateTime.toFormattedString(format: String = DATE_PATTERN): String = format(ofPattern(format))
|
||||
|
||||
fun LocalDateTime.toDate(): Date = DateTimeUtils.toDate(atZone(ZoneId.systemDefault()).toInstant())
|
||||
|
||||
/**
|
||||
* https://github.com/ThreeTen/threetenbp/issues/55
|
||||
*/
|
||||
|
||||
fun Month.getFormattedName(): String {
|
||||
return getDisplayName(FULL_STANDALONE, Locale.getDefault())
|
||||
.let {
|
||||
@ -93,9 +81,6 @@ inline val LocalDate.previousOrSameSchoolDay: LocalDate
|
||||
inline val LocalDate.weekDayName: String
|
||||
get() = format(ofPattern("EEEE", Locale.getDefault()))
|
||||
|
||||
inline val LocalDate.shortcutWeekDayName: String
|
||||
get() = format(ofPattern("EEE", Locale.getDefault()))
|
||||
|
||||
inline val LocalDate.monday: LocalDate
|
||||
get() = with(MONDAY)
|
||||
|
||||
@ -105,7 +90,6 @@ inline val LocalDate.friday: LocalDate
|
||||
/**
|
||||
* [Dz.U. 2016 poz. 1335](http://prawo.sejm.gov.pl/isap.nsf/DocDetails.xsp?id=WDU20160001335)
|
||||
*/
|
||||
|
||||
inline val LocalDate.isHolidays: Boolean
|
||||
get() = isBefore(firstSchoolDay) && isAfter(lastSchoolDay)
|
||||
|
||||
@ -121,7 +105,6 @@ inline val LocalDate.lastSchoolDay: LocalDate
|
||||
get() = LocalDate.of(year, 6, 20)
|
||||
.with(next(FRIDAY))
|
||||
|
||||
|
||||
private fun Int.getSchoolYearByMonth(monthValue: Int): Int {
|
||||
return when (monthValue) {
|
||||
in 9..12 -> this
|
||||
|
Reference in New Issue
Block a user